Logo Search packages:      
Sourcecode: labplot version File versions

Spreadsheet.cc

// LabPlot : Spreadsheet.cc

#include <stdlib.h>
#include <time.h>
#include <qtable.h>
#include <qhbox.h>
#include <qcursor.h>
#include <qclipboard.h>

#include <kmessagebox.h>
#include <kiconloader.h>

#include "Spreadsheet.h"
#include "MainWin.h"
#include "SpreadsheetValuesDialog.h"
#include "SpreadsheetPropertiesDialog.h"
#include "pixmaps/plotpixmap.h"
#include "DumpDialog.h"

#include "spreadsheetProperties.h"
#include "source.h"

Spreadsheet::Spreadsheet(QWidget *p, MainWin *mw, const char *name)
      :QWidget(p,name), mw(mw)
{
      setCaption(i18n("Spreadsheet ")+QString::number(mw->NrSpreadsheets()+1));

      table = new QTable( 100, 2, this );
      table->setRowMovingEnabled (TRUE);
      table->setColumnMovingEnabled (TRUE);

      table->horizontalHeader()->setLabel( 0, QString( "A {double} [X]" ) );
      table->horizontalHeader()->setLabel( 1, QString( "B {double} [Y]" ) );
      table->horizontalHeader()->installEventFilter(this );
      
      table->setFocusPolicy(QWidget::StrongFocus);
      table->setFocus();

      resize(table->sizeHint());
      show();
      if(mw) mw->updateSheetList();
}

bool Spreadsheet::eventFilter(QObject *object, QEvent *e) {
      if(object != (QObject *) table->horizontalHeader())
            return FALSE;

      switch(e->type()) {
      case QEvent::MouseButtonDblClick:   (new SpreadsheetPropertiesDialog(table,caption()))->show(); break;
      default: break;
      }

      return QObject::eventFilter(object,e);
}

//! clear spreadsheet
void Spreadsheet::Clear() {
      for (int i=0;i<table->numCols();i++)
            for (int j=0;j<table->numRows();j++)
                  table->setText(j,i,"");
      table->clearSelection();
}

QStringList Spreadsheet::Info() {
      QStringList s;
      s<<i18n("SIZE:")<<QString::number(table->numCols())<<i18n(" x ")<<QString::number(table->numRows());

      return s;
}

void Spreadsheet::setCurrentColumn(int i) {
      table->clearSelection();
      table->setCurrentCell(0,i);
}

//! calculate number of filled rows
int Spreadsheet::filledRows() {
      int row=1;
      while (table->text(row,0).length()>0)
            row++;
      return row;
}

void Spreadsheet::resizeEvent(QResizeEvent *e) {
      table->resize(e->size());
}

