spreadtable.cpp

Go to the documentation of this file.
00001 #include <qpainter.h>
00002 #include <qimage.h>
00003 #include <qlineedit.h>
00004 #include <qpalette.h>
00005 #include <typeinfo>
00006 #include "iis.h"
00007 #include "value.h"
00008 #include "vars.h"
00009 #include "refs.h"
00010 #include "runtime.h"
00011 #include "spreadsheet.h"
00012 #include "version.h"
00013 
00014 SpreadSheetTable::SpreadSheetTable( int numRows, int numCols, QWidget * parent, const char * name ):
00015   QTable(numRows, numCols, parent, name)
00016 {
00017 }
00018 
00019 QWidget * SpreadSheetTable::beginEdit ( int row, int col, bool replace )
00020 {
00021   if (!item(row,col))
00022     setItem(row,col,new IisCell(this, QTableItem::OnTyping ));
00023   return QTable::beginEdit(row,col,replace);
00024 }
00025 
00026 void SpreadSheetTable::queue_recalculation(IisCell * ss)
00027 {
00028   if (!ss) return;
00029   restart_recalcing();
00030   if (needs_recalculation.empty())
00031     {
00032       needs_recalculation.push_back(ss);
00033       return;
00034     }
00035   for(list<IisCell*>::iterator it=needs_recalculation.begin() ;
00036       it != needs_recalculation.end() ;
00037       it++)
00038     if (*it==ss) return;
00039   needs_recalculation.push_back(ss);
00040 }
00041 
00042 void SpreadSheetTable::insertRows(int from, int nr)
00043 {
00044   // the standard function allocates new row numbers, which is wrong,
00045   // we need to go through the entire table and shift all rows down
00046   // therefore we need to go from bottom to top through all the rows
00047   // we normally should not be changing the values, the formules however 
00048   // require updating
00049   // we cannot do this during recalculations,
00050   int br = numRows();
00051   int mc = numCols();
00052   for(int row = br-1-nr ; row >=0; row--)
00053     for(int col = 0 ; col <mc ; col++)
00054       {
00055         QTableItem * i = item(row,col);
00056         if (row>=from)
00057           {
00058             takeItem(i);
00059             setItem(row+nr,col,i);
00060             setItem(row,col,NULL);
00061           }
00062         if (i)
00063           {
00064             IisCell * ss = (IisCell*)i;
00065             ss->rowsInserted(from,nr);
00066           }
00067       }
00068 }
00069 
00070 void SpreadSheetTable::insertCols(int from, int nr)
00071 {
00072   int br = numRows();
00073   int mc = numCols();
00074   for(int col = mc-1-nr ; col >=0 ; col--)
00075     for(int row = 0 ; row <br; row++)
00076       {
00077         QTableItem * i = item(row,col);
00078         if (col>=from)
00079           {
00080             takeItem(i);
00081             setItem(row,col+nr,i);
00082             setItem(row,col,NULL);
00083           }
00084         if (i)
00085           {
00086             IisCell * ss = (IisCell*)i;
00087             ss->colsInserted(from,nr);
00088           }
00089       }
00090 }
00091 
00092 void SpreadSheetTable::insertRows()
00093 {
00094   // find the selection
00095   int cs = currentSelection();
00096   if (cs>=0)
00097     {
00098       QTableSelection S = selection(cs);
00099       int tr = S.topRow();
00100       int br = S.bottomRow();
00101       printf("Inserting %d rows at %d\n",1+br-tr,tr);
00102       insertRows(tr,1+br-tr);
00103     }
00104   else
00105     {
00106       printf("Inserting 1 row at %d\n",currentRow());
00107       insertRows(currentRow(),1);
00108     }
00109 }
00110 
00111 void SpreadSheetTable::insertCols()
00112 {
00113   // find the selection
00114   int cs = currentSelection();
00115   if (cs>=0)
00116     {
00117       QTableSelection S = selection(cs);
00118       int br = S.rightCol();
00119       int tr = S.leftCol();
00120       printf("Inserting %d cols at %d\n",1+br-tr,tr);
00121       insertCols(tr,1+br-tr);
00122     }
00123   else
00124     {
00125       printf("Inserting 1 col at %d\n",currentColumn());
00126       insertCols(currentColumn(),1);
00127     }
00128 }
00129 
00130 void SpreadSheetTable::copyRight()
00131 {
00132   int cs = currentSelection();
00133   if (cs==-1) return;
00134   QTableSelection S = selection(cs);
00135   for(int row = S.topRow() ; row <= S.bottomRow() ; row++)
00136     {
00137       IisCell *left = (IisCell*)item(row,S.leftCol());
00138       if (left)
00139         {
00140           for(int col = S.leftCol() + 1; col <= S.rightCol() ; col++)
00141             {
00142               if (!item(row,col))
00143                 setItem(row,col,new IisCell(this, QTableItem::OnTyping ));
00144               setText(row,col,left->getFormuleTextForCell(col,row));
00145             }
00146         }
00147     }
00148 }
00149 
00150 void SpreadSheetTable::copyDown()
00151 {
00152   int cs = currentSelection();
00153   if (cs==-1) return;
00154   QTableSelection S = selection(cs);
00155   for(int col = S.leftCol() ; col <= S.rightCol() ; col++)
00156     {
00157       IisCell *top = (IisCell*)item(S.topRow(),col);
00158       if (top)
00159         for(int row = S.topRow() + 1 ; row <= S.bottomRow() ; row++)
00160           {
00161             if (!item(row,col))
00162               setItem(row,col,new IisCell(this, QTableItem::OnTyping ));
00163             setText(row,col,top->getFormuleTextForCell(col,row));
00164           }
00165     }
00166 }
00167 
00168 void SpreadSheetTable::restart_recalcing()
00169 {
00170   mainapp->postEvent(this,new QCustomEvent(QEvent::User+1));
00171 }
00172 
00173 void SpreadSheetTable::recalc()
00174 {
00175   if (needs_recalculation.empty())
00176     return;
00177   IisCell * found = NULL;
00178   list<IisCell*>::iterator it;
00179   for(it = needs_recalculation.begin() ; it != needs_recalculation.end(); it++)
00180     {
00181       IisCell *sc = *it;
00182       assert(sc);
00183       if (sc->can_be_calculated_now())
00184         {
00185           found=sc;
00186           break;
00187         }
00188     }
00189   if (!found) return;
00190   needs_recalculation.erase(it);
00191   found->recalc();
00192   if (!needs_recalculation.empty())
00193     restart_recalcing();
00194 }
00195 
00196 void SpreadSheetTable::customEvent( QCustomEvent * e )
00197 {
00198   if ( e->type() == QEvent::User+1 )
00199     recalc();
00200 }
00201 
00202 void SpreadSheetTable::status_selection(bool force_recalc, bool allow_ui)
00203 {
00204   if (numSelections()==0)
00205     {
00206       IisCell * s = (IisCell *)item(currentRow(),currentColumn());
00207       if (!s) return;
00208       if (force_recalc) s->mark_recalc();
00209       if (allow_ui) s->mark_allow_ui();
00210     }
00211   else
00212     for(int i = 0 ; i < numSelections() ; i ++)
00213       {
00214         QTableSelection ts = selection(i);
00215         if (!ts.isActive()) continue;
00216         if (ts.isEmpty()) continue;
00217         for(int x = ts.leftCol() ; x <= ts.rightCol() ; x++)
00218           for(int y = ts.topRow() ; y <= ts.bottomRow() ; y++)
00219             {
00220               IisCell * s = (IisCell *)item(y,x);
00221               if (!s) continue;
00222               if (force_recalc) s->mark_recalc();
00223               if (allow_ui) s->mark_allow_ui();
00224             }
00225       }
00226   restart_recalcing();
00227 }
00228 
00229 IisCell * SpreadSheetTable::findItem(int row, int col)
00230 {
00231   IisCell * sc = (IisCell *) item(row,col);
00232   if (sc) return sc;
00233   // printf("Unable to find item at row %d and col %d\n",row,col);
00234   sc = new IisCell(this, QTableItem::OnTyping);
00235   setItem(row,col,sc);
00236   return sc;
00237 }
00238 
00239 void SpreadSheetTable::saveFile(QString filename_prefix)
00240 {
00241   int br = numRows();
00242   int mc = numCols();
00243   // count the number;
00244   int count = 0;
00245   for(int col = 0 ; col < mc ; col++)
00246     for(int row = 0 ; row < br; row++)
00247       if (item(row,col)) count++;
00248   Array<2,Data> content(count,2);
00249   int pos = 0;
00250   for(int col = 0 ; col < mc ; col++)
00251     for(int row = 0 ; row < br; row++)
00252       {
00253         QTableItem * i = item(row,col);
00254         if (!i) continue;
00255         Reference ref(col,row,false,false);
00256         content[Position<2>(pos,0)]=ref.getSaveDescription(filename_prefix);
00257         IisCell * c = (IisCell*)i;
00258         content[Position<2>(pos,1)]=c->saveFile(filename_prefix);
00259         pos++;
00260       }
00261   Token all;
00262   all["data"]=content;
00263   all["version"]=String(IIS_VERSION);
00264   QString actual_filename = filename_prefix;
00265   if (!actual_filename.endsWith(IIS_EXTENSION))
00266     actual_filename+=IIS_EXTENSION;
00267   DataTexter::write(all,actual_filename);
00268 }
00269 
00270 void SpreadSheetTable::loadFile(QString filename)
00271 {
00272   Data all_unlabeled = DataTexter::read_file((const char*)filename);
00273   Token all = all_unlabeled;
00274   Data general_content = all["data"];
00275   String version = (String)all["version"];
00276   Array<2,Data> content = general_content;
00277   // go through all the cells
00278   for(Array<2,Data>::vector_values i(content,0) ; i.more(); ++i)
00279     {
00280       Array<1,Data> &cell = i;
00281       Reference cellid((Token)cell[0]);
00282       IisCell * spreadcell = findItem(cellid.row,cellid.column);
00283       assert(spreadcell);
00284       Data   cellcontent = cell[1];
00285       spreadcell->load(cellcontent);
00286     }
00287 }

Generated on Mon Jun 5 22:08:42 2006 for iis by  doxygen 1.4.6