Logo Search packages:      
Sourcecode: labplot version File versions

EditDialog.cc

//LabPlot : EditDialog.cc

#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <iostream>
#include <math.h>
#include <qlabel.h>
#include <qhbox.h>
#include <qfontdialog.h>
#include <qprogressdialog.h>
#include <klocale.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <kfile.h>
#include "EditDialog.h"
#include "Graph2D.h"

#ifdef USE_SOLARIS
#include <ieeefp.h>
#endif

using namespace std;

EditDialog::EditDialog(Worksheet *p, const char *name, int item,ListDialog *ld)
      : Dialog(p, name),ld(ld)
{
      mw = p->getMainWin();

      setCaption(i18n("Edit Dialog")+i18n(" : ")+QString(name));

      Point *ptr=0;
      Point3D *ptr3d=0;
      Point4D *ptr4d=0;
      double *a=0;
      int i, j;

      GraphList *graphlist = p->getPlot(p->API())->getGraphList();
      GRAPHType s = graphlist->getStruct(item);

      if (s == GRAPH2D) {                        // 2D
            graph2d = graphlist->getGraph2D(item);
            graph3d = 0;
            graphm = 0;
            graph4d = 0;
            ptr = graph2d->Data();
            number = graph2d->Number();
      }
      else if (s == GRAPH3D) {                  // 3D
            graph2d = 0;
            graph3d = graphlist->getGraph3D(item);
            graphm = 0;
            graph4d = 0;
            ptr3d = graph3d->Data();
            number = graph3d->Number();
            numberx = graph3d->NX();
            numbery = graph3d->NY();
      }
      else if (s == GRAPHM) {             // M
            graph2d = 0;
            graph3d = 0;
            graph4d = 0;
            graphm = graphlist->getGraphM(item);
            a = graphm->Data();
            numberx = graphm->NX();
            numbery = graphm->NY();
      }
      else if (s == GRAPH4D) {                  // 4D
            graph2d = 0;
            graph3d = 0;
            graph4d = graphlist->getGraph4D(item);
            graphm = 0;
            ptr4d = graph4d->Data();
            number = graph4d->Number();
      }
      
      if (s==GRAPH2D) {
            new QLabel(i18n(" 2D Graph "),vbox);
            table = new QTable( number, 2, vbox );
            QHeader *header = table->horizontalHeader();
            header->setLabel( 0, i18n( "A [X]" ));
            header->setLabel( 1, i18n( "B [Y]" ) );
      }
      else if (s==GRAPH3D) {
            new QLabel(i18n(" 3D Graph "),vbox);
            table = new QTable( number, 3, vbox );
            QHeader *header = table->horizontalHeader();
            header->setLabel( 0, i18n( "A [X]" ));
            header->setLabel( 1, i18n( "B [Y]" ));
            header->setLabel( 2, i18n( "C [Z]" ));
      }
      else if (s == GRAPHM) {
            new QLabel(i18n(" M Graph "),vbox);
            table = new QTable( numbery, numberx, vbox );
      }
      else if (s==GRAPH4D) {
            new QLabel(i18n(" 4D Graph "),vbox);
            table = new QTable( number, 4, vbox );
            QHeader *header = table->horizontalHeader();
            header->setLabel( 0, i18n( "A [X]" ));
            header->setLabel( 1, i18n( "B [Y]" ));
            if (graph4d->GType() == 0) {
                  header->setLabel( 2, i18n( "C [DX]" ));
                  header->setLabel( 3, i18n( "D [DY]" ));
            }
            else if (graph4d->GType() == 1) {
                  header->setLabel( 2, i18n( "C [DY1]" ));
                  header->setLabel( 3, i18n( "D [DY2]" ));
            }
      }

      table->setSelectionMode(QTable::MultiRow);
      table->setLeftMargin(50);
      
      // fill table with values from ptr/ptr3d/a
      if (s== GRAPH2D)
            for(i=0;i<number;i++) {
                  table->setText(i,0,QString::number(ptr[i].X()));
                  table->setText(i,1,QString::number(ptr[i].Y()));
            }
      else if (s==GRAPH3D) {
            for(i=0;i<number;i++) {
                  table->setText(i,0,QString::number(ptr3d[i].X()));
                  table->setText(i,1,QString::number(ptr3d[i].Y()));
                  table->setText(i,2,QString::number(ptr3d[i].Z()));
            }
      }
      else if (s==GRAPHM) {
            for(i=0;i<numbery;i++) {
                  for(j=0;j<numberx;j++) {
                        table->setText(i,j,QString::number(a[j+numberx*i]));
                  }
            }
      }
      else if (s==GRAPH4D) {
            for(i=0;i<number;i++) {
                  table->setText(i,0,QString::number(ptr4d[i].X()));
                  table->setText(i,1,QString::number(ptr4d[i].Y()));
                  table->setText(i,2,QString::number(ptr4d[i].Z()));
                  table->setText(i,3,QString::number(ptr4d[i].T()));
            }
      }

      QHBox *hb = new QHBox(vbox);
      KPushButton *sel = new KPushButton(i18n("Select All Rows"),hb);
      QObject::connect(sel,SIGNAL(clicked()),SLOT(select()));
      KPushButton *desel = new KPushButton(i18n("Deselect All Rows"),hb);
      QObject::connect(desel,SIGNAL(clicked()),SLOT(deselect()));

      hb = new QHBox(vbox);
      KPushButton *delsel = new KPushButton(i18n("Delete Selected Rows"),hb);
      QObject::connect(delsel,SIGNAL(clicked()),SLOT(deleteSelection()));
      hb = new QHBox(vbox);
      KPushButton *sortascpb = new KPushButton(i18n("Sort Column ascending"),hb);
      QObject::connect(sortascpb,SIGNAL(clicked()),SLOT(sortascColumn()));
      KPushButton *sortdescpb = new KPushButton(i18n("Sort Column descending"),hb);
      QObject::connect(sortdescpb,SIGNAL(clicked()),SLOT(sortdescColumn()));

      hb = new QHBox(vbox);
      new QLabel(i18n(" Edit with editor : "),hb);
      editorcb = new KComboBox(hb);
        QStringList elist;
        elist << i18n("vi");
        elist << i18n("kvim");
        elist << i18n("gvim");
        elist << i18n("kwrite");
      elist << i18n("emacs");
      elist << i18n("xemacs");
      elist << i18n("kword");
      elist << i18n("StarOffice Write");
        editorcb->insertStringList(elist);
      QObject::connect(editorcb,SIGNAL(activated (int)),SLOT(edit_editor(int)));

      KPushButton *evalexp = new KPushButton(
            i18n("Evaluate Expression( a=1/a , b=sin(a) , c=a+b , etc.) :"), vbox);
      hb = new QHBox(vbox);
      QObject::connect(evalexp,SIGNAL(clicked()),SLOT(evaluateExpression()));
      evalle = new KLineEdit("",hb);

      QObject::connect(ok,SIGNAL(clicked()),SLOT(ok_clicked()));
      QObject::connect(apply,SIGNAL(clicked()),SLOT(apply_clicked()));

      setMinimumWidth(vbox->minimumSizeHint().width());
      setMinimumHeight(gbox->minimumSizeHint().height()+vbox->minimumSizeHint().height());
      resize(minimumSize().width(),(int)(1.2*minimumSize().height()));
}

