Isis 3 Programmer Reference
TableViewContent.cpp
1 #include "IsisDebug.h"
2 
3 #include "TableViewContent.h"
4 
5 #include <cmath>
6 #include <iostream>
7 
8 #include <QAction>
9 #include <QApplication>
10 #include <QDebug>
11 #include <QLabel>
12 #include <QMenu>
13 #include <QMessageBox>
14 #include <QMutex>
15 #include <QPainter>
16 #include <QPaintEvent>
17 #include <QRect>
18 #include <QScrollBar>
19 #include <QSize>
20 #include <QStyle>
21 #include <QStyleOptionViewItemV4>
22 #include <QThread>
23 #include <QVBoxLayout>
24 
25 #include "ControlMeasure.h"
26 #include "IException.h"
27 #include "IString.h"
28 
29 #include "AbstractTableDelegate.h"
30 #include "AbstractTableModel.h"
31 #include "AbstractTreeItem.h"
32 #include "TableColumn.h"
33 #include "TableColumnList.h"
34 #include <ControlPoint.h>
35 
36 
37 namespace Isis {
44  nullify();
45 
46  m_model = someModel;
47  connect(m_model, SIGNAL(modelModified()), this, SLOT(refresh()));
48  connect(m_model, SIGNAL(filterProgressChanged(int)),
49  this, SLOT(updateItemList()));
50  connect(this, SIGNAL(modelDataChanged()),
51  m_model, SLOT(applyFilter()));
52  connect(this,
53  SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)),
54  m_model,
55  SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)));
56  connect(m_model, SIGNAL(treeSelectionChanged(QList< AbstractTreeItem * >)),
58 
59  m_columns = getModel()->getColumns();
60  for (int i = 0; i < m_columns->size(); i++) {
61  TableColumn *column = (*m_columns)[i];
62 
63  connect(column, SIGNAL(visibilityChanged()), this, SLOT(refresh()));
64  connect(column, SIGNAL(visibilityChanged()),
65  this, SLOT(updateHorizontalScrollBar()));
66  connect(column, SIGNAL(widthChanged()), this, SLOT(refresh()));
67  }
68 
69  m_items = new QList< QPointer<AbstractTreeItem> >;
70  m_activeCell = new QPair<AbstractTreeItem *, int>(NULL, -1);
72  m_lastShiftSelection = new QList<AbstractTreeItem *>;
73  m_lastShiftArrowSelectedCell = new QPair< AbstractTreeItem *, int >;
74  m_lastShiftArrowSelectedCell->first = NULL;
75 
76  verticalScrollBar()->setSingleStep(1);
77 
78  m_rowHeight = QFontMetrics(font()).height() + ITEM_PADDING;
79  ASSERT(m_rowHeight > 0);
80 
81  connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
82  this, SIGNAL(horizontalScrollBarValueChanged(int)));
83 
84  setMouseTracking(true);
86 
87  createActions();
88 
89  setContextMenuPolicy(Qt::CustomContextMenu);
90  connect(this, SIGNAL(customContextMenuRequested(QPoint)),
91  this, SLOT(showContextMenu(QPoint)));
92 
93  m_activeControlNet = false;
94  }
95 
96 
101  delete m_items;
102  m_items = NULL;
103 
104  delete m_activeCell;
105  m_activeCell = NULL;
106 
107  delete m_editWidget;
108  m_editWidget = NULL;
109 
110  delete m_lastShiftSelection;
111  m_lastShiftSelection = NULL;
112 
113  delete m_applyToSelectionAct;
114  m_applyToSelectionAct = NULL;
115 
116  delete m_applyToAllAct;
117  m_applyToAllAct = NULL;
118 
121 
122  delete m_editControlPointAct;
123  m_editControlPointAct = NULL;
124 
125  delete m_lastShiftArrowSelectedCell;
126  m_lastShiftArrowSelectedCell = NULL;
127 
128  m_columns = NULL;
129  }
130 
131 
138  return QWidget::minimumSizeHint();
139  }
140 
141 
150  return minimumSizeHint();
151  }
152 
153 
160  ASSERT(m_model);
161  return m_model;
162  }
163 
164 
165  // void TableViewContent::setModel(AbstractTableModel * someModel)
166  // {
167  // if (!someModel)
168  // {
169  // IString msg = "Attempted to set a NULL m_model!";
170  // throw iException::Message(iException::Programmer, msg, _FILEINFO_);
171  // }
172  //
173  // if (getModel())
174  // {
175  // disconnect(getModel(), SIGNAL(m_modelModified()), this, SLOT(refresh()));
176  // disconnect(getModel(), SIGNAL(filterProgressChanged(int)),
177  // this, SLOT(updateItemList()));
178  // disconnect(this,
179  // SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)),
180  // getModel(),
181  // SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)));
182  // disconnect(getModel(), SIGNAL(selectionChanged(QList<AbstractTreeItem*>)),
183  // this, SLOT(scrollTo(QList<AbstractTreeItem*>)));
184  // }
185  //
186  // m_model = someModel;
187  // m_columns = someModel->getColumns();
188  //
189  // connect(m_model, SIGNAL(m_modelModified()), this, SLOT(refresh()));
190  // connect(m_model, SIGNAL(filterProgressChanged(int)),
191  // this, SLOT(updateItemList()));
192  // connect(this, SIGNAL(m_modelDataChanged()),
193  // m_model, SLOT(applyFilter()));
194  // connect(this, SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)),
195  // m_model, SIGNAL(tableSelectionChanged(QList< AbstractTreeItem * >)));
196  // connect(m_model, SIGNAL(treeSelectionChanged(QList<AbstractTreeItem*>)),
197  // this, SLOT(scrollTo(QList<AbstractTreeItem*>)));
198  //
199  // refresh();
200  // }
201 
202 
209  m_activeControlNet = activeNet;
210  }
211 
212 
217  if (m_model) {
218  if (!m_model->isFiltering()) {
219  int rowCount = m_model->getVisibleRowCount();
220  verticalScrollBar()->setRange(0, qMax(rowCount - 1, 0));
221  }
222 
223  updateItemList();
225  m_lastShiftSelection->clear();
226 
227  if (m_model->getSelectedItems().size() &&
231  }
232 
233  viewport()->update();
234  }
235  }
236 
237 
244  if (m_columns) {
245  int range = 0;
246  TableColumnList visibleCols = m_columns->getVisibleColumns();
247  for (int i = 0; i < visibleCols.size(); i++)
248  range += visibleCols[i]->getWidth() - 1;
249 
250  // For the border...
251  range -= 2;
252  horizontalScrollBar()->setRange(0, range - viewport()->width());
253  horizontalScrollBar()->setPageStep(viewport()->width());
254 
255  if (scrollRight)
256  horizontalScrollBar()->setValue(horizontalScrollBar()->maximum());
257  }
258  }
259 
260 
267  QList< AbstractTreeItem * > newlySelectedItems) {
268  if (newlySelectedItems.size())
269  scrollTo(newlySelectedItems.last());
270  }
271 
272 
278  void TableViewContent::scrollTo(AbstractTreeItem *newlySelectedItem) {
279  int row = getModel()->indexOfVisibleItem(newlySelectedItem);
280 
281  if (row >= 0) {
282  int topRow = verticalScrollBar()->value();
283 
284  if (row < topRow) {
285  verticalScrollBar()->setValue(row);
286  }
287  else {
288  int wholeVisibleRowCount = viewport()->height() / m_rowHeight;
289  int bottomRow = topRow + wholeVisibleRowCount;
290  if (row > bottomRow)
291  verticalScrollBar()->setValue(row - wholeVisibleRowCount + 1);
292  }
293  }
294 
295  viewport()->update();
296  }
297 
298 
307  bool TableViewContent::eventFilter(QObject *target, QEvent *event) {
308  return QObject::eventFilter(target, event);
309  }
310 
311 
317  void TableViewContent::mouseDoubleClickEvent(QMouseEvent *event) {
318  if (event->buttons() & Qt::LeftButton) {
319  int rowNum = event->pos().y() / m_rowHeight;
320 
321  if (m_activeCell->first && cellIsEditable(rowNum, m_activeCell->second)) {
322  const AbstractTableDelegate *delegate = m_model->getDelegate();
323  TableColumn *col =
324  m_columns->getVisibleColumns()[m_activeCell->second];
325 
326  delete m_editWidget;
327  m_editWidget = NULL;
328  m_editWidget = delegate->getWidget(col);
329  delegate->readData(m_editWidget, m_activeCell->first, col);
330  m_editWidget->setParent(this);
331  m_editWidget->setFocus(Qt::OtherFocusReason);
332  }
333 
334  viewport()->update();
335  }
336  }
337 
338 
344  void TableViewContent::mousePressEvent(QMouseEvent *event) {
345 
346  if (event->buttons() & Qt::LeftButton) {
347  // FIXME refactor this file (lol)
348  if (!(event->modifiers() & Qt::ShiftModifier))
349  updateActiveCell(event->pos());
350 
351  int rowNum = event->pos().y() / m_rowHeight;
352  int colNum = getColumnFromScreenX(event->pos().x());
353 
354  // HACK
355  // BUG
356  // TODO
357  // FIXME
358  if (colNum == 0)
359  clearActiveCell();
360 
361  if (rowNum >= 0 && rowNum < m_items->size() && m_activeCell->first) {
362  // The user clicked on a valid item, handle selection of individual
363  // cells (not rows).
364 
365  // Deselect all rows, as this will now be a cell selection.
366  m_model->setGlobalSelection(false);
367 
368  if (cellIsEditable(rowNum, m_activeCell->second)) {
369  if (event->modifiers() & Qt::ControlModifier) {
370  if (rowsWithActiveColumnSelected->indexOf(m_activeCell->first) < 0)
371  rowsWithActiveColumnSelected->append(m_activeCell->first);
372  else
373  rowsWithActiveColumnSelected->removeAll(m_activeCell->first);
374  m_lastDirectlySelectedRow = m_activeCell->first;
375 
376  m_lastShiftSelection->clear();
377  }
378  else {
379  if (event->modifiers() & Qt::ShiftModifier) {
380  updateColumnGroupSelection((*m_items)[rowNum]);
381  }
382  else {
383  // Normal click, no modifiers.
385  rowsWithActiveColumnSelected->append(m_activeCell->first);
386  m_lastDirectlySelectedRow = m_activeCell->first;
387  m_lastShiftSelection->clear();
388  }
389  }
390  }
391  }
392  else {
393  // row selections
394  if (rowNum >= 0 && rowNum < m_items->size()) {
395  int columnNum = getColumnFromScreenX(event->pos().x());
396 
397  if (columnNum != -1) {
398  TableColumn *column = m_columns->getVisibleColumns()[columnNum];
399  if (column->getTitle().isEmpty()) {
401 
402  AbstractTreeItem *const &item = m_items->at(rowNum);
403  QList< AbstractTreeItem * > newlySelectedItems;
404 
405  if (event->modifiers() & Qt::ControlModifier) {
406  if (item->getPointerType() == AbstractTreeItem::Measure)
407  item->parent()->setSelected(!item->isSelected());
408 
409  item->setSelected(!item->isSelected());
411  newlySelectedItems.append(item);
412  }
413  else {
414  if (event->modifiers() & Qt::ShiftModifier) {
415  newlySelectedItems = updateRowGroupSelection(rowNum);
416  }
417  else {
418  QList<AbstractTreeItem *> selectedItems =
419  m_model->getSelectedItems();
420 
421  foreach (AbstractTreeItem * selectedItem, selectedItems) {
422  if (selectedItem->getPointerType() ==
423  AbstractTreeItem::Measure)
424  selectedItem->parent()->setSelected(false);
425  }
426 
427  m_model->setGlobalSelection(false);
428 
429  if (item->getPointerType() == AbstractTreeItem::Measure)
430  item->parent()->setSelected(true);
431 
432  item->setSelected(true);
434  newlySelectedItems.append(item);
435  }
436  }
437 
438  QList< AbstractTreeItem * > tmp = newlySelectedItems;
439  newlySelectedItems.clear();
440  foreach (AbstractTreeItem * i, tmp) {
441  newlySelectedItems.append(i);
442  if (i->getPointerType() == AbstractTreeItem::Point) {
443  foreach (AbstractTreeItem * child, i->getChildren()) {
444  child->setSelected(true);
445  newlySelectedItems.append(child);
446  }
447  }
448  }
449 
450  emit tableSelectionChanged(newlySelectedItems);
451  }
452  }
453  }
454  }
455 
456  delete m_editWidget;
457  m_editWidget = NULL;
458 
459  viewport()->update();
460  emit tableSelectionChanged();
461  }
462  }
463 
464 
470  void TableViewContent::mouseReleaseEvent(QMouseEvent *event) {
471  }
472 
473 
479  void TableViewContent::mouseMoveEvent(QMouseEvent *event) {
480  if (!m_editWidget) {
481  if (event->buttons() & Qt::LeftButton) {
482  int rowNum = event->pos().y() / m_rowHeight;
483 
484  // used to make sure that the mouse position is inside the content
485  int yPos = event->pos().y();
486  if (yPos >= 0 && rowNum < m_items->size() && m_activeCell->first) {
487  // The user clicked on a valid item,
488  // handle selection of individual cells (not rows).
489  if (cellIsEditable(rowNum, m_activeCell->second)) {
490  updateColumnGroupSelection((*m_items)[rowNum]);
491  }
492  }
493  else {
494  // row selections
495  if (yPos >= 0 && rowNum < m_items->size()) {
496  // There is no active cell,
497  // maybe they clicked on the row number column.
498  int columnNum = getColumnFromScreenX(event->pos().x());
499 
500  if (columnNum != -1) {
502 
504  updateRowGroupSelection(rowNum);
505  QList< AbstractTreeItem * > newlySelectedItems;
506  foreach (AbstractTreeItem * i, tmp) {
507  newlySelectedItems.append(i);
508  if (i->getPointerType() == AbstractTreeItem::Point) {
509  foreach (AbstractTreeItem * child, i->getChildren()) {
510  child->setSelected(true);
511  newlySelectedItems.append(child);
512  }
513  }
514  }
515 
516  emit tableSelectionChanged(newlySelectedItems);
517  }
518  }
519  }
520 
521  QScrollBar *vertScroll = verticalScrollBar();
522 
523  if (yPos > viewport()->height() &&
524  vertScroll->value() < vertScroll->maximum()) {
525  // Scroll down to allow for more drag selections.
526  vertScroll->setValue(vertScroll->value() + 1);
527  }
528  else {
529  if (yPos < 0 && vertScroll->value() > vertScroll->minimum())
530  vertScroll->setValue(vertScroll->value() - 1);
531  }
532 
533  viewport()->update();
534  emit tableSelectionChanged();
535  }
536  }
537  }
538 
539 
545  void TableViewContent::leaveEvent(QEvent *event) {
546  // viewport()->update();
547  }
548 
549 
555  void TableViewContent::keyPressEvent(QKeyEvent *event) {
556  Qt::Key key = (Qt::Key) event->key();
557 
558  // Handle Ctrl-A (selects all rows)
559  if (key == Qt::Key_A && event->modifiers() == Qt::ControlModifier) {
560  clearActiveCell();
562  m_model->setGlobalSelection(true);
563  viewport()->update();
564 
565  emit tableSelectionChanged();
566  }
567 
568  // Handle esc key (cancel editing)
569  else if (key == Qt::Key_Escape) {
570  if (m_editWidget) {
571  delete m_editWidget;
572  m_editWidget = NULL;
573  setFocus(Qt::ActiveWindowFocusReason);
574  viewport()->update();
575  }
576  }
577 
578  // Handle delete key (delete row(s) if any are selected)
579  else if (key == Qt::Key_Delete) {
580  if (hasRowSelection())
582  }
583 
584  // Handle return or enter (stop editing)
585  else if (key == Qt::Key_Return || key == Qt::Key_Enter) {
586  finishEditing();
588  }
589 
590  // Handle
591  else if (key == Qt::Key_Tab) {
592  finishEditing();
594  }
595 
596  // Handle arrow key navigation
597  else if (key == Qt::Key_Up || key == Qt::Key_Down ||
598  key == Qt::Key_Left || key == Qt::Key_Right) {
599  if (!hasActiveCell()) {
600  ASSERT(m_items);
601  if (m_items && m_items->size()) {
602  m_activeCell->first = (*m_items)[0];
603  m_activeCell->second = 1;
604  }
605  }
606 
607  if (hasActiveCell() && !m_editWidget) {
608  // should have m_items if we have an active cell
609  ASSERT(m_items->size());
610 
611  // Handle up arrow with shift pressed
612  if (key == Qt::Key_Up && event->modifiers() == Qt::ShiftModifier) {
613  ASSERT(m_lastShiftArrowSelectedCell);
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  //ASSERT(m_itemsPrevIndex == m_items->at(m_items->size() - 1));
649  //verticalScrollBar()->setValue(qMin(prevCell + 1, ));
650  }
651  }
652 
653  viewport()->update();
654  }
655  }
656  }
657 
658  // Handle down arrow with shift pressed
659  else if (key == Qt::Key_Down && event->modifiers() == Qt::ShiftModifier) {
660  AbstractTreeItem *prevCell = m_lastShiftArrowSelectedCell->first ?
661  m_lastShiftArrowSelectedCell->first : m_activeCell->first;
662 
663  int prevCellIndex = getModel()->indexOfVisibleItem(prevCell);
664 
665  if (prevCellIndex >= 0 &&
666  prevCellIndex < getModel()->getVisibleRowCount() - 1) {
667  QList< AbstractTreeItem * > itemList =
668  getModel()->getItems(prevCellIndex + 1, prevCellIndex + 2);
669 
670  if (itemList.size()) {
671  AbstractTreeItem *curItem = itemList[0];
672 
673  if (rowsWithActiveColumnSelected->contains(curItem) ||
674  curItem == m_activeCell->first)
675  rowsWithActiveColumnSelected->removeAll(prevCell);
676  else
677  rowsWithActiveColumnSelected->append(curItem);
678 
679  if (curItem == m_activeCell->first)
680  m_lastShiftArrowSelectedCell->first = NULL;
681  else
682  m_lastShiftArrowSelectedCell->first = curItem;
683  m_lastShiftArrowSelectedCell->second = m_activeCell->second;
684  viewport()->update();
685 
686  // scroll if needed
687  int m_itemsPrevIndex = m_items->indexOf(prevCell);
688  int m_itemsCurIndex = m_items->indexOf(curItem);
689  if (m_itemsCurIndex == -1) {
690  if (m_itemsPrevIndex == m_items->size() - 1) {
691  int visibleItemCount = getModel()->getVisibleRowCount();
692  verticalScrollBar()->setValue(qMin(visibleItemCount,
693  getModel()->indexOfVisibleItem(m_items->at(1))));
694  }
695  else {
696  //int m_itemsLastIndex = m_items->size() - 1;
697  //ASSERT(m_itemsPrevIndex == m_items->at(m_items->size() - 1));
698  //verticalScrollBar()->setValue(qMin(prevCell + 1, ));
699  }
700  }
701  }
702  }
703  }
704 
705  // Handle up arrow
706  else if (key == Qt::Key_Up) {
708  }
709 
710  // Handle down arrow
711  else if (key == Qt::Key_Down) {
713  }
714 
715  // Handle left arrow
716  else if (key == Qt::Key_Left) {
718  }
719 
720  // Handle right arrow
721  else if (key == Qt::Key_Right) {
723  }
724  }
725  }
726 
727  // start editing the active cell
728  else {
729  // event->text() will be empty if a modifier was pressed.
730  if (hasActiveCell() && !event->text().isEmpty()) {
731  if (!m_items->contains(m_activeCell->first))
732  scrollTo(m_activeCell->first);
733 
734  ASSERT(m_items->contains(m_activeCell->first));
735 
736  if (m_items->contains(m_activeCell->first) &&
737  cellIsEditable(m_items->indexOf(m_activeCell->first),
738  m_activeCell->second)) {
739  AbstractTableDelegate const *delegate = m_model->getDelegate();
740  TableColumn *col =
741  m_columns->getVisibleColumns()[m_activeCell->second];
742 
743  delete m_editWidget;
744  m_editWidget = NULL;
745  m_editWidget = delegate->getWidget(col);
746  delegate->readData(m_editWidget, m_activeCell->first, col, event->text());
747  m_editWidget->setParent(this);
748  m_editWidget->setFocus(Qt::OtherFocusReason);
749  }
750 
751  viewport()->update();
752  }
753  }
754  }
755 
756 
761  if (m_editWidget) {
762  TableColumn *col =
763  m_columns->getVisibleColumns()[m_activeCell->second];
764  getModel()->getDelegate()->saveData(
765  m_editWidget, m_activeCell->first, col);
766  delete m_editWidget;
767  m_editWidget = NULL;
768 
769  cellDataChanged(col);
770  setFocus(Qt::ActiveWindowFocusReason);
771  }
772  }
773 
774 
779  int activeIndex = m_items->indexOf(m_activeCell->first);
780  if (activeIndex != -1) {
781  if (activeIndex == 0) {
782  int row = qMax(0, getModel()->indexOfVisibleItem(
783  m_activeCell->first) - 1);
784 
785  verticalScrollBar()->setValue(row);
786  }
787 
788  m_activeCell->first = (*m_items)[qMax(0, activeIndex - 1)];
790  viewport()->update();
791  }
792  }
793 
794 
799  int activeIndex = m_items->indexOf(m_activeCell->first);
800  if (activeIndex != -1) {
801  if (activeIndex == m_items->size() - 1) {
802  int row = qMin(getModel()->getVisibleRowCount() - 1,
803  getModel()->indexOfVisibleItem(m_items->at(0)));
804 
805  verticalScrollBar()->setValue(row + 1);
806  activeIndex = m_items->indexOf(m_activeCell->first);
807  }
808 
809  m_activeCell->first = (*m_items)[qMin(activeIndex + 1, m_items->size() - 1)];
811  viewport()->update();
812  }
813  }
814 
815 
820  m_activeCell->second = qMax(1, m_activeCell->second - 1);
821  int leftMostVisibleCol = getColumnFromScreenX(0);
822  if (leftMostVisibleCol == m_activeCell->second) {
823  horizontalScrollBar()->setValue(horizontalScrollBar()->value() -
824  m_columns->getVisibleColumns()[m_activeCell->second]->getWidth());
825  }
826 
828  viewport()->update();
829  }
830 
831 
836  m_activeCell->second = qMin(m_columns->getVisibleColumns().size() - 1,
837  m_activeCell->second + 1);
838  int rightMostVisibleCol = getColumnFromScreenX(viewport()->width());
839  if (rightMostVisibleCol == m_activeCell->second) {
840  horizontalScrollBar()->setValue(horizontalScrollBar()->value() +
841  m_columns->getVisibleColumns()[m_activeCell->second]->getWidth());
842  }
843 
845  viewport()->update();
846  }
847 
848 
854  void TableViewContent::paintEvent(QPaintEvent *event) {
855  ASSERT(m_model);
856  ASSERT(m_columns);
857  if (m_model && m_columns) {
858  // int startRow = verticalScrollBar()->value();
859  int rowCount = (int) ceil(viewport()->height() / (double) m_rowHeight);
860 
861  QPainter painter(viewport());
862  painter.setRenderHint(QPainter::Antialiasing, false);
863  // painter.setRenderHints(QPainter::NonCosmeticDefaultPen, true);
864 
865  bool editWidgetVisible = false;
866  for (int i = 0; i < rowCount; i++) {
867  // define the top left corner of the row and also how big the row is
868  QPoint relativeTopLeft(0, i * m_rowHeight);
869  QPoint scrollBarPos(horizontalScrollBar()->value(),
870  verticalScrollBar()->value());
871  QPoint absoluteTopLeft(relativeTopLeft + scrollBarPos);
872  QSize rowSize(viewport()->width(), (int) m_rowHeight);
873 
874  // Fill in the background with the background color
875  painter.fillRect(QRect(relativeTopLeft, rowSize), palette().base());
876 
877  if (i < m_items->size()) {
878 
879 
880 
881 
882 
883 
884  // ********************************************************
885  // HACK: FIXME: ask tree m_items if background needs to be
886  // darkened, instead figuring that out here. Also, change
887  // composition mode so that ref measure rows look different
888  // when they are highlighted as well
889  /*
890  if (m_items->at(i)->getPointerType() == AbstractTreeItem::Measure)
891  {
892  ControlMeasure * cm = (ControlMeasure *) m_items->at(i)->getPointer();
893  if (cm->Parent()->GetRefMeasure() == cm)
894  {
895  QPoint selectionTopLeft(-absoluteTopLeft.x(), relativeTopLeft.y());
896  QSize selectionSize(m_columns->getVisibleWidth(), (int) m_rowHeight);
897 
898  QRect selectionRect(selectionTopLeft, selectionSize);
899  QColor color = palette().base().color();
900  painter.fillRect(selectionRect, color.darker(110));
901  }
902  }
903  */
904  //*********************************************************
905 
906 
907 
908 
909 
910 
911 
912 
913 
914 
915 
916 
917  if (m_items->at(i)->isSelected()) {
918  QPoint selectionTopLeft(-absoluteTopLeft.x(), relativeTopLeft.y());
919  QSize selectionSize(m_columns->getVisibleWidth(), (int) m_rowHeight);
920 
921  QRect selectionRect(selectionTopLeft, selectionSize);
922  painter.fillRect(selectionRect, palette().highlight().color());
923  }
924 
925  paintRow(&painter, i, absoluteTopLeft, relativeTopLeft);
926  }
927  }
928 
929  for (int i = 0; i < rowCount; i++) {
930  if (i < m_items->size()) {
931  QPoint relativeTopLeft(0, i * m_rowHeight);
932  if (m_editWidget && m_activeCell->first == m_items->at(i)) {
933  QPair<int, int> xRange(
934  m_columns->getVisibleXRange(m_activeCell->second));
935 
936  m_editWidget->move(
937  QPoint(xRange.first - horizontalScrollBar()->value() - 1,
938  relativeTopLeft.y() + 1));
939  m_editWidget->resize(xRange.second - xRange.first, m_rowHeight + 1);
940  m_editWidget->setVisible(true);
941  editWidgetVisible = true;
942  }
943  else {
944  if (m_activeCell->first == m_items->at(i)) {
945  QPair<int, int> activeXArea =
946  m_columns->getVisibleXRange(m_activeCell->second);
947 
948  QRect activeArea(activeXArea.first, relativeTopLeft.y(),
949  activeXArea.second - activeXArea.first, m_rowHeight);
950 
951  activeArea.moveLeft(
952  activeArea.left() - horizontalScrollBar()->value());
953  activeArea.adjust(-1, -1, -2, -1);
954  QPen pen(Qt::black);
955  pen.setWidth(3);
956  painter.setPen(pen);
957  painter.drawRect(activeArea);
958  }
959  }
960  }
961  }
962 
963  if (m_editWidget && !editWidgetVisible)
964  m_editWidget->setVisible(false);
965  }
966  else {
967  QWidget::paintEvent(event);
968  }
969  }
970 
971 
977  void TableViewContent::resizeEvent(QResizeEvent *event) {
978  QAbstractScrollArea::resizeEvent(event);
980  updateItemList();
981  }
982 
983 
990  void TableViewContent::scrollContentsBy(int dx, int dy) {
991  QAbstractScrollArea::scrollContentsBy(dx, dy);
992  updateItemList();
993  }
994 
995 
1000  m_parentView = NULL;
1001  m_model = NULL;
1002  m_items = NULL;
1003  m_activeCell = NULL;
1004  m_lastShiftArrowSelectedCell = NULL;
1005  m_editWidget = NULL;
1007  m_lastShiftSelection = NULL;
1008  m_columns = NULL;
1010  m_applyToSelectionAct = NULL;
1011  m_applyToAllAct = NULL;
1012  m_deleteSelectedRowsAct = NULL;
1013  m_editControlPointAct = NULL;
1014  }
1015 
1016 
1023  if (col->hasNetworkStructureEffect())
1024  emit rebuildModels(QList< AbstractTreeItem * >());
1025 
1026  emit modelDataChanged();
1027  }
1028 
1029 
1034  m_activeCell->first = NULL;
1035  m_activeCell->second = -1;
1036  }
1037 
1038 
1043  ASSERT(m_lastShiftArrowSelectedCell);
1044  m_lastShiftArrowSelectedCell->first = NULL;
1046  }
1047 
1048 
1055  if (hasActiveCell()) {
1056  TableColumn *col = m_columns->getVisibleColumns()[m_activeCell->second];
1057 
1058  QString colTitle = col->getTitle();
1059  ASSERT(colTitle.size());
1060 
1061  // Grab the active cell's data and copy it to the selected cells that are
1062  // in the same column as the active cell.
1063  QString cellData = m_activeCell->first->getFormattedData(colTitle);
1064 
1065  QList< AbstractTreeItem * > selection = allCells ? m_model->getItems(
1066  0, m_model->getVisibleRowCount()) : *rowsWithActiveColumnSelected;
1067  ASSERT(selection.size());
1068 
1069  bool needsDialog = true;
1070  bool done = false;
1071  for (int i = 0; !done && i < selection.size(); i++) {
1072  AbstractTreeItem *row = selection[i];
1073  bool changeData = true;
1074 
1075  QString warningText =
1076  m_model->getWarningMessage(row, col, cellData);
1077  if (needsDialog && warningText.size()) {
1078  QMessageBox::StandardButton status = QMessageBox::warning(
1079  this, "Change cells?", warningText, QMessageBox::Yes |
1080  QMessageBox::No | QMessageBox::YesToAll | QMessageBox::NoToAll);
1081 
1082  switch (status) {
1083  case QMessageBox::YesToAll:
1084  needsDialog = false;
1085  break;
1086  case QMessageBox::NoToAll:
1087  done = true;
1088  case QMessageBox::No:
1089  changeData = false;
1090  default:
1091  ;
1092  }
1093  }
1094 
1095  if (changeData)
1096  row->setData(colTitle, cellData);
1097  }
1098 
1099  viewport()->update();
1100  cellDataChanged(col);
1101  }
1102  }
1103 
1104 
1109  m_applyToSelectionAct = new QAction(tr("Copy to selected cells"), this);
1110  m_applyToSelectionAct->setStatusTip(tr("Copy the contents of this cell to the"
1111  "selected cells"));
1112  connect(m_applyToSelectionAct, SIGNAL(triggered()),
1113  this, SLOT(copySelection()));
1114 
1115  m_applyToAllAct = new QAction(tr("Copy to all cells"), this);
1116  m_applyToAllAct->setStatusTip(tr("Copy the contents of this cell to all"
1117  "cells in the current column"));
1118  connect(m_applyToAllAct, SIGNAL(triggered()),
1119  this, SLOT(copyAll()));
1120 
1121  m_deleteSelectedRowsAct = new QAction(tr("Delete selected rows"), this);
1122  m_deleteSelectedRowsAct->setStatusTip(
1123  tr("Delete the currently selected rows"));
1124  connect(m_deleteSelectedRowsAct, SIGNAL(triggered()),
1125  this, SLOT(deleteSelectedRows()));
1126 
1127  m_editControlPointAct = new QAction(tr("Edit selected control point"), this);
1128  m_editControlPointAct->setStatusTip(
1129  tr("Edit the selected control point or the parent control point of control measure"));
1130  connect(m_editControlPointAct, SIGNAL(triggered()),
1131  this, SLOT(editControlPoint()));
1132  }
1133 
1134 
1143 
1144  for (int i = 0; i < m_columns->getVisibleColumns().size(); i++) {
1145  QPair<int, int> cellXRange(m_columns->getVisibleXRange(i));
1146  int deltaX = -horizontalScrollBar()->value();
1147 
1148  if (cellXRange.first + deltaX < screenX &&
1149  cellXRange.second + deltaX > screenX) {
1150  return i;
1151  }
1152  }
1153 
1154  return -1;
1155  }
1156 
1157 
1165  int TableViewContent::getRowFromScreenY(int screenY) const {
1166  int calculatedRowNum = screenY / m_rowHeight;
1167 
1168  if (calculatedRowNum >= 0 && calculatedRowNum < m_items->size() &&
1169  screenY >= 0 && screenY <= viewport()->height())
1170  return calculatedRowNum;
1171 
1172  return -1;
1173  }
1174 
1175 
1182  return (m_activeCell->first && m_activeCell->second >= 0);
1183  }
1184 
1185 
1192  return (m_model->getSelectedItems().size());
1193  }
1194 
1195 
1203  bool TableViewContent::mouseInCellSelection(QPoint mousePos) const {
1204  int colNum = getColumnFromScreenX(mousePos.x());
1205  AbstractTreeItem *row = m_items->at(getRowFromScreenY(mousePos.y()));
1206 
1207  return (rowsWithActiveColumnSelected->contains(row) &&
1208  m_activeCell->second == colNum);
1209  }
1210 
1211 
1219  bool TableViewContent::mouseInRowSelection(QPoint mousePos) const {
1220  AbstractTreeItem *row = m_items->at(getRowFromScreenY(mousePos.y()));
1221 
1222  return (m_model->getSelectedItems().contains(row));
1223  }
1224 
1225 
1233  bool TableViewContent::rowIsValid(int rowNum) const {
1234  bool valid = false;
1235 
1236  if (rowNum >= 0 && rowNum < m_items->size())
1237  valid = true;
1238 
1239  return valid;
1240  }
1241 
1242 
1250  bool TableViewContent::columnIsValid(int colNum) const {
1251  bool valid = false;
1252 
1253  if (colNum >= 0 && colNum < m_columns->getVisibleColumns().size())
1254  valid = true;
1255 
1256  return valid;
1257  }
1258 
1259 
1268  bool TableViewContent::cellIsEditable(int rowNum, int colNum) const {
1269  ASSERT(rowNum >= 0 && rowNum < m_items->size());
1270  ASSERT(colNum >= 0 && colNum < m_columns->getVisibleColumns().size());
1271 
1272  bool editable = false;
1273 
1274  QString colName = m_columns->getVisibleColumns()[colNum]->getTitle();
1275  if (m_items->at(rowNum)->isSelectable() &&
1276  m_items->at(rowNum)->isDataEditable(colName) &&
1277  !m_columns->getVisibleColumns()[colNum]->isReadOnly())
1278  editable = true;
1279 
1280  return editable;
1281  }
1282 
1283 
1291  bool TableViewContent::isDataColumn(int colNum) const {
1292  //TODO: Figure out what this does and if we can do it in a less confusing and roundabout way
1293  return m_columns->getVisibleColumns()[colNum]->getTitle().size();
1294  }
1295 
1296 
1305  void TableViewContent::paintRow(QPainter *painter, int rowNum,
1306  QPoint absolutePosition, QPoint relativePosition) {
1307  ASSERT(m_items);
1308  ASSERT(rowNum >= 0 && rowNum < m_items->size());
1309 
1310  QPoint point(-absolutePosition.x(), relativePosition.y());
1311 
1312  AbstractTreeItem *item = (*m_items)[rowNum];
1313 
1314  // should always be true, but prevents segfault in case of bug
1315  if (item) {
1316  QPen originalPen = painter->pen();
1317 
1318  QPoint textPoint(point.x() + ITEM_INDENTATION,
1319  point.y() + ITEM_PADDING / 2);
1320 
1321  // finally draw the text
1322  int textHeight = m_rowHeight - ITEM_PADDING;
1323 
1324  QFontMetrics metrics(font());
1325 
1326  QPen gridPen(Qt::gray);
1327 
1328  ASSERT(m_columns);
1329  TableColumnList visibleCols = m_columns->getVisibleColumns();
1330  for (int i = 0; i < visibleCols.size(); i++) {
1331  // draw text
1332  QPair<int, int> cellXRange(visibleCols.getVisibleXRange(i));
1333  QRect cellRect(cellXRange.first, point.y(),
1334  cellXRange.second - cellXRange.first, m_rowHeight);
1335  cellRect.moveLeft(cellRect.left() - horizontalScrollBar()->value() - 1);
1336 
1337  QString columnTitle = visibleCols[i]->getTitle();
1338  QRect textRect(textPoint, QSize(cellRect.right() - textPoint.x(),
1339  textHeight));
1340  QString text;
1341  bool textCentered = false;
1342  if (!columnTitle.isEmpty()) {
1343  text = item->getFormattedData(columnTitle);
1344 
1345  if (rowsWithActiveColumnSelected->indexOf(item) != -1 &&
1346  m_activeCell->second == i) {
1347  // This cell is selected, so render it as such.
1348  if (m_activeCell->first != item) {
1349  painter->fillRect(cellRect,
1350  QBrush(palette().highlight().color()));
1351  painter->setPen(palette().highlightedText().color());
1352  }
1353  else {
1354  painter->setPen(palette().text().color());
1355  }
1356  }
1357  else {
1358  if (item->isSelected()) {
1359  painter->setPen(palette().highlightedText().color());
1360  }
1361  else {
1362  // If the current column is not editable (i.e. read-only), or it
1363  // is locked (think edit-locked control point or measure), then
1364  // it should be grayed out.
1365  //
1366  // NOTE: The following two lines provide for graying out of edit
1367  // locked data. This is commented out because this functionality
1368  // is not fully working yet.
1369  //if (!cellIsEditable(rowNum, i) ||
1370  // item->isDataLocked(columnTitle))
1371  if (!cellIsEditable(rowNum, i)) {
1372  painter->setPen(palette().color(QPalette::Disabled,
1373  QPalette::Text));
1374  }
1375  else {
1376  painter->setPen(palette().text().color());
1377  }
1378  }
1379  }
1380  }
1381  else {
1382  // Draw the row number.
1383  text = QString::number(rowNum + verticalScrollBar()->value() + 1);
1384  textCentered = true;
1385 
1386  // We need to paint the row number column.
1387  int x = cellRect.center().x();
1388  QLinearGradient gradient(x, cellRect.top(), x, cellRect.bottom());
1389 
1390  bool selected = item->isSelected();
1391  QColor color = selected ? palette().highlight().color() :
1392  palette().button().color();
1393 
1394  int adjustment = 110;
1395  gradient.setColorAt(0, color.lighter(adjustment));
1396  gradient.setColorAt(1, color.darker(adjustment));
1397  painter->fillRect(cellRect, gradient);
1398  if (selected)
1399  painter->setPen(palette().highlightedText().color());
1400  else
1401  painter->setPen(palette().text().color());
1402  }
1403 
1404  int flags = Qt::TextDontClip;
1405  if (textCentered)
1406  flags |= Qt::AlignCenter;
1407 
1408  // TODO this shouldn't be here... an item should be able to tell
1409  // whether or not it should be bolded.
1410  QFont normalFont = painter->font();
1411 
1412  if (item->getPointerType() == AbstractTreeItem::Measure) {
1413  ControlMeasure *cm = (ControlMeasure *) item->getPointer();
1414  if (cm && cm->Parent() && cm->Parent()->GetRefMeasure() == cm) {
1415  QFont boldFont(normalFont);
1416  boldFont.setBold(true);
1417  painter->setFont(boldFont);
1418  }
1419  }
1420 
1421  painter->drawText(textRect, flags,
1422  metrics.elidedText(text, Qt::ElideRight,
1423  textRect.width() - ITEM_INDENTATION));
1424  painter->setFont(normalFont);
1425 
1426  textPoint.setX(cellRect.right() + ITEM_INDENTATION);
1427  painter->setPen(originalPen);
1428 
1429  painter->setPen(gridPen);
1430  painter->drawLine(QPoint(cellRect.right(), point.y()),
1431  QPoint(cellRect.right(), point.y() + m_rowHeight));
1432  painter->setPen(originalPen);
1433  }
1434 
1435  int left = -horizontalScrollBar()->value() - 1;
1436  int right = m_columns->getVisibleWidth();
1437 
1438  gridPen.setWidth(2);
1439  painter->setPen(gridPen);
1440  painter->drawLine(QPoint(left, point.y() + m_rowHeight),
1441  QPoint(right, point.y() + m_rowHeight));
1442  painter->setPen(originalPen);
1443  }
1444  }
1445 
1446 
1452  void TableViewContent::updateActiveCell(QPoint screenPos) {
1453  if (m_editWidget && m_activeCell->first && m_activeCell->second >= 0) {
1454  try {
1455  const TableColumn *col =
1456  m_columns->getVisibleColumns()[m_activeCell->second];
1457  m_model->getDelegate()->saveData(m_editWidget, m_activeCell->first,
1458  col);
1459 
1460  cellDataChanged(col);
1461  }
1462  catch (IException &e) {
1463  QMessageBox::critical(this, "Failed to Set Data", e.what());
1464  }
1465  }
1466 
1467  int rowNum = getRowFromScreenY(screenPos.y());
1468  int oldActiveColumn = m_activeCell->second;
1469 
1470  clearActiveCell();
1471 
1472  if (rowNum >= 0) {
1473  AbstractTreeItem *item = (*m_items)[rowNum];
1474 
1475  TableColumnList visibleCols = m_columns->getVisibleColumns();
1476  for (int i = 0; i < visibleCols.size(); i++) {
1477  QPair<int, int> cellXRange(m_columns->getVisibleXRange(i));
1478  QRect cellRect(cellXRange.first, m_rowHeight * rowNum,
1479  cellXRange.second - cellXRange.first, m_rowHeight);
1480 
1481  cellRect.moveLeft(cellRect.left() - horizontalScrollBar()->value());
1482 
1483  if (cellRect.contains(screenPos) &&
1484  (oldActiveColumn != -1 || !visibleCols[i]->getTitle().isEmpty())) {
1485  m_activeCell->first = item;
1486  m_activeCell->second = i;
1487  }
1488  }
1489  }
1490 
1491  if (oldActiveColumn != m_activeCell->second) {
1494  }
1495 
1497  }
1498 
1499 
1506  // delete current row selection
1507  foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1508  if (rowsWithActiveColumnSelected->indexOf(row) != -1)
1509  rowsWithActiveColumnSelected->removeOne(row);
1510  }
1511 
1512 
1514  *m_lastShiftSelection = m_model->getItems(
1516  }
1517  else {
1518  m_lastShiftSelection->clear();
1519  }
1520 
1521  foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1522  if (rowsWithActiveColumnSelected->indexOf(row) == -1)
1523  rowsWithActiveColumnSelected->append(row);
1524  }
1525  }
1526 
1527 
1536  foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1537  if (row->getPointerType() == AbstractTreeItem::Point)
1538  foreach (AbstractTreeItem * child, row->getChildren())
1539  child->setSelected(false);
1540 
1541  if (row->getPointerType() == AbstractTreeItem::Measure)
1542  row->parent()->setSelected(false);
1543 
1544  row->setSelected(false);
1545  }
1546 
1548  *m_lastShiftSelection = m_model->getItems(
1549  m_lastDirectlySelectedRow, m_items->at(lastRow));
1550  }
1551  else {
1552  m_lastShiftSelection->clear();
1553  }
1554 
1555  QList< AbstractTreeItem * > newlySelectedItems;
1556  foreach (AbstractTreeItem * row, *m_lastShiftSelection) {
1557  row->setSelected(true);
1558 
1559  if (row->getPointerType() == AbstractTreeItem::Measure)
1560  row->parent()->setSelected(true);
1561 
1562  newlySelectedItems.append(row);
1563  }
1564 
1565  return newlySelectedItems;
1566  }
1567 
1568 
1575  copyCellSelection(false);
1576  }
1577 
1578 
1585  copyCellSelection(true);
1586  }
1587 
1588 
1593  // Prompt the user for confirmation before deletion.
1594  QMessageBox::StandardButton status = QMessageBox::warning(
1595  this, "Delete row(s)?", "Delete selected row(s)?",
1596  QMessageBox::Yes | QMessageBox::No);
1597 
1598  if (status == QMessageBox::Yes) {
1599  // TODO should we store off the selected rows for efficiency?
1600  QList<AbstractTreeItem *> selectedRows = m_model->getSelectedItems();
1601 
1602  emit rebuildModels(selectedRows);
1603  emit modelDataChanged();
1604 
1605  m_lastShiftSelection->clear();
1606  }
1607  }
1608 
1609 
1614 
1615  ControlPoint *cp;
1616  QString serialNumber;
1617  AbstractTreeItem *item;
1618 
1619  // A single cell is chosen
1620  if (m_model->getSelectedItems().count() == 0) {
1621  item = m_activeCell->first;
1622  }
1623  // A row is chosen
1624  else {
1626  }
1627 
1628  // Item chosen from the Point table view
1629  if (item->getPointerType() == AbstractTreeItem::Point) {
1630  cp = (ControlPoint *) (item->getPointer());
1631  }
1632  // Item chosen from the Measure table view
1633  else {
1634  cp = (ControlPoint *) (item->parent()->getPointer());
1635  serialNumber = item->getData("Image ID").toString();
1636  }
1637 
1638 // qDebug()<<"activeCell cpid = "<<cp->GetId()<<" sn = "<<serialNumber;
1639 
1640  emit editControlPoint(cp, serialNumber);
1641  }
1642 
1643 
1648  ASSERT(m_items);
1649 
1650  if (m_model) {
1651  int startRow = verticalScrollBar()->value();
1652  int rowCount = (int) ceil(viewport()->height() / (double) m_rowHeight);
1653  m_items->clear();
1654  foreach (AbstractTreeItem * item,
1655  m_model->getItems(startRow, startRow + rowCount)) {
1656  m_items->append(item);
1657  }
1658 
1659  viewport()->update();
1660  }
1661  }
1662 
1663 
1669  void TableViewContent::showContextMenu(QPoint mouseLocation) {
1670  QMenu contextMenu(this);
1671 
1672  // Only add this action if a single row is selected or a cell is selected
1673  // TODO: 2017-05-17 TLS
1674  // Always allow editing of point. Should we check for editLock??
1675  QList<AbstractTreeItem *> selectedRows = m_model->getSelectedItems();
1676 
1677 
1678  // If there is a row selection, show a context menu if the user clicked
1679  // anywhere on any of the selected row(s).
1680 
1681  if (QApplication::applicationName() != "cneteditor") {
1682  if (m_activeControlNet) {
1683  m_editControlPointAct->setEnabled(true);
1684  m_applyToSelectionAct->setEnabled(true);
1685  m_applyToAllAct->setEnabled(true);
1686  }
1687  else {
1688  m_editControlPointAct->setEnabled(false);
1689  m_applyToSelectionAct->setEnabled(false);
1690  m_applyToAllAct->setEnabled(false);
1691  }
1692 
1693  // We want to be able to delete rows in a nonactive control.
1694  m_deleteSelectedRowsAct->setEnabled(true);
1695 
1696  if (hasActiveCell() && selectedRows.count() <= 1) {
1697  contextMenu.addAction(m_editControlPointAct);
1698  }
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  else {
1714  if (hasRowSelection() && mouseInRowSelection(mouseLocation)) {
1715  contextMenu.addAction(m_deleteSelectedRowsAct);
1716  }
1717 
1718  // Only show the context menu for cells if the user right-clicked on the
1719  // active cell.
1720  if (hasActiveCell() && mouseInCellSelection(mouseLocation)) {
1721  if (rowsWithActiveColumnSelected->size() > 1) {
1722  contextMenu.addAction(m_applyToSelectionAct);
1723  }
1724 
1725  contextMenu.addAction(m_applyToAllAct);
1726  }
1727  }
1728  contextMenu.exec(mapToGlobal(mouseLocation));
1729  }
1730 }
virtual ~TableViewContent()
Destructor.
void leaveEvent(QEvent *event)
Overrides QWidget::leaveEvent.
void cellDataChanged(TableColumn const *col)
Rebuilds the models when the data is changed.
void scrollTo(QList< AbstractTreeItem * >)
Scrolls to the selected items.
const char * what() const
Returns a string representation of this exception in its current state.
Definition: IException.cpp:391
void mousePressEvent(QMouseEvent *event)
Overrides QWidget::mousePressEvent.
QPair< int, int > getVisibleXRange(int visibleColumn)
void updateHorizontalScrollBar(bool scrollRight=false)
Updates the horizontal scroll bar.
void resizeEvent(QResizeEvent *event)
Updates the table when it is resized.
void copyAll()
Copies all of the cells.
void copyCellSelection(bool)
Copies the selected cells.
void editControlPoint()
Retrieves the control point from the selected cells for editing.
void finishEditing()
Saves the data from the cell the user was modifying.
void mouseMoveEvent(QMouseEvent *event)
Overrides QWidget::mouseMoveEvent.
void refresh()
Refreshes the table and viewport.
QAction * m_applyToAllAct
This action applies (copies) the contents of the active cell to all of the cells in the active cell&#39;s...
int getColumnFromScreenX(int screenX) const
Calculates the visible range of a column and returns the index of the column.
void deleteSelectedRows()
Deletes the selected rows.
void moveActiveCellDown()
Changes the viewport when the active cell is moved.
QAction * m_applyToSelectionAct
This action applies (copies) the contents of the active cell to the current selection.
void paintEvent(QPaintEvent *event)
Paints the table when there is a paint event.
void mouseDoubleClickEvent(QMouseEvent *event)
Overrides QWidget::mouseDoubleClickEvent.
bool isDataColumn(int) const
Checks if the column has a non empty title.
bool eventFilter(QObject *target, QEvent *event)
Overrides QObject::eventFilter.
void updateColumnGroupSelection(AbstractTreeItem *)
Updates which column is selected.
Translates the tree model into a table model.
void setActiveControlNet(bool activeNet)
Sets if there is an active control net.
bool mouseInCellSelection(QPoint) const
Checks if the mouse is in the selected cells.
A single control point.
Definition: ControlPoint.h:369
void mouseReleaseEvent(QMouseEvent *event)
Overrides QWidget::mouseReleaseEvent.
void copySelection()
Copies selected cells.
bool hasRowSelection() const
Checks if there is a row selected.
void updateActiveCell(QPoint)
Updates which cell is active.
QList< AbstractTreeItem *> updateRowGroupSelection(int lastRow)
Updates which row is selected.
const ControlMeasure * GetRefMeasure() const
Get the reference control measure.
bool cellIsEditable(int, int) const
Checks if the cell is editable.
void moveActiveCellLeft()
Changes the viewport when the active cell is moved.
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.
void clearActiveCell()
Clears the active cell.
AbstractTableModel * getModel()
Returns the model.
Base class for delegates which create, read, and save data in the tables.
void paintRow(QPainter *, int, QPoint, QPoint)
Repaints the row.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool columnIsValid(int colNum) const
Checks if the column number is valid.
a control measurement
QSize sizeHint() const
Returns the minimum size hint.
void moveActiveCellUp()
Shifts the active cell up.
void moveActiveCellRight()
Changes the viewport when the active cell is moved.
void keyPressEvent(QKeyEvent *event)
Overrides QWidget::keyPressEvent.
int getRowFromScreenY(int screenY) const
Calculates the visible range of a row and returns the index of the column.
Base class for an item in the tree.
void nullify()
Clears all member variables.
void createActions()
Builds the menus.
QSize minimumSizeHint() const
Returns the minimum size hint.
bool hasActiveCell() const
Checks if there is an active cell.
QAction * m_editControlPointAct
This action edits selected control point or if measure selected, edit parent control pt...
QList< AbstractTreeItem *> * rowsWithActiveColumnSelected
Stores a list of the rows that have their active column cells selected.
void showContextMenu(QPoint)
Populates the context menus based on where the user clicked.
void clearColumnSelection()
Clears the selected column.
AbstractTreeItem * m_lastDirectlySelectedRow
This is the last row that was selected by either a control-click or normal click. ...
bool rowIsValid(int rowNum) const
Checks if the row number is valid.
TableViewContent(AbstractTableModel *someModel)
Constructor.
void updateItemList()
Updates the item list.
QAction * m_deleteSelectedRowsAct
This action deletes the selected rows.