Logo Search packages:      
Sourcecode: labplot version File versions

Worksheet.cc

// LabPlot : Worksheet.cc

#include <stdlib.h>
#include <iostream>
#include <math.h>

#include <qnamespace.h>
#include <qpushbutton.h>
#include <qstring.h>
#include <qtextcodec.h>
#include <qfiledialog.h>
#include <qpaintdevicemetrics.h>
#include <qcursor.h>
#include <qpicture.h>
#include <klocale.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kmessagebox.h>

#include "Worksheet.h"
#include "GraphListDialog.h"
#include "TitleDialog.h"
#include "LegendDialog.h"
#include "AxesDialog.h"
#include "ObjectDialog.h"
#include "PlotSettingsDialog.h"
#include "WorksheetDialog.h"
#include "Plot2DSimple.h"
#include "Plot2DSurface.h"
#include "Plot3D.h"
#include "PlotPie.h"
#include "PlotPolar.h"
#include "PlotTernary.h"
#include "PlotGRASS.h"
#include "PlotVTK.h"
#include "PlotQWT3D.h"
#include "PlotGL.h"

using namespace std;

//! main worksheet class. (WNoAutoErase needed for flicker free redrawing)
Worksheet::Worksheet(QWidget *p, MainWin *mw, const char *name)
#if QT_VERSION > 0x030102     // TODO : check this
      :QWidget(p,name,Qt::WNoAutoErase), mw(mw)
#else
      :QWidget(p,name), mw(mw)
#endif
{
      setCaption(i18n("Worksheet ")+QString::number(mw->NrWorksheets()+1));

      title = i18n("Worksheet");
#if QT_VERSION > 0x030007
      timestamp = QDateTime::currentDateTime(Qt::LocalTime);
#else
      timestamp = QDateTime::currentDateTime();
#endif
      timestamp_enabled = true;

      printer = new KPrinter;
      pixmap = new QPixmap(600,400);
      
      setMinimumSize(600,400);

      background=QColor(220,240,255);
      for(int i=0;i<NR_OBJECTS;i++)
            label[i] = new Label();

      
      X = width(); Y = height();
      New();

      setMouseTracking(TRUE);
      
      show();
}

QStringList Worksheet::Info() {
      QStringList s;

      s<<title;
      s<<timestamp.toString();
      s<<"API:"<<QString::number(api);
      s<<"NR_PLOTS:"<<QString::number(nr_plots);

      return s;
}

void Worksheet::closeEvent(QCloseEvent *e) {
      kdDebug()<<"Worksheet::closeEvent()"<<endl;
      e->accept();

      mw->deleteActiveSheet();
      mw->updateSheetList();
}

void Worksheet::New() {
      kdDebug()<<"Worksheet::New()"<<endl;

      for (int i=0;i<NR_PLOTS;i++)
            if(plot[i]) plot[i]=0;
      api=0;
      nr_plots=0;

      ax=ay=anumber=bx=by=lx=ly=tx=ty=tlx=tly=0;
      labelx=labely=linesx=linesy=lineex=lineey=rectx=recty=0;
      ellipsex=ellipsey=imagex=imagey=0;
      tmagx=tmagy=tmagx2=tmagy2=0;
      tpanx=tpany=0.0;
      object_index=0;
      tmp_object_index=0;
      moving_cornerF1 = moving_cornerF2 = false;
      moving_cornerB1 = moving_cornerB2 = false;
      moving_borderx1 = moving_borderx2 = false;
      moving_bordery1 = moving_bordery2 = false;
      moving_center = false;

      updatePixmap();
}

void Worksheet::deleteActivePlot() {
      kdDebug()<<"deleting active plot"<<endl;
//    kdDebug()<<"api  "<<api<<endl;
//    kdDebug()<<"nr_plots  "<<nr_plots<<endl;
      // reorder plots
      if (api<nr_plots-1)
            plot[api]=plot[nr_plots-1];

      // hack for qwt 3d plot
      if(plot[nr_plots-1]->Type() == PQWT3D)
            plot[nr_plots-1]->draw(0,0,0);
      
      plot[nr_plots-1]=0;
      nr_plots--;

      // change api
      api=0;

//    kdDebug()<<"NEW api  "<<api<<endl;
//    kdDebug()<<"NEW nr_plots  "<<nr_plots<<endl;
      
      updatePixmap();
}

void Worksheet::newPlot(PType type) {
      switch(type) {
      case P2D:
            plot[nr_plots] = new Plot2DSimple(this);break;
      case PSURFACE:
            plot[nr_plots] = new Plot2DSurface(this);break;
      case P3D:
            plot[nr_plots] = new Plot3D(this);break;
      case PPIE:
            plot[nr_plots] = new PlotPie(this);break;
      case PPOLAR:
            plot[nr_plots] = new PlotPolar(this);break;
      case PTERNARY:
            plot[nr_plots] = new PlotTernary(this);break;
      case PGRASS:
            plot[nr_plots] = new PlotGRASS(this);break;
      case PVTK:
            plot[nr_plots] = new PlotVTK(this);break;
      case PQWT3D:
            plot[nr_plots] = new PlotQWT3D(this);break;
      case PGL:
            PlotGL *plotgl = new PlotGL(this);
            plotgl->show();
            plot[nr_plots] = plotgl;
            break;
      }
      plot[nr_plots]->setType(type);

      api=nr_plots;
      nr_plots++;
      updatePixmap();
}

void Worksheet::resizeEvent( QResizeEvent *e) {
//    kdDebug()<<"Worksheet::resizeEvent()"<<endl;

      X = width(); Y = height();
      this->resize(e->size());
      updatePixmap();
} 

//! update off screen pixmap (double buffering)
void Worksheet::updatePixmap() {
      kdDebug()<<"Worksheet::updatePixmap()"<<endl;
      pixmap->resize(size());

      QPainter p(pixmap, this);
      Draw(&p,X,Y);

      if(mw->defining_maglens==2 && tmagx2>0 && tmagx2-tmagx>0) {
            p.setBrush(Qt::NoBrush);
            
            p.drawRect(tmagx,tmagy,tmagx2-tmagx,tmagy2-tmagy);
      }

      // draw plot numbers and rects
      for (unsigned int i=0;i<nr_plots;i++) {
            int x = (int)(plot[i]->Position().X()*X)+16*i;
            int y = (int)(plot[i]->Position().Y()*Y);
            p.drawRect(x+5,y+5,15,15);
            if (i==api)
                  p.fillRect(x+6,y+6,13,13,Qt::green);
            p.setFont(QFont("Adobe Times",8));
            p.drawText(x+5+4,y+17,QString::number(i));
      }
      
      update();
      mw->updateSheetList();  //needed when opening a project file
}

void Worksheet::paintEvent(QPaintEvent *event) {
//    kdDebug()<<"Worksheet::paintEvent()"<<endl;
      QMemArray<QRect> rects = event->region().rects();
      for (int i = 0; i < (int)rects.size(); ++i)
            bitBlt(this, rects[i].topLeft(), pixmap, rects[i]);
}