void EditDialog::apply_clicked() {
      if(graph2d) {
            double x,y,xmin=0,xmax=0,ymin=0,ymax=0;
            Point *ptr = graph2d->Data();
            for (int i=0;i<table->numRows();i++) {
                  x=(table->text(i,0)).toDouble();
                  y=(table->text(i,1)).toDouble();
                  if (i==0) {
                        xmin=xmax=x;
                        ymin=ymax=y;
                  }
                  else {
                        x<xmin?xmin=x:0;
                        x>xmax?xmax=x:0;
                        y<ymin?ymin=y:0;
                        y>ymax?ymax=y:0;
                  }
                  ptr[i].setPoint(x,y);
            }
            LRange range[2];
            range[0] = LRange(xmin,xmax);
            range[1] = LRange(ymin,ymax);
            graph2d->setRange(range);

            kdDebug()<<"EditDialog :"<<endl;
            kdDebug()<<"new 2D Range :"<<endl;
            kdDebug()<<"            "<<xmin<<' '<<xmax<<endl;
            kdDebug()<<"            "<<ymin<<' '<<ymax<<endl;

            graph2d->setNumber(table->numRows());
      }
      else if(graph3d) {
            double x,y,z,xmin=0,xmax=0,ymin=0,ymax=0,zmin=0,zmax=0;
            Point3D *ptr = graph3d->Data();

            for (int i=0;i<table->numRows();i++) {
                  x=(table->text(i,0)).toDouble();
                  y=(table->text(i,1)).toDouble();
                  z=(table->text(i,2)).toDouble();

                  if (i == 0) {
                        xmin=xmax=x;
                        ymin=ymax=y;
                        zmin=zmax=z;
                  }
                  else {
                        x<xmin?xmin=x:0;
                        x>xmax?xmax=x:0;
                        y<ymin?ymin=y:0;
                        y>ymax?ymax=y:0;
                        z<zmin?zmin=z:0;
                        z>zmax?zmax=z:0;
                  }
                  ptr[i].setPoint(x,y,z);
            }
            LRange range[3];
            range[0] = LRange(xmin,xmax);
            range[1] = LRange(ymin,ymax);
            range[2] = LRange(zmin,zmax);

            kdDebug()<<"EditDialog :"<<endl;
            kdDebug()<<"3D Range :"<<endl;
            kdDebug()<<"            "<<xmin<<' '<<xmax<<endl;
            kdDebug()<<"            "<<ymin<<' '<<ymax<<endl;
            kdDebug()<<"            "<<zmin<<' '<<zmax<<endl;

            graph3d->setRange(range);
            graph3d->setNumber(table->numRows());
      }
      else if(graphm) {
            double z, zmin=0,zmax=0;
            double *a = graphm->Data();

            for (int i=0;i<table->numRows();i++) {
                  for (int j=0;j<table->numCols();j++) {
                        z=(table->text(i,j)).toDouble();
                        if (i == 0) {
                              zmin=zmax=z;
                        }
                        else {
                              z<zmin?zmin=z:0;
                              z>zmax?zmax=z:0;
                        }
                        kdDebug()<<" EditDialog graphm : z = "<<z<<endl;

                        a[j+i*(table->numCols())]=z;
                  }
            }
            LRange range[1];
            range[0] = LRange(zmin,zmax);

            graphm->setZRange(range);
            graphm->setNumber(table->numCols(),table->numRows());
      }
      else if(graph4d) {
            double x,y,z,t,xmin=0,xmax=0,ymin=0,ymax=0,zmin=0,zmax=0,tmin=0,tmax=0;
            Point4D *ptr = graph4d->Data();

            for (int i=0;i<table->numRows();i++) {
                  x=(table->text(i,0)).toDouble();
                  y=(table->text(i,1)).toDouble();
                  z=(table->text(i,2)).toDouble();
                  t=(table->text(i,3)).toDouble();

                  if (i == 0) {
                        xmin=xmax=x;
                        ymin=ymax=y;
                        zmin=zmax=z;
                        tmin=tmax=t;
                  }
                  else {
                        x<xmin?xmin=x:0;
                        x>xmax?xmax=x:0;
                        y<ymin?ymin=y:0;
                        y>ymax?ymax=y:0;
                        z<zmin?zmin=z:0;
                        z>zmax?zmax=z:0;
                        t<tmin?tmin=t:0;
                        t>tmax?tmax=t:0;
                  }
                  ptr[i].setPoint(x,y,z,t);
            }
            LRange range[4];
            range[0] = LRange(xmin,xmax);
            range[1] = LRange(ymin,ymax);
            range[2] = LRange(zmin,zmax);
            range[3] = LRange(tmin,tmax);

            kdDebug()<<"EditDialog :"<<endl;
            kdDebug()<<"4D Range :"<<endl;
            kdDebug()<<"            "<<xmin<<' '<<xmax<<endl;
            kdDebug()<<"            "<<ymin<<' '<<ymax<<endl;
            kdDebug()<<"            "<<zmin<<' '<<zmax<<endl;
            kdDebug()<<"            "<<tmin<<' '<<tmax<<endl;

            graph4d->setRange(range);
            graph4d->setNumber(table->numRows());
      }

      p->resetRanges();
      p->updatePixmap();

      if(ld) ld->updateList();
}

