/***************************************************************************
 *   Copyright (C) 2005 by Armando Navarro Vazquez   *
 *   qoajnv@usc.es   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <iostream>

#include <kurl.h>
#include <kapplication.h>
#include <kdebug.h>

#include <QPrinter>
#include <q3picture.h>
#include <qpixmap.h>
#include <qpainter.h>
#include <q3paintdevicemetrics.h>
#include <q3popupmenu.h>
#include <qcursor.h>
#include <qimage.h>
//Added by qt3to4:
#include <QResizeEvent>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QRubberBand>
#include <kmessagebox.h>
#include <qwt_scale_draw.h>
#include <qwt_scale_engine.h>
#include "spectralwidget.h"
#include "nmrfile.h"
#include "parsers.h"
#include "qrecttracker.h"
#include "qlinetracker.h"
#include "spectrum.h"
#include "peakpicker.h"
#include "integrator.h"
#include "nmrspectrum.h"
#include "kzerofilldialog.h"


const float spectrumbaselinepos=0.8;
const int scalecoarse=10;
const int scalefine=10;

SpectralWidget::SpectralWidget ( QWidget* parent, const char* name ) : QWidget ( parent, name )
{
  //this is necessary to avoid flickering when resizing
  //setWFlags ( Qt::WNoAutoErase );
  m_scale= new QwtScaleDraw();
  m_scaleengine = new QwtLinearScaleEngine();
  m_scalepalette = new QPalette();
  m_scalepalette->setColor ( QColorGroup::Text, QColor ( 255,255,255 ) );
  m_scalepalette->setColor ( QColorGroup::Foreground, QColor ( 255,255,255 ) );

  m_mouseaction=NONE;
  m_recttracker= new QRubberBand ( QRubberBand::Rectangle,this );
  m_linetracker= new QRubberBand ( QRubberBand::Line, this );
  m_spectrum=NULL;
  m_integrator=NULL;
  m_lgrabbed=false;
  m_bshowpeaks=true;
  InitMenus();
  m_peakpicker=new PeakPicker();

}


void SpectralWidget::InitMenus()
{
  m_fidmenu = new Q3PopupMenu ( this );
  m_spectrummenu= new Q3PopupMenu ( this );
  m_peakpickingmenu = new Q3PopupMenu ( this );
  m_fidmenu->insertItem ( "FT",this,SLOT ( OnFT() ),0,0 );
  m_fidmenu->insertItem ( "Zero Filling",this,SLOT ( OnZeroFillDialog() ),0,1 );
  //m_fidmenu->insertItem("WLT",this,SLOT(OnWLT()),0,1);
  // m_fidmenu->insertItem("RemoveSolvent",this,SLOT(OnRemoveSolvent()),0,2);
  m_spectrummenu->insertItem ( "Show Peaks",this,SLOT ( OnShowPeaks() ),0,0 );
  //m_spectrummenu->insertItem("CorrectBaseline",this,SLOT(OnCorrectBaseline()),0,1);
  m_spectrummenu->setItemChecked ( 0,m_bshowpeaks );
  m_peakpickingmenu->insertItem ( "Clear All",this,SLOT ( OnClearPeaks() ),0,0 );
}


SpectralWidget::~SpectralWidget()
{
  delete m_integrator;
  delete m_spectrum;
}

void SpectralWidget::paintEvent ( QPaintEvent* e )
{

  if ( !m_spectrum ) return;
  QRect myrect=this->rect();
  //double buffering stuff
  QPixmap pix ( myrect.size() );
  QPainter* p=new QPainter ( &pix );
  Draw ( p,myrect );
  p->end();
  p->begin ( this );
  p->drawPixmap ( myrect.topLeft(), pix );

}

void SpectralWidget::Draw ( QPainter* p,const QRect& rect, bool bprint/*=false*/ )
{
  //clear the background
  if ( !m_spectrum ) return;
  p->save();
  if ( !bprint )
    p->fillRect ( rect,Qt::black );

  if ( bprint )
    p->setPen ( Qt::black );
  else
    p->setPen ( Qt::green );
  m_spectrum->Draw ( p,rect );
  if ( bprint )
    p->setPen ( Qt::black );
  else
    p->setPen ( Qt::white );
  if ( this->size().width() > 50 ) m_scale->draw ( p,m_scalepalette->active() );
  if ( m_mouseaction == PHASE && !bprint )
    DrawPivot ( p );
  if ( m_bshowpeaks || m_mouseaction==PEAKPICKING )
    m_peakpicker->Draw ( p,this->rect() );
  if ( /*m_bshowintegrals ||*/ m_mouseaction==INTEGRAL )
    m_integrator->Draw ( p,this->rect() );
  p->restore();
}