void Spreadsheet::closeEvent(QCloseEvent *e) {
      e->accept();

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

void Spreadsheet::contextMenuEvent(QContextMenuEvent *e) {
      QPopupMenu menu(this);
      QPopupMenu plotmenu(this);
      QPopupMenu fillmenu(this);
      QPopupMenu normmenu(this);
      QPopupMenu convertmenu(this);
      QPopupMenu sortmenu(this);

      QPixmap plot2dIcon = QPixmap(plot2d_xpm);
        QPixmap plot3dIcon = QPixmap(plot3d_xpm);
        QPixmap plotqwt3dIcon = QPixmap(plotQWT3D_xpm);
        QPixmap plotsurfaceIcon = QPixmap(plotsurface_xpm);
      QPixmap plotpieIcon = QPixmap(plotpie_xpm);
        QPixmap plotpolarIcon = QPixmap(plotpolar_xpm);
        QPixmap plotternaryIcon = QPixmap(plotternary_xpm);

      QPixmap cutIcon = KGlobal::iconLoader()->loadIcon("editcut", KIcon::Small);
      QPixmap copyIcon = KGlobal::iconLoader()->loadIcon("editcopy", KIcon::Small);
      QPixmap pasteIcon = KGlobal::iconLoader()->loadIcon("editpaste", KIcon::Small);
      QPixmap clearIcon = KGlobal::iconLoader()->loadIcon("editclear", KIcon::Small);

      QPixmap setIcon = KGlobal::iconLoader()->loadIcon("pagesetup", KIcon::Small); 
      QPixmap fillIcon = KGlobal::iconLoader()->loadIcon("fill", KIcon::Small);     
      QPixmap normIcon = KGlobal::iconLoader()->loadIcon("tool_normal", KIcon::Small);    
      QPixmap convertIcon = KGlobal::iconLoader()->loadIcon("transform", KIcon::Small);   
      QPixmap exportIcon = KGlobal::iconLoader()->loadIcon("fileexport", KIcon::Small);   

      QPixmap deleteIcon = KGlobal::iconLoader()->loadIcon("editdelete", KIcon::Small);
      QPixmap addIcon = KGlobal::iconLoader()->loadIcon("edit_add", KIcon::Small);
      QPixmap sortIcon = KGlobal::iconLoader()->loadIcon("unsorted_list", KIcon::Small);
      QPixmap sortascIcon = KGlobal::iconLoader()->loadIcon("sort_incr", KIcon::Small);
      QPixmap sortdesIcon = KGlobal::iconLoader()->loadIcon("sort_decrease", KIcon::Small);
      QPixmap propertiesIcon = KGlobal::iconLoader()->loadIcon("site_properties", KIcon::Small);
      
      menu.insertItem(plot2dIcon, i18n( "Plot" ),&plotmenu );
      plotmenu.insertItem(plot2dIcon, i18n( "2D Plot (XY)" ),this,SLOT(plot2DSimple()) );
      plotmenu.insertItem(plot2dIcon, i18n( "2D Plot (XYDY)" ),this,SLOT(plot3DXYDY()) );
      plotmenu.insertItem(plot2dIcon, i18n( "2D Plot (XYDXDY)" ),this,SLOT(plot4DXYDXDY()) );
      plotmenu.insertItem(plot2dIcon, i18n( "2D Plot (XYDYDY)" ),this,SLOT(plot4DXYDYDY()) );
      plotmenu.insertItem(plot3dIcon, i18n( "3D Plot (XYZ)" ),this,SLOT(plot3DSimple()) );
      plotmenu.insertItem(plotqwt3dIcon, i18n( "3D QWT Plot (MATRIX)" ),this,SLOT(plotQWT3D()) );
      plotmenu.insertItem(plotsurfaceIcon, i18n( "Surface Plot" ),this,SLOT(plotSurface()) );
      plotmenu.insertItem(plotpieIcon, i18n( "Pie Plot (XY)" ),this,SLOT(plot2DPie()) );
      plotmenu.insertItem(plotpolarIcon, i18n( "Polar Plot (XY)" ),this,SLOT(plot2DPolar()) );
      plotmenu.insertItem(plotternaryIcon, i18n( "Ternary Plot (XYZ)" ),this,SLOT(plot3DTernary()) );
      menu.insertSeparator();
      menu.insertItem( cutIcon, i18n( "Cut" ),this,SLOT(cutSelection()) );
      menu.insertItem( copyIcon, i18n( "Copy" ),this,SLOT(copySelection()) );
      menu.insertItem( pasteIcon, i18n( "Paste" ),this,SLOT(pasteSelection()) );
      menu.insertItem( clearIcon, i18n( "Clear" ),this,SLOT(clearSelection()) );
      menu.insertSeparator();
      menu.insertItem( setIcon, i18n( "Set column values" ),this,SLOT(setValues()) );
      menu.insertItem( fillIcon, i18n( "Fill with" ),&fillmenu );
      fillmenu.insertItem( i18n( "Row number" ),this,SLOT(fillRowNumber()) );
      fillmenu.insertItem( i18n( "Random values" ),this,SLOT(fillRandom()) );
      menu.insertItem( normIcon, i18n( "Normalize" ),&normmenu );
      normmenu.insertItem( i18n( "Sum=1" ),this,SLOT(normSum()) );
      normmenu.insertItem( i18n( "Max=1" ),this,SLOT(normMax()) );
      menu.insertItem( convertIcon, i18n( "Convert" ),&convertmenu );
      convertmenu.insertItem( i18n( "Transpose Matrix" ),this,SLOT(transposeMatrix()) );
      convertmenu.insertItem( i18n( "Matrix -> XYZ" ),this,SLOT(convertMatrixtoXYZ()) );
      convertmenu.insertItem( i18n( "XYZ -> Matrix" ),this,SLOT(convertXYZtoMatrix()) );
      menu.insertItem(exportIcon, i18n("Export data"),this,SLOT(exportData()));
      menu.insertSeparator();
      menu.insertItem( addIcon, i18n( "Add Column" ),this,SLOT(addColumn()) );
      menu.insertItem( deleteIcon, i18n( "Delete selected Columns" ),this,SLOT(deleteColumns()) );
      menu.insertItem( deleteIcon, i18n( "Delete selected Rows" ),this,SLOT(deleteRows()) );
      menu.insertSeparator();
      menu.insertItem( sortIcon, i18n( "Sort" ),&sortmenu );
      sortmenu.insertItem( sortascIcon, i18n( "Ascending" ),this,SLOT(sortAscending()) );
      sortmenu.insertItem( sortdesIcon, i18n( "Descending" ),this,SLOT(sortDescending()) );
      menu.insertSeparator();
      menu.insertItem(propertiesIcon, i18n( "Properties" ),this,SLOT(setProperties()) );
      
      menu.exec(QCursor::pos());
}

void Spreadsheet::save(QTextStream *t) {
      *t<<table->numCols()<<' '<<table->numRows()<<endl;
      
      // dump header
      for(int i=0;i<table->numCols();i++)
            *t<<table->horizontalHeader()->label(i)<<endl;
            
      // dump data
      for(int i=0;i<table->numRows();i++) {
            for(int j=0;j<table->numCols();j++) {
                  *t<<"\""<<table->text(i,j)<<"\" ";
            }
            *t<<endl;
      }
}

void Spreadsheet::open(QTextStream *t, int version) {
      kdDebug()<<"Spreadsheet::open()"<<endl;
      int nx,ny;
      *t>>nx>>ny;
      table->setNumCols(nx);
      table->setNumRows(ny);
      kdDebug()<<"NX="<<nx<<" NY="<<ny<<endl;
            
      // read header
      QString tmp;
      t->readLine();
      for(int i=0;i<table->numCols();i++) {
            tmp = t->readLine();
            kdDebug()<<"Label "<<i<<'='<<tmp<<endl;
            table->horizontalHeader()->setLabel(i,tmp);
      }
      
      // read data
      for(int i=0;i<table->numRows();i++) {
            tmp = t->readLine();
            tmp = tmp.simplifyWhiteSpace();
            QStringList oneline;
            if(tmp.contains('"'))
                  oneline = QStringList::split("\" ",tmp);  // new style
            else
                  oneline = QStringList::split(" ",tmp);          // old style (onyl 1.4.0.pre/rc)
            int j=0;
            for ( QStringList::Iterator it = oneline.begin(); it != oneline.end(); ++it ) {
                        QString entry=*it;
                        entry.remove('"');
                                table->setText(i,j++,entry);
            }
      }
}

//! return format index for column col
int Spreadsheet::formatItem(int col) {
      QString header = table->horizontalHeader()->label(col);
      int pos1 = header.find(QRegExp("\\{"));
      int pos2 = header.find(QRegExp("\\}"));
      QString format = header.mid(pos1,pos2-pos1+1);
      for(int i=0;i<NR_FORMATS;i++)
            if(format==QString(formatList[i]))
                  return i;
      return -1;
}

// return name of column col
QString Spreadsheet::columnTitle(int col) {
      QString label = table->horizontalHeader()->label(col);
      label.remove(QRegExp(" \\{.+\\]"));
      
      return label;
}

void Spreadsheet::setColumnTitle(int col, QString name) {
      if(col==0)
            table->horizontalHeader()->setLabel(col, name+QString(" {double} [X]"));
      else
            table->horizontalHeader()->setLabel(col, name+QString(" {double} [Y]"));
}

//! make 2d plot with x-y-dy
void Spreadsheet::plot3DXYDY() {
      // if less than 3 columns selected -> select all columns
      QTableSelection ts = table->selection(table->currentSelection());
#if QT_VERSION > 0x030102
        if(ts.numCols()<3)
#else
        if(ts.rightCol()-ts.leftCol()<3)
#endif
            for (int i=0;i<table->numCols();i++)
                  table->selectColumn(i);

      // find x,y,dy column
      int indexx=-1,indexy=-1,indexz=-1;
      for(int i=table->numCols()-1;i>=0;i--) {
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[X]")>0)
                  indexx=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[Y]")>0)
                  indexy=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[DY]")>0)
                  indexz=i;
      }

      Worksheet *p = mw->newWorksheet();
      p->newPlot(P2D);
                  
      Point3D *ptr = new Point3D[table->numRows()];
      // read x and y values
      double x, y, z, xmin=0,xmax=1,ymin=0,ymax=1, zmin=0, zmax=1;
      for (int row=0;row<table->numRows();row++) {
            if(indexx==-1)
                  x = (double) row;
            else
                  x = mw->formatLabel(table->text(row,indexx),formatItem(indexx));
            y = mw->formatLabel(table->text(row,indexy),formatItem(indexy));
            z = mw->formatLabel(table->text(row,indexz),formatItem(indexz));
            //kdDebug()<<"x/y ="<<x<<' '<<y<<endl;
            
            if(row==0) {
                  xmin=xmax=x;
                  ymin=ymax=y;
                  zmin=zmax=z;
            }
            
            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[row].setPoint(x,y,z);
      };
      
      // make new Graph3D
      LRange range[3];
      range[0] = LRange(xmin,xmax);
      range[1] = LRange(ymin,ymax);
      range[2] = LRange(zmin,zmax);
      Style style;
      Symbol symbol;
      
      Graph3D *g = new Graph3D(caption(),columnTitle(indexy),range,SSPREADSHEET,P2D,style,symbol,ptr,table->numRows(),1);

      p->addGraph3D(g);
}

//! make 2d plot with x-y-dx-dy
void Spreadsheet::plot4DXYDXDY() {
      // if less than 4 columns selected -> select all columns
      QTableSelection ts = table->selection(table->currentSelection());
#if QT_VERSION > 0x030102
        if(ts.numCols()<4)
#else
        if(ts.rightCol()-ts.leftCol()<4)
#endif
            for (int i=0;i<table->numCols();i++)
                  table->selectColumn(i);

      // find x,y,dy column
      int indexx=-1,indexy=-1,indexz=-1, indext=-1;
      for(int i=table->numCols()-1;i>=0;i--) {
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[X]")>0)
                  indexx=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[Y]")>0)
                  indexy=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[DX]")>0)
                  indexz=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[DY]")>0)
                  indext=i;
      }

      Worksheet *p = mw->newWorksheet();
      p->newPlot(P2D);

      Point4D *ptr = new Point4D[table->numRows()];
      // read x and y values
      double x, y, z, t, xmin=0,xmax=1,ymin=0,ymax=1, zmin=0, zmax=1, tmin=0,tmax=1;
      for (int row=0;row<table->numRows();row++) {
            if(indexx==-1)
                  x = (double) row;
            else
                  x = mw->formatLabel(table->text(row,indexx),formatItem(indexx));
            y = mw->formatLabel(table->text(row,indexy),formatItem(indexy));
            z = mw->formatLabel(table->text(row,indexz),formatItem(indexz));
            t = mw->formatLabel(table->text(row,indext),formatItem(indext));
            //kdDebug()<<"x/y ="<<x<<' '<<y<<endl;
            
            if(row==0) {
                  xmin=xmax=x;
                  ymin=ymax=y;
                  zmin=zmax=z;
                  tmin=tmax=t;
            }
            
            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[row].setPoint(x,y,z,t);
      };
      
      // make new Graph4D
      LRange range[4];
      range[0] = LRange(xmin,xmax);
      range[1] = LRange(ymin,ymax);
      range[2] = LRange(zmin,zmax);
      range[3] = LRange(tmin,tmax);
      Style style;
      Symbol symbol;
      
      Graph4D *g = new Graph4D(caption(),columnTitle(indexy),range,SSPREADSHEET,P2D,style,symbol,ptr,table->numRows(),FALSE);

      p->addGraph4D(g);
}

//! make 2d plot with x-y-dy1-dy2
void Spreadsheet::plot4DXYDYDY() {
      // if less than 4 columns selected -> select all columns
      QTableSelection ts = table->selection(table->currentSelection());
#if QT_VERSION > 0x030102
        if(ts.numCols()<4)
#else
        if(ts.rightCol()-ts.leftCol()<4)
#endif
            for (int i=0;i<table->numCols();i++)
                  table->selectColumn(i);

      // find x,y,dy column
      int indexx=-1,indexy=-1,indexz=-1, indext=-1;
      for(int i=table->numCols()-1;i>=0;i--) {
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[X]")>0)
                  indexx=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[Y]")>0)
                  indexy=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[DY]")>0)
                  indexz=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[DY2]")>0)
                  indext=i;
      }

      Worksheet *p = mw->newWorksheet();
      p->newPlot(P2D);

      Point4D *ptr = new Point4D[table->numRows()];
      // read x and y values
      double x, y, z, t, xmin=0,xmax=1,ymin=0,ymax=1, zmin=0, zmax=1, tmin=0,tmax=1;
      for (int row=0;row<table->numRows();row++) {
            if(indexx==-1)
                  x = (double) row;
            else
                  x = mw->formatLabel(table->text(row,indexx),formatItem(indexx));
            y = mw->formatLabel(table->text(row,indexy),formatItem(indexy));
            z = mw->formatLabel(table->text(row,indexz),formatItem(indexz));
            t = mw->formatLabel(table->text(row,indext),formatItem(indext));
            //kdDebug()<<"x/y ="<<x<<' '<<y<<endl;

            if(row==0) {
                  xmin=xmax=x;
                  ymin=ymax=y;
                  zmin=zmax=z;
                  tmin=tmax=t;
            }

            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[row].setPoint(x,y,z,t);
      };
      
      // make new Graph4D
      LRange range[4];
      range[0] = LRange(xmin,xmax);
      range[1] = LRange(ymin,ymax);
      range[2] = LRange(zmin,zmax);
      range[3] = LRange(tmin,tmax);
      Style style;
      Symbol symbol;

      Graph4D *g = new Graph4D(caption(),columnTitle(indexy),range,SSPREADSHEET,P2D,style,symbol,ptr,table->numRows(),TRUE);

      p->addGraph4D(g);
}

void Spreadsheet::plot2D(PType type) {
      // if less than 2 columns selected -> select all columns
      QTableSelection ts = table->selection(table->currentSelection());
#if QT_VERSION > 0x030102
        if(ts.numCols()<2)
#else
        if(ts.rightCol()-ts.leftCol()<2)
#endif
      
      for (int i=0;i<table->numCols();i++)
            table->selectColumn(i);

      // find x column
      int indexx=-1;
      for(int i=table->numCols()-1;i>=0;i--) {
            // use only selected columns
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[X]")>0)
                  indexx=i;
      }

      // create worksheet with 2d plot
      Worksheet *p = mw->newWorksheet();
      p->newPlot(type);

      for(int i=0;i<table->numCols();i++) {
            // use only selected y cols
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[Y]")>0) {
                  Point *ptr = new Point[table->numRows()];
                  // read x and y values
                  double x, y, xmin=0,xmax=1,ymin=0,ymax=1;
                  for (int row=0;row<table->numRows();row++) {
                        if(indexx==-1)
                              x =(double) row;
                        else
                              x = mw->formatLabel(table->text(row,indexx),formatItem(indexx));
                        y = mw->formatLabel(table->text(row,i),formatItem(i));
                        kdDebug()<<"x/y ="<<x<<' '<<y<<endl;
            
                        if(row==0) {
                              xmin=xmax=x;
                              ymin=ymax=y;
                        }
            
                        x<xmin?xmin=x:0;
                        x>xmax?xmax=x:0;
                        y<ymin?ymin=y:0;
                        y>ymax?ymax=y:0;

                        ptr[row].setPoint(x,y);
                  }
                  kdDebug()<<"xmin/xmax = "<<(int)xmin<<' '<<(int)xmax<<endl;
      
                  // make new Graph2D
                  LRange range[2];
                  range[0] = LRange(xmin,xmax);
                  range[1] = LRange(ymin,ymax);
                  Style style;
                  Symbol symbol;

                  Graph2D *g = new Graph2D(caption(),columnTitle(i),range,SSPREADSHEET,type,style,symbol,ptr,table->numRows());

                  p->addGraph2D(g);
            }
      }
}