void Worksheet::mouseDoubleClickEvent(QMouseEvent *e) {
      kdDebug()<<"Worksheet::mouseDoubleClickEvent : plot = "<<api<<endl;
      
      // dont crash if moving over empty worksheet
      if (plot[api]==0)
            return;
      
      int x=e->x(), y=e->y();
      PType type = plot[api]->Type();
      Point pos = plot[api]->Position();
      Point size = plot[api]->Size();
      int xmin=(int)(X*(pos.X()+plot[api]->P1().X()*size.X()));
      int xmax=(int)(X*(pos.X()+plot[api]->P2().X()*size.X()));
      int ymin=(int)(Y*(pos.Y()+plot[api]->P1().Y()*size.Y()));
      int ymax=(int)(Y*(pos.Y()+plot[api]->P2().Y()*size.Y()));
      kdDebug()<<"xmin/xmax ymin/ymax = "<<xmin<<'/'<<xmax<<' '<<ymin<<'/'<<ymax<<endl;

      for (unsigned int i=0;i<nr_plots;i++) {
            int redrectx = (int)(plot[i]->Position().X()*X)+5+16*i;
            int redrecty = (int)(plot[i]->Position().Y()*Y)+5;
            if(x>redrectx && x <redrectx+15 && y>redrecty && y<redrecty+15) {
                  api=i;
                  (new PlotSettingsDialog(this,"PlotSettingsDialog"))->show();
                  return;
            }
      }

      if (type == P2D || type == PSURFACE || type == PGRASS || type == PVTK|| type == PPIE || 
            type == PPOLAR || type == PTERNARY) {
            if (plot[api]->Title()->inside(x,y,pos,size,X,Y)) {
                  (new TitleDialog(this,0))->show();
                  return;
            }
            if (plot[api]->insideLegend(x,y)) {
                  (new LegendDialog(this,0))->show();
                  return;
            }
            for (int i=0;i<NR_OBJECTS;i++) {
                  if (label[i]->inside(x,y,pos,size,X,Y)) {
                        (new ObjectDialog(this,0,1))->show();
                        return;
                  }
                  if (line[i].inside(x,y,X,Y)) {
                        (new ObjectDialog(this,0,0))->show();
                        return;
                  }
                  if (rect[i].inside(x,y,X,Y)) {
                        (new ObjectDialog(this,0,2))->show();
                        return;
                  }
                  if (ellipse[i].inside(x,y,X,Y)) {
                        (new ObjectDialog(this,0,3))->show();
                        return;
                  }
                  if (image[i].inside(x,y,X,Y)) {
                        (new ObjectDialog(this,0,4))->show();
                        return;
                  }
            }
            if (x>xmin && x<xmax && y>ymin && y<ymax) {
                  (new GraphListDialog(mw,0))->show();
                  return;
            }
            else {
                  // pie plot has no axes
                  if(type == PPOLAR || type == PTERNARY) {
                        (new AxesDialog(this,0,0))->show();
                        return;     
                  }
                  else if(type !=PPIE) {
                        if(plot[api]->inside(x/(double)X,y/(double)Y)) {
                              if(y>ymax) {
                                    (new AxesDialog(this,0,0))->show();
                                    return;
                              }
                              else if(x<xmin) {
                                    (new AxesDialog(this,0,1))->show();
                                    return;
                              }
                              else if(x>xmax) {
                                    (new AxesDialog(this,0,2))->show();
                                    return;
                              }
                              else if(y<ymin) {
                                    (new AxesDialog(this,0,3))->show();
                                    return;
                              }
                        }
                  }
                  
            }
            // default
            (new WorksheetDialog(this,0))->show();
      }
      else if (type == P3D) {
            int x1,x2,y1,y2;
            // d = (y1(x2-x3)+y2(x3-x1)+y3(x1-x2))/(y2-y1)
            x1=xmin; x2=(xmax+xmin)/2; y1=ymax; y2=(ymax+ymin)/2;
            int dy = (y1*(x2-x)+y2*(x-x1)+y*(x1-x2))/(y2-y1);
            x1=xmax; x2=(3*xmax-xmin)/2; y1=ymax; y2=(ymax+ymin)/2;
            int dy2 = (y1*(x2-x)+y2*(x-x1)+y*(x1-x2))/(y2-y1);
            x1=xmax; x2=(3*xmax-xmin)/2; y1=ymin; y2=ymin-(ymax-ymin)/2;
            int dy3 = (y1*(x2-x)+y2*(x-x1)+y*(x1-x2))/(y2-y1);
            x1=xmin; x2=(xmax+xmin)/2; y1=ymin; y2=ymin-(ymax-ymin)/2;
            int dy4 = (y1*(x2-x)+y2*(x-x1)+y*(x1-x2))/(y2-y1);

            if (plot[api]->insideLegend(x,y)) {
                  (new LegendDialog(this,0))->show();
            }
            else if (plot[api]->Title()->inside(x,y,pos,size,X,Y)) {
                  (new TitleDialog(this,0))->show();
            }
            else if (x>(xmax+xmin)/2 && x<(3*xmax-xmin)/2 && y>=(ymax+ymin)/2 && y<(ymax+ymin)/2+20)
                  (new AxesDialog(this,0,0))->show(); // x
            else if (x>xmin && x<xmax && y>=ymax && y<ymax+20)
                  (new AxesDialog(this,0,3))->show(); // x2
            else if (x>xmin && x<xmax && y>ymin-20 && y<=ymin)
                  (new AxesDialog(this,0,6))->show(); // x3
            else if (x>(xmax+xmin)/2 && x<(3*xmax-xmin)/2 && y>ymin-(ymax-ymin)/2-20 && y<=ymin-(ymax-ymin)/2)
                  (new AxesDialog(this,0,9))->show(); // x4
            else if (x>(xmin+xmax)/2-20 && x<=(xmin+xmax)/2 && y>ymin-(ymax-ymin)/2 && y<(ymax+ymin)/2)
                  (new AxesDialog(this,0,2))->show(); // z
            else if (x>xmin-20 && x<=xmin && y>ymin && y<ymax)
                  (new AxesDialog(this,0,5))->show(); // z2
            else if (x>=xmax && x<xmax+20 && y>ymin && y<ymax)
                  (new AxesDialog(this,0,8))->show(); // z3
            else if (x>=(3*xmax-xmin)/2 && x<(3*xmax-xmin)/2+20 && y>ymin-(ymax-ymin)/2 && y<(ymax+ymin)/2)
                  (new AxesDialog(this,0,11))->show();      // z4
            else if (dy<=0 && dy >-20 )
                  (new AxesDialog(this,0,1))->show(); // y
            else if (dy2<20 && dy2 >=0 )
                  (new AxesDialog(this,0,4))->show(); // y2
            else if (dy3<20 && dy3 >=0 )
                  (new AxesDialog(this,0,7))->show(); // y3
            else if (dy4<=0 && dy4 >-20 )
                  (new AxesDialog(this,0,10))->show();      // y4
            else {
                  if (plot[api]->inside(x,y))
                        (new GraphListDialog(mw,0))->show();
                  else
                        (new WorksheetDialog(this,0))->show();
            }
      }
}