void SpectralWidget::resizeEvent ( QResizeEvent* e )
{
  UpdateDrawingRect ( this->rect() );
}

void SpectralWidget::UpdateDrawingRect ( const QRect& rect,bool autoscale/*=false*/ )
{
  if ( !m_spectrum ) return;
  m_spectrum->UpdateDrawing ( rect,autoscale );
//  const_cast<QwtScaleDraw*> ( m_scale->scaleDraw() )->setGeometry ( rect.left(),rect.top() +rect.height() *0.9,rect.width(),QwtScaleDraw::Bottom );
  m_scale->move ( QPoint ( rect.left(),rect.top() +rect.height() *0.9 ) );
  m_scale->setLength ( rect.width() );

  if ( /*m_bshowintegrals ||*/ m_mouseaction==INTEGRAL )
    m_integrator->UpdateDrawing ( rect );
}

void SpectralWidget::OpenFile ( QString file )
{
  m_mouseaction=NONE;
  kDebug() << "Opening file:" << file << endl;
  QString s=file;
  NMRFile::NMRFileType stype;
  try
  {
    stype=NMRFile::GetFileType ( file );
  }
  catch ( ... )
  {
    KMessageBox::error ( 0,"Sorry, error ascertaining file type" );
    return;
  }
  switch ( stype )
  {
    case NMRFile::BrukerFID:
    case NMRFile::BrukerSpectrum:
      m_parser=new BrukerParser ( s );
      std::cout << "Bruker Spectrum" << std::endl;
      break;
    case NMRFile::VarianFID:
      m_parser=new VarianParser ( s );
      std::cout << "Varian Spectrum" << std::endl;
      break;
    case NMRFile::JCAMPDX:
      m_parser=new JCAMPDXParser ( s );
      std::cout << "JCAMP-DX" << std::endl;
      break;
    case NMRFile::None:
    default:
      std::cout << "null spectrum" << std::endl;
      m_parser=NULL;
  }

  if ( !m_parser ) return;

  try
  {
    m_spectrum=m_parser->ParseFile();
  }
  catch ( ... )
  {
    KMessageBox::error ( 0,"Sorry, internal error parsing file" );
    return;
  }

  if ( !m_spectrum ) return;
  /* switch(m_spectrum->Type())
   {
   case Spectrum::FID:
     m_spectrum->SetBaseLine(0.5);
     break;
   case Spectrum::SPECTRUM:
   case Spectrum::IRSPECTRUM:
     m_spectrum->SetBaseLine(spectrumbaselinepos);
     break;
   }*/

  //Setup pickpicker
  m_peakpicker->SetSpectrum ( m_spectrum );
  m_integrator = new Integrator ( m_spectrum );
  m_spectrum->ResetZoom();

  //setup the scale
  float left,right;

  m_spectrum->GetLimits ( left,right );
  //const_cast<QwtScaleDraw*> ( m_scale->scaleDraw() )->setScale ( left,right,scalecoarse,scalefine );
  m_scale->setScaleDiv(m_scaleengine->divideScale(left,right,scalecoarse,scalefine,0.0));

  //At the beginning does not call resizeEvent so we must setup scale geometry
// const_cast<QwtScaleDraw*>(m_scale->scaleDraw())->setGeometry(this->rect().left(),this->rect().top()+this->rect().height()*0.9,this->rect().width(),QwtScaleDraw::Bottom);
  //m_scale->setTitle("fdafasdfasfasfd");

//  m_spectrum->UpdateDrawing(this->rect(),true);
  UpdateDrawingRect ( this->rect(), true );
  update();
  //m_visualmode=eNORMAL;
  //SetCursor();
}

