3 #include "CnetEditorWidget.h"
6 #include <QApplication>
12 #include <QHBoxLayout>
13 #include <QHeaderView>
14 #include <QItemSelection>
16 #include <QMessageBox>
17 #include <QModelIndex>
18 #include <QScrollArea>
23 #include <QStringList>
27 #include <QVBoxLayout>
35 #include "AbstractMeasureItem.h"
36 #include "AbstractPointItem.h"
37 #include "AbstractTreeItem.h"
38 #include "CnetDisplayProperties.h"
39 #include "CnetEditorSortConfigDialog.h"
41 #include "MeasureTableModel.h"
42 #include "PointTableModel.h"
43 #include "TableView.h"
44 #include "TableViewHeader.h"
46 #include "ImageImageTreeModel.h"
47 #include "FilterWidget.h"
48 #include "PointMeasureTreeModel.h"
49 #include "ImagePointTreeModel.h"
53 using namespace CnetViz;
59 const QString CnetEditorWidget::VERSION =
"0.1";
66 CnetEditorWidget::CnetEditorWidget(ControlNet *cNet,
67 QString pathForSettings) {
70 m_workingVersion =
new QString;
74 m_updatingSelection =
false;
77 connect(CnetDisplayProperties::getInstance(), SIGNAL(compositionFinished()),
78 this, SLOT(rebuildModels()));
80 m_settingsPath =
new QString(pathForSettings);
82 QBoxLayout *mainLayout = createMainLayout();
83 setLayout(mainLayout);
91 installEventFilter(
this);
95 CnetEditorWidget::~CnetEditorWidget() {
98 delete m_workingVersion;
99 m_workingVersion = NULL;
101 delete m_settingsPath;
102 m_settingsPath = NULL;
104 delete m_pointTreeView;
105 m_pointTreeView = NULL;
107 delete m_imageTreeView;
108 m_imageTreeView = NULL;
110 delete m_connectionTreeView;
111 m_connectionTreeView = NULL;
113 delete m_pointTableView;
114 m_pointTableView = NULL;
116 delete m_measureTableView;
117 m_measureTableView = NULL;
119 delete m_pointFilterWidget;
120 m_pointFilterWidget = NULL;
122 delete m_serialFilterWidget;
123 m_serialFilterWidget = NULL;
125 delete m_connectionFilterWidget;
126 m_connectionFilterWidget = NULL;
128 delete m_menuActions;
129 m_menuActions = NULL;
131 delete m_toolBarActions;
132 m_toolBarActions = NULL;
134 m_pointTableBox = NULL;
135 m_measureTableBox = NULL;
136 m_mainSplitter = NULL;
146 delete m_connectionModel;
147 m_connectionModel = NULL;
151 void CnetEditorWidget::nullify() {
152 m_pointTreeView = NULL;
153 m_imageTreeView = NULL;
154 m_connectionTreeView = NULL;
158 m_connectionModel = NULL;
160 m_pointTableModel = NULL;
161 m_measureTableModel = NULL;
163 m_pointTableBox = NULL;
164 m_measureTableBox = NULL;
166 m_pointTableView = NULL;
167 m_measureTableView = NULL;
169 m_mainSplitter = NULL;
171 m_menuActions = NULL;
172 m_toolBarActions = NULL;
176 m_pointFilterWidget = NULL;
177 m_serialFilterWidget = NULL;
178 m_connectionFilterWidget = NULL;
181 m_settingsPath = NULL;
182 m_workingVersion = NULL;
187 m_pointModel->stopWorking();
188 m_imageModel->stopWorking();
189 m_connectionModel->stopWorking();
191 bool ignoreAll =
false;
192 foreach (AbstractTreeItem * item, itemsToDelete) {
194 item->deleteSource();
196 catch (IException &e) {
197 QString message = e.what();
200 if (item == itemsToDelete.last()) {
201 QMessageBox::warning(
202 this,
"Failed to delete row", message, QMessageBox::Ok);
205 message +=
"\n\nOkay to continue?";
207 QMessageBox::StandardButton status = QMessageBox::warning(
208 this,
"Failed to delete row", message, QMessageBox::Yes |
209 QMessageBox::YesToAll | QMessageBox::No);
211 if (status == QMessageBox::YesToAll)
213 else if (status == QMessageBox::No)
220 m_pointModel->rebuildItems();
221 m_imageModel->rebuildItems();
222 m_connectionModel->rebuildItems();
226 QBoxLayout *CnetEditorWidget::createMainLayout() {
227 createPointTreeView();
228 createSerialTreeView();
229 createConnectionTreeView();
231 connect(m_pointTreeView, SIGNAL(activated()),
232 m_imageTreeView, SLOT(deactivate()));
233 connect(m_pointTreeView, SIGNAL(activated()),
234 m_connectionTreeView, SLOT(deactivate()));
236 connect(m_imageTreeView, SIGNAL(activated()),
237 m_pointTreeView, SLOT(deactivate()));
238 connect(m_imageTreeView, SIGNAL(activated()),
239 m_connectionTreeView, SLOT(deactivate()));
241 connect(m_connectionTreeView, SIGNAL(activated()),
242 m_pointTreeView, SLOT(deactivate()));
243 connect(m_connectionTreeView, SIGNAL(activated()),
244 m_imageTreeView, SLOT(deactivate()));
248 createPointTableView();
249 m_pointTableBox =
new QGroupBox(tr(
"Control Point Table"));
250 QHBoxLayout *pointTableLayout =
new QHBoxLayout;
251 pointTableLayout->addWidget(m_pointTableView);
252 m_pointTableBox->setLayout(pointTableLayout);
254 createMeasureTableView();
255 m_measureTableBox =
new QGroupBox(tr(
"Control Measure Table"));
256 QHBoxLayout *measureTableLayout =
new QHBoxLayout;
257 measureTableLayout->addWidget(m_measureTableView);
258 m_measureTableBox->setLayout(measureTableLayout);
260 m_mainSplitter =
new QSplitter(Qt::Vertical);
261 m_mainSplitter->addWidget(m_pointTableBox);
262 m_mainSplitter->addWidget(m_measureTableBox);
264 QBoxLayout *mainLayout =
new QHBoxLayout;
265 mainLayout->addWidget(m_mainSplitter);
271 void CnetEditorWidget::createActions() {
272 ASSERT(m_menuActions);
274 QAction *freezeTablesAct =
new QAction(QIcon(FileName(
"$base/icons/ice.png").expanded()),
275 tr(
"&Freeze Tables"),
this);
276 freezeTablesAct->setCheckable(
true);
277 freezeTablesAct->setToolTip(tr(
"Freeze tables (filters will not take "
278 "effect until unfrozen)"));
279 freezeTablesAct->setStatusTip(tr(
"Freeze tables (filters will not take "
280 "effect until unfrozen)"));
281 freezeTablesAct->setWhatsThis(tr(
"<html>When frozen, the contents of the "
282 "tables will be locked. Current filters will not be applied to the "
283 "tables until they are unfrozen.</html>"));
284 connect(freezeTablesAct, SIGNAL(toggled(
bool)),
285 this, SLOT(setTablesFrozen(
bool)));
287 freezeTablesLocation.append(tr(
"&Tables"));
288 m_menuActions->insert(freezeTablesAct, freezeTablesLocation);
290 QAction *configureSortAct =
new QAction(QIcon(FileName(
"$base/icons/sort.png").expanded()),
291 tr(
"&Sorting Options..."),
this);
292 QString configureSortToolTipText = tr(
"Configure table sorting options");
293 configureSortAct->setToolTip(configureSortToolTipText);
294 configureSortAct->setStatusTip(configureSortToolTipText);
295 configureSortAct->setWhatsThis(tr(
"<html>Click here to configure options "
296 "related to the sorting of table columns.</html>"));
297 connect(configureSortAct, SIGNAL(triggered()),
298 this, SLOT(configSorting()));
300 configureSortLocation.append(tr(
"&Tables"));
301 m_menuActions->insert(configureSortAct, configureSortLocation);
303 QAction *whatsThisAct = QWhatsThis::createAction(
this);
305 whatsThisLocation.append(tr(
"&Help"));
306 m_menuActions->insert(whatsThisAct, whatsThisLocation);
309 tbActionList.append(freezeTablesAct);
310 tbActionList.append(configureSortAct);
311 m_toolBarActions->insert(
"settingsToolBar", tbActionList);
315 void CnetEditorWidget::createPointTreeView() {
316 m_pointTreeView =
new TreeView();
317 m_pointTreeView->setTitle(
"Point View");
318 m_pointModel =
new PointMeasureTreeModel(m_controlNet, m_pointTreeView, qApp);
319 m_pointTreeView->setModel(m_pointModel);
323 void CnetEditorWidget::createSerialTreeView() {
324 m_imageTreeView =
new TreeView();
325 m_imageTreeView->setTitle(
"Cube View");
326 m_imageModel =
new ImagePointTreeModel(m_controlNet, m_imageTreeView, qApp);
327 m_imageTreeView->setModel(m_imageModel);
331 void CnetEditorWidget::createConnectionTreeView() {
332 m_connectionTreeView =
new TreeView();
333 m_connectionTreeView->setTitle(
"Cube Connection View");
334 m_connectionModel =
new ImageImageTreeModel(m_controlNet, m_connectionTreeView, qApp);
335 m_connectionTreeView->setModel(m_connectionModel);
339 void CnetEditorWidget::createFilterArea() {
340 ASSERT(m_pointModel);
341 ASSERT(m_imageModel);
342 ASSERT(m_connectionModel);
344 FilterWidget *pointFilter =
new FilterWidget(
"Points and Measures");
346 m_pointModel->setFilter(pointFilter);
349 QHBoxLayout *pointFilterLayout =
new QHBoxLayout;
350 pointFilterLayout->addWidget(pointFilter);
352 pointArea->setLayout(pointFilterLayout);
353 QScrollArea *pointFilterScrollArea =
new QScrollArea;
354 pointFilterScrollArea->setWidget(pointArea);
355 pointFilterScrollArea->setWidgetResizable(
true);
356 m_pointFilterWidget = pointFilterScrollArea;
358 FilterWidget *serialFilter =
new FilterWidget(
"Images and Points");
360 m_imageModel->setFilter(serialFilter);
363 QHBoxLayout *serialFilterLayout =
new QHBoxLayout;
364 serialFilterLayout->addWidget(serialFilter);
366 serialArea->setLayout(serialFilterLayout);
367 QScrollArea *serialFilterScrollArea =
new QScrollArea;
368 serialFilterScrollArea->setWidget(serialArea);
369 serialFilterScrollArea->setWidgetResizable(
true);
370 m_serialFilterWidget = serialFilterScrollArea;
372 FilterWidget *connectionFilter =
new FilterWidget(
"Connections");
373 if (m_connectionModel) {
374 m_connectionModel->setFilter(connectionFilter);
377 QHBoxLayout *connectionFilterLayout =
new QHBoxLayout;
378 connectionFilterLayout->addWidget(connectionFilter);
380 connectionArea->setLayout(connectionFilterLayout);
381 QScrollArea *connectionFilterScrollArea =
new QScrollArea;
382 connectionFilterScrollArea->setWidget(connectionArea);
383 connectionFilterScrollArea->setWidgetResizable(
true);
384 m_connectionFilterWidget = connectionFilterScrollArea;
388 void CnetEditorWidget::createPointTableView() {
389 m_pointTableModel =
new PointTableModel(m_pointModel);
390 m_pointTableView =
new TableView(m_pointTableModel, *m_settingsPath,
392 m_pointTableView->setWhatsThis(
"<html>Each row in the table is a control "
393 "point. Each column in the table is an attribute of a control "
394 "point.<br/><br/>Cells that are gray are not editable.</html>");
395 connect(m_pointTableView, SIGNAL(modelDataChanged()),
396 this, SIGNAL(cnetModified()));
398 connect(m_pointTreeView, SIGNAL(selectionChanged()),
399 m_pointTableView, SLOT(handleModelSelectionChanged()));
400 connect(m_pointTableView, SIGNAL(selectionChanged()),
401 m_pointTreeView, SLOT(handleModelSelectionChanged()));
403 connect(m_pointTableView,
408 connect(m_pointTableView, SIGNAL(filterCountsChanged(
int,
int)),
409 this, SLOT(handlePointTableFilterCountsChanged(
int,
int)));
411 for (
int i = 0; i < AbstractPointItem::COLS; i++) {
413 AbstractPointItem::getColumnName((AbstractPointItem::Column) i),
this);
414 act->setCheckable(
true);
415 connect(act, SIGNAL(toggled(
bool)),
this, SLOT(pointColToggled()));
416 m_pointTableView->getHorizontalHeader()->addAction(act);
419 m_pointTableView->getHorizontalHeader()->setContextMenuPolicy(
420 Qt::ActionsContextMenu);
424 void CnetEditorWidget::createMeasureTableView() {
425 m_measureTableModel =
new MeasureTableModel(m_pointModel);
426 m_measureTableView =
new TableView(m_measureTableModel, *m_settingsPath,
427 "m_measureTableView");
428 m_measureTableView->setWhatsThis(
"<html>Each row in the table is a control "
429 "measure. Each column in the table is an attribute of a control "
430 "measure.<br/><br/>Rows with bold text are reference measures. "
431 "Cells that are gray are not editable.</html>");
432 ASSERT(m_pointTableView);
433 connect(m_pointTableView,
438 connect(m_measureTableView,
444 connect(m_measureTableView, SIGNAL(modelDataChanged()),
445 this, SIGNAL(cnetModified()));
446 connect(m_pointTreeView, SIGNAL(selectionChanged()),
447 m_measureTableView, SLOT(handleModelSelectionChanged()));
448 connect(m_measureTableView, SIGNAL(selectionChanged()),
449 m_pointTreeView, SLOT(handleModelSelectionChanged()));
450 connect(m_measureTableView,
455 connect(m_measureTableView, SIGNAL(filterCountsChanged(
int,
int)),
456 this, SLOT(handleMeasureTableFilterCountsChanged(
int,
int)));
458 for (
int i = 0; i < AbstractMeasureItem::COLS; i++) {
460 (AbstractMeasureItem::Column) i),
this);
461 act->setCheckable(
true);
462 connect(act, SIGNAL(toggled(
bool)),
this, SLOT(measureColToggled()));
463 m_measureTableView->getHorizontalHeader()->addAction(act);
466 m_measureTableView->getHorizontalHeader()->setContextMenuPolicy(
467 Qt::ActionsContextMenu);
471 void CnetEditorWidget::rebuildModels() {
476 void CnetEditorWidget::pointColToggled() {
478 m_pointTableView->getHorizontalHeader()->actions();
480 for (
int i = 0; i < actions.size(); i++) {
481 m_pointTableView->setColumnVisible(actions[i]->text(),
482 actions[i]->isChecked());
487 void CnetEditorWidget::measureColToggled() {
489 m_measureTableView->getHorizontalHeader()->actions();
490 for (
int i = 0; i < actions.size(); i++)
491 m_measureTableView->setColumnVisible(actions[i]->text(),
492 actions[i]->isChecked());
495 void CnetEditorWidget::handlePointTableFilterCountsChanged(
496 int visibleRows,
int totalRows) {
497 handleTableFilterCountsChanged(visibleRows, totalRows, m_pointTableBox,
498 "Control Point Table");
502 void CnetEditorWidget::handleMeasureTableFilterCountsChanged(
503 int visibleRows,
int totalRows) {
504 handleTableFilterCountsChanged(visibleRows, totalRows, m_measureTableBox,
505 "Control Measure Table");
509 void CnetEditorWidget::handleTableFilterCountsChanged(
510 int visibleRows,
int totalRows, QGroupBox *box, QString initialText) {
512 QString newTitle = initialText +
" (";
513 if (visibleRows > -1)
514 newTitle += QString::number(visibleRows);
518 newTitle +=
" / " + QString::number(totalRows) +
")";
520 box->setTitle(newTitle);
525 void CnetEditorWidget::upgradeVersion() {
526 if (*m_workingVersion ==
"") {
527 *m_workingVersion =
"0.1";
530 if (*m_workingVersion != VERSION)
535 void CnetEditorWidget::readSettings() {
536 ASSERT(m_workingVersion);
537 ASSERT(m_settingsPath);
538 ASSERT(m_measureTableView);
540 QSettings settings(*m_settingsPath, QSettings::NativeFormat);
541 *m_workingVersion = settings.value(
"version",
"").toString();
543 m_mainSplitter->restoreState(settings.value(
"mainSplitter").toByteArray());
548 m_measureTableView->getHorizontalHeader()->actions();
549 for (
int i = 0; i < actions.size(); i++) {
550 key = m_measureTableView->objectName() +
" " +
551 AbstractMeasureItem::getColumnName((AbstractMeasureItem::Column) i);
552 key.replace(
" ",
"_");
553 actions[i]->setChecked(settings.value(key,
true).toBool());
556 actions = m_pointTableView->getHorizontalHeader()->actions();
557 for (
int i = 0; i < actions.size(); i++) {
558 key = m_pointTableView->objectName() +
" " +
559 AbstractPointItem::getColumnName((AbstractPointItem::Column) i);
560 key.replace(
" ",
"_");
561 actions[i]->setChecked(settings.value(key,
true).toBool());
565 setMeasureTableSortingEnabled(
566 settings.value(
"measureTableSortingEnabled",
true).toBool());
567 setMeasureTableSortLimit(
568 settings.value(
"measureTableSortLimit", 500000).toInt());
569 setPointTableSortingEnabled(
570 settings.value(
"pointTableSortingEnabled",
true).toBool());
571 setPointTableSortLimit(
572 settings.value(
"pointTableSortLimit", 100000).toInt());
576 void CnetEditorWidget::writeSettings() {
577 ASSERT(m_mainSplitter);
578 ASSERT(m_settingsPath);
579 ASSERT(m_measureTableView);
581 QSettings settings(*m_settingsPath, QSettings::NativeFormat);
582 settings.setValue(
"version", VERSION);
583 settings.setValue(
"mainSplitter", m_mainSplitter->saveState());
588 m_measureTableView->getHorizontalHeader()->actions();
589 for (
int i = 0; i < actions.size(); i++) {
590 key = m_measureTableView->objectName() +
" " +
591 AbstractMeasureItem::getColumnName((AbstractMeasureItem::Column) i);
592 key.replace(
" ",
"_");
593 settings.setValue(key, actions[i]->isChecked());
596 actions = m_pointTableView->getHorizontalHeader()->actions();
597 for (
int i = 0; i < actions.size(); i++) {
598 key = m_pointTableView->objectName() +
" " +
599 AbstractPointItem::getColumnName((AbstractPointItem::Column) i);
600 key.replace(
" ",
"_");
601 settings.setValue(key, actions[i]->isChecked());
605 settings.setValue(
"measureTableSortingEnabled",
606 measureTableSortingEnabled());
607 settings.setValue(
"measureTableSortLimit",
608 measureTableSortLimit());
609 settings.setValue(
"pointTableSortingEnabled",
610 pointTableSortingEnabled());
611 settings.setValue(
"pointTableSortLimit",
612 pointTableSortLimit());
615 QWidget *CnetEditorWidget::pointTreeView() {
616 return m_pointTreeView;
620 QWidget *CnetEditorWidget::serialTreeView() {
621 return m_imageTreeView;
625 QWidget *CnetEditorWidget::connectionTreeView() {
626 return m_connectionTreeView;
630 QWidget *CnetEditorWidget::pointFilterWidget() {
631 return m_pointFilterWidget;
635 QWidget *CnetEditorWidget::serialFilterWidget() {
636 return m_serialFilterWidget;
640 QWidget *CnetEditorWidget::connectionFilterWidget() {
641 return m_connectionFilterWidget;
645 CnetViz::AbstractTableModel *CnetEditorWidget::measureTableModel() {
646 return m_measureTableModel;
650 CnetViz::AbstractTableModel *CnetEditorWidget::pointTableModel() {
651 return m_pointTableModel;
656 ASSERT(m_menuActions);
657 return *m_menuActions;
662 ASSERT(m_toolBarActions);
663 return *m_toolBarActions;
667 ControlNet *CnetEditorWidget::filteredNetwork()
const {
668 ControlNet *filteredCnet =
new ControlNet(*m_controlNet);
671 AbstractTreeModel::MeasureItems | AbstractTreeModel::PointItems,
true);
675 for (
int pointIndex = filteredCnet->GetNumPoints() - 1;
678 if (networkItems.isEmpty()) {
679 ControlPoint *cp = filteredCnet->GetPoint(pointIndex);
680 cp->SetEditLock(
false);
682 for (
int measureIndex = 0;
683 measureIndex < cp->GetNumMeasures();
685 cp->GetMeasure(measureIndex)->SetEditLock(
false);
688 filteredCnet->DeletePoint(cp);
690 else if (networkItems.last()->getPointerType() ==
691 AbstractTreeItem::Point) {
692 ControlPoint *networkItemsCp =
693 (ControlPoint *)networkItems.last()->getPointer();
694 ControlPoint *cp = filteredCnet->GetPoint(pointIndex);
695 if (cp->GetId() != networkItemsCp->GetId()) {
696 cp->SetEditLock(
false);
698 for (
int measureIndex = 0;
699 measureIndex < cp->GetNumMeasures();
701 cp->GetMeasure(measureIndex)->SetEditLock(
false);
704 filteredCnet->DeletePoint(cp);
707 networkItems.removeLast();
710 else if (networkItems.last()->getPointerType() ==
711 AbstractTreeItem::Measure) {
712 ControlPoint *cp = filteredCnet->GetPoint(pointIndex);
713 ControlMeasure *networkItemsCm =
714 (ControlMeasure *)networkItems.last()->getPointer();
716 if (cp->GetId() != networkItemsCm->Parent()->GetId()) {
717 cp->SetEditLock(
false);
719 for (
int measureIndex = 0;
720 measureIndex < cp->GetNumMeasures();
722 cp->GetMeasure(measureIndex)->SetEditLock(
false);
725 filteredCnet->DeletePoint(cp);
729 for (
int measureIndex = cp->GetNumMeasures() - 1;
730 networkItemsCm && measureIndex >= 0;
732 ControlMeasure *cm = cp->GetMeasure(measureIndex);
733 if (cm->GetCubeSerialNumber() !=
734 networkItemsCm->GetCubeSerialNumber()) {
735 cm->SetEditLock(
false);
739 networkItems.removeLast();
740 networkItemsCm = NULL;
742 if (networkItems.last()->getPointerType() ==
743 AbstractTreeItem::Measure) {
745 (ControlMeasure *)networkItems.last()->getPointer();
762 bool CnetEditorWidget::measureTableSortingEnabled()
const {
763 return m_measureTableModel->sortingIsEnabled();
767 int CnetEditorWidget::measureTableSortLimit()
const {
768 return m_measureTableModel->sortLimit();
772 bool CnetEditorWidget::pointTableSortingEnabled()
const {
773 return m_pointTableModel->sortingIsEnabled();
777 int CnetEditorWidget::pointTableSortLimit()
const {
778 return m_pointTableModel->sortLimit();
782 void CnetEditorWidget::setMeasureTableSortingEnabled(
bool enabled) {
783 m_measureTableModel->setSortingEnabled(enabled);
787 void CnetEditorWidget::setMeasureTableSortLimit(
int limit) {
788 m_measureTableModel->setSortLimit(limit);
792 void CnetEditorWidget::setPointTableSortingEnabled(
bool enabled) {
793 m_pointTableModel->setSortingEnabled(enabled);
797 void CnetEditorWidget::setPointTableSortLimit(
int limit) {
798 m_pointTableModel->setSortLimit(limit);
802 void CnetEditorWidget::configSorting() {
803 CnetEditorSortConfigDialog *dialog =
new CnetEditorSortConfigDialog(
this);
804 dialog->setAttribute(Qt::WA_DeleteOnClose);
809 void CnetEditorWidget::setTablesFrozen(
bool freezeTables) {
811 m_connectionModel->setFrozen(
true);
812 m_imageModel->setFrozen(
true);
813 m_pointModel->setFrozen(
true);
816 m_pointModel->setFrozen(
false);
817 m_imageModel->setFrozen(
false);
818 m_connectionModel->setFrozen(
false);