void Worksheet::mousePressEvent(QMouseEvent *e) {
      kdDebug()<<"Worksheet::mousePressEvent"<<endl;
      int x=e->x(), y=e->y();
      PType type = P2D;
      int tmpapi=-1;

      // dont crash if clicking on empty worksheet
      if (plot[api]==0)
            return;

      Point pos = plot[api]->Position();
      Point size = plot[api]->Size();
      LRange *range = plot[api]->ActRanges();
      int xmin=(int)(X*(pos.X()+plot[api]->P1().X()*size.X()));
      int xmax=(int)(X*(pos.X()+plot[api]->P2().X()*size.X()));
      int ymin=(int)(Y*(pos.Y()+plot[api]->P1().Y()*size.Y()));
      int ymax=(int)(Y*(pos.Y()+plot[api]->P2().Y()*size.Y()));

      // if right mouse reset maglens
      if (e->button()==Qt::RightButton) {
            mw->defining_maglens=0;
            setCursor(Qt::ArrowCursor);
      }
            
      // magnifying lens
      if(mw->defining_maglens == 1) {
            tmagx=x; tmagy=y;
            mw->defining_maglens=2;
      }
      else if(mw->defining_maglens == 2) {            // set actrange of active plot to selected area
            double newx1 = range[0].rMin() + (tmagx-xmin)/(double)(xmax-xmin)*(range[0].rMax()-range[0].rMin());
            double newx2 = range[0].rMin() + (x-xmin)/(double)(xmax-xmin)*(range[0].rMax()-range[0].rMin());
            double newy1 = range[1].rMin() + (ymax-y)/(double)(ymax-ymin)*(range[1].rMax()-range[1].rMin());
            double newy2 = range[1].rMin() + (ymax-tmagy)/(double)(ymax-ymin)*(range[1].rMax()-range[1].rMin());
            
            kdDebug()<<"x1/x2 | y1/y2 = "<<newx1<<'/'<<newx2<<" | "<<newy1<<'/'<<newy2<<endl;
            
            plot[api]->setXRange(newx1,newx2);
            plot[api]->setYRange(newy1,newy2);
            // TODO : if 3D -> set ZRange (not good !)
                  
            mw->defining_maglens=0;
            tmagx=tmagx2=tmagy=tmagy2=0;
            setCursor(Qt::ArrowCursor);
            updatePixmap();
      }

      // pan zoom
      if(mw->defining_panzoom==1) {
            setCursor(QCursor(Qt::PointingHandCursor));
            tpanx = range[0].rMin()+(x-xmin)/(double)(xmax-xmin)*(range[0].rMax()-range[0].rMin()); 
            tpany = range[1].rMin()+(ymax-y)/(double)(ymax-ymin)*(range[1].rMax()-range[1].rMin()); 
            mw->defining_panzoom=2;
      }
      
      // if click inside plot rect set api
      for (unsigned int i=0;i<nr_plots;i++) {
            int redrectx = (int)(plot[i]->Position().X()*X)+5+16*i;
            int redrecty = (int)(plot[i]->Position().Y()*Y)+5;
            if(x>redrectx && x <redrectx+15 && y>redrecty && y<redrecty+15) {
                  tmpapi = i;
            }
      }
      // if click inside plot set api
      if(tmpapi==-1) {
            for (unsigned int i=0;i<nr_plots;i++) {
                  if (plot[i]->inside(x/(double)X,y/(double)Y))
                        tmpapi = i;
            }
            // overlayed plots : use api
            if (plot[api]->inside(x/(double)X,y/(double)Y))
                        tmpapi = api;
      }
      if(tmpapi!=-1)
            api=tmpapi;

      //kdDebug()<<"nr_plots = "<<nr_plots<<endl;
      //kdDebug()<<"API = "<<api<<endl;

      if (plot[api]!=0) {
            type = plot[api]->Type();

            if (plot[api]->insideF1Corner(x/(double)X,y/(double)Y))
                  moving_cornerF1 = true;
            if (plot[api]->insideF2Corner(x/(double)X,y/(double)Y))
                  moving_cornerF2 = true;
            if (plot[api]->insideB1Corner(x/(double)X,y/(double)Y))
                  moving_cornerB1 = true;
            if (plot[api]->insideB2Corner(x/(double)X,y/(double)Y))
                  moving_cornerB2 = true;
            else if (plot[api]->insideX1Border(x/(double)X,y/(double)Y))
                  moving_borderx1 = true;
            else if (plot[api]->insideX2Border(x/(double)X,y/(double)Y))
                  moving_borderx2 = true;
            else if (plot[api]->insideY1Border(x/(double)X,y/(double)Y))
                  moving_bordery1 = true;
            else if (plot[api]->insideY2Border(x/(double)X,y/(double)Y))
                  moving_bordery2 = true;
            else if (plot[api]->insideCenter(x/(double)X,y/(double)Y))
                  moving_center = true;
      }

      if(mw->defining_baseline == true) { // position
            kdDebug()<<"DEFINING BASELINE"<<endl;
            double yvalue=YCoordinate(y,ymin,ymax);
            plot[api]->setBaselineEnabled(true);
            plot[api]->setBaseline(yvalue);
            repaint();
            //mw->defining_baseline=false;
      }
      if(mw->defining_region == 1) {      // left position
            double xvalue=XCoordinate(x,xmin,xmax);
            plot[api]->setRegionMin(xvalue);
            mw->message(i18n("Define Region : click on right position"));
            mw->defining_region=2;
            return;
      }
      else if (mw->defining_region == 2) {      // right position
            double xvalue=XCoordinate(x,xmin,xmax);
            plot[api]->setRegionMax(xvalue);
            mw->defining_region=0;
            updatePixmap();
            return;
      }
      if(mw->defining_line == 1) {  // first position
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            while (line[tmp_object_index].startPoint().X() != line[tmp_object_index].endPoint().X())
                  tmp_object_index++;
            line[tmp_object_index].setStartPoint(xvalue,yvalue);
            mw->message(i18n("Define Line : click on second position"));
            mw->defining_line=2;
            return;
      }
      else if (mw->defining_line == 2) {  // second position
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            line[tmp_object_index].setEndPoint(xvalue,yvalue);
            mw->defining_line=0;
            tmp_object_index=0;
            updatePixmap();
            return;
      }
      if(mw->defining_label == true) {    // position
            kdDebug()<<"defining label ..";
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            kdDebug()<<"tmp_object_index="<<tmp_object_index<<endl;
            kdDebug()<<" label[]="<<label[tmp_object_index]->title()<<endl;
            while (label[tmp_object_index]->title().length() != 0)
                  tmp_object_index++;
            label[tmp_object_index]->setPosition(xvalue,yvalue);
            mw->defining_label=0;
            (new ObjectDialog(this,"ObjectDialog",1))->show();
            return;
      }

      if(mw->defining_rect == 1) {  // first position
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            while (rect[tmp_object_index].endPoint().X() != 0)
                  tmp_object_index++;
            rect[tmp_object_index].setStartPoint(xvalue,yvalue);
            mw->message(i18n("Define Rectangle : click on lower right corner"));
            mw->defining_rect=2;
            return;
      }
      else if (mw->defining_rect == 2) {  // second position
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            Point start = rect[tmp_object_index].startPoint();
            rect[tmp_object_index].setEndPoint(xvalue-start.X(),yvalue-start.Y());
            mw->defining_rect=0;
            tmp_object_index=0;
            updatePixmap();
            return;
      }
      if(mw->defining_ellipse == 1) {     // first position
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            while (ellipse[tmp_object_index].endPoint().X() != 0)
                  tmp_object_index++;
            ellipse[tmp_object_index].setStartPoint(xvalue,yvalue);
            mw->message(i18n("Define Ellipse : click on lower right corner"));
            mw->defining_ellipse=2;
            return;
      }
      else if (mw->defining_ellipse == 2) {     // second position
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            Point start = ellipse[tmp_object_index].startPoint();
            ellipse[tmp_object_index].setEndPoint(xvalue-start.X(),yvalue-start.Y());
            mw->defining_ellipse=0;
            tmp_object_index=0;
            updatePixmap();
            return;
      }
      if(mw->defining_image == true) {    // position
            double xvalue=x/(double)X;
            double yvalue=y/(double)Y;
            while (image[tmp_object_index].Pos().X() != 0)
                  tmp_object_index++;
            image[tmp_object_index].setPos(xvalue,yvalue);
            mw->defining_image=0;
            (new ObjectDialog(this,"ObjectDialog",4))->show();
            return;
      }

      double tmpx=0, tmpy=0;
      if (plot != 0) {
            tmpx = X*size.X();
            tmpy = Y*size.Y();
      }

      // if inside legend, take it
      if (plot[api] && plot[api]->insideLegend(x,y)) {
            lx = x - (int) (plot[api]->getLegend()->X()*tmpx);
            ly = y - (int) (plot[api]->getLegend()->Y()*tmpy);
      }

      // if inside title, take it
      Label *title = 0;
      if (plot[api]!=0)
            title = plot[api]->Title();

      if(title && title->inside(x,y,pos,size,X,Y)) {
            kdDebug()<<"inside TITLE"<<endl;
            tx = (int)(x - title->X()*tmpx);
            ty = (int)(y - title->Y()*tmpy);
            kdDebug()<<" TX/TY : "<<tx<<' '<<ty<<endl;
      }
      
      kdDebug()<<"after title/legend check"<<endl;

      for (int i=0;i<NR_OBJECTS;i++) {
            if(label[i]->inside(x,y,pos,size,X,Y)) {
                  labelx = (int)(x - label[i]->X()*X);
                  labely = (int)(y - label[i]->Y()*Y);
                  object_index=i;
            }
            else if(line[i].inside(x,y,X,Y)) {
                  linesx = (int)(x - line[i].startPoint().X()*X);
                  linesy = (int)(y - line[i].startPoint().Y()*Y);
                  lineex = (int)(x - line[i].endPoint().X()*X);
                  lineey = (int)(y - line[i].endPoint().Y()*Y);
                  object_index=i;
            }
            else if(rect[i].inside(x,y,X,Y)) {
                  rectx = (int)(x - rect[i].startPoint().X()*X);
                  recty = (int)(y - rect[i].startPoint().Y()*Y);
//                object_index=i;
            }
            else if(ellipse[i].inside(x,y,X,Y)) {
                  ellipsex = (int)(x - ellipse[i].startPoint().X()*X);
                  ellipsey = (int)(y - ellipse[i].startPoint().Y()*Y);
                  object_index=i;
            }
            else if(image[i].inside(x,y,X,Y)) {
                  imagex = (int)(x - image[i].Pos().X()*X);
                  imagey = (int)(y - image[i].Pos().Y()*Y);
                  object_index=i;
            }
      }

      // if inside axis take the axes label
      if (type == P2D || type == PSURFACE) {
            for (int i=0;i<4;i++) {
                  Label *label = 0;
                  if(plot[api])
                        label = plot[api]->getAxis(i)->label();

                  if (i==0 || i==3) {     // x,x2
                        if (label && label->inside(x,y,pos,size,X,Y)) {
                              kdDebug()<<"INSIDE X/X2 AXIS"<<endl;
                              ax = (int)(x - label->X()*tmpx);
                              ay = (int)(y - label->Y()*tmpy);
                              anumber = i;
                        }
                  }
                  else {      // y,y2
                        if (label && label->insideY(x,y,pos,size,X,Y)) {
                              kdDebug()<<"INSIDE Y/Y2 AXIS"<<endl;
                              ax = (int)(x - label->X()*tmpx);
                              ay = (int)(y - label->Y()*tmpy);
                              anumber = i;
                        }
                  }
            }
      }
      else if (type == P3D) {
            kdDebug()<<"type = P3D"<<endl;
            for (int i=0;i<12;i++) {
                  Label *label = plot[api]->getAxis(i)->label();
                  bool inside=FALSE;

                  if (i==0 || i==3 || i==6 || i==9) {       // z,z2,z3,z4
                        if (label->inside(x,y,pos,size,X,Y))
                              inside =TRUE;
                  }
                  else if (i==1 || i==4 || i==7 || i==10)   {     // y,y2,y3,y4
                        if (label->insideZ(x,y,pos,size,X,Y))
                              inside =TRUE;
                  }
                  else {                                    // z,z2,z3,z4
                        if (label->insideY(x,y,pos,size,X,Y))
                              inside =TRUE;
                  }
                  if (inside) {
                        ax = (int)(x - label->X()*tmpx);
                        ay = (int)(y - label->Y()*tmpy);
                        anumber = i;
                  }
            }
      }

      // if near border of axes (+/- 10) take it
      kdDebug()<<" CHECK BORDER : x="<<x<<" / xmin="<<xmin<<endl;
      if (type == P2D || type == PSURFACE) {
            if (x>xmin-5 && x<xmin+5 && y>ymin && y<ymax) { // xmin
                  kdDebug()<<"NEAR XMIN"<<endl;
                  bx=x-xmin;
                  by=y-ymin;
                  anumber = 1;
            }
            else if (x>xmax-5 && x<xmax+5 && y>ymin && y<ymax) { // xmax
                  kdDebug()<<"NEAR XMAX"<<endl;
                  bx=x-xmax;
                  by=y-ymin;
                  anumber = 2;
            }
            else if (x>xmin && x<xmax && y>ymin-5 && y<ymin+5) { // ymin
                  kdDebug()<<"NEAR YMIN"<<endl;
                  bx=x-xmin;
                  by=y-ymin;
                  anumber = 3;
            }
            else if (x>xmin && x<xmax && y>ymax-5 && y<ymax+5) { // ymax
                  if (type == PSURFACE)   // why ?
                        bx=x-xmin;
                  else
                        bx=1; // must be != 0
                  by=y-ymax;
                  anumber = 0;
                  kdDebug()<<"NEAR YMAX bx/by = "<<bx<<' '<<by<<endl;
            }
      }
      else if (type == P3D) {
            if (x>xmin &&  x<xmax && y>=ymax && y<ymax+20) {
                  bx=x-xmin;
                  by=y-ymax;
                  anumber = 0;
            }
            if (x>xmin-20 &&  x<=xmin && y>ymin && y<ymax) {
                  bx=x-xmin;
                  by=y-ymax;
                  anumber = 1;
            }
      }
      updatePixmap();   // update api mark
      kdDebug()<<"Worksheet::mousePressEvent OK"<<endl;
}