void SpectralWidget::OnPrint()
{
  QPrinter printer ( QPrinter::HighResolution );//=new

  printer.setOrientation ( QPrinter::Landscape );
  //pP->setResolution(150);
  if ( printer.setup ( kapp->mainWidget() ) )
  {
    QPainter p ( &printer );// QPainter(k);     dont create with new, (any printing)
    QRect myrect;
    Q3PaintDeviceMetrics Metric=Q3PaintDeviceMetrics ( &printer );
    myrect.setRect ( 0,0,Metric.width(),Metric.height() );
    UpdateDrawingRect ( myrect,true );

    Draw ( &p,myrect,true );
    UpdateDrawingRect ( this->rect() );
  }
}

void SpectralWidget::OnExport ( const QString& file )
{

  Q3Picture p;
  QRect rect ( 0,0,m_spectrum->Data().size(),m_spectrum->Data().size() /2 );

  QPainter painter;
  painter.begin ( &p );
  m_spectrum->DrawVector ( &painter,rect );
  //const_cast<QwtScaleDraw*> ( m_scale->scaleDraw() )->setGeometry ( rect.left(),rect.top() +rect.height() *0.9,rect.width(),QwtScaleDraw::Bottom );
  m_scale->move ( QPoint ( rect.left(),rect.top() +rect.height() *0.9 ) );
  m_scale->setLength ( rect.width() );
  m_scale->draw( &painter,m_scalepalette->active() );
  painter.end();

 // const_cast<QwtScaleDraw*> ( m_scale->scaleDraw() )->setGeometry ( this->rect().left(),this->rect().top() +this->rect().height() *0.9,this->rect().width(),QwtScaleDraw::Bottom );
  m_scale->move ( QPoint ( this->rect().left(),this->rect().top() +this->rect().height() *0.9 ) );
  m_scale->setLength ( this->rect().width() );
  p.setBoundingRect ( QRect ( 0,0,400,200 ) );
  p.save ( file,"SVG" );
}

void SpectralWidget::mousePressEvent ( QMouseEvent* e )
{
  switch ( e->button() )
  {
    case Qt::LeftButton:
      switch ( m_mouseaction )
      {
        case ZOOM:
        case PEAKPICKING:
          m_recttracker->move ( e->pos() );
          m_recttracker->show();
          m_lgrabbed=true;
          break;
        case INFO:
          m_linetracker->move ( e->pos() );
          m_linetracker->show();
          emit info ( m_spectrum->Info ( this->rect(),e->pos() ) );
          m_lgrabbed=true;
          break;
        case PHASE:
          m_lgrabbed=true;
          break;
        case INTEGRAL:
          m_recttracker->move( e->pos() );
          m_recttracker->show();
          m_lgrabbed=true;
          break;
        default:
          break;
      }
      break;
    case Qt::RightButton:
      switch ( m_mouseaction )
      {

        case PHASE:
          m_rgrabbed=true;
          break;
        case PEAKPICKING:
          m_peakpickingmenu->exec ( QCursor::pos() );
          break;
        default:
          if ( NMRSpectrum* sp=dynamic_cast<NMRSpectrum*> ( m_spectrum ) )
          {
            switch ( sp->DataType() )
            {
              case NMRSpectrum::FID:
                m_fidmenu->exec ( QCursor::pos() );
                break;
              case NMRSpectrum::SPECTRUM:
                m_spectrummenu->exec ( QCursor::pos() );
                break;
              default:
                break;
            }
          }
      }
      break;
    default:
      break;
  }

  m_lastpoint=e->pos();

}

