Isis 3 Programmer Reference
TableMainWindow.cpp
1#include "TableMainWindow.h"
2
3#include <iostream>
4
5#include <QAction>
6#include <QDockWidget>
7#include <QFileDialog>
8#include <QHeaderView>
9#include <QMenuBar>
10#include <QMessageBox>
11#include <QSettings>
12#include <QStatusBar>
13#include <QTableWidget>
14#include <QToolBar>
15
16
17namespace Isis {
24 TableMainWindow::TableMainWindow(QString title, QWidget *parent) : MainWindow(title, parent) {
25 p_parent = parent;
26
27 p_title = title;
28 p_table = NULL;
30 p_currentRow = 0;
32 setObjectName(title);
34 readSettings(QSize(500, 300));
36 }
37
38
39 TableMainWindow::~TableMainWindow() {
41 }
42
43
44 void TableMainWindow::clear() {
46 p_table->clear();
47 p_listWidget->clear();
48 p_table->setRowCount(0);
49 p_table->setColumnCount(0);
50 }
51
52
53 QList<QListWidgetItem *> TableMainWindow::itemList() const {
54 QList<QListWidgetItem *> result;
55
56 if (p_listWidget)
57 result = p_listWidget->findItems(QString("*"), Qt::MatchWrap | Qt::MatchWildcard);
58
59 return result;
60 }
61
62 void TableMainWindow::resizeColumn(int columnIndex) {
63 QHeaderView* header = p_table->horizontalHeader();
64
65 QString columnName(p_table->model()->headerData(columnIndex, Qt::Horizontal).toString());
66
67 if (columnName.isEmpty())
68 {
69 return;
70 }
71
72 if (header->sectionResizeMode(columnIndex) == QHeaderView:: ResizeToContents) {
73 header->setSectionResizeMode(columnIndex, QHeaderView::Interactive);
74 }
75 else {
76 header->setSectionResizeMode(columnIndex, QHeaderView::ResizeToContents);
77 }
78 }
79
87#if defined(__APPLE__)
88 setWindowFlags(Qt::Tool);
89#endif
90
91#ifndef __APPLE__
92 setWindowFlags(Qt::Dialog);
93#endif
94
95 statusBar()->setSizeGripEnabled(true);
96 // Create the table widget
97 p_table = new QTableWidget(this);
98 p_table->setAlternatingRowColors(true);
99 //
100 QHeaderView* columnHeader = p_table->horizontalHeader();
101 columnHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
102 connect ( columnHeader, SIGNAL( sectionPressed(int) ),
103 this, SLOT( resizeColumn(int) ) );
104
105 setCentralWidget(p_table);
106
107 // Create the dock area
108 p_dock = new QDockWidget("Columns", this);
109 p_dock->setObjectName("dock");
110 p_dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
111 p_dock->setMinimumWidth(190);
112 p_listWidget = new QListWidget(p_dock);
113 p_dock->setWidget(p_listWidget);
114 addDockWidget(Qt::LeftDockWidgetArea, p_dock, Qt::Vertical);
115 connect(p_listWidget, SIGNAL(itemChanged(QListWidgetItem *)),
116 this, SLOT(syncColumns()));
117
118 // Create the file menu
119 QMenuBar *menuBar = this->menuBar();
120 QMenu *fileMenu = menuBar->addMenu("&File");
121
122 p_save = new QAction(this);
123 p_save->setText("Save...");
124 p_save->setShortcut(Qt::CTRL + Qt::Key_S);
125 connect(p_save, SIGNAL(triggered()), this, SLOT(saveTable()));
126 p_save->setDisabled(true);
127
128 QAction *saveas = new QAction(this);
129 saveas->setText("Save As...");
130 connect(saveas, SIGNAL(triggered()), this, SLOT(saveAsTable()));
131
132 QAction *load = new QAction(this);
133 load->setText("Load...");
134 connect(load, SIGNAL(triggered()), this, SLOT(loadTable()));
135
136 QAction *del = new QAction(this);
137 del->setText("Delete Selected Row(s)");
138 del->setShortcut(Qt::Key_Delete);
139 connect(del, SIGNAL(triggered()), this, SLOT(deleteRows()));
140
141 QAction *clear = new QAction(this);
142 clear->setText("Clear table");
143 clear->setShortcut(Qt::CTRL + Qt::Key_Delete);
144 connect(clear, SIGNAL(triggered()), this, SLOT(clearTable()));
145
146 QAction *close = new QAction(this);
147 close->setText("Close");
148 connect(close, SIGNAL(triggered()), this, SLOT(hide()));
149
150 fileMenu->addAction(p_save);
151 fileMenu->addAction(saveas);
152 fileMenu->addAction(load);
153 fileMenu->addAction(del);
154 fileMenu->addAction(clear);
155 fileMenu->addAction(close);
156
157 //2009-01-12
158 //If we have the Mainwindow flag set to Qt::Tool so that on Macs the
159 //table window always stays on top, then we can not access the
160 //menu bar to the table window, so we need to add the file options
161 //for the table to the tool bar.
162#if defined(__APPLE__)
163 QToolBar *toolBar = new QToolBar();
164 toolBar->setObjectName("ToolBar");
165 toolBar->addAction(p_save);
166 toolBar->addAction(saveas);
167 toolBar->addAction(load);
168 toolBar->addAction(del);
169 toolBar->addAction(clear);
170 toolBar->addAction(close);
171 this->addToolBar(toolBar);
172#endif
173
174 // Create the view menu
175 QMenu *viewMenu = menuBar->addMenu("&View");
176 QAction *cols = new QAction(this);
177 cols->setText("Columns");
178 connect(cols, SIGNAL(triggered()), p_dock, SLOT(show()));
179 viewMenu->addAction(cols);
180 this->setMenuBar(menuBar);
181 installEventFilter(this);
182 }
183
184
191 void TableMainWindow::setStatusMessage(QString message) {
192 this->statusBar()->showMessage(message);
193 }
194
195
208 void TableMainWindow::addToTable(bool setOn, const QString &heading,
209 const QString &menuText, int insertAt,
210 Qt::Orientation o, QString toolTip) {
211 // Insert the new column
212 int startCol = p_table->columnCount();
213
214 for(int i = 0; !heading.section(":", i, i).isEmpty(); i++) {
215 QString htext = heading.section(":", i, i);
216
217 int destinationColumn = insertAt;
218
219 if (insertAt >= 0) {
220 p_table->insertColumn(insertAt);
221 }
222 else {
223 destinationColumn = startCol + i;
224 p_table->insertColumn(startCol + i);
225 }
226 QTableWidgetItem *header = new QTableWidgetItem(htext);
227 if (insertAt >= 0) {
228
229 if (o == Qt::Horizontal) {
230 p_table->setHorizontalHeaderItem(insertAt, header);
231 }
232 else {
233 p_table->setVerticalHeaderItem(insertAt, header);
234 }
235 }
236 else {
237
238 if (o == Qt::Horizontal) {
239 p_table->setHorizontalHeaderItem(startCol + i, header);
240 }
241 else {
242 p_table->setVerticalHeaderItem(startCol + i, header);
243 }
244 }
245
246 p_table->setColumnWidth(destinationColumn,
247 QFontMetrics(header->font()).width(header->text()) + 20);
248 // Removed: rounding and int?
249 // qRound(QFontMetrics(header->font()).width(header->text()) + 20));
250 }
251
252 int endCol = p_table->columnCount() - 1;
253
254 // Insert the column name into the columns dock area
255 if (!menuText.isEmpty()) {
256 QListWidgetItem *item = new QListWidgetItem();
257
258 item->setText(menuText);
259 if (toolTip.isEmpty()) {
260 item->setToolTip(heading);
261 }
262 else {
263 item->setToolTip(toolTip);
264 }
265
266 if (insertAt >= 0) {
267 p_listWidget->insertItem(insertAt, item);
268 }
269 else {
270 p_listWidget->insertItem(endCol, item);
271 }
272
273 item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
274
275 readItemSettings(menuText, item, setOn);
276
277 p_startColumn.push_back(startCol);
278 p_endColumn.push_back(endCol);
279
280 readItemSettings(heading, item, setOn);
281 }
283 }
284
285
292 if (this->isHidden()) {
293 return;
294 }
295
297 for(int i = 0; i < p_listWidget->count(); i++) {
298 QListWidgetItem *item = p_listWidget->item(i);
299 int index = itemList().indexOf(item);
300
301 if (index != -1) {
302 for(int col = p_startColumn[index]; col <= p_endColumn[index]; col++) {
303
304 if (item->checkState() == Qt::Checked) {
305 p_table->setColumnHidden(col, false);
307 }
308 else {
309 p_table->setColumnHidden(col, true);
310 }
311
312 }
313 }
314 }
315 }
316
317
324 if (!isHidden()) {
326 for (int i = 0; i < p_listWidget->count(); i++) {
327 QListWidgetItem *item = p_listWidget->item(i);
328 int index = itemList().indexOf(item);
329
330 if (index != -1) {
331
332 for (int col = p_startColumn[index];
333 col <= p_endColumn[index];
334 col++) {
335
336 if (item->checkState() == Qt::Checked) {
337 p_table->setRowHidden(col, false);
339 }
340 else {
341 p_table->setRowHidden(col, true);
342 }
343
344 }
345 }
346 }
347 }
348 }
349
350
357 if (p_table != NULL) {
358 p_table->setColumnCount(p_table->columnCount() - 1);
359
360 bool vis = p_table->isVisible();
361 p_table = NULL;
362 p_listWidget = NULL;
363 close();
364
365 if (vis) showTable();
366 }
367 }
368
369
384 if (p_table == NULL) createTable();
385 this->show();
386 syncColumns();
387 }
388
389
395 if (p_table->rowCount() == 0) return;
396 for(int r = 0; r < p_table->rowCount(); r++) {
397 for(int c = 0; c < p_table->columnCount(); c++) {
398 p_table->item(r, c)->setText("");
399 }
400 }
401
402 p_table->scrollToItem(p_table->item(0, 0), QAbstractItemView::PositionAtTop);
403 p_currentRow = 0;
404 p_currentIndex = 0;
405 }
406
407
415 QList<QTableWidgetItem *> list = p_table->selectedItems();
416 QList<int> selectedRows;
417
418 for(int i = 0; i < list.size(); i++) {
419 if (selectedRows.size() == 0) {
420 selectedRows.push_back(p_table->row(list[i]));
421 }
422 else if (!selectedRows.contains(p_table->row(list[i]))) {
423 selectedRows.push_back(p_table->row(list[i]));
424 }
425 }
426
427 qSort(selectedRows.begin(), selectedRows.end());
428 for(int d = selectedRows.size(); d > 0; d--) {
429 p_table->removeRow(selectedRows[d-1]);
430 }
431
432 // get the number of rows that are filled in
433 int filledRows = 0;
434 for(int r = 0; r < p_table->rowCount(); r++) {
435 for(int c = 0; c < p_table->columnCount(); c++) {
436 if (!p_table->item(r, c) || p_table->item(r, c)->text() != "") {
437 filledRows++;
438 break;
439 }
440 }
441 }
442
443 p_currentRow = filledRows;
444 }
445
446
453 if (!this->isVisible()) return;
454
455 for(int c = 0; c < p_table->columnCount(); c++) {
456 p_table->item(row, c)->setText("");
457 }
458 }
459
466 QString fn = QFileDialog::getSaveFileName((QWidget *)parent(),
467 "Choose filename to save under",
468 ".",
469 "Text Files (*.txt)");
470 QString filename;
471
472 //Make sure the filename is valid
473 if (!fn.isEmpty()) {
474 if (!fn.endsWith(".txt")) {
475 filename = fn + ".txt";
476 }
477 else {
478 filename = fn;
479 }
480 }
481 //The user cancelled, or the filename is empty
482 else {
483 return;
484 }
485
486 p_currentFile.setFileName(filename);
487
488 p_save->setEnabled(true);
489 saveTable();
490 }
491
497 if (p_currentFile.fileName().isEmpty()) return;
498
499 //if (p_currentFile.exists()) p_currentFile.remove();
500 bool success = p_currentFile.open(QIODevice::WriteOnly);
501 if (!success) {
502 QMessageBox::critical((QWidget *)parent(),
503 "Error", "Cannot open file, please check permissions");
504 p_currentFile.setFileName("");
505 p_save->setDisabled(true);
506 return;
507 }
508
509 QString currentText;
510 QTextStream t(&p_currentFile);
511 QString line = "";
512 bool first = true;
513
514 //Write each column's header to the first line in CSV format
515 for(int i = 0; i < p_table->columnCount(); i++) {
516 if (!p_table->isColumnHidden(i)) {
517 QTableWidgetItem *header = p_table->horizontalHeaderItem(i);
518 QString temp = header->text();
519 temp.replace("\n", " ");
520 if (first) {
521 line = line + "\"" + temp + "\"";
522 first = false;
523 }
524 else {
525 line = line + ",\"" + temp + "\"";
526 }
527 }
528 }
529 //Add the headers to the file
530 t << line << endl;
531
532 //Add each row to the file
533 for(int i = 0; i < p_table->rowCount(); i++) {
534 bool first = true;
535 line = "";
536
537 //Add each column to the line
538 for(int j = 0; j < p_table->columnCount(); j++) {
539
540 if (!p_table->isColumnHidden(j)) {
541 if (p_table->item(i, j) == 0) break;
542 currentText = p_table->item(i, j)->text();
543
544 if (first) {
545 line = line + currentText;
546 first = false;
547 }
548 else {
549 line = line + "," + currentText;
550 }
551 }
552 }
553 //If the line is not empty, add it to the file
554 if (line.split(",", QString::SkipEmptyParts).count() != 0)
555 t << line << endl;
556 }
557 p_currentFile.close();
558 this->setWindowTitle(p_title + " : " + p_currentFile.fileName());
559 }
560
561
572 QListWidgetItem *item, bool defaultChecked) {
573 QSettings settings(settingsFileName(), QSettings::NativeFormat);
574
575 QString itemTitle = "item-" + item->text();
576 Qt::CheckState defaultState = defaultChecked? Qt::Checked : Qt::Unchecked;
577 Qt::CheckState state = (Qt::CheckState)
578 settings.value(itemTitle, defaultState).toInt();
579 item->setCheckState(state);
580 }
581
589
590 QHeaderView *header = p_table->horizontalHeader();
591 QSettings settings(settingsFileName(), QSettings::NativeFormat);
592
593 for (int columnIndex = 0; columnIndex < p_table->model()->columnCount(); columnIndex++) {
594
595 QString headerName = p_table->model()->headerData(columnIndex, Qt::Horizontal).toString();
596 QString settingName = "column-" + headerName;
597 QString value = settings.value(settingName, "auto").toString();
598
599 if (value == "auto" || value == "0") {
600 header->setSectionResizeMode(columnIndex, QHeaderView::ResizeToContents);
601 }
602 else {
603 int width = value.toInt();
604
605 header->setSectionResizeMode(columnIndex, QHeaderView::Interactive);
606 p_table->setColumnWidth(columnIndex, width);
607 }
608 }
609 }
610
611
625 if (p_listWidget) {
626 QSettings settings(settingsFileName(), QSettings::NativeFormat);
627
628 foreach (QListWidgetItem *item, itemList()) {
629 QString itemTitle = "item-" + item->text();
630 settings.setValue(itemTitle, item->checkState());
631 }
632
633 QHeaderView *header = p_table->horizontalHeader();
634 for(int columnIndex = 0; columnIndex < p_table->model()->columnCount(); columnIndex++)
635 {
636 QString headerName = p_table->model()->headerData(columnIndex, Qt::Horizontal).toString();
637 QString settingName = "column-" + headerName;
638
639 if (header->sectionResizeMode(columnIndex) == QHeaderView::ResizeToContents)
640 {
641 settings.setValue(settingName, "auto");
642 }
643 else
644 {
645 settings.setValue( settingName, header->sectionSize(columnIndex) );
646 }
647 }
648 }
649 }
650
651
657 QString fn = QFileDialog::getOpenFileName((QWidget *)parent(),
658 "Select file to load",
659 ".",
660 "Text Files (*.txt)");
661
662 //If the user cancelled or the filename is empty return
663 if (fn.isEmpty()) return;
664
665 p_currentFile.setFileName(fn);
666 p_save->setEnabled(true);
667
668 bool success = p_currentFile.open(QIODevice::ReadOnly);
669 if (!success) {
670 QMessageBox::critical((QWidget *)parent(),
671 "Error", "Cannot open file, please check permissions");
672 p_currentFile.setFileName("");
673 p_save->setDisabled(true);
674 return;
675 }
676
677 clearTable();
678
679 QList<int> column = QList<int>();
680
681 //Set all headers to be hidden
682 for(int i = 0; i < p_listWidget->count() ; i++) {
683 p_listWidget->item(i)->setCheckState(Qt::Unchecked);
684 }
685
686 // Strip headers off the table into the temp string
687 QString temp = p_currentFile.readLine();
688 temp.remove("Positive ");
689 temp.remove("\"");
690 temp.remove("\n");
691 QStringList list = temp.split(",");
692
693 // Loop through checking header names and setting relevant columns visible
694 for(int i = 0; i < list.count(); i++) {
695 for(int j = 0; j < itemList().size(); j++) {
696 QListWidgetItem *item = itemList()[j];
697
698 //Special cases
699 if (item->text() == "Ground Range" && (list[i] == "Start Latitude" || list[i] == "Start Longitude" ||
700 list[i] == "End Latitude" || list[i] == "End Longitude")) {
701 item->setCheckState(Qt::Checked);
702 break;
703 }
704 if (item->text() == "Pixel Range" && (list[i] == "Start Sample" || list[i] == "Start Line" ||
705 list[i] == "End Sample" || list[i] == "End Line")) {
706 item->setCheckState(Qt::Checked);
707 break;
708 }
709 if (item->text() == "Pixel Range" && (list[i] == "Sample" || list[i] == "Line")) {
710 item->setCheckState(Qt::Checked);
711 break;
712 }
713 if (item->text() == "Sample:Line" && (list[i] == "Sample" || list[i] == "Line")) {
714 item->setCheckState(Qt::Checked);
715 break;
716 }
717 if (item->text() == "Planetocentric Lat" && list[i] == "Planetocentric Latitude") {
718 item->setCheckState(Qt::Checked);
719 break;
720 }
721 if (item->text() == "Planetographic Lat" && list[i] == "Planetographic Latitude") {
722 item->setCheckState(Qt::Checked);
723 break;
724 }
725 if (item->text() == "Projected X:Projected Y" && (list[i] == "Projected X" || list[i] == "Projected Y")) {
726 item->setCheckState(Qt::Checked);
727 break;
728 }
729 if (item->text() == "Radius" && list[i] == "Local Radius") {
730 item->setCheckState(Qt::Checked);
731 break;
732 }
733 if (item->text() == "XYZ" && (list[i] == "Point X" || list[i] == "Point Y" || list[i] == "Point Z")) {
734 item->setCheckState(Qt::Checked);
735 break;
736 }
737 if (item->text() == "Ra:Dec" && (list[i] == "Right Ascension" || list[i] == "Declination")) {
738 item->setCheckState(Qt::Checked);
739 break;
740 }
741 if (item->text() == "Spacecraft Position" && (list[i] == "Spacecraft X" || list[i] == "Spacecraft Y" || list[i] == "Spacecraft Z")) {
742 item->setCheckState(Qt::Checked);
743 break;
744 }
745 if (item->text() == "Ephemeris Time" && list[i] == "Ephemeris Time") {
746 item->setCheckState(Qt::Checked);
747 break;
748 }
749 if (item->text() == "Local Solar Time" && list[i] == "Local Solar Time") {
750 item->setCheckState(Qt::Checked);
751 break;
752 }
753 if (item->text() == "Segments Sum" && list[i] == "Segments Sum km") {
754 item->setCheckState(Qt::Checked);
755 break;
756 }
757 //End special cases
758
759
760 if (item->text() == list[i]) {
761 item->setCheckState(Qt::Checked);
762 break;
763 }
764 }
765
766 // Loop through column headers to try to find a match
767 bool match = false;
768 for(int cols = 0; cols < p_table->columnCount(); cols++) {
769 QString header = p_table->horizontalHeaderItem(cols)->text();
770
771 header.remove("Positive");
772 header.remove("\n");
773 header.remove(" ");
774
775 list[i].remove(" ");
776
777 if (header == list[i]) {
778 column.push_back(cols);
779 match = true;
780 break;
781
782 }
783 }
784 if (!match) column.push_back(-1);
785 }
786
787 // Read data into table
788 QString str = p_currentFile.readLine();
789
790 while(str.count() != 0) {
791 // Do we need more rows?
792 if (p_currentRow + 1 > p_table->rowCount()) {
793 p_table->insertRow(p_currentRow);
794 for(int c = 0; c < p_table->columnCount(); c++) {
795 QTableWidgetItem *item = new QTableWidgetItem("");
796 p_table->setItem(p_currentRow, c, item);
797 if (c == 0) p_table->scrollToItem(item);
798 }
799 }
800
801 str.remove("\n");
802
803 QStringList list = str.split(",");
804
805 for(int i = 0; i < column.size(); i++) {
806 QTableWidgetItem *newItem = new QTableWidgetItem(list[i]);
807 if (column[i] != -1) {
808 p_table->setItem(p_currentRow, column[i], newItem);
809 }
810 }
811 p_currentRow++;
813
814
815 str = p_currentFile.readLine();
816 }
817
818 p_currentFile.close();
819 this->setWindowTitle(p_title + " : " + fn);
820 emit fileLoaded();
821 }
822
823
832 switch(e->type()) {
833 case QEvent::Close: {
834 this->writeSettings();
835 }
836
837 default: {
838 return false;
839 }
840 }
841 }
842
843
850 void TableMainWindow::closeEvent(QCloseEvent *event) {
853 event->accept();
854 }
855
856
863 void TableMainWindow::hideEvent(QHideEvent *event) {
864// this->writeSettings();
865 }
866
867
876 p_trackItems = track;
877 }
878
879
889
890
897 p_currentRow = row;
898 }
899
900
906 void TableMainWindow::setCurrentIndex(int currentIndex) {
908 }
909
910}
Base class for the Qisis main windows.
Definition MainWindow.h:24
virtual void closeEvent(QCloseEvent *event)
This method is overridden so that we can be sure to write the current settings of the Main window.
virtual void readSettings(QSize defaultSize=QSize())
This method ensure that the settings get written even if the Main window was only hidden,...
bool p_trackItems
Boolean to track items.
void loadTable()
This method loads a text file into the table.
void showTable()
This method checks to see if the table has been created.
void addToTable(bool setOn, const QString &heading, const QString &menuText="", int insertAt=-1, Qt::Orientation o=Qt::Horizontal, QString toolTip="")
Adds a new column to the table when a new curve is added to the plot.
QPointer< QListWidget > p_listWidget
List widget.
void setCurrentRow(int row)
Sets the current row to row.
void fileLoaded()
Signal emitted when a file has loaded.
bool eventFilter(QObject *o, QEvent *e)
This event filter is installed in the constructor.
void createTable()
This creates the table main window.
QTableWidget * p_table
The table.
int p_currentIndex
Current index.
void writeSettings() const
This overriden method is called when the Tablemainwindow is closed or hidden to write the size and lo...
void hideEvent(QHideEvent *event)
int p_visibleColumns
Number of visible columns.
QWidget * p_parent
The parent widget.
void clearTable()
This method clears all items from each row and column.
bool trackListItems()
Returns whether or not we should track items.
void readColumnSettings()
This method reads the columns in the table and sets their size to the appropriate size,...
QList< int > p_endColumn
List of end columns.
int currentIndex() const
Returns the current index.
void syncColumns()
This method hides and shows the columns according to which items the user has selected to be view-abl...
void setTrackListItems(bool track=false)
If this property is true, the class will keep track of the checked/unchecked items in the dock area w...
void deleteRows()
This method is called when the user selects a row or rows uses the delete button or selects the delet...
QString p_title
The title string.
QFile p_currentFile
The current file.
QDockWidget * p_dock
The dock widget.
int selectedRows() const
Returns the selected rows.
void closeEvent(QCloseEvent *event)
void clearRow(int row)
This method clears the text of the given row.
void deleteColumn(int item)
This method deletes a column from the table.
void syncRows()
Use this method to sync the table with the dock widget list if the table orientation is horizontal.
int p_currentRow
Current row.
void readItemSettings(QString heading, QListWidgetItem *item, bool defaultChecked)
This method reads the 'checked' settings on the items listed in the dock area which determine which t...
TableMainWindow(QString title, QWidget *parent=0)
Constructs a new TableMainWindow object.
void saveAsTable()
This method will select a file, set it as the current file and save the table.
void saveTable()
This method allows the user to save the data from the table to the current file.
QAction * p_save
Action to save the table to the current file.
void setCurrentIndex(int currentIndex)
Sets the current index to currentIndex.
void setStatusMessage(QString message)
sets the status message in the lower lefthand corner of the window.
QList< int > p_startColumn
List of start columns.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16