![]() |
TinkerCell Core 1.0
TinkerCell's Core library providing all basic functionalities
|
00001 /**************************************************************************** 00002 00003 Copyright (c) 2008 Deepak Chandran 00004 Contact: Deepak Chandran (dchandran1@gmail.com) 00005 See COPYRIGHT.TXT 00006 00007 This file defines the DataTable class. 00008 The DataTable is a template class that contains a 2D vector (values) and two vectors 00009 of QStrings (row names and column names). It provides various functions for manipulating 00010 the table. 00011 00012 ****************************************************************************/ 00013 00014 #ifndef TINKERCELL_DATATABLE_H 00015 #define TINKERCELL_DATATABLE_H 00016 00017 #include <QList> 00018 #include <QHash> 00019 #include <QVector> 00020 #include <QString> 00021 #include <QStringList> 00022 #include <QUndoCommand> 00023 #include <QDebug> 00024 00025 #ifndef TINKERCELLCOREEXPORT 00026 #ifdef Q_WS_WIN 00027 # if defined(TC_EXPORTS) || defined(TinkerCellCore_EXPORTS) 00028 # define TINKERCELLCOREEXPORT __declspec(dllexport) 00029 # else 00030 # define TINKERCELLCOREEXPORT __declspec(dllimport) 00031 # endif 00032 #else 00033 # define TINKERCELLCOREEXPORT 00034 #endif 00035 #endif 00036 00037 namespace Tinkercell 00038 { 00042 template <typename T> 00043 class TINKERCELLCOREEXPORT DataTable 00044 { 00045 protected: 00047 QVector<T> dataMatrix; 00049 QVector<QString> colHeaders, rowHeaders; 00051 QHash<QString,int> colHash, rowHash; 00053 QString desc; 00054 00055 public: 00056 00058 virtual ~DataTable(); 00059 00061 DataTable(); 00062 00064 DataTable(int rows,int columns); 00065 00067 virtual QString description() const; 00068 00070 virtual QString& description(); 00071 00075 virtual QStringList columnNames() const; 00080 virtual bool hasRow(const QString&) const; 00085 virtual bool hasColumn(const QString&) const; 00089 virtual QStringList rowNames() const; 00090 00095 virtual QString rowName(int i) const; 00096 00101 virtual QString columnName(int i) const; 00102 00108 virtual bool setRowName(int i, const QString& name); 00109 00115 virtual bool setColumnName(int i, const QString& name); 00116 00121 virtual void setColumnNames(const QStringList& names); 00122 00127 virtual void setRowNames(const QStringList& names); 00128 00132 virtual int rows() const; 00133 00137 virtual int columns() const; 00138 00144 virtual T& value (int i, int j=0) ; 00145 00151 virtual T& operator() (int i, int j=0) ; 00152 00158 virtual T operator() (int i, int j=0) const; 00159 00165 virtual T& value (const QString& r, const QString& c); 00166 00172 virtual T& operator() (const QString& r, const QString& c); 00173 00179 virtual T operator() (const QString& r, const QString& c) const; 00180 00186 virtual T& value (const QString& r, int j=0); 00187 00193 virtual T& operator() (const QString& r, int j=0); 00194 00200 virtual T operator() (const QString& r, int j=0) const; 00201 00207 virtual T& value (int i, const QString& c); 00208 00214 virtual T& operator() (int i, const QString& c); 00215 00221 virtual T operator() (int i, const QString& c) const; 00222 00227 virtual bool operator == (const DataTable<T>& D); 00228 00233 virtual bool operator != (const DataTable<T>& D); 00234 00240 virtual T at (int i, int j=0) const; 00241 00247 virtual T at (const QString& r, const QString& c) const; 00248 00254 virtual T at (const QString& r, int j=0) const; 00255 00261 virtual T at (int i, const QString& c) const; 00262 00268 virtual void resize(int m, int n=1); 00269 00276 virtual bool insertRow(int k, const QString& row); 00277 00284 virtual bool insertColumn(int k, const QString& col); 00285 00290 virtual bool removeRow(int k); 00291 00296 virtual bool removeRow(const QString& name); 00297 00302 virtual bool removeColumn(int k); 00303 00308 virtual bool removeColumn(const QString& name); 00309 00315 virtual void swapRows(int i1, int i2); 00316 00322 virtual void swapColumns(int j1, int j2); 00323 00329 virtual void swapRows(const QString& s1, const QString& s2); 00330 00336 virtual void swapColumns(const QString& s1, const QString& s2); 00337 00341 virtual DataTable<T> transpose() const; 00342 00343 }; 00344 00345 00350 template <typename T> 00351 class TINKERCELLCOREEXPORT ChangeDataCommand : public QUndoCommand 00352 { 00353 public: 00359 ChangeDataCommand(const QString& name, DataTable<T>* oldDataTable, const DataTable<T>* newDataTable); 00365 ChangeDataCommand(const QString& name,const QList< DataTable<T>* >& oldDataTable,const QList< DataTable<T>* >& newDataTable); 00367 void redo(); 00369 void undo(); 00371 QList< DataTable<T>* > targetDataTable; 00373 QList< DataTable<T> > newDataTable; 00375 QList< DataTable<T> > oldDataTable; 00376 }; 00377 00381 template <typename T1, typename T2> 00382 class TINKERCELLCOREEXPORT Change2DataCommand : public QUndoCommand 00383 { 00384 public: 00392 Change2DataCommand(const QString& name, DataTable<T1>* oldDataTable1, const DataTable<T1>* newDataTable1, DataTable<T2>* oldDataTable2, const DataTable<T2>* newDataTable2); 00400 Change2DataCommand(const QString& name,const QList< DataTable<T1>* >& oldDataTable1,const QList< DataTable<T1>* >& newDataTable1,const QList< DataTable<T2>* >& oldDataTable2,const QList< DataTable<T2>* >& newDataTable2); 00402 void redo(); 00404 void undo(); 00406 QList< DataTable<T1>* > targetDataTable1; 00408 QList< DataTable<T1> > newDataTable1; 00410 QList< DataTable<T1> > oldDataTable1; 00412 QList< DataTable<T2>* > targetDataTable2; 00414 QList< DataTable<T2> > newDataTable2; 00416 QList< DataTable<T2> > oldDataTable2; 00417 }; 00418 00419 #if defined(TC_EXPORTS) || defined(TinkerCellCore_EXPORTS) 00420 00422 template <typename T> 00423 DataTable<T>::~DataTable() 00424 { 00425 } 00426 00428 template <typename T> 00429 DataTable<T>::DataTable() 00430 { 00431 } 00432 00434 template <typename T> 00435 DataTable<T>::DataTable(int r,int c) 00436 { 00437 resize(r,c); 00438 } 00439 00440 template <typename T> QString DataTable<T>::description() const { return desc; } 00441 00443 template <typename T> QString& DataTable<T>::description() { return desc; } 00444 00448 template <typename T> QStringList DataTable<T>::columnNames() const { return QStringList(colHeaders.toList()); } 00452 template <typename T> QStringList DataTable<T>::rowNames() const { return QStringList(rowHeaders.toList()); } 00457 template <typename T> bool DataTable<T>::hasRow(const QString& s) const { return rowHash.contains(s); } 00462 template <typename T> bool DataTable<T>::hasColumn(const QString& s) const { return colHash.contains(s); } 00468 template <typename T> bool DataTable<T>::setColumnName(int i, const QString& name) 00469 { 00470 if (colHash.contains(name)) 00471 { 00472 /*if (colHash[name] != i) 00473 { 00474 int k = colHash[name]; 00475 removeColumn(i); 00476 if (k > i) 00477 --i; 00478 } 00479 else*/ 00480 return false; 00481 } 00482 00483 if (i < 0) 00484 i = 0; 00485 00486 if (i >= colHeaders.size()) 00487 resize(rowHeaders.size(), i+1); 00488 colHash.remove(colHeaders[i]); 00489 colHeaders[i]= name; 00490 colHash[name] = i; 00491 return true; 00492 } 00497 template <typename T> QString DataTable<T>::rowName(int i) const 00498 { 00499 if (i < 0 || i >= rowHeaders.size()) 00500 { 00501 return QString(); 00502 } 00503 return rowHeaders.at(i); 00504 } 00509 template <typename T> QString DataTable<T>::columnName(int i) const 00510 { 00511 if (i < 0 || i >= colHeaders.size()) 00512 return QString(); 00513 return colHeaders.at(i); 00514 } 00519 template <typename T> bool DataTable<T>::setRowName(int i, const QString& name) 00520 { 00521 if (rowHash.contains(name)) 00522 { 00523 /*if (rowHash[name] != i) 00524 { 00525 int k = rowHash[name]; 00526 removeRow(i); 00527 if (k > i) 00528 --i; 00529 } 00530 else*/ 00531 return false; 00532 } 00533 00534 if (i < 0) 00535 i = 0; 00536 00537 if (i >= rowHeaders.size()) 00538 resize(i+1, colHeaders.size()); 00539 rowHash.remove(rowHeaders[i]); 00540 rowHeaders[i] = name; 00541 rowHash[name] = i; 00542 return true; 00543 } 00548 template <typename T> void DataTable<T>::setColumnNames(const QStringList& lst) 00549 { 00550 QStringList names; 00551 for (int i=0; i < lst.size(); ++i) 00552 if (!names.contains(lst[i])) 00553 names << lst[i]; 00554 if (names.size() != colHeaders.size()) 00555 resize(rowHeaders.size(),names.size()); 00556 colHeaders = QVector<QString>::fromList(names); 00557 colHash.clear(); 00558 for (int i=0; i < names.size(); ++i) 00559 colHash[ names[i] ] = i; 00560 } 00565 template <typename T> void DataTable<T>::setRowNames(const QStringList& lst) 00566 { 00567 QStringList names; 00568 for (int i=0; i < lst.size(); ++i) 00569 if (!names.contains(lst[i])) 00570 names << lst[i]; 00571 if (names.size() != colHeaders.size()) 00572 resize(names.size(),colHeaders.size()); 00573 rowHeaders = QVector<QString>::fromList(names); 00574 00575 rowHash.clear(); 00576 for (int i=0; i < names.size(); ++i) 00577 rowHash[ names[i] ] = i; 00578 } 00582 template <typename T> int DataTable<T>::rows() const 00583 { 00584 return rowHeaders.size(); 00585 } 00589 template <typename T> int DataTable<T>::columns() const 00590 { 00591 return colHeaders.size(); 00592 } 00598 template <typename T> T& DataTable<T>::value (int i, int j) 00599 { 00600 if (i < 0) i = 0; 00601 if (j < 0) j = 0; 00602 00603 int k = i*colHeaders.size()+j; 00604 if (k >= dataMatrix.size() || j >= colHeaders.size() || i >= rowHeaders.size()) 00605 { 00606 int m = rowHeaders.size(), n = colHeaders.size(); 00607 if (i >= rowHeaders.size()) m = i + 1; 00608 if (j >= colHeaders.size()) n = j + 1; 00609 while (k >= m*n) ++m; 00610 resize(m,n); 00611 } 00612 00613 return dataMatrix[k]; 00614 } 00621 template <typename T> T& DataTable<T>::value (const QString& r, const QString& c) 00622 { 00623 int m = rowHeaders.size(), n = colHeaders.size(); 00624 if (!rowHash.contains(r)) 00625 ++m; 00626 if (!colHash.contains(c)) 00627 ++n; 00628 if (m != rowHeaders.size() || n != colHeaders.size()) 00629 { 00630 resize(m,n); 00631 if (!rowHash.contains(r)) 00632 { 00633 rowHeaders[ rowHeaders.size()-1 ] = r; 00634 rowHash[ r ] = rowHeaders.size()-1; 00635 } 00636 if (!colHeaders.contains(c)) 00637 { 00638 colHeaders[ colHeaders.size()-1 ] = c; 00639 colHash[ c ] = colHeaders.size()-1; 00640 } 00641 } 00642 int i = rowHash[r], j = colHash[c]; 00643 return value(i,j); 00644 } 00651 template <typename T> T& DataTable<T>::value (const QString& r, int j) 00652 { 00653 int m = rowHeaders.size(), n = colHeaders.size(); 00654 if (!rowHash.contains(r)) 00655 ++m; 00656 if (j >= n) 00657 n = j + 1; 00658 if (m != rowHeaders.size() || n != colHeaders.size()) 00659 { 00660 resize(m,n); 00661 if (!rowHash.contains(r)) 00662 { 00663 rowHeaders[ rowHeaders.size()-1 ] = r; 00664 rowHash[ r ] = rowHeaders.size()-1; 00665 } 00666 } 00667 int i = rowHash[r]; 00668 return value(i,j); 00669 } 00676 template <typename T> T& DataTable<T>::value (int i, const QString& c) 00677 { 00678 int m = rowHeaders.size(), n = colHeaders.size(); 00679 if (!colHash.contains(c)) 00680 ++n; 00681 if (i >= m) 00682 m = i + 1; 00683 if (m != rowHeaders.size() || n != colHeaders.size()) 00684 { 00685 resize(m,n); 00686 if (!colHash.contains(c)) 00687 { 00688 colHeaders[ colHeaders.size()-1 ] = c; 00689 colHash[ c ] = colHeaders.size()-1; 00690 } 00691 } 00692 int j = colHash[c]; 00693 return value(i,j); 00694 } 00699 template <typename T> bool DataTable<T>::operator == (const DataTable<T>& D) 00700 { 00701 return dataMatrix == D.dataMatrix && colHeaders == D.colHeaders && rowHeaders == D.rowHeaders; 00702 } 00707 template <typename T> bool DataTable<T>::operator != (const DataTable<T>& D) 00708 { 00709 return !( operator==(D) ); 00710 } 00716 template <typename T> T DataTable<T>::at (int i, int j) const 00717 { 00718 if (i < 0) i = 0; 00719 if (j < 0) j = 0; 00720 00721 int k = i*colHeaders.size()+j; 00722 if (k >= dataMatrix.size() || j >= colHeaders.size() || i >= rowHeaders.size()) 00723 { 00724 return T(); 00725 } 00726 00727 return dataMatrix.at(k); 00728 } 00734 template <typename T> T DataTable<T>::at (const QString& r, const QString& c) const 00735 { 00736 if (!rowHash.contains(r) || !colHash.contains(c)) 00737 return T(); 00738 00739 int i = rowHash[r], j = colHash[c]; 00740 return at(i,j); 00741 } 00747 template <typename T> T DataTable<T>::at (const QString& r, int j) const 00748 { 00749 if (!rowHash.contains(r)) 00750 return T(); 00751 00752 int i = rowHash[r]; 00753 return at(i,j); 00754 } 00760 template <typename T> T DataTable<T>::at (int i, const QString& c) const 00761 { 00762 if (!colHash.contains(c)) 00763 return T(); 00764 00765 int j = colHash[c]; 00766 return at(i,j); 00767 } 00773 template <typename T> void DataTable<T>::resize(int m, int n) 00774 { 00775 if (m < 0 || n < 0) return; 00776 00777 int m0 = rowHeaders.size(), n0 = colHeaders.size(); 00778 QVector<T> oldMatrix(dataMatrix); 00779 00780 if (m < m0) 00781 for (int i=m; i < m0; ++i) 00782 rowHash.remove( rowHeaders[i] ); 00783 00784 if (n < n0) 00785 for (int i=n; i < n0; ++i) 00786 colHash.remove( colHeaders[i] ); 00787 00788 dataMatrix.clear(); 00789 dataMatrix.resize(m*n); 00790 rowHeaders.resize(m); 00791 colHeaders.resize(n); 00792 00793 int k0=0, k1=0; 00794 for (int i=0; i < m0 && i < m; ++i) 00795 for (int j=0; j < n0 && j < n; ++j) 00796 { 00797 k0 = i*n0 + j; 00798 k1 = i*n + j; 00799 dataMatrix[k1] = oldMatrix[k0]; 00800 } 00801 } 00808 template <typename T> bool DataTable<T>::insertRow(int k, const QString& row) 00809 { 00810 if (rowHash.contains(row)) return false; 00811 int m = rowHeaders.size(); 00812 resize( m+1, colHeaders.size() ); 00813 rowHeaders[ m ] = row; 00814 rowHash[ row ] = m; 00815 return true; 00816 } 00823 template <typename T> bool DataTable<T>::insertColumn(int k, const QString& col) 00824 { 00825 if (colHash.contains(col)) return false; 00826 int n = colHeaders.size(); 00827 resize( rowHeaders.size() , n + 1 ); 00828 colHeaders[ n ] = col; 00829 colHash[ col ] = n; 00830 return true; 00831 } 00836 template <typename T> bool DataTable<T>::removeRow(int k) 00837 { 00838 if (k < 0 || k >= rowHeaders.size()) return false; 00839 int n = rowHeaders.size()-1; 00840 00841 QVector<T> dataMatrix2( n * colHeaders.size() ); 00842 00843 for (int i=0; i < rowHeaders.size(); ++i) 00844 for (int j=0; j < colHeaders.size(); ++j) 00845 { 00846 if (i < k) 00847 dataMatrix2[ i*colHeaders.size()+j ] = dataMatrix[ i*colHeaders.size()+j ]; 00848 else 00849 if (i > k) 00850 dataMatrix2[ (i-1)*colHeaders.size()+j ] = dataMatrix[ i*colHeaders.size()+j ]; 00851 } 00852 00853 dataMatrix = dataMatrix2; 00854 rowHash.clear(); 00855 rowHeaders.remove(k); 00856 00857 for (int i=0; i < rowHeaders.size(); ++i) 00858 rowHash[ rowHeaders[i] ] = i; 00859 00860 return true; 00861 } 00866 template <typename T> bool DataTable<T>::removeRow(const QString& name) 00867 { 00868 if (rowHash.contains(name)) 00869 return removeRow(rowHash[name]); 00870 return false; 00871 } 00876 template <typename T> bool DataTable<T>::removeColumn(int k) 00877 { 00878 if (k < 0 || k >= colHeaders.size()) return false; 00879 00880 int n = colHeaders.size()-1; 00881 00882 QVector<T> dataMatrix2( n * rowHeaders.size() ); 00883 00884 for (int i=0; i < rowHeaders.size(); ++i) 00885 for (int j=0; j < colHeaders.size(); ++j) 00886 { 00887 if (j < k) 00888 dataMatrix2[ i*n+j ] = dataMatrix[ i*colHeaders.size()+j ]; 00889 else 00890 if (j > k) 00891 dataMatrix2[ i*n+j-1 ] = dataMatrix[ i*colHeaders.size()+j ]; 00892 } 00893 00894 dataMatrix = dataMatrix2; 00895 colHash.clear(); 00896 colHeaders.remove(k); 00897 00898 for (int i=0; i < colHeaders.size(); ++i) 00899 colHash[ colHeaders[i] ] = i; 00900 00901 return true; 00902 } 00907 template <typename T> bool DataTable<T>::removeColumn(const QString& name) 00908 { 00909 if (colHash.contains(name)) 00910 return removeColumn(colHash[name]); 00911 return false; 00912 } 00918 template <typename T> void DataTable<T>::swapRows(int i1, int i2) 00919 { 00920 if (i1 < 0 || i2 < 0 || i1 >= rowHeaders.size() || i2 >= rowHeaders.size()) return; 00921 00922 QString str = rowHeaders[i1]; 00923 rowHeaders[i1] = rowHeaders[i2]; 00924 rowHeaders[i2] = str; 00925 00926 rowHash[ rowHeaders[i1] ] = i1; 00927 rowHash[ rowHeaders[i2] ] = i2; 00928 00929 int n = colHeaders.size(); 00930 int k1,k2; 00931 T temp; 00932 for (int j=0; j < n; ++j) 00933 { 00934 k1 = i1*n + j; 00935 k2 = i2*n + j; 00936 temp = dataMatrix[k1]; 00937 dataMatrix[k1] = dataMatrix[k2]; 00938 dataMatrix[k2] = temp; 00939 } 00940 } 00946 template <typename T> void DataTable<T>::swapColumns(int j1, int j2) 00947 { 00948 if (j1 < 0 || j2 < 0 || j1 >= colHeaders.size() || j2 >= colHeaders.size()) return; 00949 00950 QString str = colHeaders[j1]; 00951 colHeaders[j1] = colHeaders[j2]; 00952 colHeaders[j2] = str; 00953 00954 colHash[ colHeaders[j1] ] = j1; 00955 colHash[ colHeaders[j2] ] = j2; 00956 00957 int n = colHeaders.size(), m = rowHeaders.size(); 00958 int k1,k2; 00959 T temp; 00960 for (int i=0; i < m; ++i) 00961 { 00962 k1 = i*n + j1; 00963 k2 = i*n + j2; 00964 temp = dataMatrix[k1]; 00965 dataMatrix[k1] = dataMatrix[k2]; 00966 dataMatrix[k2] = temp; 00967 } 00968 } 00974 template <typename T> void DataTable<T>::swapRows(const QString& s1, const QString& s2) 00975 { 00976 if (rowHash.contains(s1) && rowHash.contains(s2)) 00977 swapRows( rowHash[s1], rowHash[s2] ); 00978 } 00984 template <typename T> void DataTable<T>::swapColumns(const QString& s1, const QString& s2) 00985 { 00986 if (colHash.contains(s1) && colHash.contains(s2)) 00987 swapColumns( colHash[s1], colHash[s2] ); 00988 } 00992 template <typename T> DataTable<T> DataTable<T>::transpose() const 00993 { 00994 DataTable<T> newTable; 00995 newTable.resize( colHeaders.size(), rowHeaders.size() ); 00996 00997 newTable.colHeaders = rowHeaders; 00998 newTable.rowHeaders = colHeaders; 00999 newTable.rowHash = rowHash; 01000 newTable.colHash = colHash; 01001 01002 for (int i=0; i < rows(); ++i) 01003 for (int j=0; j < columns(); ++j) 01004 newTable.value(j,i) = at(i,j); 01005 01006 return newTable; 01007 } 01008 /* 01009 template <typename T> void DataTable<T>::appendRows(DataTable<T>* other) 01010 { 01011 QList< DataTable<T> * > list; 01012 list << this << other; 01013 DataTable<T> A = appendRows(list); 01014 dataMatrix = A.dataMatrix; 01015 rowHeaders = A.rowHeaders; 01016 colHeaders = A.colHeaders; 01017 colHash = A.colHash; 01018 rowHash = A.rowHash; 01019 } 01020 01021 template <typename T> DataTable<T> DataTable<T>::appendRows(const QList< DataTable<T>* >& list) 01022 { 01023 DataTable<T> newTable; 01024 QHash<QString,int> colHash, rowHash; 01025 QStringList colHeaders, rowHeaders; 01026 01027 QString s; 01028 01029 int rows = 0, cols = 0, p; 01030 01031 for (int i=0; i < list.size(); ++i) 01032 if (list[i]) 01033 { 01034 for (int j=0; j < list[i]->rows(); ++j) //get all rows with unique names 01035 { 01036 s = list[i]->rowName(j); 01037 p = rows; 01038 if (s.isEmpty() || !rowHash.contains(s)) 01039 { 01040 rowHeaders << s; 01041 if (!s.isEmpty()) 01042 rowHash[s] = rows; 01043 ++rows; 01044 } 01045 } 01046 01047 for (int j=0; j < list[i]->columns(); ++j) //get all rows with unique names 01048 { 01049 s = list[i]->columnName(j); 01050 if (s.isEmpty() || !colHash.contains(s)) 01051 { 01052 colHeaders << s; 01053 if (!s.isEmpty()) 01054 colHash[s] = rows; 01055 ++cols; 01056 } 01057 } 01058 } 01059 01060 newTable.resize(rows,cols); 01061 for (int i=0; i < colHeaders.size(); ++i) 01062 newTable.colHeaders[i] = colHeaders[i]; 01063 newTable.colHash = colHash; 01064 for (int i=0; i < rowHeaders.size(); ++i) 01065 newTable.rowHeaders[i] = rowHeaders[i]; 01066 newTable.rowHash = rowHash; 01067 01068 rows = 0; 01069 for (int i=0; i < list.size(); ++i) 01070 if (list[i]) 01071 { 01072 for (int j=0; j < list[i]->columns(); ++j) //get all rows with unique names 01073 { 01074 if (colHash.contains(list[i]->columnName(j))) 01075 cols = colHash[ list[i]->columnName(j) ]; 01076 else 01077 cols = j; 01078 for (int k=0; k < list[i]->rows(); ++k) 01079 { 01080 newTable.value(rows, cols) = list[i]->value(k, j); 01081 ++rows; 01082 } 01083 } 01084 } 01085 01086 return newTable; 01087 } 01088 01089 template <typename T> void DataTable<T>::appendColumns(DataTable<T>* other) 01090 { 01091 QList< DataTable<T> * > list; 01092 list << this << other; 01093 DataTable<T> A = appendColumns(list); 01094 dataMatrix = A.dataMatrix; 01095 rowHeaders = A.rowHeaders; 01096 colHeaders = A.colHeaders; 01097 colHash = A.colHash; 01098 rowHash = A.rowHash; 01099 } 01100 01101 template <typename T> DataTable<T> DataTable<T>::appendColumns(const QList< DataTable<T>* >& list) 01102 { 01103 DataTable<T> newTable; 01104 QHash<QString,int> colHash, rowHash; 01105 QStringList colHeaders, rowHeaders; 01106 01107 QString s; 01108 01109 int rows = 0, cols = 0, p; 01110 01111 for (int i=0; i < list.size(); ++i) 01112 if (list[i]) 01113 { 01114 for (int j=0; j < list[i]->rows(); ++j) //get all rows with unique names 01115 { 01116 s = list[i]->rowName(j); 01117 if (s.isEmpty() ||!rowHash.contains(s)) 01118 { 01119 rowHeaders << s; 01120 if (!s.isEmpty()) 01121 rowHash[s] = rows; 01122 ++rows; 01123 } 01124 } 01125 01126 for (int j=0; j < list[i]->columns(); ++j) //get all rows with unique names 01127 { 01128 s = list[i]->columnName(j); 01129 p = cols; 01130 if (s.isEmpty() || !colHash.contains(s)) 01131 { 01132 colHeaders << s; 01133 if (!s.isEmpty()) 01134 colHash[s] = cols; 01135 ++cols; 01136 } 01137 } 01138 } 01139 01140 newTable.resize(rows,cols); 01141 for (int i=0; i < colHeaders.size(); ++i) 01142 newTable.colHeaders[i] = colHeaders[i]; 01143 newTable.colHash = colHash; 01144 for (int i=0; i < rowHeaders.size(); ++i) 01145 newTable.rowHeaders[i] = rowHeaders[i]; 01146 newTable.rowHash = rowHash; 01147 01148 cols = 0; 01149 for (int i=0; i < list.size(); ++i) 01150 if (list[i]) 01151 { 01152 for (int j=0; j < list[i]->rows(); ++j) //get all rows with unique names 01153 { 01154 if (rowHash.contains(list[i]->rowName(j))) 01155 rows = rowHash[ list[i]->rowName(j) ]; 01156 else 01157 rows = j; 01158 for (int k=0; k < list[i]->columns(); ++k) 01159 { 01160 newTable.value(rows, cols) = list[i]->value(j, k); 01161 ++cols; 01162 } 01163 } 01164 } 01165 01166 return newTable; 01167 } 01168 */ 01169 01170 template <typename T> T& DataTable<T>::operator() (int r, int c) 01171 { 01172 return this->value(r,c); 01173 } 01174 01175 template <typename T> T DataTable<T>::operator() (int r, int c) const 01176 { 01177 return this->at(r,c); 01178 } 01179 01180 template <typename T> T& DataTable<T>::operator() (const QString& r, const QString& c) 01181 { 01182 return this->value(r,c); 01183 } 01184 01185 template <typename T> T DataTable<T>::operator() (const QString& r, const QString& c) const 01186 { 01187 return this->at(r,c); 01188 } 01189 01190 template <typename T> T& DataTable<T>::operator() (const QString& r, int c) 01191 { 01192 return this->value(r,c); 01193 } 01194 01195 template <typename T> T DataTable<T>::operator() (const QString& r, int c) const 01196 { 01197 return this->at(r,c); 01198 } 01199 01200 template <typename T> T& DataTable<T>::operator() (int r, const QString& c) 01201 { 01202 return this->value(r,c); 01203 } 01204 01205 template <typename T> T DataTable<T>::operator() (int r, const QString& c) const 01206 { 01207 return this->at(r,c); 01208 } 01209 01210 template <typename T> 01211 ChangeDataCommand<T>::ChangeDataCommand(const QString& name, DataTable<T>* oldDataTable, const DataTable<T>* newDataTable) 01212 : QUndoCommand(name) 01213 { 01214 if (newDataTable && oldDataTable) 01215 { 01216 this->newDataTable += *newDataTable; 01217 this->oldDataTable += *oldDataTable; 01218 this->targetDataTable += oldDataTable; 01219 } 01220 } 01221 01222 template <typename T> 01223 ChangeDataCommand<T>::ChangeDataCommand(const QString& name,const QList< DataTable<T>* >& oldDataTable,const QList< DataTable<T>* >& newDataTable) 01224 : QUndoCommand(name) 01225 { 01226 for (int i=0; i < oldDataTable.size() && i < newDataTable.size(); ++i) 01227 if (newDataTable[i] && oldDataTable[i]) 01228 { 01229 this->newDataTable += *(newDataTable[i]); 01230 this->oldDataTable += *(oldDataTable[i]); 01231 this->targetDataTable += (oldDataTable[i]); 01232 } 01233 } 01234 01235 template <typename T> 01236 void ChangeDataCommand<T>::redo() 01237 { 01238 for (int i=0; i < targetDataTable.size() && i < newDataTable.size(); ++i) 01239 if (targetDataTable[i]) 01240 (*(targetDataTable[i])) = newDataTable[i]; 01241 } 01242 01243 template <typename T> 01244 void ChangeDataCommand<T>::undo() 01245 { 01246 for (int i=0; i < targetDataTable.size() && i < oldDataTable.size(); ++i) 01247 if (targetDataTable[i]) 01248 (*(targetDataTable[i])) = oldDataTable[i]; 01249 } 01250 01251 template <typename T1, typename T2> 01252 Change2DataCommand<T1,T2>::Change2DataCommand(const QString& name, DataTable<T1>* oldDataTable1, const DataTable<T1>* newDataTable1, DataTable<T2>* oldDataTable2, const DataTable<T2>* newDataTable2) 01253 : QUndoCommand(name) 01254 { 01255 if (newDataTable1 && oldDataTable1) 01256 { 01257 DataTable<T1> dat1n(*(newDataTable1)); 01258 DataTable<T1> dat1o(*(oldDataTable1)); 01259 01260 this->newDataTable1 += dat1n; 01261 this->oldDataTable1 += dat1o; 01262 this->targetDataTable1 += oldDataTable1; 01263 } 01264 01265 if (newDataTable2 && oldDataTable2) 01266 { 01267 DataTable<T2> dat2n(*(newDataTable2)); 01268 DataTable<T2> dat2o(*(oldDataTable2)); 01269 01270 this->newDataTable2 += dat2n; 01271 this->oldDataTable2 += dat2o; 01272 this->targetDataTable2 += oldDataTable2; 01273 } 01274 } 01275 01276 template <typename T1, typename T2> 01277 Change2DataCommand<T1,T2>::Change2DataCommand(const QString& name,const QList< DataTable<T1>* >& oldDataTable1,const QList< DataTable<T1>* >& newDataTable1,const QList< DataTable<T2>* >& oldDataTable2,const QList< DataTable<T2>* >& newDataTable2) 01278 : QUndoCommand(name) 01279 { 01280 for (int i=0; i < newDataTable1.size() && i < oldDataTable1.size(); ++i) 01281 if (newDataTable1[i] && oldDataTable1[i]) 01282 { 01283 DataTable<T1> dat1n(*(newDataTable1[i])); 01284 DataTable<T1> dat1o(*(oldDataTable1[i])); 01285 01286 this->newDataTable1 += dat1n; 01287 this->oldDataTable1 += dat1o; 01288 this->targetDataTable1 += (oldDataTable1.at(i)); 01289 } 01290 01291 for (int i=0; i < newDataTable2.size() && i < oldDataTable2.size(); ++i) 01292 if (newDataTable2[i] && oldDataTable2[i]) 01293 { 01294 DataTable<T2> dat2n(*(newDataTable2[i])); 01295 DataTable<T2> dat2o(*(oldDataTable2[i])); 01296 01297 this->newDataTable2 += dat2n; 01298 this->oldDataTable2 += dat2o; 01299 this->targetDataTable2 += (oldDataTable2[i]); 01300 } 01301 } 01302 01303 template <typename T1, typename T2> 01304 void Change2DataCommand<T1,T2>::redo() 01305 { 01306 for (int i=0; i < targetDataTable1.size() && i < newDataTable1.size(); ++i) 01307 if (targetDataTable1[i]) 01308 (*(targetDataTable1[i])) = newDataTable1[i]; 01309 01310 for (int i=0; i < targetDataTable2.size() && i < newDataTable2.size(); ++i) 01311 if (targetDataTable2[i]) 01312 (*(targetDataTable2[i])) = newDataTable2[i]; 01313 } 01314 01315 template <typename T1, typename T2> 01316 void Change2DataCommand<T1,T2>::undo() 01317 { 01318 for (int i=0; i < targetDataTable1.size() && i < oldDataTable1.size(); ++i) 01319 if (targetDataTable1[i]) 01320 (*(targetDataTable1[i])) = oldDataTable1[i]; 01321 01322 for (int i=0; i < targetDataTable2.size() && i < oldDataTable2.size(); ++i) 01323 if (targetDataTable2[i]) 01324 (*(targetDataTable2[i])) = oldDataTable2[i]; 01325 } 01326 01327 #endif 01328 01332 typedef DataTable<QString> TextDataTable; 01333 01337 typedef DataTable<qreal> NumericalDataTable; 01338 01342 typedef ChangeDataCommand<QString> ChangeTextDataCommand; 01343 01347 typedef ChangeDataCommand<qreal> ChangeNumericalDataCommand; 01348 01349 } 01350 #endif