void Worksheet::mouseMoveEvent(QMouseEvent *e) {
      int x=e->x(), y=e->y();
      PType type = P2D;
      int xmin, xmax, ymin, ymax;
      
      // dont crash if moving over empty worksheet
      if (plot[api]==0)
            return;

      Point pos = plot[api]->Position(), size = plot[api]->Size();
      type = plot[api]->Type();
      xmin=(int)(X*(pos.X()+plot[api]->P1().X()*size.X()));
      xmax=(int)(X*(pos.X()+plot[api]->P2().X()*size.X()));
      ymin=(int)(Y*(pos.Y()+plot[api]->P1().Y()*size.Y()));
      ymax=(int)(Y*(pos.Y()+plot[api]->P2().Y()*size.Y()));

      if(mw->defining_maglens==2) {
            tmagx2=x; tmagy2=y;
            updatePixmap();
      }
      else if (mw->defining_panzoom==2) { // constantly set new actual ranges
            LRange *range = plot[api]->ActRanges();
            kdDebug()<<"PAN ZOOM : tpanx/tpany = "<<tpanx<<' '<<tpany<<endl;
            double newx1 = tpanx - (x-xmin)/(double)(xmax-xmin)*(range[0].rMax()-range[0].rMin());
            double newx2 = newx1+(range[0].rMax()-range[0].rMin());
            double newy1 = tpany - (ymax-y)/(double)(ymax-ymin)*(range[1].rMax()-range[1].rMin());
            double newy2 = newy1+(range[1].rMax()-range[1].rMin());
            plot[api]->setXRange(newx1,newx2);
            plot[api]->setYRange(newy1,newy2);
            updatePixmap();
      }
            
      if (mw->defining_maglens>0 || mw->defining_panzoom>0) {
            // leave cursor as is
      }
      else if (plot[api]->insideF1Corner(x/(double)X,y/(double)Y) ||plot[api]->insideF2Corner(x/(double)X,y/(double)Y) )
            setCursor(QCursor(Qt::SizeFDiagCursor));
      else if (plot[api]->insideB1Corner(x/(double)X,y/(double)Y) || plot[api]->insideB2Corner(x/(double)X,y/(double)Y))
            setCursor(QCursor(Qt::SizeBDiagCursor));
      else if (plot[api]->insideX1Border(x/(double)X,y/(double)Y) || plot[api]->insideX2Border(x/(double)X,y/(double)Y))
            setCursor(QCursor(Qt::SizeVerCursor));
      else if (plot[api]->insideY1Border(x/(double)X,y/(double)Y) || plot[api]->insideY2Border(x/(double)X,y/(double)Y))
            setCursor(QCursor(Qt::SizeHorCursor));
      else if (plot[api]->insideCenter(x/(double)X,y/(double)Y))
            setCursor(QCursor(Qt::SizeAllCursor));
      else
            setCursor(Qt::ArrowCursor);

      if(moving_cornerF1) {
            plot[api]->setSize(pos.X()+size.X()-x/(double)X,pos.Y()+size.Y()-y/(double)Y);
            plot[api]->setPosition(x/(double)X,y/(double)Y);
            repaint();
      }
      else if(moving_cornerF2) {
            plot[api]->setSize(x/(double)X-pos.X(),y/(double)Y-pos.Y());
            repaint();
      }
      else if(moving_cornerB2) {
            plot[api]->setSize(x/(double)X-pos.X(),size.Y()+pos.Y()-y/(double)Y);
            plot[api]->setPosition(pos.X(),y/(double)Y);
            repaint();
      }
      else if(moving_cornerB1) {
            plot[api]->setSize(size.X()+pos.X()-x/(double)X,y/(double)Y-pos.Y());
            plot[api]->setPosition(x/(double)X,pos.Y());
            repaint();
      }
      else if (moving_borderx1) {
            plot[api]->setSize(size.X(),y/(double)Y-pos.Y());
            repaint();
      }
      else if (moving_borderx2) {
            plot[api]->setSize(size.X(),size.Y()+pos.Y()-y/(double)Y);
            plot[api]->setPosition(pos.X(),y/(double)Y);
            repaint();
      }
      else if (moving_bordery1) {
            plot[api]->setSize(pos.X()+size.X()-x/(double)X,size.Y());
            plot[api]->setPosition(x/(double)X,pos.Y());
            repaint();
      }
      else if (moving_bordery2) {
            plot[api]->setSize(x/(double)X-pos.X(),size.Y());
            repaint();
      }
      else if (moving_center) {
            plot[api]->setPosition(x/(double)X-size.X()/2.0,y/(double)Y-size.Y()/2.0);
            repaint();
      }

      if(mw->defining_region != 0)
            return;
      if(mw->defining_line != 0)
            return;
      if(mw->defining_label == true)
            return;
      if(mw->defining_rect != 0)
            return;
      if(mw->defining_ellipse != 0)
            return;
      if(mw->defining_image == true)
            return;

      if(mw->defining_baseline == true) { // position
            double yvalue=YCoordinate(y,ymin,ymax);
            plot[api]->setBaseline(yvalue);
            repaint();
            return;
      }
      
      double tmpx = X*plot[api]->Size().X();
      double tmpy = Y*plot[api]->Size().Y();

      if (lx > 0) {           // only if legend is dragged
            plot[api]->getLegend()->setPosition((x-lx)/tmpx,(y-ly)/tmpy);
            updatePixmap();
      }
      else if (tx > 0) {            // only if title is dragged
            Label *title = plot[api]->Title();
            title->setPosition((x-tx)/tmpx,(y-ty)/tmpy);
            updatePixmap();
      }
      else if (labelx > 0) {
            label[object_index]->setPosition((x-labelx)/(double)X,(y-labely)/(double)Y);
            updatePixmap();
      }
      else if (linesx > 0) {
            line[object_index].setEndPoint((x-lineex)/(double)X,(y-lineey)/(double)Y);
            line[object_index].setStartPoint((x-linesx)/(double)X,(y-linesy)/(double)Y);
            updatePixmap();
      }
      else if (rectx > 0) {
            rect[object_index].setStartPoint((x-rectx)/(double)X,(y-recty)/(double)Y);
            updatePixmap();
      }
      else if (ellipsex > 0) {
            ellipse[object_index].setStartPoint((x-ellipsex)/(double)X,(y-ellipsey)/(double)Y);
            updatePixmap();
      }
      else if (imagex > 0) {
            image[object_index].setPos((x-imagex)/(double)X,(y-imagey)/(double)Y);
            updatePixmap();
      }
      else if (ax!=0) {
            Label *label = plot[api]->getAxis(anumber)->label();
            label->setPosition((x-ax)/tmpx,(y-ay)/tmpy);
            updatePixmap();
      }
      else if (bx!=0) {
            if (type == P2D || type == PSURFACE) {
                  Label *label = plot[api]->getAxis(anumber)->label();
                  if (anumber==0) { // x
                        kdDebug()<<"MOVING X Axis"<<endl;
                        label->setPosition(label->X(),label->Y()+(y-ymax+by)/(double)Y);
                        plot[api]->setYMax(by+y,Y);
                  }
                  else if (anumber==1) {  // y
                        label->setPosition(label->X()+(x-xmin+bx)/(double)X,label->Y());
                        plot[api]->setXMin(bx+x,X);
                  }
                  else if (anumber==2) {  // y2
                        label->setPosition(label->X()+(x-xmax+bx)/(double)X,label->Y());
                        plot[api]->setXMax(bx+x,X);
                  }
                  else if (anumber==3) {  // x2
                        label->setPosition(label->X(),label->Y()+(y-ymin+by)/(double)Y);
                        plot[api]->setYMin(by+y,Y);
                  }
            }
            else if (type == P3D) {
                  if (anumber==0) { // x
                        Label *label = plot[api]->getAxis(3)->label();
                        label->setPosition(label->X(),label->Y()+(y-ymax+by)/(double)Y);
                        plot[api]->setYMax(by+y,Y);
                  }
                  if (anumber==1) { // z
                        Label *label = plot[api]->getAxis(5)->label();
                        label->setPosition(label->X()+(x-xmin+bx)/(double)X,label->Y());
                        plot[api]->setXMin(bx+x,X);
                  }
            }

            updatePixmap();
      }
      
      if (plot[api]->insidePlottingArea(x/(double)X,y/(double)Y)) {
            double xvalue=0, yvalue=0;
            // TODO : ternary & polar coordinates
            // TODO : format for coordinates ?
            if (type != PPIE && type != PTERNARY && type != PPOLAR) {
                  xvalue = XCoordinate(x,xmin,xmax);
                  yvalue=YCoordinate(y,ymin,ymax);
            }
            mw->message("( " + QString::number(xvalue) + " / " + QString::number(yvalue) + " )");
      }
      else if (mw->defining_maglens==1)
                  mw->message(i18n("magnify : click on first position"));
      else if (mw->defining_maglens==2)
                  mw->message(i18n("magnify : click on second position"));
      else
            mw->message("");
}