void SpectralWidget::mouseMoveEvent ( QMouseEvent* e )
{

  switch ( m_mouseaction )
  {
    case ZOOM:
    case PEAKPICKING:
      if ( m_lgrabbed )
        {
        int width=e->pos().x()-m_recttracker->rect().left();
        int height=e->pos().y()-m_recttracker->rect().top();
        m_recttracker->resize(width,height);
        }
      break;
    case INFO:
      if ( m_lgrabbed )
      {
        m_linetracker->move ( e->pos() );
        emit info ( m_spectrum->Info ( this->rect(),e->pos() ) );

      }
      break;
    case INTEGRAL:
      if ( m_lgrabbed )
      {
        int width=e->pos().x()-m_recttracker->rect().left();
        int height=e->pos().y()-m_recttracker->rect().top();
        m_recttracker->resize(width,height);
      }
      break;
    case PHASE:
      if ( m_lastpoint != e->pos() && m_lgrabbed )
      {
        int displacement=e->pos().y()-m_lastpoint.y();
        if ( displacement != 0 )
        {
          m_spectrum->ZerothOrderPhase ( displacement/360. );
          m_spectrum->UpdateDrawing ( this->rect() );
          update();
        }
      }
      if ( m_lastpoint != e->pos() && m_rgrabbed )
      {

        int displacement=e->pos().y()-m_lastpoint.y();
        if ( displacement != 0 )
        {
          m_spectrum->FirstOrderPhase ( displacement/360.0 );
          m_spectrum->UpdateDrawing ( this->rect() );
          update();
        }
      }
      break;
    case REFERENCE:
      if ( m_lgrabbed )
      {
        m_linetracker->move ( e->pos() );
        if ( m_peakpicker->HasPeakAt ( e->pos(),this->rect() ) )
        {
          //Do stuff
        }
      }
      break;
    default:
      break;
  }

  m_lastpoint=e->pos();
}

void SpectralWidget::mouseReleaseEvent ( QMouseEvent* e )
{
  switch ( e->button() )
  {
    case Qt::LeftButton:
    {
      switch ( m_mouseaction )
      {
        case ZOOM:
        {
          QRect rct=m_recttracker->rect();
          m_recttracker->hide();
          if ( rct.width() >6 )
          {
            float offsetl=fabs ( static_cast<float> ( rct.left()-this->rect().left() ) /this->rect().width() ) ;
            float offsetr=fabs ( static_cast<float> ( rct.right()-this->rect().left() ) /this->rect().width() );
            m_spectrum->SetZoom ( offsetl, offsetr );
            OnFullUpdate();
          }
        }
        m_lgrabbed=false;
        break;
        case PEAKPICKING:
        {
          QRect rct=m_recttracker->rect();
          m_recttracker->hide();
          if ( rct.width() >6 )
          {
            m_peakpicker->Calculate ( rct,this->rect() );
            update();
          }
        }
        m_lgrabbed=false;
        break;
        case INTEGRAL:
        {
          QRect rct=m_recttracker->rect();
          m_recttracker->hide();
          if ( rct.width() > 6 )
          {
            m_integrator->AddIntegral ( rct,this->rect() );
            m_integrator->UpdateDrawing ( this->rect() );
            update();
          }
        }
        m_lgrabbed=false;
        break;
        case INFO:
          if ( m_lgrabbed )
          {
            m_lgrabbed=false;
            m_linetracker->hide();
            update();
          }
          break;
        case PHASE:
          if ( m_lgrabbed )
            m_lgrabbed=false;
          break;
        case REFERENCE:
          if ( m_lgrabbed )
          {
            m_lgrabbed=false;
            m_recttracker->hide();
            update();
          }
          break;
        default:
          m_lgrabbed=false;
          break;
      }
    }
    break;
    case Qt::RightButton:
      m_rgrabbed=false;
      break;
    default:
      break;
  }
}

void SpectralWidget::OnZoom ( bool b )
{
  b? m_mouseaction=ZOOM : m_mouseaction=NONE;
  SetCursor();
}

void SpectralWidget::OnPhase ( bool b )
{
  if ( b )
  {
    m_mouseaction=PHASE;
    m_spectrum->SetPivot();
    update();
  }
  else
  {
    m_mouseaction=NONE;
    update();
  }

  SetCursor();
}

void SpectralWidget::OnIntegral ( bool b )
{
  b  ? m_mouseaction=INTEGRAL : m_mouseaction=NONE;
  SetCursor();
  update();
}

void SpectralWidget::OnPeakPicking ( bool b )
{
  b? m_mouseaction=PEAKPICKING : m_mouseaction=NONE;
  SetCursor();
  update();
}

void SpectralWidget::OnInfo ( bool b )
{
  b? m_mouseaction=INFO : m_mouseaction=NONE;
  SetCursor();
}

void SpectralWidget::OnFull()
{
  m_spectrum->ResetZoom();
  OnFullUpdate();

}

void SpectralWidget::SetCursor()
{}

