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
00045
00046
00047
00048
00049
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
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
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
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
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
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 }