double Worksheet::XCoordinate(double x, double xmin, double xmax) {
      LRange* actrange = plot[api]->ActRanges();
      double xvalue=0;
      TScale xscale = plot[api]->getAxis(0)->Scale();
      double minx = actrange[0].rMin(), maxx = actrange[0].rMax();
            
      if (xscale == LINEAR)
            xvalue = minx+(maxx-minx)*(x-xmin)/(xmax-xmin);
      else if (xscale == LOG10)
            xvalue = pow(10,log10(minx)+(double)(x-xmin)/(xmax-xmin)*log10(maxx/minx));
      else if (xscale == LOG2)
            xvalue = pow(2,log2(minx)+(double)(x-xmin)/(xmax-xmin)*log2(maxx/minx));
      else if (xscale == LN)
            xvalue = pow(M_E,log(minx)+(double)(x-xmin)/(xmax-xmin)*log(maxx/minx));
      else if (xscale == SQRT)
            // TODO : check this
            //xvalue = pow(sqrt(minx)+(double)(x-xmin)/(xmax-xmin)*sqrt(maxx-minx),2);
            xvalue = minx+(double)(x-xmin)/(xmax-xmin)*(maxx-minx);

      return xvalue;
}

double Worksheet::YCoordinate(double y, double ymin, double ymax) {
      LRange* actrange = plot[api]->ActRanges();
      double yvalue=0;
      TScale yscale = plot[api]->getAxis(1)->Scale();
      double miny = actrange[1].rMin(), maxy = actrange[1].rMax();
      
      if (yscale == LINEAR)
            yvalue = miny+(maxy-miny)*(double)(y-ymax)/(ymin-ymax);
      else if (yscale == LOG10)
            yvalue = pow(10,log10(miny)+(double)(y-ymax)/(ymin-ymax)*log10(maxy/miny));
      else if (yscale == LOG2)
            yvalue = pow(2,log2(miny)+(double)(y-ymax)/(ymin-ymax)*log2(maxy/miny));
      else if (yscale == LN)
            yvalue = pow(M_E,log(miny)+(double)(y-ymax)/(ymin-ymax)*log(maxy/miny));
      else if (yscale == SQRT)
            // TODO : check this
            //yvalue = pow(sqrt(miny)+(double)(y-ymin)/(ymax-ymin)*sqrt(maxy-miny),2);
            yvalue = miny+(maxy-miny)*(double)(y-ymax)/(ymin-ymax);

      return yvalue;
}

