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