Isis 3 Programmer Reference
TableViewContent.cpp
1
7/* SPDX-License-Identifier: CC0-1.0 */
8
9#include "TableViewContent.h"
10
11#include <cmath>
12#include <iostream>
13
14#include <QAction>
15#include <QApplication>
16#include <QDebug>
17#include <QLabel>
18#include <QMenu>
19#include <QMessageBox>
20#include <QMutex>
21#include <QPainter>
22#include <QPaintEvent>
23#include <QRect>
24#include <QScrollBar>
25#include <QSize>
26#include <QStyle>
27#include <QStyleOptionViewItemV4>
28#include <QThread>
29#include <QVBoxLayout>
30
31#include "ControlMeasure.h"
32#include "IException.h"
33#include "IString.h"
34
35#include "AbstractTableDelegate.h"
36#include "AbstractTableModel.h"
37#include "AbstractTreeItem.h"
38#include "TableColumn.h"
39#include "TableColumnList.h"
40#include <ControlPoint.h>
41
42
43namespace Isis {
50 nullify();
51
52 m_model = someModel;
53 connect(m_model, SIGNAL(modelModified()), this, SLOT(refresh()));
54 connect(m_model, SIGNAL(filterProgressChanged(int)),
55 this, SLOT(updateItemList()));
56 connect(this, SIGNAL(modelDataChanged()),
57 m_model, SLOT(applyFilter()));
58 connect(this,
59 SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)),
60 m_model,
61 SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)));
62 connect(m_model, SIGNAL(treeSelectionChanged(QList< AbstractTreeItem * >)),
63 this, SLOT(scrollTo(QList< AbstractTreeItem * >)));
64
65 m_columns = getModel()->getColumns();
66 for (int i = 0; i < m_columns->size(); i++) {
67 TableColumn *column = (*m_columns)[i];
68
69 connect(column, SIGNAL(visibilityChanged()), this, SLOT(refresh()));
70 connect(column, SIGNAL(visibilityChanged()),
71 this, SLOT(updateHorizontalScrollBar()));
72 connect(column, SIGNAL(widthChanged()), this, SLOT(refresh()));
73 }
74
75 m_items = new QList< QPointer<AbstractTreeItem> >;
76 m_activeCell = new QPair<AbstractTreeItem *, int>(NULL, -1);
77 rowsWithActiveColumnSelected = new QList<AbstractTreeItem *>;
78 m_lastShiftSelection = new QList<AbstractTreeItem *>;
79 m_lastShiftArrowSelectedCell = new QPair< AbstractTreeItem *, int >;
80 m_lastShiftArrowSelectedCell->first = NULL;
81
82 verticalScrollBar()->setSingleStep(1);
83
84 m_rowHeight = QFontMetrics(font()).height() + ITEM_PADDING;
85
86 connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
87 this, SIGNAL(horizontalScrollBarValueChanged(int)));
88
89 setMouseTracking(true);
91
93
94 setContextMenuPolicy(Qt::CustomContextMenu);
95 connect(this, SIGNAL(customContextMenuRequested(QPoint)),
96 this, SLOT(showContextMenu(QPoint)));
97
98 m_activeControlNet = false;
99 }
100
101
106 delete m_items;
107 m_items = NULL;
108
109 delete m_activeCell;
110 m_activeCell = NULL;
111
112 delete m_editWidget;
113 m_editWidget = NULL;
114
115 delete m_lastShiftSelection;
116 m_lastShiftSelection = NULL;
117
120
121 delete m_applyToAllAct;
122 m_applyToAllAct = NULL;
123
126
129
130 delete m_lastShiftArrowSelectedCell;
131 m_lastShiftArrowSelectedCell = NULL;
132
133 m_columns = NULL;
134 }
135
136
143 return QWidget::minimumSizeHint();
144 }
145
146
155 return minimumSizeHint();
156 }
157
158
165 return m_model;
166 }
167
168
169 // void TableViewContent::setModel(AbstractTableModel * someModel)
170 // {
171 // if (!someModel)
172 // {
173 // IString msg = "Attempted to set a NULL m_model!";
174 // throw iException::Message(iException::Programmer, msg, _FILEINFO_);
175 // }
176 //
177 // if (getModel())
178 // {
179 // disconnect(getModel(), SIGNAL(m_modelModified()), this, SLOT(refresh()));
180 // disconnect(getModel(), SIGNAL(filterProgressChanged(int)),
181 // this, SLOT(updateItemList()));
182 // disconnect(this,
183 // SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)),
184 // getModel(),
185 // SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)));
186 // disconnect(getModel(), SIGNAL(selectionChanged(QList<AbstractTreeItem*>)),
187 // this, SLOT(scrollTo(QList<AbstractTreeItem*>)));
188 // }
189 //
190 // m_model = someModel;
191 // m_columns = someModel->getColumns();
192 //
193 // connect(m_model, SIGNAL(m_modelModified()), this, SLOT(refresh()));
194 // connect(m_model, SIGNAL(filterProgressChanged(int)),
195 // this, SLOT(updateItemList()));
196 // connect(this, SIGNAL(m_modelDataChanged()),
197 // m_model, SLOT(applyFilter()));
198 // connect(this, SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)),
199 // m_model, SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)));
200 // connect(m_model, SIGNAL(treeSelectionChanged(QList<AbstractTreeItem*>)),
201 // this, SLOT(scrollTo(QList<AbstractTreeItem*>)));
202 //
203 // refresh();
204 // }
205
206
213 m_activeControlNet = activeNet;
214 }
215
216
221 if (m_model) {
222 if (!m_model->isFiltering()) {
223 int rowCount = m_model->getVisibleRowCount();
224 verticalScrollBar()->setRange(0, qMax(rowCount - 1, 0));
225 }
226
229 m_lastShiftSelection->clear();
230
231 if (m_model->getSelectedItems().size() &&
235 }
236
237 viewport()->update();
238 }
239 }
240
241
248 if (m_columns) {
249 int range = 0;
250 TableColumnList visibleCols = m_columns->getVisibleColumns();
251 for (int i = 0; i < visibleCols.size(); i++)
252 range += visibleCols[i]->getWidth() - 1;
253
254 // For the border...
255 range -= 2;
256 horizontalScrollBar()->setRange(0, range - viewport()->width());
257 horizontalScrollBar()->setPageStep(viewport()->width());
258
259 if (scrollRight)
260 horizontalScrollBar()->setValue(horizontalScrollBar()->maximum());
261 }
262 }
263
264
271 QList< AbstractTreeItem * > newlySelectedItems) {
272 if (newlySelectedItems.size())
273 scrollTo(newlySelectedItems.last());
274 }
275
276
283 int row = getModel()->indexOfVisibleItem(newlySelectedItem);
284
285 if (row >= 0) {
286 int topRow = verticalScrollBar()->value();
287
288 if (row < topRow) {
289 verticalScrollBar()->setValue(row);
290 }
291 else {
292 int wholeVisibleRowCount = viewport()->height() / m_rowHeight;
293 int bottomRow = topRow + wholeVisibleRowCount;
294 if (row > bottomRow)
295 verticalScrollBar()->setValue(row - wholeVisibleRowCount + 1);
296 }
297 }
298
299 viewport()->update();
300 }
301
302
311 bool TableViewContent::eventFilter(QObject *target, QEvent *event) {
312 return QObject::eventFilter(target, event);
313 }
314
315
322 if (event->buttons() & Qt::LeftButton) {
323 int rowNum = event->pos().y() / m_rowHeight;
324
325 if (m_activeCell->first && cellIsEditable(rowNum, m_activeCell->second)) {
326 const AbstractTableDelegate *delegate = m_model->getDelegate();
327 TableColumn *col =
328 m_columns->getVisibleColumns()[m_activeCell->second];
329
330 delete m_editWidget;
331 m_editWidget = NULL;
332 m_editWidget = delegate->getWidget(col);
333 delegate->readData(m_editWidget, m_activeCell->first, col);
334 m_editWidget->setParent(this);
335 m_editWidget->setFocus(Qt::OtherFocusReason);
336 }
337
338 viewport()->update();
339 }
340 }
341
342
348 void TableViewContent::mousePressEvent(QMouseEvent *event) {
349
350 if (event->buttons() & Qt::LeftButton) {
351 // FIXME refactor this file (lol)
352 if (!(event->modifiers() & Qt::ShiftModifier))
353 updateActiveCell(event->pos());
354
355 int rowNum = event->pos().y() / m_rowHeight;
356 int colNum = getColumnFromScreenX(event->pos().x());
357
358 // HACK
359 // BUG
360 // TODO
361 // FIXME
362 if (colNum == 0)
364
365 if (rowNum >= 0 && rowNum < m_items->size() && m_activeCell->first) {
366 // The user clicked on a valid item, handle selection of individual
367 // cells (not rows).
368
369 // Deselect all rows, as this will now be a cell selection.
370 m_model->setGlobalSelection(false);
371
372 if (cellIsEditable(rowNum, m_activeCell->second)) {
373 if (event->modifiers() & Qt::ControlModifier) {
374 if (rowsWithActiveColumnSelected->indexOf(m_activeCell->first) < 0)
375 rowsWithActiveColumnSelected->append(m_activeCell->first);
376 else
377 rowsWithActiveColumnSelected->removeAll(m_activeCell->first);
378 m_lastDirectlySelectedRow = m_activeCell->first;
379
380 m_lastShiftSelection->clear();
381 }
382 else {
383 if (event->modifiers() & Qt::ShiftModifier) {
384 updateColumnGroupSelection((*m_items)[rowNum]);
385 }
386 else {
387 // Normal click, no modifiers.
389 rowsWithActiveColumnSelected->append(m_activeCell->first);
390 m_lastDirectlySelectedRow = m_activeCell->first;
391 m_lastShiftSelection->clear();
392 }
393 }
394 }
395 }
396 else {
397 // row selections
398 if (rowNum >= 0 && rowNum < m_items->size()) {
399 int columnNum = getColumnFromScreenX(event->pos().x());
400
401 if (columnNum != -1) {
402 TableColumn *column = m_columns->getVisibleColumns()[columnNum];
403 if (column->getTitle().isEmpty()) {
405
406 AbstractTreeItem *const &item = m_items->at(rowNum);
407 QList< AbstractTreeItem * > newlySelectedItems;
408
409 if (event->modifiers() & Qt::ControlModifier) {
410 if (item->getPointerType() == AbstractTreeItem::Measure)
411 item->parent()->setSelected(!item->isSelected());
412
413 item->setSelected(!item->isSelected());
415 newlySelectedItems.append(item);
416 }
417 else {
418 if (event->modifiers() & Qt::ShiftModifier) {
419 newlySelectedItems = updateRowGroupSelection(rowNum);
420 }
421 else {
422 QList<AbstractTreeItem *> selectedItems =
423 m_model->getSelectedItems();
424
425 foreach (AbstractTreeItem * selectedItem, selectedItems) {
426 if (selectedItem->getPointerType() ==
427 AbstractTreeItem::Measure)
428 selectedItem->parent()->setSelected(false);
429 }
430
431 m_model->setGlobalSelection(false);
432
433 if (item->getPointerType() == AbstractTreeItem::Measure)
434 item->parent()->setSelected(true);
435
436 item->setSelected(true);
438 newlySelectedItems.append(item);
439 }
440 }
441
442 QList< AbstractTreeItem * > tmp = newlySelectedItems;
443 newlySelectedItems.clear();
444 foreach (AbstractTreeItem * i, tmp) {
445 newlySelectedItems.append(i);
446 if (i->getPointerType() == AbstractTreeItem::Point) {
447 foreach (AbstractTreeItem * child, i->getChildren()) {
448 child->setSelected(true);
449 newlySelectedItems.append(child);
450 }
451 }
452 }
453
454 emit tableSelectionChanged(newlySelectedItems);
455 }
456 }
457 }
458 }
459
460 delete m_editWidget;
461 m_editWidget = NULL;
462
463 viewport()->update();
464 emit tableSelectionChanged();
465 }
466 }
467
468
474 void TableViewContent::mouseReleaseEvent(QMouseEvent *event) {
475 }
476
477
483 void TableViewContent::mouseMoveEvent(QMouseEvent *event) {
484 if (!m_editWidget) {
485 if (event->buttons() & Qt::LeftButton) {
486 int rowNum = event->pos().y() / m_rowHeight;
487
488 // used to make sure that the mouse position is inside the content
489 int yPos = event->pos().y();
490 if (yPos >= 0 && rowNum < m_items->size() && m_activeCell->first) {
491 // The user clicked on a valid item,
492 // handle selection of individual cells (not rows).
493 if (cellIsEditable(rowNum, m_activeCell->second)) {
494 updateColumnGroupSelection((*m_items)[rowNum]);
495 }
496 }
497 else {
498 // row selections
499 if (yPos >= 0 && rowNum < m_items->size()) {
500 // There is no active cell,
501 // maybe they clicked on the row number column.
502 int columnNum = getColumnFromScreenX(event->pos().x());
503
504 if (columnNum != -1) {
506
507 QList< AbstractTreeItem * > tmp =
509 QList< AbstractTreeItem * > newlySelectedItems;
510 foreach (AbstractTreeItem * i, tmp) {
511 newlySelectedItems.append(i);
512 if (i->getPointerType() == AbstractTreeItem::Point) {
513 foreach (AbstractTreeItem * child, i->getChildren()) {
514 child->setSelected(true);
515 newlySelectedItems.append(child);
516 }
517 }
518 }
519
520 emit tableSelectionChanged(newlySelectedItems);
521 }
522 }
523 }
524
525 QScrollBar *vertScroll = verticalScrollBar();
526
527 if (yPos > viewport()->height() &&
528 vertScroll->value() < vertScroll->maximum()) {
529 // Scroll down to allow for more drag selections.
530 vertScroll->setValue(vertScroll->value() + 1);
531 }
532 else {
533 if (yPos < 0 && vertScroll->value() > vertScroll->minimum())
534 vertScroll->setValue(vertScroll->value() - 1);
535 }
536
537 viewport()->update();
538 emit tableSelectionChanged();
539 }
540 }
541 }
542
543
549 void TableViewContent::leaveEvent(QEvent *event) {
550 // viewport()->update();
551 }
552
553
559 void TableViewContent::keyPressEvent(QKeyEvent *event) {
560 Qt::Key key = (Qt::Key) event->key();
561
562 // Handle Ctrl-A (selects all rows)
563 if (key == Qt::Key_A && event->modifiers() == Qt::ControlModifier) {
566 m_model->setGlobalSelection(true);
567 viewport()->update();
568
569 emit tableSelectionChanged();
570 }
571
572 // Handle esc key (cancel editing)
573 else if (key == Qt::Key_Escape) {
574 if (m_editWidget) {
575 delete m_editWidget;
576 m_editWidget = NULL;
577 setFocus(Qt::ActiveWindowFocusReason);
578 viewport()->update();
579 }
580 }
581
582 // Handle delete key (delete row(s) if any are selected)
583 else if (key == Qt::Key_Delete) {
584 if (hasRowSelection())
586 }
587
588 // Handle return or enter (stop editing)
589 else if (key == Qt::Key_Return || key == Qt::Key_Enter) {
592 }
593
594 // Handle
595 else if (key == Qt::Key_Tab) {
598 }
599
600 // Handle arrow key navigation
601 else if (key == Qt::Key_Up || key == Qt::Key_Down ||
602 key == Qt::Key_Left || key == Qt::Key_Right) {
603 if (!hasActiveCell()) {
604 if (m_items && m_items->size()) {
605 m_activeCell->first = (*m_items)[0];
606 m_activeCell->second = 1;
607 }
608 }
609
610 if (hasActiveCell() && !m_editWidget) {
611
612 // Handle up arrow with shift pressed
613 if (key == Qt::Key_Up && event->modifiers() == Qt::ShiftModifier) {
614
615 AbstractTreeItem *prevCell = m_lastShiftArrowSelectedCell->first ?
616 m_lastShiftArrowSelectedCell->first : m_activeCell->first;
617
618 int prevCellIndex = getModel()->indexOfVisibleItem(prevCell);
619
620 if (prevCellIndex > 0) {
621 QList< AbstractTreeItem * > itemList =
622 getModel()->getItems(prevCellIndex - 1, prevCellIndex);
623
624 if (itemList.size()) {
625 AbstractTreeItem *curItem = itemList[0];
626
627 if (rowsWithActiveColumnSelected->contains(curItem) ||
628 curItem == m_activeCell->first)
629 rowsWithActiveColumnSelected->removeAll(prevCell);
630 else
631 rowsWithActiveColumnSelected->append(curItem);
632
633 if (curItem == m_activeCell->first)
634 m_lastShiftArrowSelectedCell->first = NULL;
635 else
636 m_lastShiftArrowSelectedCell->first = curItem;
637 m_lastShiftArrowSelectedCell->second = m_activeCell->second;
638
639 // scroll if needed
640 int m_itemsPrevIndex = m_items->indexOf(prevCell);
641 int m_itemsCurIndex = m_items->indexOf(curItem);
642 if (m_itemsCurIndex == -1) {
643 if (m_itemsPrevIndex == 0) { // then need to scroll up!
644 verticalScrollBar()->setValue(qMax(0, prevCellIndex - 1));
645 }
646 else {
647 //int m_itemsLastIndex = m_items->size() - 1;
648 //verticalScrollBar()->setValue(qMin(prevCell + 1, ));
649 }
650 }
651
652 viewport()->update();
653 }
654 }
655 }
656
657 // Handle down arrow with shift pressed
658 else if (key == Qt::Key_Down && event->modifiers() == Qt::ShiftModifier) {
659 AbstractTreeItem *prevCell = m_lastShiftArrowSelectedCell->first ?
660 m_lastShiftArrowSelectedCell->first : m_activeCell->first;
661
662 int prevCellIndex = getModel()->indexOfVisibleItem(prevCell);
663
664 if (prevCellIndex >= 0 &&
665 prevCellIndex < getModel()->getVisibleRowCount() - 1) {
666 QList< AbstractTreeItem * > itemList =
667 getModel()->getItems(prevCellIndex + 1, prevCellIndex + 2);
668
669 if (itemList.size()) {
670 AbstractTreeItem *curItem = itemList[0];
671
672 if (rowsWithActiveColumnSelected->contains(curItem) ||
673 curItem == m_activeCell->first)
674 rowsWithActiveColumnSelected->removeAll(prevCell);
675 else
676 rowsWithActiveColumnSelected->append(curItem);
677
678 if (curItem == m_activeCell->first)
679 m_lastShiftArrowSelectedCell->first = NULL;
680 else
681 m_lastShiftArrowSelectedCell->first = curItem;
682 m_lastShiftArrowSelectedCell->second = m_activeCell->second;
683 viewport()->update();
684
685 // scroll if needed
686 int m_itemsPrevIndex = m_items->indexOf(prevCell);
687 int m_itemsCurIndex = m_items->indexOf(curItem);
688 if (m_itemsCurIndex == -1) {
689 if (m_itemsPrevIndex == m_items->size() - 1) {
690 int visibleItemCount = getModel()->getVisibleRowCount();
691 verticalScrollBar()->setValue(qMin(visibleItemCount,
692 getModel()->indexOfVisibleItem(m_items->at(1))));
693 }
694 else {
695 //int m_itemsLastIndex = m_items->size() - 1;
696 //verticalScrollBar()->setValue(qMin(prevCell + 1, ));
697 }
698 }
699 }
700 }
701 }
702
703 // Handle up arrow
704 else if (key == Qt::Key_Up) {
706 }
707
708 // Handle down arrow
709 else if (key == Qt::Key_Down) {
711 }
712
713 // Handle left arrow
714 else if (key == Qt::Key_Left) {
716 }
717
718 // Handle right arrow
719 else if (key == Qt::Key_Right) {
721 }
722 }
723 }
724
725 // start editing the active cell
726 else {
727 // event->text() will be empty if a modifier was pressed.
728 if (hasActiveCell() && !event->text().isEmpty()) {
729 if (!m_items->contains(m_activeCell->first))
730 scrollTo(m_activeCell->first);
731
732 if (m_items->contains(m_activeCell->first) &&
733 cellIsEditable(m_items->indexOf(m_activeCell->first),
734 m_activeCell->second)) {
735 AbstractTableDelegate const *delegate = m_model->getDelegate();
736 TableColumn *col =
737 m_columns->getVisibleColumns()[m_activeCell->second];
738
739 delete m_editWidget;
740 m_editWidget = NULL;
741 m_editWidget = delegate->getWidget(col);
742 delegate->readData(m_editWidget, m_activeCell->first, col, event->text());
743 m_editWidget->setParent(this);
744 m_editWidget->setFocus(Qt::OtherFocusReason);
745 }
746
747 viewport()->update();
748 }
749 }
750 }
751
752
757 if (m_editWidget) {
758 TableColumn *col =
759 m_columns->getVisibleColumns()[m_activeCell->second];
760 getModel()->getDelegate()->saveData(
761 m_editWidget, m_activeCell->first, col);
762 delete m_editWidget;
763 m_editWidget = NULL;
764
765 cellDataChanged(col);
766 setFocus(Qt::ActiveWindowFocusReason);
767 }
768 }
769
770
775 int activeIndex = m_items->indexOf(m_activeCell->first);
776 if (activeIndex != -1) {
777 if (activeIndex == 0) {
778 int row = qMax(0, getModel()->indexOfVisibleItem(
779 m_activeCell->first) - 1);
780
781 verticalScrollBar()->setValue(row);
782 }
783
784 m_activeCell->first = (*m_items)[qMax(0, activeIndex - 1)];
786 viewport()->update();
787 }
788 }
789
790
795 int activeIndex = m_items->indexOf(m_activeCell->first);
796 if (activeIndex != -1) {
797 if (activeIndex == m_items->size() - 1) {
798 int row = qMin(getModel()->getVisibleRowCount() - 1,
799 getModel()->indexOfVisibleItem(m_items->at(0)));
800
801 verticalScrollBar()->setValue(row + 1);
802 activeIndex = m_items->indexOf(m_activeCell->first);
803 }
804
805 m_activeCell->first = (*m_items)[qMin(activeIndex + 1, m_items->size() - 1)];
807 viewport()->update();
808 }
809 }
810
811
816 m_activeCell->second = qMax(1, m_activeCell->second - 1);
817 int leftMostVisibleCol = getColumnFromScreenX(0);
818 if (leftMostVisibleCol == m_activeCell->second) {
819 horizontalScrollBar()->setValue(horizontalScrollBar()->value() -
820 m_columns->getVisibleColumns()[m_activeCell->second]->getWidth());
821 }
822
824 viewport()->update();
825 }
826
827
832 m_activeCell->second = qMin(m_columns->getVisibleColumns().size() - 1,
833 m_activeCell->second + 1);
834 int rightMostVisibleCol = getColumnFromScreenX(viewport()->width());
835 if (rightMostVisibleCol == m_activeCell->second) {
836 horizontalScrollBar()->setValue(horizontalScrollBar()->value() +
837 m_columns->getVisibleColumns()[m_activeCell->second]->getWidth());
838 }
839
841 viewport()->update();
842 }
843
844
850 void TableViewContent::paintEvent(QPaintEvent *event) {
851 if (m_model && m_columns) {
852 // int startRow = verticalScrollBar()->value();
853 int rowCount = (int) ceil(viewport()->height() / (double) m_rowHeight);
854
855 QPainter painter(viewport());
856 painter.setRenderHint(QPainter::Antialiasing, false);
857 // painter.setRenderHints(QPainter::NonCosmeticDefaultPen, true);
858
859 bool editWidgetVisible = false;
860 for (int i = 0; i < rowCount; i++) {
861 // define the top left corner of the row and also how big the row is
862 QPoint relativeTopLeft(0, i * m_rowHeight);
863 QPoint scrollBarPos(horizontalScrollBar()->value(),
864 verticalScrollBar()->value());
865 QPoint absoluteTopLeft(relativeTopLeft + scrollBarPos);
866 QSize rowSize(viewport()->width(), (int) m_rowHeight);
867
868 // Fill in the background with the background color
869 painter.fillRect(QRect(relativeTopLeft, rowSize), palette().base());
870
871 if (i < m_items->size()) {
872
873
874
875
876
877
878 // ********************************************************
879 // HACK: FIXME: ask tree m_items if background needs to be
880 // darkened, instead figuring that out here. Also, change
881 // composition mode so that ref measure rows look different
882 // when they are highlighted as well
883 /*
884 if (m_items->at(i)->getPointerType() == AbstractTreeItem::Measure)
885 {
886 ControlMeasure * cm = (ControlMeasure *) m_items->at(i)->getPointer();
887 if (cm->Parent()->GetRefMeasure() == cm)
888 {
889 QPoint selectionTopLeft(-absoluteTopLeft.x(), relativeTopLeft.y());
890 QSize selectionSize(m_columns->getVisibleWidth(), (int) m_rowHeight);
891
892 QRect selectionRect(selectionTopLeft, selectionSize);
893 QColor color = palette().base().color();
894 painter.fillRect(selectionRect, color.darker(110));
895 }
896 }
897 */
898 //*********************************************************
899
900
901
902
903
904
905
906
907
908
909
910
911 if (m_items->at(i)->isSelected()) {
912 QPoint selectionTopLeft(-absoluteTopLeft.x(), relativeTopLeft.y());
913 QSize selectionSize(m_columns->getVisibleWidth(), (int) m_rowHeight);
914
915 QRect selectionRect(selectionTopLeft, selectionSize);
916 painter.fillRect(selectionRect, palette().highlight().color());
917 }
918
919 paintRow(&painter, i, absoluteTopLeft, relativeTopLeft);
920 }
921 }
922
923 for (int i = 0; i < rowCount; i++) {
924 if (i < m_items->size()) {
925 QPoint relativeTopLeft(0, i * m_rowHeight);
926 if (m_editWidget && m_activeCell->first == m_items->at(i)) {
927 QPair<int, int> xRange(
928 m_columns->getVisibleXRange(m_activeCell->second));
929
930 m_editWidget->move(
931 QPoint(xRange.first - horizontalScrollBar()->value() - 1,
932 relativeTopLeft.y() + 1));
933 m_editWidget->resize(xRange.second - xRange.first, m_rowHeight + 1);
934 m_editWidget->setVisible(true);
935 editWidgetVisible = true;
936 }
937 else {
938 if (m_activeCell->first == m_items->at(i)) {
939 QPair<int, int> activeXArea =
940 m_columns->getVisibleXRange(m_activeCell->second);
941
942 QRect activeArea(activeXArea.first, relativeTopLeft.y(),
943 activeXArea.second - activeXArea.first, m_rowHeight);
944
945 activeArea.moveLeft(
946 activeArea.left() - horizontalScrollBar()->value());
947 activeArea.adjust(-1, -1, -2, -1);
948 QPen pen(Qt::black);
949 pen.setWidth(3);
950 painter.setPen(pen);
951 painter.drawRect(activeArea);
952 }
953 }
954 }
955 }
956
957 if (m_editWidget && !editWidgetVisible)
958 m_editWidget->setVisible(false);
959 }
960 else {
961 QWidget::paintEvent(event);
962 }
963 }
964
965
971 void TableViewContent::resizeEvent(QResizeEvent *event) {
972 QAbstractScrollArea::resizeEvent(event);
975 }
976
977
985 QAbstractScrollArea::scrollContentsBy(dx, dy);
987 }
988
989
994 m_parentView = NULL;
995 m_model = NULL;
996 m_items = NULL;
997 m_activeCell = NULL;
998 m_lastShiftArrowSelectedCell = NULL;
999 m_editWidget = NULL;
1001 m_lastShiftSelection = NULL;
1002 m_columns = NULL;
1004 m_applyToSelectionAct = NULL;
1005 m_applyToAllAct = NULL;
1007 m_editControlPointAct = NULL;
1008 }
1009
1010
1017 if (col->hasNetworkStructureEffect())
1018 emit rebuildModels(QList< AbstractTreeItem * >());
1019
1020 emit modelDataChanged();
1021 }
1022
1023
1028 m_activeCell->first = NULL;
1029 m_activeCell->second = -1;
1030 }
1031
1032
1037 m_lastShiftArrowSelectedCell->first = NULL;
1039 }
1040
1041
1048 if (hasActiveCell()) {
1049 TableColumn *col = m_columns->getVisibleColumns()[m_activeCell->second];
1050
1051 QString colTitle = col->getTitle();
1052
1053 // Grab the active cell's data and copy it to the selected cells that are
1054 // in the same column as the active cell.
1055 QString cellData = m_activeCell->first->getFormattedData(colTitle);
1056
1057 QList< AbstractTreeItem * > selection = allCells ? m_model->getItems(
1058 0, m_model->getVisibleRowCount()) : *rowsWithActiveColumnSelected;
1059
1060 bool needsDialog = true;
1061 bool done = false;
1062 for (int i = 0; !done && i < selection.size(); i++) {
1063 AbstractTreeItem *row = selection[i];
1064 bool changeData = true;
1065
1066 QString warningText =
1067 m_model->getWarningMessage(row, col, cellData);
1068 if (needsDialog && warningText.size()) {
1069 QMessageBox::StandardButton status = QMessageBox::warning(
1070 this, "Change cells?", warningText, QMessageBox::Yes |
1071 QMessageBox::No | QMessageBox::YesToAll | QMessageBox::NoToAll);
1072
1073 switch (status) {
1074 case QMessageBox::YesToAll:
1075 needsDialog = false;
1076 break;
1077 case QMessageBox::NoToAll:
1078 done = true;
1079 case QMessageBox::No:
1080 changeData = false;
1081 default:
1082 ;
1083 }
1084 }
1085
1086 if (changeData)
1087 row->setData(colTitle, cellData);
1088 }
1089
1090 viewport()->update();
1091 cellDataChanged(col);
1092 }
1093 }
1094
1095
1100 m_applyToSelectionAct = new QAction(tr("Copy to selected cells"), this);
1101 m_applyToSelectionAct->setStatusTip(tr("Copy the contents of this cell to the"
1102 "selected cells"));
1103 connect(m_applyToSelectionAct, SIGNAL(triggered()),
1104 this, SLOT(copySelection()));
1105
1106 m_applyToAllAct = new QAction(tr("Copy to all cells"), this);
1107 m_applyToAllAct->setStatusTip(tr("Copy the contents of this cell to all"
1108 "cells in the current column"));
1109 connect(m_applyToAllAct, SIGNAL(triggered()),
1110 this, SLOT(copyAll()));
1111
1112 m_deleteSelectedRowsAct = new QAction(tr("Delete selected rows"), this);
1113 m_deleteSelectedRowsAct->setStatusTip(
1114 tr("Delete the currently selected rows"));
1115 connect(m_deleteSelectedRowsAct, SIGNAL(triggered()),
1116 this, SLOT(deleteSelectedRows()));
1117
1118 m_editControlPointAct = new QAction(tr("Edit selected control point"), this);
1119 m_editControlPointAct->setStatusTip(
1120 tr("Edit the selected control point or the parent control point of control measure"));
1121 connect(m_editControlPointAct, SIGNAL(triggered()),
1122 this, SLOT(editControlPoint()));
1123 }
1124
1125
1134
1135 for (int i = 0; i < m_columns->getVisibleColumns().size(); i++) {
1136 QPair<int, int> cellXRange(m_columns->getVisibleXRange(i));
1137 int deltaX = -horizontalScrollBar()->value();
1138
1139 if (cellXRange.first + deltaX < screenX &&
1140 cellXRange.second + deltaX > screenX) {
1141 return i;
1142 }
1143 }
1144
1145 return -1;
1146 }
1147
1148
1157 int calculatedRowNum = screenY / m_rowHeight;
1158
1159 if (calculatedRowNum >= 0 && calculatedRowNum < m_items->size() &&
1160 screenY >= 0 && screenY <= viewport()->height())
1161 return calculatedRowNum;
1162
1163 return -1;
1164 }
1165
1166
1173 return (m_activeCell->first && m_activeCell->second >= 0);
1174 }
1175
1176
1183 return (m_model->getSelectedItems().size());
1184 }
1185
1186
1194 bool TableViewContent::mouseInCellSelection(QPoint mousePos) const {
1195 int colNum = getColumnFromScreenX(mousePos.x());
1196 AbstractTreeItem *row = m_items->at(getRowFromScreenY(mousePos.y()));
1197
1198 return (rowsWithActiveColumnSelected->contains(row) &&
1199 m_activeCell->second == colNum);
1200 }
1201
1202
1210 bool TableViewContent::mouseInRowSelection(QPoint mousePos) const {
1211 AbstractTreeItem *row = m_items->at(getRowFromScreenY(mousePos.y()));
1212
1213 return (m_model->getSelectedItems().contains(row));
1214 }
1215
1216
1224 bool TableViewContent::rowIsValid(int rowNum) const {
1225 bool valid = false;
1226
1227 if (rowNum >= 0 && rowNum < m_items->size())
1228 valid = true;
1229
1230 return valid;
1231 }
1232
1233
1241 bool TableViewContent::columnIsValid(int colNum) const {
1242 bool valid = false;
1243
1244 if (colNum >= 0 && colNum < m_columns->getVisibleColumns().size())
1245 valid = true;
1246
1247 return valid;
1248 }
1249
1250
1259 bool TableViewContent::cellIsEditable(int rowNum, int colNum) const {
1260
1261 bool editable = false;
1262
1263 QString colName = m_columns->getVisibleColumns()[colNum]->getTitle();
1264 if (m_items->at(rowNum)->isSelectable() &&
1265 m_items->at(rowNum)->isDataEditable(colName) &&
1266 !m_columns->getVisibleColumns()[colNum]->isReadOnly())
1267 editable = true;
1268
1269 return editable;
1270 }
1271
1272
1280 bool TableViewContent::isDataColumn(int colNum) const {
1281 //TODO: Figure out what this does and if we can do it in a less confusing and roundabout way
1282 return m_columns->getVisibleColumns()[colNum]->getTitle().size();
1283 }
1284
1285
1294 void TableViewContent::paintRow(QPainter *painter, int rowNum,
1295 QPoint absolutePosition, QPoint relativePosition) {
1296
1297 QPoint point(-absolutePosition.x(), relativePosition.y());
1298
1299 AbstractTreeItem *item = (*m_items)[rowNum];
1300
1301 // should always be true, but prevents segfault in case of bug
1302 if (item) {
1303 QPen originalPen = painter->pen();
1304
1305 QPoint textPoint(point.x() + ITEM_INDENTATION,
1306 point.y() + ITEM_PADDING / 2);
1307
1308 // finally draw the text
1309 int textHeight = m_rowHeight - ITEM_PADDING;
1310
1311 QFontMetrics metrics(font());
1312
1313 QPen gridPen(Qt::gray);
1314
1315 TableColumnList visibleCols = m_columns->getVisibleColumns();
1316 for (int i = 0; i < visibleCols.size(); i++) {
1317 // draw text
1318 QPair<int, int> cellXRange(visibleCols.getVisibleXRange(i));
1319 QRect cellRect(cellXRange.first, point.y(),
1320 cellXRange.second - cellXRange.first, m_rowHeight);
1321 cellRect.moveLeft(cellRect.left() - horizontalScrollBar()->value() - 1);
1322
1323 QString columnTitle = visibleCols[i]->getTitle();
1324 QRect textRect(textPoint, QSize(cellRect.right() - textPoint.x(),
1325 textHeight));
1326 QString text;
1327 bool textCentered = false;
1328 if (!columnTitle.isEmpty()) {
1329 text = item->getFormattedData(columnTitle);
1330
1331 if (rowsWithActiveColumnSelected->indexOf(item) != -1 &&
1332 m_activeCell->second == i) {
1333 // This cell is selected, so render it as such.
1334 if (m_activeCell->first != item) {
1335 painter->fillRect(cellRect,
1336 QBrush(palette().highlight().color()));
1337 painter->setPen(palette().highlightedText().color());
1338 }
1339 else {
1340 painter->setPen(palette().text().color());
1341 }
1342 }
1343 else {
1344 if (item->isSelected()) {
1345 painter->setPen(palette().highlightedText().color());
1346 }
1347 else {
1348 // If the current column is not editable (i.e. read-only), or it
1349 // is locked (think edit-locked control point or measure), then
1350 // it should be grayed out.
1351 //
1352 // NOTE: The following two lines provide for graying out of edit
1353 // locked data. This is commented out because this functionality
1354 // is not fully working yet.
1355 //if (!cellIsEditable(rowNum, i) ||
1356 // item->isDataLocked(columnTitle))
1357 if (!cellIsEditable(rowNum, i)) {
1358 painter->setPen(palette().color(QPalette::Disabled,
1359 QPalette::Text));
1360 }
1361 else {
1362 painter->setPen(palette().text().color());
1363 }
1364 }
1365 }
1366 }
1367 else {
1368 // Draw the row number.
1369 text = QString::number(rowNum + verticalScrollBar()->value() + 1);
1370 textCentered = true;
1371
1372 // We need to paint the row number column.
1373 int x = cellRect.center().x();
1374 QLinearGradient gradient(x, cellRect.top(), x, cellRect.bottom());
1375
1376 bool selected = item->isSelected();
1377 QColor color = selected ? palette().highlight().color() :
1378 palette().button().color();
1379
1380 int adjustment = 110;
1381 gradient.setColorAt(0, color.lighter(adjustment));
1382 gradient.setColorAt(1, color.darker(adjustment));
1383 painter->fillRect(cellRect, gradient);
1384 if (selected)
1385 painter->setPen(palette().highlightedText().color());
1386 else
1387 painter->setPen(palette().text().color());
1388 }
1389
1390 int flags = Qt::TextDontClip;
1391 if (textCentered)
1392 flags |= Qt::AlignCenter;
1393
1394 // TODO this shouldn't be here... an item should be able to tell
1395 // whether or not it should be bolded.
1396 QFont normalFont = painter->font();
1397
1398 if (item->getPointerType() == AbstractTreeItem::Measure) {
1399 ControlMeasure *cm = (ControlMeasure *) item->getPointer();
1400 if (cm && cm->Parent() && cm->Parent()->GetRefMeasure() == cm) {
1401 QFont boldFont(normalFont);
1402 boldFont.setBold(true);
1403 painter->setFont(boldFont);
1404 }
1405 }
1406
1407 painter->drawText(textRect, flags,
1408 metrics.elidedText(text, Qt::ElideRight,
1409 textRect.width() - ITEM_INDENTATION));
1410 painter->setFont(normalFont);
1411
1412 textPoint.setX(cellRect.right() + ITEM_INDENTATION);
1413 painter->setPen(originalPen);
1414
1415 painter->setPen(gridPen);
1416 painter->drawLine(QPoint(cellRect.right(), point.y()),
1417 QPoint(cellRect.right(), point.y() + m_rowHeight));
1418 painter->setPen(originalPen);
1419 }
1420
1421 int left = -horizontalScrollBar()->value() - 1;
1422 int right = m_columns->getVisibleWidth();
1423
1424 gridPen.setWidth(2);
1425 painter->setPen(gridPen);
1426 painter->drawLine(QPoint(left, point.y() + m_rowHeight),
1427 QPoint(right, point.y() + m_rowHeight));
1428 painter->setPen(originalPen);
1429 }
1430 }
1431
1432
1438 void TableViewContent::updateActiveCell(QPoint screenPos) {
1439 if (m_editWidget && m_activeCell->first && m_activeCell->second >= 0) {
1440 try {
1441 const TableColumn *col =
1442 m_columns->getVisibleColumns()[m_activeCell->second];
1443 m_model->getDelegate()->saveData(m_editWidget, m_activeCell->first,
1444 col);
1445
1446 cellDataChanged(col);
1447 }
1448 catch (IException &e) {
1449 QMessageBox::critical(this, "Failed to Set Data", e.what());
1450 }
1451 }
1452
1453 int rowNum = getRowFromScreenY(screenPos.y());
1454 int oldActiveColumn = m_activeCell->second;
1455
1457
1458 if (rowNum >= 0) {
1459 AbstractTreeItem *item = (*m_items)[rowNum];
1460
1461 TableColumnList visibleCols = m_columns->getVisibleColumns();
1462 for (int i = 0; i < visibleCols.size(); i++) {
1463 QPair<int, int> cellXRange(m_columns->getVisibleXRange(i));
1464 QRect cellRect(cellXRange.first, m_rowHeight * rowNum,
1465 cellXRange.second - cellXRange.first, m_rowHeight);
1466
1467 cellRect.moveLeft(cellRect.left() - horizontalScrollBar()->value());
1468
1469 if (cellRect.contains(screenPos) &&
1470 (oldActiveColumn != -1 || !visibleCols[i]->getTitle().isEmpty())) {
1471 m_activeCell->first = item;
1472 m_activeCell->second = i;
1473 }
1474 }
1475 }
1476
1477 if (oldActiveColumn != m_activeCell->second) {
1480 }
1481
1483 }
1484
1485
1492 // delete current row selection
1493 foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1494 if (rowsWithActiveColumnSelected->indexOf(row) != -1)
1495 rowsWithActiveColumnSelected->removeOne(row);
1496 }
1497
1498
1500 *m_lastShiftSelection = m_model->getItems(
1502 }
1503 else {
1504 m_lastShiftSelection->clear();
1505 }
1506
1507 foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1508 if (rowsWithActiveColumnSelected->indexOf(row) == -1)
1509 rowsWithActiveColumnSelected->append(row);
1510 }
1511 }
1512
1513
1521 QList< AbstractTreeItem * > TableViewContent::updateRowGroupSelection(int lastRow) {
1522 foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1523 if (row->getPointerType() == AbstractTreeItem::Point)
1524 foreach (AbstractTreeItem * child, row->getChildren())
1525 child->setSelected(false);
1526
1527 if (row->getPointerType() == AbstractTreeItem::Measure)
1528 row->parent()->setSelected(false);
1529
1530 row->setSelected(false);
1531 }
1532
1534 *m_lastShiftSelection = m_model->getItems(
1535 m_lastDirectlySelectedRow, m_items->at(lastRow));
1536 }
1537 else {
1538 m_lastShiftSelection->clear();
1539 }
1540
1541 QList< AbstractTreeItem * > newlySelectedItems;
1542 foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1543 row->setSelected(true);
1544
1545 if (row->getPointerType() == AbstractTreeItem::Measure)
1546 row->parent()->setSelected(true);
1547
1548 newlySelectedItems.append(row);
1549 }
1550
1551 return newlySelectedItems;
1552 }
1553
1554
1563
1564
1573
1574
1579 // Prompt the user for confirmation before deletion.
1580 QMessageBox::StandardButton status = QMessageBox::warning(
1581 this, "Delete row(s)?", "Delete selected row(s)?",
1582 QMessageBox::Yes | QMessageBox::No);
1583
1584 if (status == QMessageBox::Yes) {
1585 // TODO should we store off the selected rows for efficiency?
1586 QList<AbstractTreeItem *> selectedRows = m_model->getSelectedItems();
1587
1588 emit rebuildModels(selectedRows);
1589 emit modelDataChanged();
1590
1591 m_lastShiftSelection->clear();
1592 }
1593 }
1594
1595
1600
1601 ControlPoint *cp;
1602 QString serialNumber;
1603 AbstractTreeItem *item;
1604
1605 // A single cell is chosen
1606 if (m_model->getSelectedItems().count() == 0) {
1607 item = m_activeCell->first;
1608 }
1609 // A row is chosen
1610 else {
1612 }
1613
1614 // Item chosen from the Point table view
1615 if (item->getPointerType() == AbstractTreeItem::Point) {
1616 cp = (ControlPoint *) (item->getPointer());
1617 }
1618 // Item chosen from the Measure table view
1619 else {
1620 cp = (ControlPoint *) (item->parent()->getPointer());
1621 serialNumber = item->getData("Image ID").toString();
1622 }
1623
1624// qDebug()<<"activeCell cpid = "<<cp->GetId()<<" sn = "<<serialNumber;
1625
1626 emit editControlPoint(cp, serialNumber);
1627 }
1628
1629
1634
1635 if (m_model) {
1636 int startRow = verticalScrollBar()->value();
1637 int rowCount = (int) ceil(viewport()->height() / (double) m_rowHeight);
1638 m_items->clear();
1639 foreach (AbstractTreeItem * item,
1640 m_model->getItems(startRow, startRow + rowCount)) {
1641 m_items->append(item);
1642 }
1643
1644 viewport()->update();
1645 }
1646 }
1647
1648
1654 void TableViewContent::showContextMenu(QPoint mouseLocation) {
1655 QMenu contextMenu(this);
1656
1657 // Only add this action if a single row is selected or a cell is selected
1658 // TODO: 2017-05-17 TLS
1659 // Always allow editing of point. Should we check for editLock??
1660 QList<AbstractTreeItem *> selectedRows = m_model->getSelectedItems();
1661
1662
1663 // If there is a row selection, show a context menu if the user clicked
1664 // anywhere on any of the selected row(s).
1665
1666 if (QApplication::applicationName() != "cneteditor") {
1667 if (m_activeControlNet) {
1668 m_editControlPointAct->setEnabled(true);
1669 m_applyToSelectionAct->setEnabled(true);
1670 m_applyToAllAct->setEnabled(true);
1671 }
1672 else {
1673 m_editControlPointAct->setEnabled(false);
1674 m_applyToSelectionAct->setEnabled(false);
1675 m_applyToAllAct->setEnabled(false);
1676 }
1677
1678 // We want to be able to delete rows in a nonactive control.
1679 m_deleteSelectedRowsAct->setEnabled(true);
1680
1681 if (hasActiveCell() && selectedRows.count() <= 1) {
1682 contextMenu.addAction(m_editControlPointAct);
1683 }
1684 if (hasRowSelection() && mouseInRowSelection(mouseLocation)) {
1685 contextMenu.addAction(m_deleteSelectedRowsAct);
1686 }
1687
1688 // Only show the context menu for cells if the user right-clicked on the
1689 // active cell.
1690 if (hasActiveCell() && mouseInCellSelection(mouseLocation)) {
1691 if (rowsWithActiveColumnSelected->size() > 1) {
1692 contextMenu.addAction(m_applyToSelectionAct);
1693 }
1694
1695 contextMenu.addAction(m_applyToAllAct);
1696 }
1697 }
1698 else {
1699 if (hasRowSelection() && mouseInRowSelection(mouseLocation)) {
1700 contextMenu.addAction(m_deleteSelectedRowsAct);
1701 }
1702
1703 // Only show the context menu for cells if the user right-clicked on the
1704 // active cell.
1705 if (hasActiveCell() && mouseInCellSelection(mouseLocation)) {
1706 if (rowsWithActiveColumnSelected->size() > 1) {
1707 contextMenu.addAction(m_applyToSelectionAct);
1708 }
1709
1710 contextMenu.addAction(m_applyToAllAct);
1711 }
1712 }
1713 contextMenu.exec(mapToGlobal(mouseLocation));
1714 }
1715}
Base class for delegates which create, read, and save data in the tables.
Translates the tree model into a table model.
Base class for an item in the tree.
a control measurement
A single control point.
Isis exception class.
Definition IException.h:91
QPair< int, int > getVisibleXRange(int visibleColumn)
bool hasActiveCell() const
Checks if there is an active cell.
void mouseDoubleClickEvent(QMouseEvent *event)
Overrides QWidget::mouseDoubleClickEvent.
QList< AbstractTreeItem * > updateRowGroupSelection(int lastRow)
Updates which row is selected.
void moveActiveCellDown()
Changes the viewport when the active cell is moved.
int getRowFromScreenY(int screenY) const
Calculates the visible range of a row and returns the index of the column.
void paintEvent(QPaintEvent *event)
Paints the table when there is a paint event.
AbstractTableModel * getModel()
Returns the model.
void clearActiveCell()
Clears the active cell.
void refresh()
Refreshes the table and viewport.
void leaveEvent(QEvent *event)
Overrides QWidget::leaveEvent.
void resizeEvent(QResizeEvent *event)
Updates the table when it is resized.
void scrollTo(QList< AbstractTreeItem * >)
Scrolls to the selected items.
void mousePressEvent(QMouseEvent *event)
Overrides QWidget::mousePressEvent.
void copyCellSelection(bool)
Copies the selected cells.
void updateItemList()
Updates the item list.
void createActions()
Builds the menus.
void updateColumnGroupSelection(AbstractTreeItem *)
Updates which column is selected.
void editControlPoint()
Retrieves the control point from the selected cells for editing.
void finishEditing()
Saves the data from the cell the user was modifying.
QSize sizeHint() const
Returns the minimum size hint.
void copyAll()
Copies all of the cells.
QAction * m_applyToSelectionAct
This action applies (copies) the contents of the active cell to the current selection.
QAction * m_editControlPointAct
This action edits selected control point or if measure selected, edit parent control pt.
void clearColumnSelection()
Clears the selected column.
void cellDataChanged(TableColumn const *col)
Rebuilds the models when the data is changed.
void moveActiveCellRight()
Changes the viewport when the active cell is moved.
QAction * m_deleteSelectedRowsAct
This action deletes the selected rows.
void updateHorizontalScrollBar(bool scrollRight=false)
Updates the horizontal scroll bar.
bool eventFilter(QObject *target, QEvent *event)
Overrides QObject::eventFilter.
bool rowIsValid(int rowNum) const
Checks if the row number is valid.
AbstractTreeItem * m_lastDirectlySelectedRow
This is the last row that was selected by either a control-click or normal click.
bool cellIsEditable(int, int) const
Checks if the cell is editable.
void moveActiveCellLeft()
Changes the viewport when the active cell is moved.
void deleteSelectedRows()
Deletes the selected rows.
void updateActiveCell(QPoint)
Updates which cell is active.
QSize minimumSizeHint() const
Returns the minimum size hint.
QAction * m_applyToAllAct
This action applies (copies) the contents of the active cell to all of the cells in the active cell's...
TableViewContent(AbstractTableModel *someModel)
Constructor.
bool hasRowSelection() const
Checks if there is a row selected.
void paintRow(QPainter *, int, QPoint, QPoint)
Repaints the row.
bool columnIsValid(int colNum) const
Checks if the column number is valid.
QList< AbstractTreeItem * > * rowsWithActiveColumnSelected
Stores a list of the rows that have their active column cells selected.
void keyPressEvent(QKeyEvent *event)
Overrides QWidget::keyPressEvent.
void copySelection()
Copies selected cells.
void nullify()
Clears all member variables.
bool isDataColumn(int) const
Checks if the column has a non empty title.
void moveActiveCellUp()
Shifts the active cell up.
void mouseReleaseEvent(QMouseEvent *event)
Overrides QWidget::mouseReleaseEvent.
void mouseMoveEvent(QMouseEvent *event)
Overrides QWidget::mouseMoveEvent.
void showContextMenu(QPoint)
Populates the context menus based on where the user clicked.
bool mouseInRowSelection(QPoint) const
Checks if the mouse is in the selected row.
void scrollContentsBy(int dx, int dy)
Updates the item list when the user scrolls.
virtual ~TableViewContent()
Destructor.
void setActiveControlNet(bool activeNet)
Sets if there is an active control net.
int getColumnFromScreenX(int screenX) const
Calculates the visible range of a column and returns the index of the column.
bool mouseInCellSelection(QPoint) const
Checks if the mouse is in the selected cells.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16