void Worksheet::mouseReleaseEvent(QMouseEvent *e) {
      kdDebug()<<"Worksheet::mouseReleaseEvent()"<<endl;
      lx = ly = ax = ay = tx = ty = bx = by = 0;
      labelx=labely=linesx=linesy=lineex=lineey=rectx=recty=0;
      ellipsex=ellipsey=imagex=imagey=0;
      object_index=0;
      anumber = 0;
      moving_cornerF1 = moving_cornerF2 = false;
      moving_cornerB1 = moving_cornerB2 = false;
      moving_borderx1 = moving_borderx2 = false;
      moving_bordery1 = moving_bordery2 = false;
      moving_center=0;

      if (mw->defining_panzoom==2) {
            // TODO : release range 
            setCursor(Qt::ArrowCursor);
            mw->defining_panzoom=0;
            repaint();
      }
      
      mw->defining_baseline=false;
}

void Worksheet::Print(QString fn) {
      kdDebug()<<"Worksheet::Print()"<<endl;

      setupPrinter(printer,fn);
      
      if (fn == QString("out.ps"))
            printer->setup(this);

      QPainter p(printer);
      QPaintDeviceMetrics metrics( printer );

      int w = metrics.width();
      int h = metrics.height();
      kdDebug()<<"Metrics = "<<w<<' '<<h<<endl;

      if(plot[api]->Type() == PQWT3D) {
            kdDebug()<<"printing Qwt3D plot"<<endl;
            ((PlotQWT3D*) plot[api])->Export(printer->outputFileName(),"PS",w,h);
            plot[api]->draw(0,X,Y);       // update QWT3D plot

      }
      else 
            Draw(&p,w,h);
}

void Worksheet::ExportSVG(QString filename) {
      if(filename.length()<1)
            filename = QFileDialog::getSaveFileName(i18n("out.svg"),QString("*.svg"),this);
      
      // check if svg file exists
      if ( QFile::exists(filename) ) {
            int answer = KMessageBox::warningYesNoCancel( this, 
                  i18n( "Overwrite\n\'%1\'?" ).arg( filename ), i18n("Export to SVG"));
            if (answer != KMessageBox::Yes)
                  return;
      }

      QPicture pic;
      QPainter p;
      p.begin( &pic );        // paint in picture
      Draw(&p,X,Y);           // draw it
      p.end();                      // painting done
      pic.save(filename,"svg");
}

void Worksheet::ExportPIC(QString filename) {
      if(filename.length()<1)
            filename = QFileDialog::getSaveFileName(i18n("out.pic"),QString("*.pic"),this);

      // check if pic file exists
      if ( QFile::exists(filename) ) {
            int answer = KMessageBox::warningYesNoCancel( this, 
                  i18n( "Overwrite\n\'%1\'?" ).arg( filename ), i18n("Export to PIC"));
            if (answer != KMessageBox::Yes)
                  return;
      }
      
      QPicture pic;
      QPainter p;
      p.begin( &pic );        // paint in picture
      Draw(&p,X,Y);                 // draw it
      p.end();                      // painting done
      pic.save(filename);            // save to native qpicture format
}

void Worksheet::ExportPS(QString fn) {
      if(fn.length()<1)
            fn = QFileDialog::getSaveFileName(i18n("out.ps"),QString("*.ps"),this);

      // check if file exists
      if ( QFile::exists(fn) ) {
            int answer = KMessageBox::warningYesNoCancel( this, 
                  i18n( "Overwrite\n\'%1\'?" ).arg( fn ), i18n("Export to PS"));
            if (answer != KMessageBox::Yes)
                  return;
      }
      
      // use a clean KPrinter object
      KPrinter printer(false);
      setupPrinter(&printer,fn);

      QPainter p(&printer);
      QPaintDeviceMetrics metrics( &printer );

      int w = metrics.width();
      int h = metrics.height();
      kdDebug()<<"Metrics = "<<w<<' '<<h<<endl;
      
      printer.setPrintProgram( "gs -sDEVICE=pswrite -sPAPERSIZE=%psl -sOutputFile=%out %in" );

      Draw(&p,w,h);
}

void Worksheet::ExportEPS(QString fn) {
      if(fn.length()<1)
            fn = QFileDialog::getSaveFileName(i18n("out.eps"),QString("*.eps"),this);

      // check if file exists
      if ( QFile::exists(fn) ) {
            int answer = KMessageBox::warningYesNoCancel( this, 
                  i18n( "Overwrite\n\'%1\'?" ).arg( fn ), i18n("Export to EPS"));
            if (answer != KMessageBox::Yes)
                  return;
      }
      
      // use a clean KPrinter object
      KPrinter printer(false);
      setupPrinter(&printer,fn);

      QPainter p(&printer);
      QPaintDeviceMetrics metrics( &printer );

      int w = metrics.width();
      int h = metrics.height();
      kdDebug()<<"Metrics = "<<w<<' '<<h<<endl;
      
      printer.setPrintProgram( "gs -sDEVICE=epswrite -sPAPERSIZE=%psl -sOutputFile=%out %in" );

      Draw(&p,w,h);
}

void Worksheet::ExportPDF(QString fn) {
      if(fn.length()<1)
            fn = QFileDialog::getSaveFileName(i18n("out.pdf"),QString("*.pdf"),this);

      // check if file exists
      if ( QFile::exists(fn) ) {
            int answer = KMessageBox::warningYesNoCancel( this, 
                  i18n( "Overwrite\n\'%1\'?" ).arg( fn), i18n("Export to PDF"));
            if (answer != KMessageBox::Yes)
                  return;
      }
      
      // use a clean KPrinter object
      KPrinter printer(false);
      setupPrinter(&printer,fn);

      QPainter p(&printer);
      QPaintDeviceMetrics metrics( &printer );

      int w = metrics.width();
      int h = metrics.height();
      kdDebug()<<"Metrics = "<<w<<' '<<h<<endl;
      
      printer.setPrintProgram( "gs -sDEVICE=pdfwrite -sPAPERSIZE=%psl -sOutputFile=%out %in" );

      Draw(&p,w,h);
}