const float movebaseline=0.04;
void SpectralWidget::OnUp()
{
  m_spectrum->SetBaseLine ( m_spectrum->Baseline()-movebaseline );
  m_spectrum->UpdateDrawing ( this->rect() );
  update();
}

void SpectralWidget::OnDown()
{
  m_spectrum->SetBaseLine ( m_spectrum->Baseline() +movebaseline );
  m_spectrum->UpdateDrawing ( this->rect() );
  update();
}

const float movezoom=0.02;
void SpectralWidget::OnLeft()
{
  m_spectrum->MoveZoom ( -movezoom );
  m_spectrum->UpdateDrawing ( this->rect() );
  float left,right;
  m_spectrum->GetLimits ( left,right );
  m_scale->setScaleDiv(m_scaleengine->divideScale(left,right,scalecoarse,scalefine,0.0));
  update();
}

void SpectralWidget::OnRight()
{
  m_spectrum->MoveZoom ( movezoom );
  m_spectrum->UpdateDrawing ( this->rect() );
  float left,right;
  m_spectrum->GetLimits ( left,right );
  m_scale->setScaleDiv(m_scaleengine->divideScale(left,right,scalecoarse,scalefine,0.0));
  update();
}

const float scalefactor=1.25;
void SpectralWidget::OnPlus()
{
  m_spectrum->SetScale ( m_spectrum->Scale() *scalefactor );
  m_spectrum->UpdateDrawing ( this->rect() );
  update();
}

void SpectralWidget::OnFullUpdate()
{
   m_spectrum->UpdateDrawing ( this->rect() );
  float left,right;
  m_spectrum->GetLimits ( left,right );
  m_scale->setScaleDiv(m_scaleengine->divideScale(left,right,scalecoarse,scalefine,0.0));
  m_integrator->UpdateDrawing(this->rect() );
  update();
}

void SpectralWidget::OnMinus()
{
  m_spectrum->SetScale ( m_spectrum->Scale() /scalefactor );
  m_spectrum->UpdateDrawing ( this->rect() );
  update();
}

// void SpectralWidget::OnWLT()
// {
//   NMRSpectrum* spec=dynamic_cast<NMRSpectrum*>(m_spectrum);
//   if(!spec) return;
//   fidarray& data=spec->Data();
//   spec->ZeroFilling();
//   if( data.empty() ) return;
//   data.wlt(1,12);
//   spec->UpdateDrawing(this->rect(),true);
//   update();
// }

// void SpectralWidget::OnRemoveSolvent()
// {
//   NMRSpectrum* spec=dynamic_cast<NMRSpectrum*>(m_spectrum);
//   if(!spec) return;
//   fidarray& data=spec->Data();
//   spec->ZeroFilling();
//  //  data.quadrature();
//   //Get the maximum
//   fidarray mf=spec->Data();
//   short direction;
//  // mf.quadrature();
//   mf.fft(1);
//   mf.magnitude();
//   float max=0;
//   int k=0;
//   //mf.fft(1);
//   for(size_t i=0;i<mf.size();++i)
//   {
//      if ( mf[i].re > max )
//      {
//        max=mf[i].re;
//        k=i;
//      }
//   }
//   int diff=k;
//   mf=spec->Data();
//  // mf.quadrature();
//  mf.fft(1);
//  mf.cshift(-diff);
//  // mf.quadrature();
//   mf.fft(-1);
//   mf.wlt(1,12);
//   for(size_t i=0;i<1024;++i)
//      mf[i]=0;
//   mf.wlt(-1,12);
//
//   spec->Data()=mf;
//   spec->UpdateDrawing(this->rect(),true);
//   update();
//
//
// }

