00001 //# TBDataTab.qo.h: Widget used to display table data. 00002 //# Copyright (C) 2005 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: $ 00027 #ifndef TBDATATAB_H_ 00028 #define TBDATATAB_H_ 00029 00030 #include <casaqt/QtBrowser/TBDataTab.ui.h> 00031 00032 #include <vector> 00033 00034 #include <casa/BasicSL/String.h> 00035 00036 namespace casa { 00037 00038 //# Forward Declarations 00039 class TBTable; 00040 class QCloseableWidget; 00041 class TBFilterRuleSequence; 00042 class TBFormat; 00043 class QFontColor; 00044 class TBTableTabs; 00045 class ProgressHelper; 00046 class TBArrayPanel; 00047 class TBData; 00048 00049 // <summary> 00050 // Subclass of QTableWidgetItem that allows for custom sorting. 00051 // <summary> 00052 // 00053 // <synopsis> 00054 // TBDataItem takes a value and a type. The object saves the value in two 00055 // ways using Qt::DisplayRole and Qt::UserRole. The value is stored as a 00056 // string using QtDisplayRole, and this is what is actually shown in the 00057 // QTableWidget. The data stored with Qt::UserRole, however, may be of a 00058 // different type, such as an integer. This storage is used when sorting 00059 // so that, for example, numbers can be sorted numerically rather than 00060 // lexiographically. Array types are sorted using the first element for 00061 // one-dimensional arrays and the first dimension for other arrays. 00062 // </synopsis> 00063 00064 class TBDataItem : public QTableWidgetItem { 00065 public: 00066 // Constructor to take the String value and the type. 00067 //TBDataItem(String value, String type); 00068 00069 TBDataItem(TBData* data); 00070 00071 ~TBDataItem(); 00072 00073 00074 // Override QTableWidgetItem's less-than operator. Returns true if the 00075 // value of this TBDataItem is less than that of the given TBDataItem, 00076 // false otherwise. If other is not of type TBDataItem, the behavior is 00077 // undefined. Also, since this operator is only used for custom sorting, 00078 // the other TBDataItem is assumed to have the same type as this one. 00079 virtual bool operator<(const QTableWidgetItem& other) const; 00080 00081 private: 00082 // Holds the data type. 00083 String type; 00084 00085 // Is true if the value stored for Qt::UserRole is an array dimension, 00086 // false otherwise. 00087 bool arrayDimension; 00088 00089 TBData* tdata; 00090 00091 00092 // Set the Qt::UserRole and, if text is true, the Qt::DisplayRole values. 00093 void set(String value, bool text); 00094 }; 00095 00096 // <summary> 00097 // Widget used to display table data. 00098 // <summary> 00099 // 00100 // <synopsis> 00101 // TBDataTab is the tab responsible for displaying table data in a 00102 // QTableWidget. It also provides functionality for changing page and number 00103 // of rows loaded, catching and passing on edit events, and handling 00104 // double-click events. 00105 // </synopsis> 00106 00107 class TBDataTab : public QWidget, Ui::DataTab { 00108 Q_OBJECT 00109 00110 public: 00111 // Constructor that takes the parent TBTableTabs. 00112 TBDataTab(TBTableTabs* tt); 00113 00114 ~TBDataTab(); 00115 00116 00117 // Returns the QTableWidget that displays the data. 00118 QTableWidget* getTableWidget(); 00119 00120 // Returns the QBrush that is used to draw the background of any selected 00121 // cells in the QTableWidget. 00122 QBrush& getSelectedCellBackground(); 00123 00124 // Retruns the QBrush that is used to draw the background of any unselected 00125 // cells in the QTableWidget. 00126 QBrush& getUnselectedCellBackground(); 00127 00128 // Returns the current row filter, or NULL if there is none. 00129 TBFilterRuleSequence* getFilter(); 00130 00131 // Sets the current filter to the given rules, but does NOT apply it. 00132 void setFilter(TBFilterRuleSequence* rule); 00133 00134 // Returns the current format for the field at the given index, or NULL if 00135 // there is none. 00136 TBFormat* formatAt(int index); 00137 00138 // Returns the current sort on the displayed data. Each pair in the vector 00139 // is the name of the field with a bool indicating whether the sort is 00140 // ascending or not. 00141 std::vector<std::pair<String, bool> >* getSortFields(); 00142 00143 00144 // Updates the QTableWidget with new data that has been loaded into the 00145 // table backend. If a ProgressHelper is provided, it will be updated 00146 // periodically with progress information. 00147 void updateTable(ProgressHelper* pp = NULL); 00148 00149 // Sets the given cell in the QTableWidget to the new value, but does NOT 00150 // update the backend. If format is true, then any existing format will 00151 // be applied to the new value. 00152 void setData(int row, int col, TBData* newVal, bool format = true); 00153 00154 // Loads the given page into the table backend, which then updates the 00155 // display. If the page is valid, the result of TBTableTabs::loadRows() 00156 // is returned; otherwise false is returned. 00157 bool loadPage(int p); 00158 00159 // Refreshes the table backend using TBTable::refresh(), then updates the 00160 // displayed data using setData(). 00161 void refresh(int row, int col, bool format = true); 00162 00163 // Sorts the displayed data with the given order. Each pair in the vector 00164 // is the name of the field with a bool indicating whether the sort is 00165 // ascending or not. 00166 void sortBy(std::vector<std::pair<String, bool> >& s); 00167 00168 // Sets the sort indicator on the QTableWidget for the given column with an 00169 // ascending arrow if asc is true or a descending arrow otherwise. 00170 void setSortIndicator(int index, bool asc); 00171 00172 // Clears the sort indicator on the QTableWidget. 00173 void clearSortIndicator(); 00174 00175 // Selects and highlights the given row in the table widget. 00176 void highlight(int row); 00177 00178 // Returns the visible index for the row with the given logical index. 00179 // Rows may have differing visible and logical indices when a sort has 00180 // been entered. 00181 int visibleIndex(int logicalIndex); 00182 00183 // Returns the logical index for the row with the given visible index. 00184 // Rows may have differing visible and logical indices when a sort has 00185 // been entered. 00186 int logicalIndex(int visibleIndex); 00187 00188 // Hides (or shows) the column with the given index. Whether the column 00189 // is shown or hidden depends on the "hidden" parameter. 00190 void hideColumn(int index, bool hidden); 00191 00192 // Opens a format dialog for the field with the given index. Applies the 00193 // format that the user enters. 00194 void formatField(int index); 00195 00196 //Remembers whether you pressed the next or previous button. Uses this 00197 //when filter rules are applied to avoid displaying blank pages. 00198 bool goForward; 00199 00200 public slots: 00201 // Shows the given widget in the side panel. isArray should be true if 00202 // the widget is a TBViewArray, false otherwise. 00203 void showWidgetInSplitter(QWidget* widget, bool isArray = false); 00204 00205 // Clears whatever widget (if any) is currently being displayed in the side 00206 // panel. 00207 void clearWidgetInSplitter(); 00208 00209 // Applies the given format to the field at the given index. 00210 void applyFormat(int index, TBFormat* format); 00211 00212 // Clears the format on the field at the given index. 00213 void clearFormat(int index); 00214 00215 // Clears all formats on all fields. 00216 void clearAllFormats(); 00217 00218 signals: 00219 // This signal is emitted when the user has edited a cell. The parameter 00220 // describe which cell was edited and its new value. 00221 void dataChanged(int row, int col, String newVal); 00222 00223 // This signal is emitted when the side panel is closed. The QWidget 00224 // points to the widget that was just closed. 00225 void rightWidgetClosed(QWidget* which); 00226 00227 // This signal is emitted when the user right-clicks on an index and 00228 // selects the "Follow subtable index reference" command. The String 00229 // indicates which subtable was chosen, and the index indicates the chosen 00230 // index which is the value of the cell that was right-clicked on. 00231 void followReferenceRequested(String subtable, int index); 00232 00233 // This signal is emitted when a sort is applied to the table. 00234 void sortEntered(); 00235 00236 // This signal is emitted when a sort is cleared from the table. 00237 void sortCleared(); 00238 00239 // This signal is emitted when a column is shown or hidden. 00240 void columnHidden(int index, bool hidden); 00241 00242 protected: 00243 // Catches the right-click event; if the right click is on a table cell and 00244 // the displayed data could be an index, show the subtable index reference 00245 // menu. Also show action for copying to the clipboard. 00246 void contextMenuEvent(QContextMenuEvent* event); 00247 00248 private: 00249 // Useful pointers to table backend. 00250 // <group> 00251 TBTableTabs* ttabs; 00252 TBTable* table; 00253 // </group> 00254 00255 // The currently loaded page. 00256 int page; 00257 00258 // How many rows per page are loaded at once. 00259 int loadRows; 00260 00261 // Side panel. 00262 QCloseableWidget* rightWidget; 00263 00264 // List of cells that are highlighted (the row and column of the currently 00265 // selected cell). 00266 std::vector<QTableWidgetItem*> highlightedCells; 00267 00268 // Brushes used to draw the backgrounds of unselected and selected cells in 00269 // the QTableWidget, respectively. 00270 // <group> 00271 QBrush unselectedBackground; 00272 QBrush selectedBackground; 00273 // </group> 00274 00275 // Current row filter, or NULL if there is none. 00276 TBFilterRuleSequence* filter; 00277 00278 // Current field formats. 00279 std::vector<TBFormat*> formats; 00280 00281 // "Cleared" format for cell text. 00282 QFontColor* defaultFormat; 00283 00284 // Indicates whether the side panel is currently open with an array or not. 00285 bool arrayOpened; 00286 00287 // Points to the current array panel, or NULL if there is none. 00288 TBArrayPanel* arrayPanel; 00289 00290 // Keeps track of the un-sorted order of the rows. 00291 // Doing rowItems[logicalRow]->row() returns the visualRow. 00292 std::vector<QTableWidgetItem*> rowItems; 00293 00294 // Keeps track of the un-sorted order of the rows. 00295 // Doing rowIndices[visualRow] returns the logicalRow. 00296 std::vector<int> rowIndices; 00297 00298 // The current sort order. 00299 std::vector<std::pair<String, bool> > currSort; 00300 00301 // Used for handling right-clicks on headers. Keeps track of the last 00302 // right-clicked header column number. 00303 int clickedHeader; 00304 00305 00306 // Update widgets that keep track of what page the browser is on. 00307 void updatePageTrackers(); 00308 00309 // Sorts on the given row. If asc is true, sorts in ascending order, 00310 // otherwise sorts in descending order. 00311 void sort(int col, bool asc); 00312 00313 // Applies the current filter to the displayed rows. 00314 void applyFilter(); 00315 00316 private slots: 00317 // Slot for page back button. Goes back a page. 00318 void pageBack(); 00319 00320 // Slot for page forward button. Goes forward a page. 00321 void pageForward(); 00322 00323 // Slot to go to first page. 00324 void pageFirst(); 00325 00326 // Slot to go to last page. 00327 void pageLast(); 00328 00329 // Slot for page go button. Goes to the page specified in the page line 00330 // edit. 00331 void pageGo(); 00332 00333 // Slot for QTableWidget::cellChanged(). Catches changes from the 00334 // QTableWidget and emits signals as needed. 00335 void notifyDataChanged(int row, int col); 00336 00337 // Slot for QTableWidget::currentCellChanged(). Updates the display to 00338 // highlight the row and column of the selected cell. 00339 void cellClicked(int row, int col); 00340 00341 // Slot for the menu command chosen from the reference menu shown on a 00342 // right click. Catches which subtable the user followed a reference and 00343 // emits signals as needed. 00344 void referenceMenuClicked(QAction* which); 00345 00346 // Slot for QTableWidget::cellDoubleClicked(). Catches a double-click 00347 // event on a cell in the QTableWidget. If the value is a table type, 00348 // opens the indicated table in a new tab. If the value is an array type, 00349 // opens the array in the side panel. Otherwise, if the table is currently 00350 // editable, enters into editing mode on that cell. 00351 void doubleClicked(int row, int col); 00352 00353 // Displays the tooltip for the last clicked header in a dialog. 00354 void displayFieldInfo(); 00355 00356 // Displays statistics (min, max, mean) for the last clicked header in a 00357 // dialog. 00358 void displayFieldStatistics(); 00359 00360 // Hides the column that was just right-clicked. 00361 void hideColumn(); 00362 00363 // Formats the field that was just right-clicked. 00364 void formatField(); 00365 00366 // Slot for when a column header is moved. Enables the "restore columns" 00367 // button. 00368 void headerMoved(); 00369 00370 // Slot for the restore columns button. Moves all columns back to their 00371 // original locations. 00372 void restoreColumns(); 00373 00374 // Slot for the resize headers button. Resizes the row and column headers 00375 // to fit displayed contents. See QTableWidget::resizeRowsToContents() and 00376 // QTableWidget::resizeColumnsToContents(). 00377 void resizeHeaders(); 00378 00379 // Slot for QHeaderView::sectionClicked(). Catches a sorting click event 00380 // on a column header and sorts accordingly. 00381 void headerClicked(int index); 00382 00383 // Slot for the clear sort button. Clears the sort on the table by moving 00384 // the rows back to their original order. 00385 void clearSort(); 00386 00387 // Slot for copying the currently selected text into the system clipboard. 00388 void copyData(); 00389 }; 00390 00391 } 00392 00393 #endif /* TBDATATAB_H_ */