void Worksheet::setupPrinter(KPrinter *pr,QString fn) {
      KConfig *config = mw->Config();
      
      pr->setCreator(QString("LabPlot ")+LVERSION);
      pr->setOutputToFile( true );
      pr->setOutputFileName( fn );
      pr->setPageSize((KPrinter::PageSize)config->readNumEntry("PageSize",9));
      if (config->readNumEntry("Landscape",1))
            pr->setOrientation(KPrinter::Landscape);
      else
            pr->setOrientation(KPrinter::Portrait);

      if (config->readBoolEntry("ColorMode",true))
            pr->setColorMode(KPrinter::Color);
      else
            pr->setColorMode(KPrinter::GrayScale);
}

void Worksheet::Draw( QPainter *p, int width, int height ) {
      kdDebug()<<"Worksheet:Draw()"<<endl;
      
      // draw background color
      p->setBrush(background);
      p->setPen(NoPen);
      p->drawRect(0,0,width,height);
      //kdDebug()<<"    Worksheet   width = "<<X<<" / height = "<<Y<<endl;
      //kdDebug()<<"    drawing with      width = "<<width<<" / height = "<<height<<endl;

      kdDebug()<<"Worksheet:Draw() drawing "<<nr_plots<<" plots"<<endl;
      for (unsigned int i=0;i<nr_plots;i++) {
            kdDebug()<<"Worksheet:Draw() drawing plot "<<i+1<<" of type "<<plot[i]->Type()<<endl;
            if(plot[i]!=0 && i!=api)
                  plot[i]->draw(p,width,height);
      }
      // draw api plot at last
      if(nr_plots>0 && plot[api]!=0)
            plot[api]->draw(p,width,height);

      kdDebug()<<"Worksheet:Draw() drawing objects"<<endl;
      // TODO : dont draw it if 0
      for (int i=0;i<NR_OBJECTS;i++) {
            line[i].draw(p,(double)width,(double)height);
            label[i]->draw(p,Point(0,0),Point(1,1),width,height,0);
            rect[i].draw(p,(double)width,(double)height);
            ellipse[i].draw(p,(double)width,(double)height);
            image[i].draw(p,(double)width,(double)height);
      }

      // draw title and timestamp with standard font at the end
      p->setFont(QFont(QString("Adobe Helvetica"),10));

      if(title_enabled)
            p->drawText(10,20,title);

      if(timestamp_enabled)
            p->drawText(10,height-10,timestamp.toString(Qt::TextDate));
}

void Worksheet::Export(QString fn, QString format) {
      if(plot[api]->Type() == PQWT3D)
            ((PlotQWT3D *) plot[api])->Export(fn,format,X,Y);
      QPixmap pm(X,Y);
      QPainter p;

      pm.fill( background );
      p.begin(&pm);
      Draw(&p,X,Y);
      // TODO : options for eps format ?
      pm.save(fn,format);
      p.end();
}

void Worksheet::save(QTextStream *t) {

      *t<<X<<' '<<Y<<endl;

      // NEW : worksheet settings
      *t<<title<<endl;
      *t<<title_enabled<<endl;
      *t<<background.name()<<endl;
#if QT_VERSION > 0x030007
      *t<<timestamp.toTime_t()<<endl;
#else
      QDateTime stoneage(QDate(1970,1,1));
      *t<<stoneage.secsTo(timestamp)<<endl;
#endif
      *t<<timestamp_enabled<<endl;
      *t<<api<<' '<<nr_plots<<endl;

      // "drawing objects"
      for(int i=0;i<NR_OBJECTS;i++) {
            label[i]->save(t);
            line[i].save(t);
            rect[i].save(t);
            ellipse[i].save(t);
            image[i].save(t);
      }

      // save all plots
      for (unsigned int i=0;i<nr_plots;i++) {
            *t<<plot[i]->Type()<<endl;
            plot[i]->save(t);
      }
}

//! open worksheet : type : old type from version <11
void Worksheet::open(QTextStream *t,int version,PType oldtype) {
      kdDebug()<<"Worksheet::open() : version = "<<version<<endl;
      QString tmp;
      int tmpint, type, tmpnr_plots;

      *t>>X>>Y;

      kdDebug()<<"Dimension "<<X<<' '<<Y<<endl;

      // NEW : worksheet settings
      if(version > 10) {
            t->readLine();
            title = t->readLine();
            *t>>tmpint;
            title_enabled = (bool)tmpint;
            *t>>tmp;
            background = QColor(tmp);
            t->readLine();
            if(version > 14) {
                  *t>>tmpint;
                  timestamp.setTime_t(tmpint);
            }
            else {
                  tmp = t->readLine();
                  kdDebug()<<" timestring "<<tmp<<endl;
                  timestamp = QDateTime::fromString(tmp);
            }
            *t>>tmpint;
            timestamp_enabled = (bool)tmpint;
            *t>>api>>tmpnr_plots;

            kdDebug()<<"Title : "<<title<<endl;
            kdDebug()<<"Title enabled : "<<title_enabled<<endl;
            kdDebug()<<"background : "<<background.name()<<endl;
            kdDebug()<<"Timestamp : "<<timestamp.toString()<<endl;
            kdDebug()<<"Timestamp enabled : "<<timestamp_enabled<<endl;
            kdDebug()<<"API/NR_PLOTS = "<<api<<' '<<tmpnr_plots<<endl;
      }

      // drawing objects
      if (version > 7) {
            for(int i=0;i<NR_OBJECTS;i++) {
                  label[i]->open(t,version);
                  line[i].open(t,version);
                  rect[i].open(t,version);
                  ellipse[i].open(t,version);
                  image[i].open(t,version);
            }
      }

      // open all plots
      if(version<11) {
            type=oldtype;
            api=0;
            tmpnr_plots=1;
      }

      kdDebug()<<"API = "<<api<<" / NR_PLOTS = "<<nr_plots<<endl;
      for (int i=0;i<tmpnr_plots;i++) {
            if (version>10)
                  *t>>type;
            kdDebug()<<" PLOT "<<i<<" / Type = "<<type<<endl;
            newPlot((PType)type);
            plot[i]->open(t, version);
      }

      if (!mw->Config()->readBoolEntry("Cascade",false)) {
            QSize mwsize=mw->size();
            this->resize(mwsize.width()-20,mwsize.height()-75);
      }
}

void Worksheet::addGraph2D(Graph2D *g, PType type) {

      kdDebug()<<"Worksheet::addGraph2D() api = "<<api<<" / type = "<<type<<endl;
      kdDebug()<<"      Graph2D Name = "<<g->Name()<<endl;

      if(plot[api] != 0)
            plot[api]->getGraphList()->addGraph2D(g);
      else {
            if (type == P2D || type == PPIE)
                  newPlot(type);
            
            plot[nr_plots-1]->getGraphList()->addGraph2D(g);
      }

      resetRanges();

      // set actrange for new plots
      LRange *actrange = plot[api]->ActRanges();
      if (actrange[0].rMax()-actrange[0].rMin() == 0)
            plot[api]->setActRanges(plot[api]->Ranges());

      updatePixmap();
}

void Worksheet::addGraph3D(Graph3D *g,PType type) {
      kdDebug()<<"Worksheet::addGraph3D()"<<endl;
      kdDebug()<<"g->Number() = "<<g->Number()<<endl;

      if(plot[api] != 0)
            plot[api]->getGraphList()->addGraph3D(g);
      else {
            // TODO : what if 2derr ?
            newPlot(type);
            plot[nr_plots-1]->getGraphList()->addGraph3D(g);
      }

      resetRanges();

      LRange *actrange = plot[api]->ActRanges();
      if (actrange[0].rMax()-actrange[0].rMin() == 0)
            plot[api]->setActRanges(plot[api]->Ranges());

      updatePixmap();
}