// void SpectralWidget::OnCorrectBaseline()
// {
//    NMRSpectrum* spec=dynamic_cast<NMRSpectrum*>(m_spectrum);
//   fidarray mf=spec->Data();
//   mf.wlt(1,12);
//   for(size_t i=0;i<64;++i)
//   {
//     mf[i]=0;
//   }
//   mf.wlt(-1,12);
//   spec->Data()=mf;
//   spec->UpdateDrawing(this->rect(),true);
//   update();
//
// }
void SpectralWidget::OnFT()
{
  NMRSpectrum* spec=dynamic_cast<NMRSpectrum*> ( m_spectrum );
  if ( !spec ) return;
  fidarray& data=spec->Data();
  if ( data.empty() ) return;


  // m_config->setGroup("Process");

  //First do quadrature operation
  data.quadrature();
  ////Go for a power of two
  spec->ZeroFilling();

  //This is due to the
  data[0]*=0.5;

  short direction;
  switch ( spec->Vendor() )
  {
    case NMRSpectrum::VARIAN:
      direction=-1;
      break;
    default:
      direction=1;
  }

  if ( !spec->IsSequential() )  //complex normal spectra
  {

    data.fft ( direction );
  }
  else     //sequential bruker spectra
  {
    fidarray f ( data );
    spec->ZeroFilling ( data.size() *2 );

    for ( size_t i=0;i<f.size();i++ )
    {
      data[2*i].real()=f[i].real();
      data[2*i+1].real()=f[i].imag();
      data[2*i].imag()=0.0f;
      data[2*i+1].imag()=0.0f;
    }
    data.fft ( direction );
    spec->ZeroFilling ( f.size() );
  }
  data.normalize();


  //Reset the phase
  /* m_fid.m_phase.z0=0;
   m_fid.m_phase.z1=0;*/

  /*  //Do automatic phase
    if( m_config->readBoolEntry("AutoPhase",defaults::autophase) )    //modify this in order to avoid disk reading
      m_fid.DoPAMPAS();

    m_bftied=true;
    emit ftied(true);*/
  spec->SetDataType ( NMRSpectrum::SPECTRUM );
  spec->UpdateDrawing ( this->rect(),true );


  float left,right;
  spec->GetLimits ( left,right );
  m_scale->setScaleDiv(m_scaleengine->divideScale(left,right,scalecoarse,scalefine,0.0));

  emit ft ( true );
  update();

}

void SpectralWidget::DrawPivot ( QPainter* p )
{

  p->save();
  p->setPen ( QColor ( 255,255,255 ) );
 
  QPoint pos=m_spectrum->PosOnWidget ( m_spectrum->Pivot(),this->rect() );
  QPoint point[2];
  point[0]=QPoint(pos.x(),rect().top());
  point[1]=QPoint(pos.x(),rect().bottom());
  p->drawPoints(point,2);
  p->restore();
}

void SpectralWidget::OnClearPeaks()
{
  m_peakpicker->Clear();
  update();
}

void SpectralWidget::OnShowPeaks()
{
  m_bshowpeaks=!m_bshowpeaks;
  m_spectrummenu->setItemChecked ( 0,m_bshowpeaks );
  update();
}

void SpectralWidget::OnZeroFillDialog()
{
  NMRSpectrum* spec=dynamic_cast<NMRSpectrum*> ( m_spectrum );
  if ( !spec ) return;
  KZeroFillDialog* k= new KZeroFillDialog ( spec->Data().size() );
  connect ( k,SIGNAL ( npoints ( int ) ),this,SLOT ( OnZeroFill ( int ) ) );
  k->exec();
}

void SpectralWidget::OnZeroFill ( int n )
{
  NMRSpectrum* spec=dynamic_cast<NMRSpectrum*> ( m_spectrum );
  if ( !spec ) return;
  spec->ZeroFilling ( n );
  spec->UpdateDrawing ( this->rect() );
  float left,right;
  m_spectrum->GetLimits ( left,right );
  m_scale->setScaleDiv(m_scaleengine->divideScale(left,right,scalecoarse,scalefine,0.0));
  update();
}


void SpectralWidget::GetImage ( QImage& img, int width, int height )
{
  QRect rect;
  rect.setWidth ( width );
  rect.setHeight ( height );
  QPixmap pix ( rect.size() );
  //pix.convertFromImage(img);
  m_spectrum->UpdateDrawing ( rect,true );
  float left,right;
  m_spectrum->GetLimits ( left,right );
  m_scale->setScaleDiv(m_scaleengine->divideScale(left,right,scalecoarse,scalefine,0.0));
  QPainter p ( &pix );
  Draw ( &p,rect,false );
  //p.fillRect(rect,QBrush(QColor(255,0,0)));
  img = pix.convertToImage();
}