void EditDialog::edit_editor(int editor) {
      KProcess* proc = new KProcess;

      switch(editor) {
      case 0:
            *proc << "xterm"<<"-e"<<"vim";
            break;
      case 1:
            *proc << "kvim"<<"-f";
            break;
      case 2:
            *proc << "gvim"<<"-f";
            break;
      case 3:
            *proc << "kwrite";
            break;
      case 4:
            *proc<<"emacs";
            break;
      case 5:
            *proc<<"xemacs";
            break;
      case 6:
            *proc<<"kword";
            break;
      case 7:
            *proc<<"soffice";
      }
      // TODO ; kate doesn't work : exit signal shortly after start (background job)

      // tmp file for vim;
      KTempFile *tmpfile = new KTempFile(QString::null,".dat");
      tmpfile->setAutoDelete(true);
      filename = tmpfile->name();

      // file as argument
      *proc<<filename;

      QTextStream *t = tmpfile->textStream();

      for (int i=0;i<table->numRows();i++) {
            for (int j=0;j<table->numCols();j++) {
                        *t << table->text(i,j).toDouble()<<' ';
            }
            *t<<endl;
      }
      tmpfile->close();

      connect(proc, SIGNAL(processExited(KProcess*)),this, SLOT(readfile(KProcess*)));
      if ( !proc->start(KProcess::NotifyOnExit) ) {
            KMessageBox::error( this,i18n("Could not start selected Editor."));
      }
}