void Worksheet::addGraphM(GraphM *g, PType type) {
      kdDebug()<<"Worksheet::addGraphM() : type = "<<type<<endl;
      bool resizing=FALSE;

      if (plot[api]==0 || plot[api]->Type() != type) {
            switch (type) {
            case PSURFACE : {
                  Plot2DSurface *newplot = new Plot2DSurface(this);
                  newplot->getGraphList()->addGraphM(g);
                  newplot->setSize(width()/(double)X,height()/(double)Y);
                  plot[api] = newplot;
                  plot[api]->setType(PSURFACE);
                  resizing = TRUE;  // resize later
                  }; break;
            case P3D : {
                  Plot3D *newplot = new Plot3D(this);
                  newplot->getGraphList()->addGraphM(g);
                  newplot->setSize(width()/(double)X,height()/(double)Y);
                  plot[api] = newplot;
                  plot[api]->setType(P3D);
                  resizing = TRUE;  // resize later
                  }; break;
            case PQWT3D: {
                  PlotQWT3D *newplot = new PlotQWT3D(this);
                  newplot->getGraphList()->addGraphM(g);
                  newplot->draw(0,X,Y);         // update QWT3D plot
                  plot[api] = newplot;
                  plot[api]->setType(PQWT3D);
                  resizing==TRUE;
                  }; break;
             default : break;
             }
      }
      else {
            switch (type) {
            case PSURFACE : case P3D : {
                  plot[api]->getGraphList()->addGraphM(g);
                  resizing = TRUE;  // resize later
                  }; break;
            case PQWT3D: {
                  plot[api]->getGraphList()->addGraphM(g);
                  plot[api]->draw(0,X,Y);       // update QWT3D plot
                  }; break;
            default: break;
            }
      }
      
      resetRanges();

      LRange *actrange = plot[api]->ActRanges();
      if (actrange[0].rMax()-actrange[0].rMin() == 0)
            plot[api]->setActRanges(plot[api]->Ranges());

      updatePixmap();
}

void Worksheet::addGraphGRASS(GraphGRASS *g) {

      kdDebug()<<"Worksheet::addGraphGRASS() api = "<<api<<endl;

      if(plot[api] != 0)
            plot[api]->getGraphList()->addGraphGRASS(g);
      else {
            newPlot(PGRASS);
            plot[nr_plots-1]->getGraphList()->addGraphGRASS(g);
      }
      
      resetRanges();

      // set actrange for new plots
      LRange *actrange = plot[api]->ActRanges();
      if (actrange[0].rMax()-actrange[0].rMin() == 0)
            plot[api]->setActRanges(plot[api]->Ranges());

      updatePixmap();
}

void Worksheet::addGraphVTK(GraphVTK *g) {

      kdDebug()<<"Worksheet::addGraphVTK() api = "<<api<<endl;

      if(plot[api] != 0)
            plot[api]->getGraphList()->addGraphVTK(g);
      else {
            newPlot(PVTK);
            plot[nr_plots-1]->getGraphList()->addGraphVTK(g);
      }
      
      resetRanges();

      // set actrange for new plots
      LRange *actrange = plot[api]->ActRanges();
      if (actrange[0].rMax()-actrange[0].rMin() == 0)
            plot[api]->setActRanges(plot[api]->Ranges());

      updatePixmap();
}

void Worksheet::addGraph4D(Graph4D *g) {
      kdDebug()<<"Worksheet::addGraph4D()"<<endl;
      kdDebug()<<"g->Number() = "<<g->Number()<<endl;

      if(plot[api] != 0)
            plot[api]->getGraphList()->addGraph4D(g);
      else {
            newPlot(P2D);
            plot[nr_plots-1]->getGraphList()->addGraph4D(g);
      }

      resetRanges();

      LRange *actrange = plot[api]->ActRanges();
      if (actrange[0].rMax()-actrange[0].rMin() == 0)
            plot[api]->setActRanges(plot[api]->Ranges());

      updatePixmap();
}

void Worksheet::addGraphIMAGE(GraphIMAGE *g) {
      kdDebug()<<"Worksheet::addGraphIMAGE()"<<endl;
      kdDebug()<<"g->Number() = "<<g->Number()<<endl;

      if(plot[api] != 0)
            plot[api]->getGraphList()->addGraphIMAGE(g);
      else {
            newPlot(PSURFACE);
            plot[nr_plots-1]->getGraphList()->addGraphIMAGE(g);
      }

      resetRanges();

      LRange *actrange = plot[api]->ActRanges();
      if (actrange[0].rMax()-actrange[0].rMin() == 0)
            plot[api]->setActRanges(plot[api]->Ranges());

      updatePixmap();
}

// reset xrange, yrange, zrange
void Worksheet::resetRanges() {
      double xmin=0,xmax=1,ymin=0,ymax=1,zmin=0,zmax=1;
      GraphList *graphlist = plot[api]->getGraphList();
      for (unsigned int i=0;i<graphlist->getNumber();i++) {
            if(!graphlist->getGraph(i)->isShown())
                  continue;   // dont use hidden graphs
                  
            GRAPHType s = graphlist->getStruct(i);

            kdDebug()<<"resetRanges() : Graph "<<i<<endl;
            kdDebug()<<"Graph type = "<<s<<endl;

            LRange xrange,yrange,zrange;
            if(s == GRAPH2D) {
                  Graph2D *g = graphlist->getGraph2D(i);
                  xrange = g->Range(0);
                  yrange = g->Range(1);
            }
            else if(s == GRAPH3D) {
                  Graph3D *g = graphlist->getGraph3D(i);
                  PType t = plot[api]->Type();

                  xrange = g->Range(0);
                  if(t == P2D)      // x-y-dy
                        yrange = g->ErrorDYRange();
                  else
                        yrange = g->Range(1);
                  zrange = g->Range(2);
            }
            else if(s == GRAPHM) {
                  GraphM *g = graphlist->getGraphM(i);
                  xrange = g->Range(0);
                  yrange = g->Range(1);
                  zrange = g->Range(2);
            }
            else if(s == GRAPH4D) {
                  Graph4D *g = graphlist->getGraph4D(i);
                  xrange = g->ErrorDXRange();
                  yrange = g->ErrorDYRange();
            }
            else if(s == GRAPHIMAGE) {
                  GraphIMAGE *g = graphlist->getGraphIMAGE(i);
                  xrange = g->Range(0);
                  yrange = g->Range(1);
            }
            if (i==0) { // first graph
                  xmin=xrange.rMin();
                  xmax=xrange.rMax();
                  ymin=yrange.rMin();
                  ymax=yrange.rMax();
                  
                  if (s == GRAPH3D || s == GRAPHM) {
                        zmin=zrange.rMin();
                        zmax=zrange.rMax();
                  }
            }
            else {
                  xrange.rMin()<xmin?xmin=xrange.rMin():0;
                  xrange.rMax()>xmax?xmax=xrange.rMax():0;
                  yrange.rMin()<ymin?ymin=yrange.rMin():0;
                  yrange.rMax()>ymax?ymax=yrange.rMax():0;

                  if (s == GRAPH3D || s == GRAPHM) {              
                        zrange.rMin()<zmin?zmin=zrange.rMin():0;
                        zrange.rMax()>zmax?zmax=zrange.rMax():0;
                  }                 
            }           
      }
      kdDebug()<<"xmin/xmax "<<xmin<<' '<<xmax<<endl;
      kdDebug()<<"ymin/ymax "<<ymin<<' '<<ymax<<endl;
      kdDebug()<<"zmin/zmax "<<zmin<<' '<<zmax<<endl;

      LRange range[3];
      range[0] = LRange(xmin,xmax);
      range[1] = LRange(ymin,ymax);
      range[2] = LRange(zmin,zmax);

      plot[api]->setRanges(range);

      mw->setModified();
}

Generated by  Doxygen 1.6.0   Back to index