void Spreadsheet::plot3D(PType type) {
      // if less than 3 columns selected -> select all columns
      QTableSelection ts = table->selection(table->currentSelection());
#if QT_VERSION > 0x030102
        if(ts.numCols()<3)
#else
        if(ts.rightCol()-ts.leftCol()<3)
#endif
            for (int i=0;i<table->numCols();i++)
                  table->selectColumn(i);

      // find x,y column
      int indexx=-1, indexy=-1;
      for(int i=table->numCols()-1;i>=0;i--) {
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[X]")>0)
                  indexx=i;
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[Y]")>0)
                  indexy=i;
      }

      // create worksheet with 3d plot
      Worksheet *p = mw->newWorksheet();
      p->newPlot(type);

      // use all z cols
      for(int i=0;i<table->numCols();i++) {
            if(table->isColumnSelected(i) && table->horizontalHeader()->label(i).findRev("[Z]")>0 ) {
                  Point3D *ptr = new Point3D[table->numRows()];
                  // read x and y values
                  double xmin=0,xmax=1,ymin=0,ymax=1,zmin=0,zmax=1;
                  for (int row=0;row<table->numRows();row++) {
                        double x = mw->formatLabel(table->text(row,indexx),formatItem(indexx));
                        double y = mw->formatLabel(table->text(row,indexy),formatItem(indexy));
                        double z = mw->formatLabel(table->text(row,i),formatItem(i));
                        kdDebug()<<"x/y/z ="<<x<<' '<<y<<' '<<z<<endl;
            
                        if (i == 0) {
                              if (type == PTERNARY) {
                                    xmin=0;
                                    xmax=x+y+z;
                              }
                              else
                                    xmin=xmax=x;      
                              ymin=ymax=y;
                              zmin=zmax=z;
                        }
                        else {
                              if (type != PTERNARY) {
                                    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[row].setPoint(x,y,z);
                  };
      
                  // make new Graph3D
                  LRange range[3];
                  range[0] = LRange(xmin,xmax);
                  range[1] = LRange(ymin,ymax);
                  range[2] = LRange(zmin,zmax);
                  Style style;
                  Symbol symbol;
                  kdDebug()<<"X RANGE : "<<xmin<<' '<<xmax<<endl;
                  kdDebug()<<"Y RANGE : "<<ymin<<' '<<ymax<<endl;
                  kdDebug()<<"Z RANGE : "<<zmin<<' '<<zmax<<endl;
      
                  // TODO : sqrt(row)*sqrt(row) unpretty
                  int cols = table->numRows();
                  if(type == PTERNARY)
                        cols=1;
                  Graph3D *g = new Graph3D(caption(),columnTitle(i),range,SSPREADSHEET,type,style,symbol,ptr,
                        table->numRows(),cols);

                  p->addGraph3D(g);
            }
      }
}

void Spreadsheet::plotMatrix(PType type) {
      Worksheet *p = mw->newWorksheet();
      p->newPlot(type);
      
      int NX = table->numCols(), NY = table->numRows();
      double *a = new double[NY*NX];
      
      double z, zmin=0, zmax=1;
      for(int i=0;i<NY;i++) {
            for(int j=0;j<NX;j++) {
                  z = mw->formatLabel(table->text(i,j),formatItem(j));
                  if (!finite(z)) z=0;

                  if(i==0 && j==0) {
                        zmin=zmax=z;
                  }

                  z<zmin?zmin=z:0;
                  z>zmax?zmax=z:0;

                  a[j+NX*i] = z;
            }
      }

      // make new GraphM
      LRange range[3];
      range[0] = LRange(0,NX);
      range[1] = LRange(0,NY);
      range[2] = LRange(zmin,zmax);

      Style style(0);
      Symbol symbol(SNONE);
      GraphM *g = new GraphM(caption(),i18n("Matrix"),range,SSPREADSHEET,type,style,symbol,a,NX,NY);

      p->addGraphM(g,type);
}

void Spreadsheet::cutSelection() {
      copySelection();
      clearSelection();
}

void Spreadsheet::copySelection() {
      QString text;
      QTableSelection ts = table->selection(table->currentSelection());
      
      for (int i=ts.topRow();i<=ts.bottomRow();i++) {
            for (int j=ts.leftCol();j<ts.rightCol();j++)
                  text += table->text(i,j)+"\t";
            text += table->text(i,ts.rightCol())+"\n";
      }
      
      // Copy text into the clipboard
      QApplication::clipboard()->setText(text);
}

void Spreadsheet::pasteSelection() {
      QString text = QApplication::clipboard()->text();

      QStringList rowTexts = QStringList::split ("\n",text,TRUE);
      int rows = int(rowTexts.count())-1;
      QStringList cellTexts = QStringList::split ("\t",rowTexts[0],TRUE);
      int cols = int(cellTexts.count());

      int top,bottom,right,left;
      
      QTableSelection ts = table->selection(table->currentSelection());
#if QT_VERSION > 0x030102
      if (!ts.isEmpty()) {
#else
      if (!((ts.bottomRow()-ts.topRow())*(ts.rightCol()-ts.leftCol()))) {
#endif
            top=ts.topRow();
            bottom=ts.bottomRow();
            left=ts.leftCol();
            right=ts.rightCol();
      }
      else {
            top=0;
            bottom=rows;
            left=ts.leftCol();
            right=ts.leftCol()+cols;
      
            int tableCols=table->numCols();
            if (right>tableCols)
                  right=tableCols-1;
      }
      
      QStringList allCells;   
      for (int i=0;i<rows;i++) {
            cellTexts=QStringList::split ("\t",rowTexts[i],TRUE);
            for (int j=0;j<cols;j++)
                  allCells<<cellTexts[j];
      }
      
      // currentSelection < text
      int col=right-left+1;
      if (rows>(bottom-top+1) || cols>col) {
            switch( KMessageBox::questionYesNo(this,
                  i18n("The text in the clipboard is larger then your current selection!\n")+
                        i18n("Do you want to adjust it to the current selection?")))  {
            case 3:     // Yes
                  for (int i=top;i<=bottom;i++) {
                        for (int j=left;j<=right;j++)
                              table->setText(i,j,allCells[(i-top)*cols+j-left]);
                  }
                  return;
                  break;
            }
      }
      
      // insert text
      for (int i=top;i<top+rows;i++) {
            for (int j=left;j<left+cols;j++)
                  table->setText(i,j,allCells[(i-top)*cols+(j-left)]);
      }
}

void Spreadsheet::clearSelection() {
      QTableSelection ts = table->selection(table->currentSelection());
      
      for(int i=ts.topRow();i<=ts.bottomRow();i++) {
            for(int j=ts.leftCol();j<=ts.rightCol();j++) {
                  table->clearCell(i,j);
                  table->updateCell(i,j);
            }
      }
}

void Spreadsheet::setValues(int startrow, int endrow, QString expression) {
      if(expression.length()<1)
            (new SpreadsheetValuesDialog(mw,table,caption()))->show();
      else{
            if (endrow<=0)
                  endrow=table->numRows();
                  
            for(int i=startrow;i<=endrow;i++) {
                  QString tmp(expression.lower());
            
                  // TODO
                  // replace a,b,c,d,...
                  for(int j=0;j<table->numCols();j++)
                        tmp = mw->parseExpression(tmp,table->text(i-1,j).toDouble(),j);
            
                  double result = parse((char *) tmp.latin1());
                  
                  table->setText(i-1,table->currentColumn(),QString::number(result));
            }
      }     
}

void Spreadsheet::fillRowNumber() {
      for(int i=0;i<table->numRows();i++)
            table->setText(i,table->currentColumn(),QString::number(i+1));    
}

void Spreadsheet::fillRandom(double max) {
      srandom(time(0));
      for(int i=0;i<table->numRows();i++)
            table->setText(i,table->currentColumn(),QString::number(max*random()/(double)RAND_MAX));
}

void Spreadsheet::normSum() {
      // calculate sum
      double sum=0;
      int row=0, col = table->currentColumn();
      do {
            sum += table->text(row,col).toDouble();
            row++;
      }while(table->text(row,0).length()>0);
      
      // set value;
      row=0;
      do {
            double value = table->text(row,col).toDouble();
            table->setText(row,col,QString::number(value/sum));
            row++;
      }while(table->text(row,0).length()>0);
}

void Spreadsheet::normMax(double maximum) {
      // calculate max
      double max=0;
      int row=0, col = table->currentColumn();
      do {
            double value = table->text(row,col).toDouble();
            if(row==0)
                  max=value;
            if(max<value)
                  max = value;
            row++;
      }while(table->text(row,0).length()>0);
      
      // set value;
      row=0;
      do {
            double value = table->text(row,col).toDouble();
            table->setText(row,col,QString::number(maximum*value/max));
            row++;
      }while(table->text(row,0).length()>0);
}

void Spreadsheet::transposeMatrix() {
      int nx = table->numCols();
      int ny = table->numRows();

      QString *data = new QString[nx*ny];
      for(int i=0;i<ny;i++)
            for(int j=0;j<nx;j++)
                  data[j+i*nx]=table->text(i,j);

      table->setNumRows(nx);
      table->setNumCols(ny);
                  
      for(int i=0;i<ny;i++)
            for(int j=0;j<nx;j++)
                  table->setText(j,i,data[j+i*nx]);
}

void Spreadsheet::convertMatrixtoXYZ() {
      int nx = table->numCols();
      int ny = filledRows();
      
      double *data = new double[nx*ny];
      
      for(int i=0;i<ny;i++)
            for(int j=0;j<nx;j++)
                  data[j+i*nx]=table->text(i,j).toDouble();

      table->setNumCols(3);
      table->horizontalHeader()->setLabel( 2, QString( "C {double} [Z]" ) );
      table->setNumRows(nx*ny);
      for(int i=0;i<nx*ny;i++) {
            table->setText(i,0,QString::number(i%nx+1));
            table->setText(i,1,QString::number(i/nx+1));
            table->setText(i,2,QString::number(data[i]));
      }
}

void Spreadsheet::convertXYZtoMatrix() {
      int rows = filledRows();
      
      // find x,y,z column
      int indexx=-1, indexy=-1, indexz=-1;
      for(int i=table->numCols();i>=0;i--) {
            if(table->horizontalHeader()->label(i).findRev("[X]")>0)
                  indexx=i;
            if(table->horizontalHeader()->label(i).findRev("[Y]")>0)
                  indexy=i;
            if(table->horizontalHeader()->label(i).findRev("[Z]")>0)
                  indexz=i;
      }
      
      // sort y
      table->selectColumn(indexy);
      sortAscending();
      // TODO : sort x in segment too
      
      double *data = new double[rows];
      for (int i=0;i<rows;i++)
            data[i]=table->text(i,indexz).toDouble();
      
      // build table
      int nx = (int) sqrt((double)rows);
      table->setNumCols(nx);
      table->setNumRows(nx);
      table->selectColumn(-1);
      
      // fill table
      for(int i=0;i<nx;i++)
            for(int j=0;j<nx;j++)
                  table->setText(j,i,QString::number(data[i+j*nx]));
}

void Spreadsheet::exportData() {
      (new DumpDialog(mw,"spreadsheet",-1))->show();
}

void Spreadsheet::selectColumns(int left, int right) {
      if(right==-1) right=left;
            
      kdDebug()<<"selecting columns "<<left<<" to "<<right<<endl;
      table->selectCells(0,left,table->numRows(),right);
}

void Spreadsheet::selectRows(int top, int bottom){
      if(bottom==-1) bottom=top;
      
      kdDebug()<<"selecting rows "<<top<<" to "<<bottom<<endl;
      table->selectCells(top,0,bottom,table->numCols());
}

void Spreadsheet::deleteRows() {
      QTableSelection ts = table->selection(table->currentSelection());
      kdDebug()<<"removing rows "<<ts.topRow()<<" to row "<<ts.bottomRow()<<endl;

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

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

void Spreadsheet::addColumn() {
      int col = table->numCols();
      table->insertColumns(col);
      if(col<26)
            table->horizontalHeader()->setLabel( col, QChar(col+65)+QString( " {double} [Y]" ) );
      else
            table->horizontalHeader()->setLabel( col, QChar(84)+QString( " {double} [Y]" ) );
}

void Spreadsheet::deleteColumns() {
      QTableSelection ts = table->selection(table->currentSelection());
      kdDebug()<<"removing column "<<ts.leftCol()<<" to column "<<ts.rightCol()<<endl;

      for (int i=ts.rightCol();i>=ts.leftCol();i--)
            table->removeColumn(i);
      
      table->clearSelection();
      table->setCurrentCell(0,0);
}

void Spreadsheet::sortAscending() {
      ascending=TRUE;
      sort();
}

void Spreadsheet::sortDescending() {
      ascending=FALSE;
      sort();
}

void Spreadsheet::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 Spreadsheet::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 Spreadsheet::setProperties(QString label, int type, int format, int rows) {
      if(label.length()<1)
            (new SpreadsheetPropertiesDialog(table,caption()))->show();
      else {
            table->setNumRows(rows);
            table->horizontalHeader()->setLabel(table->currentColumn(),label +' '+ 
                  formatList[format]+' '+columnTypeItems[type]);
      }
}

Generated by  Doxygen 1.6.0   Back to index