//read data from tmp file into table
void EditDialog::readfile(KProcess *process) {
      QFile file(filename);
      if ( ! file.open( IO_ReadOnly )) {
            KMessageBox::error(this,i18n("temporary data file not found!"));
            return;
      }
      QTextStream t(&file);

      int i=0;
      while(!(t.atEnd())) {
            QStringList line = QStringList::split(' ',t.readLine());
            int j=0;
            for ( QStringList::Iterator it = line.begin(); it != line.end(); ++it ) {
                  table->setText(i,j++,(*it));
            }
            i++;
            // add additional rows
            if(i>=table->numRows())
                  table->setNumRows ( table->numRows()+1 );
      }

      // remove obsolete rows
      int oldnumrows=table->numRows();
      for(int k=i;k<oldnumrows;k++)
            table->removeRow(i);

      file.close();
}

void EditDialog::deleteSelection() {
      QTableSelection ts = table->selection(table->currentSelection());

      for (int i=ts.anchorRow();i<=ts.bottomRow();i++)
            table->removeRow(ts.anchorRow());

      table->clearSelection();
      table->setCurrentCell(0,0);
}

void EditDialog::sortascColumn() {
      ascending=TRUE;
      sort();
}

void EditDialog::sortdescColumn() {
      ascending=FALSE;
      sort();
}
 
void EditDialog::sort() {
      QTableSelection ts = table->selection(table->currentSelection());
      if(ts.topRow()<ts.bottomRow())
            qsort(ts.topRow(),ts.bottomRow());
      else
            qsort(0,table->numRows()-1);

      table->clearSelection();
      table->repaintContents();
}

void EditDialog::qsort(int s, int e) {
      if(e>s+1) {
            int col = table->currentColumn();
            double mid = table->text((s+e)/2,col).toDouble();
            
            int i=s, j=e;
            while (i<j) {
                  if(ascending) {
                        while (table->text(i,col).toDouble() < mid) i++;
                        while (mid < table->text(j,col).toDouble())  j--;
                  }
                  else {
                        while (table->text(i,col).toDouble() > mid) i++;
                        while (mid > table->text(j,col).toDouble())  j--;
                  }
                  
                  if(i<j) {
                        table->swapRows(i,j);
                        i++;j--;
                  }
            }
            
            qsort(s,j);
            qsort(i,e);
      }
}

void EditDialog::evaluateExpression() {
      QString expr = evalle->text();
      int index=-1;           // index for evaluation  (a=...) 0:a, 1:b, 2:c, 3:d

      int pos = expr.find( QRegExp("="), 1 );

      kdDebug()<<"Position : "<<pos<<endl;

      // read first two chars ("a=")
      if(expr.left(pos).find(QString("a"),0,FALSE)==0) {
            index=0;
      }
      else if(expr.left(pos).find(QString("b"),0,FALSE)==0) {
            index=1;
      }
      else if(expr.left(pos).find(QString("c"),0,FALSE)==0) {
            if (table->numCols()>2)
                  index=2;
      }
      else if(expr.left(pos).find(QString("d"),0,FALSE)==0) {
            if (table->numCols()>3)
                  index=3;
      }

      if (index == -1) {
            kdDebug()<<"ERROR : wrong expression entered"<<endl;
      }
      else {
            expr=expr.right(expr.length()-pos-1);

            QProgressDialog progress( "applying expression ...", "Cancel", table->numRows(), this, "progress", TRUE );

            for (int i=0;i<table->numRows();i++) {
                  if(table->isRowSelected(i)) {
                        if(i%100==0) progress.setProgress( i );
                        qApp->processEvents();

                        QString tmp(expr.lower());

                        // replace a,b,c,d,...
                        for(int j=0;j<table->numCols();j++)
                              tmp = mw->parseExpression(tmp,table->text(i,j).toDouble(),j);
                        
                        double result = parse((char *) tmp.latin1());

                        if(!finite(result))
                              result=0;
                        table->setText(i,index,QString::number(result));
                        if ( progress.wasCancelled() )
                              return;
                  }
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index