13 #include <QMessageBox>
17 #include <QTableWidget>
18 #include <QTableWidgetItem>
27 #include "ControlPointEdit.h"
30 #include "MainWindow.h"
31 #include "MatchToolDeletePointDialog.h"
32 #include "MatchToolNewPointDialog.h"
36 #include "PvlEditDialog.h"
41 #include "ViewportMainWindow.h"
62 m_newPointDialog = NULL;
76 m_leftReference = NULL;
77 m_leftMeasureType = NULL;
78 m_leftGoodness = NULL;
79 m_rightReference = NULL;
80 m_rightMeasureType = NULL;
81 m_rightGoodness = NULL;
82 m_lockLeftMeasure = NULL;
83 m_ignoreLeftMeasure = NULL;
84 m_lockRightMeasure = NULL;
85 m_ignoreRightMeasure = NULL;
89 m_rightMeasure = NULL;
90 m_templateModified =
false;
91 m_measureWindow = NULL;
92 m_measureTable = NULL;
102 connect(
this, SIGNAL(toolActivated()),
this, SLOT(activateTool()));
108 if (parentMainWindow) {
109 connect(parent, SIGNAL(closeWindow()),
this, SLOT(
exiting()));
117 MatchTool::~MatchTool () {
123 delete m_pointEditor;
124 m_pointEditor = NULL;
125 delete m_newPointDialog;
126 m_newPointDialog = NULL;
129 delete m_leftMeasure;
130 m_leftMeasure = NULL;
131 delete m_rightMeasure;
132 m_rightMeasure = NULL;
168 m_matchTool->setWindowTitle(
"Match Tool");
169 m_matchTool->setObjectName(
"MatchTool");
170 connect(m_matchTool, SIGNAL(destroyed(
QObject *)),
this, SLOT(clearEditPoint()));
179 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
180 m_pointEditor, SIGNAL(newControlNetwork(
ControlNet *)));
184 connect(
this, SIGNAL(measureChanged()),
187 m_savePoint =
new QPushButton (
"Save Point");
188 m_savePoint->setShortcut(Qt::Key_P);
189 m_savePoint->setToolTip(
"Save the edit control point to the control network. "
190 "<strong>Shortcut: P</strong>");
191 m_savePoint->setWhatsThis(
"Save the edit control point to the control "
192 "network which is loaded into memory in its entirety. "
193 "When a control point is selected for editing, "
194 "a copy of the point is made so that the original control "
195 "point remains in the network.");
196 m_saveDefaultPalette = m_savePoint->palette();
197 connect (m_savePoint,SIGNAL(clicked()),
this,SLOT(
savePoint()));
199 QHBoxLayout * addMeasureLayout =
new QHBoxLayout;
200 addMeasureLayout->addStretch();
201 addMeasureLayout->addWidget(m_savePoint);
204 m_cnetFileNameLabel =
new QLabel(
"Control Network: " + m_cnetFileName);
205 m_cnetFileNameLabel->setToolTip(
"Name of opened control network file.");
206 m_cnetFileNameLabel->setWhatsThis(
"Name of opened control network file.");
208 m_templateFileNameLabel =
new QLabel(
"Template File: " +
209 m_pointEditor->templateFileName());
210 m_templateFileNameLabel->setToolTip(
"Sub-pixel registration template File.");
214 m_templateFileNameLabel->setWhatsThis(
"FileName of the sub-pixel "
215 "registration template. Refer to $ISISROOT/doc/documents/"
216 "PatternMatch/PatternMatch.html for a description of the "
217 "contents of this file.");
219 QVBoxLayout * centralLayout =
new QVBoxLayout;
221 centralLayout->addWidget(m_cnetFileNameLabel);
222 centralLayout->addWidget(m_templateFileNameLabel);
224 centralLayout->addStretch();
225 centralLayout->addWidget(m_pointEditor);
226 centralLayout->addLayout(addMeasureLayout);
228 centralWidget->setLayout(centralLayout);
230 QScrollArea *scrollArea =
new QScrollArea();
231 scrollArea->setObjectName(
"MatchToolScroll");
232 scrollArea->setWidget(centralWidget);
233 scrollArea->setWidgetResizable(
true);
234 centralWidget->adjustSize();
235 m_matchTool->setCentralWidget(scrollArea);
239 connect(
this, SIGNAL(editPointChanged()),
249 QHBoxLayout * measureLayout =
new QHBoxLayout;
253 QVBoxLayout * groupBoxesLayout =
new QVBoxLayout;
255 groupBoxesLayout->addStretch();
256 groupBoxesLayout->addLayout(measureLayout);
259 groupBoxesWidget->setLayout(groupBoxesLayout);
263 QSplitter * topSplitter =
new QSplitter;
264 topSplitter->addWidget(groupBoxesWidget);
265 topSplitter->addWidget(m_templateEditorWidget);
266 topSplitter->setStretchFactor(0, 4);
267 topSplitter->setStretchFactor(1, 3);
269 m_templateEditorWidget->hide();
279 m_ptIdValue =
new QLabel;
280 m_numMeasures =
new QLabel;
281 QVBoxLayout * leftLayout =
new QVBoxLayout;
282 leftLayout->addWidget(m_ptIdValue);
283 leftLayout->addWidget(m_numMeasures);
286 m_lockPoint =
new QCheckBox(
"Edit Lock Point");
287 connect(m_lockPoint, SIGNAL(clicked(
bool)),
this, SLOT(
setLockPoint(
bool)));
288 m_ignorePoint =
new QCheckBox(
"Ignore Point");
289 connect(m_ignorePoint, SIGNAL(clicked(
bool)),
291 connect(
this, SIGNAL(ignorePointChanged()), m_ignorePoint, SLOT(toggle()));
293 QVBoxLayout * rightLayout =
new QVBoxLayout;
294 rightLayout->addWidget(m_lockPoint);
295 rightLayout->addWidget(m_ignorePoint);
297 QHBoxLayout * mainLayout =
new QHBoxLayout;
298 mainLayout->addLayout(leftLayout);
299 mainLayout->addStretch();
300 mainLayout->addLayout(rightLayout);
303 QGroupBox * groupBox =
new QGroupBox(
"Control Point");
304 groupBox->setLayout(mainLayout);
314 m_leftCombo->view()->installEventFilter(
this);
315 m_leftCombo->setToolTip(
"Choose left control measure");
316 m_leftCombo->setWhatsThis(
"Choose left control measure identified by "
318 connect(m_leftCombo, SIGNAL(activated(
int)),
320 m_lockLeftMeasure =
new QCheckBox(
"Edit Lock Measure");
321 connect(m_lockLeftMeasure, SIGNAL(clicked(
bool)),
323 m_ignoreLeftMeasure =
new QCheckBox(
"Ignore Measure");
324 connect(m_ignoreLeftMeasure, SIGNAL(clicked(
bool)),
326 connect(
this, SIGNAL(ignoreLeftChanged()),
327 m_ignoreLeftMeasure, SLOT(toggle()));
328 m_leftReference =
new QLabel();
329 m_leftMeasureType =
new QLabel();
330 m_leftSampShift =
new QLabel();
331 m_leftSampShift->setToolTip(
"Sample shift between apriori and current");
332 m_leftSampShift->setWhatsThis(
"The shift between the apriori sample and "
333 "the current sample. The apriori sample is set "
334 "when creating a new measure.");
335 m_leftLineShift =
new QLabel();
336 m_leftLineShift->setToolTip(
"Line shift between apriori and current");
337 m_leftLineShift->setWhatsThis(
"The shift between the apriori line and "
338 "the current line. The apriori line is set "
339 "when creating a new measure.");
340 m_leftGoodness =
new QLabel();
341 m_leftGoodness->setToolTip(
"Goodness of Fit result from sub-pixel "
343 m_leftGoodness->setWhatsThis(
"Resulting Goodness of Fit from sub-pixel "
345 QVBoxLayout * leftLayout =
new QVBoxLayout;
346 leftLayout->addWidget(m_leftCombo);
347 leftLayout->addWidget(m_lockLeftMeasure);
348 leftLayout->addWidget(m_ignoreLeftMeasure);
349 leftLayout->addWidget(m_leftReference);
350 leftLayout->addWidget(m_leftMeasureType);
351 leftLayout->addWidget(m_leftSampShift);
352 leftLayout->addWidget(m_leftLineShift);
353 leftLayout->addWidget(m_leftGoodness);
355 QGroupBox * leftGroupBox =
new QGroupBox(
"Left Measure");
356 leftGroupBox->setLayout(leftLayout);
375 m_rightCombo->view()->installEventFilter(
this);
379 QShortcut *nextMeasure =
new QShortcut(Qt::Key_PageDown, m_matchTool);
381 QShortcut *prevMeasure =
new QShortcut(Qt::Key_PageUp, m_matchTool);
384 m_rightCombo->setToolTip(
"Choose right control measure. "
385 "<strong>Shorcuts: PageUp/PageDown</strong>");
386 m_rightCombo->setWhatsThis(
"Choose right control measure identified by "
388 "Note: PageUp selects previous measure; "
389 "PageDown selects next measure.");
390 connect(m_rightCombo, SIGNAL(activated(
int)),
392 m_lockRightMeasure =
new QCheckBox(
"Edit Lock Measure");
393 connect(m_lockRightMeasure, SIGNAL(clicked(
bool)),
395 m_ignoreRightMeasure =
new QCheckBox(
"Ignore Measure");
396 connect(m_ignoreRightMeasure, SIGNAL(clicked(
bool)),
398 connect(
this, SIGNAL(ignoreRightChanged()),
399 m_ignoreRightMeasure, SLOT(toggle()));
400 m_rightReference =
new QLabel();
401 m_rightMeasureType =
new QLabel();
402 m_rightSampShift =
new QLabel();
403 m_rightSampShift->setToolTip(m_leftSampShift->toolTip());
404 m_rightSampShift->setWhatsThis(m_leftSampShift->whatsThis());
405 m_rightLineShift =
new QLabel();
406 m_rightLineShift->setToolTip(m_leftLineShift->toolTip());
407 m_rightLineShift->setWhatsThis(m_leftLineShift->whatsThis());
408 m_rightGoodness =
new QLabel();
409 m_rightGoodness->setToolTip(m_leftGoodness->toolTip());
410 m_rightGoodness->setWhatsThis(m_leftGoodness->whatsThis());
413 QVBoxLayout * rightLayout =
new QVBoxLayout;
414 rightLayout->addWidget(m_rightCombo);
415 rightLayout->addWidget(m_lockRightMeasure);
416 rightLayout->addWidget(m_ignoreRightMeasure);
417 rightLayout->addWidget(m_rightReference);
418 rightLayout->addWidget(m_rightMeasureType);
419 rightLayout->addWidget(m_rightSampShift);
420 rightLayout->addWidget(m_rightLineShift);
421 rightLayout->addWidget(m_rightGoodness);
423 QGroupBox * rightGroupBox =
new QGroupBox(
"Right Measure");
424 rightGroupBox->setLayout(rightLayout);
426 return rightGroupBox;
435 toolBar->addAction(m_openTemplateFile);
436 toolBar->addSeparator();
437 toolBar->addAction(m_saveTemplateFile);
438 toolBar->addAction(m_saveTemplateFileAs);
440 m_templateEditor =
new QTextEdit;
441 connect(m_templateEditor, SIGNAL(textChanged()),
this,
444 QVBoxLayout *mainLayout =
new QVBoxLayout;
445 mainLayout->addWidget(toolBar);
446 mainLayout->addWidget(m_templateEditor);
448 m_templateEditorWidget =
new QWidget;
449 m_templateEditorWidget->setLayout(mainLayout);
463 "Save Control Network ...",
465 m_saveNet->setShortcut(Qt::CTRL + Qt::Key_S);
466 m_saveNet->setToolTip(
"Save current control network");
467 m_saveNet->setStatusTip(
"Save current control network");
468 QString whatsThis =
"<b>Function:</b> Saves the current <i>"
469 "control network</i>";
470 m_saveNet->setWhatsThis(whatsThis);
471 connect(m_saveNet, SIGNAL(triggered()),
this, SLOT(
saveNet()));
474 "Save Control Network &As...",
476 m_saveAsNet->setToolTip(
"Save current control network to chosen file");
477 m_saveAsNet->setStatusTip(
"Save current control network to chosen file");
478 whatsThis =
"<b>Function:</b> Saves the current <i>"
479 "control network</i> under chosen filename";
480 m_saveAsNet->setWhatsThis(whatsThis);
481 connect(m_saveAsNet, SIGNAL(triggered()),
this, SLOT(
saveAsNet()));
486 m_closeMatchTool->setToolTip(
"Close this window");
487 m_closeMatchTool->setStatusTip(
"Close this window");
488 m_closeMatchTool->setShortcut(Qt::ALT + Qt::Key_F4);
489 whatsThis =
"<b>Function:</b> Closes the Match Tool window for this point "
490 "<p><b>Shortcut:</b> Alt+F4 </p>";
491 m_closeMatchTool->setWhatsThis(whatsThis);
492 connect(m_closeMatchTool, SIGNAL(triggered()), m_matchTool, SLOT(close()));
495 "&View/edit registration template",
497 m_showHideTemplateEditor->setCheckable(
true);
498 m_showHideTemplateEditor->setToolTip(
"View and/or edit the registration template");
499 m_showHideTemplateEditor->setStatusTip(
"View and/or edit the registration template");
500 whatsThis =
"<b>Function:</b> Displays the curent registration template. "
501 "The user may edit and save changes under a chosen filename.";
502 m_showHideTemplateEditor->setWhatsThis(whatsThis);
503 connect(m_showHideTemplateEditor, SIGNAL(triggered()),
this,
504 SLOT(showHideTemplateEditor()));
507 "Save registration chips",
509 m_saveChips->setToolTip(
"Save registration chips");
510 m_saveChips->setStatusTip(
"Save registration chips");
511 whatsThis =
"<b>Function:</b> Save registration chips to file. "
512 "Each chip: pattern, search, fit will be saved to a separate file.";
513 m_saveChips->setWhatsThis(whatsThis);
514 connect(m_saveChips, SIGNAL(triggered()),
this, SLOT(
saveChips()));
517 "&Open registration template",
519 m_openTemplateFile->setToolTip(
"Set registration template");
520 m_openTemplateFile->setStatusTip(
"Set registration template");
521 whatsThis =
"<b>Function:</b> Allows user to select a new file to set as "
522 "the registration template";
523 m_openTemplateFile->setWhatsThis(whatsThis);
524 connect(m_openTemplateFile, SIGNAL(triggered()),
this, SLOT(
openTemplateFile()));
527 "&Save template file",
529 m_saveTemplateFile->setToolTip(
"Save the template file");
530 m_saveTemplateFile->setStatusTip(
"Save the template file");
531 m_saveTemplateFile->setWhatsThis(
"Save the registration template file");
532 connect(m_saveTemplateFile, SIGNAL(triggered()),
this,
536 "&Save template as...",
538 m_saveTemplateFileAs->setToolTip(
"Save the template file as");
539 m_saveTemplateFileAs->setStatusTip(
"Save the template file as");
540 m_saveTemplateFileAs->setWhatsThis(
"Save the registration template file as");
541 connect(m_saveTemplateFileAs, SIGNAL(triggered()),
this,
547 m_whatsThis->setShortcut(Qt::SHIFT | Qt::Key_F1);
548 m_whatsThis->setToolTip(
"Activate What's This and click on items on "
549 "user interface to see more information.");
550 connect(m_whatsThis, SIGNAL(triggered()),
this, SLOT(enterWhatsThisMode()));
552 m_showHelp =
new QAction(QPixmap(
toolIconDir() +
"/help-contents.png"),
"Help", m_matchTool);
553 m_showHelp->setToolTip(
"Help");
554 connect(m_showHelp, SIGNAL(triggered()),
this, SLOT(showHelp()));
571 QMenu *fileMenu = m_matchTool->menuBar()->addMenu(
"&File");
572 fileMenu->addAction(m_saveNet);
573 fileMenu->addAction(m_saveAsNet);
574 fileMenu->addAction(m_closeMatchTool);
576 QMenu * regMenu = m_matchTool->menuBar()->addMenu(
"&Registration");
577 regMenu->addAction(m_openTemplateFile);
578 regMenu->addAction(m_showHideTemplateEditor);
579 regMenu->addAction(m_saveChips);
581 QMenu *helpMenu = m_matchTool->menuBar()->addMenu(
"&Help");
582 helpMenu->addAction(m_whatsThis);
586 void MatchTool::createToolBars() {
589 toolBar->setObjectName(
"TemplateEditorToolBar");
590 toolBar->setFloatable(
false);
591 toolBar->addAction(m_saveNet);
592 toolBar->addSeparator();
593 toolBar->addAction(m_showHideTemplateEditor);
594 toolBar->addAction(m_saveChips);
595 toolBar->addAction(m_showHelp);
596 toolBar->addAction(m_whatsThis);
598 m_matchTool->addToolBar(Qt::TopToolBarArea, toolBar);
616 action->setIcon(QPixmap(
toolIconDir()+
"/stock_draw-connector-with-arrows.png"));
617 action->setToolTip(
"Match Tool - Control Point Editor (T)");
618 action->setShortcut(Qt::Key_T);
624 QWidget *MatchTool::createToolBarWidget(QStackedWidget *parent) {
628 QToolButton *openNetButton =
new QToolButton(hbox);
629 openNetButton->setIcon(QPixmap(
toolIconDir() +
"/fileopen.png"));
630 openNetButton->setIconSize(QSize(22,22));
631 openNetButton->setToolTip(
"Open control network");
632 openNetButton->setEnabled(
true);
633 connect(openNetButton, SIGNAL(clicked()),
this, SLOT(openNet()));
635 QToolButton *saveAsNetButton =
new QToolButton(hbox);
636 saveAsNetButton->setDefaultAction(m_saveAsNet);
637 saveAsNetButton->setIconSize(QSize(22,22));
639 QToolButton *saveNetButton =
new QToolButton(hbox);
640 saveNetButton->setDefaultAction(m_saveNet);
641 saveNetButton->setIconSize(QSize(22,22));
643 QToolButton *helpButton =
new QToolButton(hbox);
644 helpButton->setDefaultAction(m_showHelp);
645 helpButton->setIconSize(QSize(22, 22));
647 QHBoxLayout *layout =
new QHBoxLayout;
648 layout->setMargin(0);
649 layout->addWidget(openNetButton);
650 layout->addWidget(saveAsNetButton);
651 layout->addWidget(saveNetButton);
652 layout->addStretch();
653 layout->addWidget(helpButton);
654 hbox->setLayout(layout);
661 void MatchTool::activateTool() {
664 m_controlNet =
new ControlNet();
695 list.
add(fileName.name(),fileName.expanded());
714 QString serialNumber;
720 catch (IException &e) {
721 serialNumber =
"Unknown";
797 if (*origLeftMeasure == *m_leftMeasure && *origRightMeasure == *m_rightMeasure) {
801 if (m_editPoint->IsIgnored()) {
802 QString message =
"You are saving changes to a measure on an ignored ";
803 message +=
"point. Do you want to set Ignore = False on the point and ";
804 message +=
"both measures?";
805 switch (QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
806 message,
"&Yes",
"&No", 0, 0)) {
810 emit ignorePointChanged();
811 if (m_leftMeasure->IsIgnored()) {
812 m_leftMeasure->SetIgnored(
false);
813 emit ignoreLeftChanged();
815 if (m_rightMeasure->IsIgnored()) {
816 m_rightMeasure->SetIgnored(
false);
817 emit ignoreRightChanged();
825 bool savedAMeasure =
false;
827 bool leftChangeOk = validateMeasureChange(m_leftMeasure);
830 *origLeftMeasure = *m_leftMeasure;
831 savedAMeasure =
true;
833 bool rightChangeOk = validateMeasureChange(m_rightMeasure);
836 *origRightMeasure = *m_rightMeasure;
837 savedAMeasure =
true;
842 *m_leftMeasure = *m_rightMeasure;
845 m_editPoint->
GetId());
853 emit editPointChanged();
874 if (*m == *origMeasure)
return false;
878 QString side =
"right";
891 QString message =
"The " + side +
" measure is editLocked ";
892 message +=
"for editing. Do you want to set EditLock = False for this ";
893 message +=
"measure?";
894 int response = QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
895 message, QMessageBox::Yes | QMessageBox::No);
897 if (response == QMessageBox::Yes) {
898 m->SetEditLock(
false);
899 if (side ==
"left") {
900 m_lockLeftMeasure->setChecked(
false);
903 m_lockRightMeasure->setChecked(
false);
912 if (origMeasure->IsIgnored() && m->IsIgnored()) {
913 QString message =
"The " + side +
"measure is ignored. ";
914 message +=
"Do you want to set Ignore = False on the measure?";
915 switch(QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
916 message,
"&Yes",
"&No", 0, 0)){
919 m->SetIgnored(
false);
920 if (side ==
"left") {
921 emit ignoreLeftChanged();
924 emit ignoreRightChanged();
936 if (m->GetSample() != origMeasure->GetSample() || m->GetLine() != origMeasure->GetLine()) {
937 QString message =
"You are making a change to the reference measure. You ";
938 message +=
"may need to move all of the other measures to match the new ";
939 message +=
" coordinate of the reference measure. Do you really want to ";
940 message +=
" change the reference measure's location? ";
941 switch(QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
942 message,
"&Yes",
"&No", 0, 0)){
954 else if (side ==
"left" && (refMeasure->GetCubeSerialNumber() != m->
GetCubeSerialNumber())) {
956 QString message =
"This control network was created by the <i>coreg</i> program, and the "
957 "reference measure needs to remain the same as what <i>coreg</i> set. "
958 "Therefore, you cannot change which measure is the reference. To "
959 "save this point, move the reference measure (measure in BOLD) back "
961 QMessageBox::information(m_matchTool,
"Cannot change reference", message);
964 QString message =
"This point already contains a reference measure. ";
965 message +=
"Would you like to replace it with the measure on the left?";
966 int response = QMessageBox::question(m_matchTool,
967 "Match Tool Save Measure", message,
968 QMessageBox::Yes | QMessageBox::No,
971 if (response == QMessageBox::Yes) {
975 QString fname = FileName(file).name();
976 int iref = m_leftCombo->findText(fname);
979 QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
980 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
981 iref = m_rightCombo->findText(fname);
982 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
985 fname = FileName(file).name();
986 iref = m_leftCombo->findText(fname);
987 m_leftCombo->setItemData(iref,font,Qt::FontRole);
988 iref = m_rightCombo->findText(fname);
989 m_rightCombo->setItemData(iref,font,Qt::FontRole);
998 if (side ==
"left") {
1020 void MatchTool::checkReference() {
1027 QString message =
"This point already contains a reference measure. ";
1028 message +=
"Would you like to replace it with the measure on the left?";
1029 int response = QMessageBox::question(m_matchTool,
1030 "Match Tool Save Measure", message,
1031 QMessageBox::Yes | QMessageBox::No,
1034 if (response == QMessageBox::Yes) {
1038 QString fname = FileName(file).name();
1039 int iref = m_leftCombo->findText(fname);
1042 QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
1043 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1044 iref = m_rightCombo->findText(fname);
1045 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1048 fname = FileName(file).name();
1049 iref = m_leftCombo->findText(fname);
1050 m_leftCombo->setItemData(iref,font,Qt::FontRole);
1051 iref = m_rightCombo->findText(fname);
1052 m_rightCombo->setItemData(iref,font,Qt::FontRole);
1084 *updatePoint = *m_editPoint;
1088 if (m_controlNet->ContainsPoint(updatePoint->
GetId())) {
1090 p = m_controlNet->GetPoint(QString(updatePoint->
GetId()));
1096 m_controlNet->AddPoint(updatePoint);
1100 m_savePoint->setPalette(m_saveDefaultPalette);
1103 emit editPointChanged();
1105 m_netChanged =
true;
1107 m_pointEditor->refreshChips();
1122 if (m_editPoint == NULL)
return;
1141 if (m_editPoint == NULL)
return;
1145 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1146 QString message =
"Unable to change Ignored on point. Set EditLock ";
1147 message +=
" to False.";
1148 QMessageBox::critical(m_matchTool,
"Error", message);
1174 if (m_editPoint->IsEditLocked()) {
1175 m_lockLeftMeasure->setChecked(m_leftMeasure->
IsEditLocked());
1176 QMessageBox::warning(m_matchTool,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1177 " before changing a measure.");
1178 m_lockLeftMeasure->setChecked(m_leftMeasure->
IsEditLocked());
1182 if (m_leftMeasure != NULL) m_leftMeasure->SetEditLock(lock);
1186 if (m_rightMeasure != NULL) {
1188 m_rightMeasure->SetEditLock(lock);
1189 m_lockRightMeasure->setChecked(lock);
1192 emit measureChanged();
1214 if (m_leftMeasure != NULL) m_leftMeasure->SetIgnored(ignore);
1218 if (m_rightMeasure != NULL) {
1220 m_rightMeasure->SetIgnored(ignore);
1221 m_ignoreRightMeasure->setChecked(ignore);
1224 emit measureChanged();
1245 if (m_editPoint->IsEditLocked()) {
1246 m_lockRightMeasure->setChecked(m_rightMeasure->
IsEditLocked());
1247 QMessageBox::warning(m_matchTool,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1248 " before changing a measure.");
1249 m_lockRightMeasure->setChecked(m_rightMeasure->
IsEditLocked());
1253 if (m_rightMeasure != NULL) m_rightMeasure->SetEditLock(lock);
1256 if (m_leftMeasure != NULL) {
1258 m_leftMeasure->SetEditLock(lock);
1259 m_lockLeftMeasure->setChecked(lock);
1262 emit measureChanged();
1284 if (m_rightMeasure != NULL) m_rightMeasure->SetIgnored(ignore);
1288 if (m_leftMeasure != NULL) {
1290 m_leftMeasure->SetIgnored(ignore);
1291 m_ignoreLeftMeasure->setChecked(ignore);
1294 emit measureChanged();
1299 void MatchTool::openNet() {
1302 if (m_controlNet->GetNumPoints() != 0 && m_netChanged) {
1303 QString message =
"A control net has already been created. Do you want to save before "
1304 "opening a new control net?";
1305 int response = QMessageBox::question(m_matchTool,
"Save current control net?",
1307 QMessageBox::Yes | QMessageBox::No,
1310 if (response == QMessageBox::Yes) {
1313 m_matchTool->setVisible(
false);
1315 delete m_controlNet;
1316 m_controlNet = NULL;
1319 m_newPointDialog = NULL;
1323 m_netChanged =
false;
1325 QApplication::restoreOverrideCursor();
1326 QString filter =
"Control net (*.net *.cnet *.ctl);;";
1327 filter +=
"Pvl file (*.pvl);;";
1328 filter +=
"Text file (*.txt);;";
1329 filter +=
"All (*)";
1330 m_cnetFileName = QFileDialog::getOpenFileName((
QWidget *)parent(),
1331 "Select a control network",
1334 QApplication::setOverrideCursor(Qt::WaitCursor);
1335 if (!m_cnetFileName.isEmpty()) {
1338 m_controlNet =
new ControlNet(m_cnetFileName, &progress);
1340 m_coregReferenceSN =
"";
1341 if (m_controlNet->GetNetworkId() ==
"Coreg") {
1345 m_coregReferenceSN = m_controlNet->GetPoint(0)->GetReferenceSN();
1348 catch (IException &e) {
1349 QApplication::restoreOverrideCursor();
1350 QString message =
"Invalid control network. \n";
1351 message += e.toString();
1352 QMessageBox::critical(m_matchTool,
"Error", message);
1353 m_cnetFileName.clear();
1354 delete m_controlNet;
1355 m_controlNet = NULL;
1359 QApplication::restoreOverrideCursor();
1360 m_matchTool->setWindowTitle(
"Match Tool - Control Network File: " + m_cnetFileName);
1361 m_cnetFileNameLabel->setText(
"Control Network: " + m_cnetFileName);
1374 if (m_cnetFileName.isEmpty()) {
1375 QString message =
"This is a new network, you must select "
1376 "\"Save As\" under the File Menu or on the toolbar.";
1377 QMessageBox::critical(m_matchTool,
"Error", message);
1381 m_controlNet->Write(m_cnetFileName);
1382 m_netChanged =
false;
1385 QMessageBox::critical(m_matchTool, tr(
"Error Writing Control Net"), e.
what());
1397 QString fn = QFileDialog::getSaveFileName(m_matchTool,
1398 "Choose filename to save under",
1400 "Control Files (*.net)");
1405 m_controlNet->Write(fn);
1406 m_netChanged =
false;
1409 QMessageBox::critical(m_matchTool, tr(
"Error Writing Control Net"), e.
what());
1412 m_cnetFileName = fn;
1452 if (mvp == NULL)
return;
1460 if (s == Qt::LeftButton) {
1462 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1463 QString message =
"No points exist for editing. Create points ";
1464 message +=
"using the right mouse button.";
1465 QMessageBox::warning(m_matchTool,
"Warning", message);
1473 point = m_controlNet->FindClosest(sn, samp, line);
1476 QString message =
"Cannot find point for editing.";
1478 QMessageBox::warning(m_matchTool,
"Warning", message);
1484 else if (s == Qt::MidButton) {
1485 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1486 QString message =
"No points exist for deleting. Create points ";
1487 message +=
"using the right mouse button.";
1488 QMessageBox::warning(m_matchTool,
"Warning", message);
1493 ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
1495 if (point == NULL) {
1496 QString message =
"No points exist for deleting. Create points ";
1497 message +=
"using the right mouse button.";
1498 QMessageBox::warning(m_matchTool,
"Warning", message);
1504 else if (s == Qt::RightButton) {
1505 if (m_newPointDialog) {
1506 addMeasure(mvp, samp, line);
1514 QString message =
"Cannot create control point.\n\n";
1516 QMessageBox::critical(m_matchTool,
"Error", message);
1529 for (
int i=0; i<point->GetNumMeasures(); i++) {
1535 return missingCubes;
1549 connect(m_newPointDialog, SIGNAL(measuresFinished()),
this, SLOT(doneWithMeasures()));
1550 connect(m_newPointDialog, SIGNAL(newPointCanceled()),
this, SLOT(cancelNewPoint()));
1555 images<<cubeFile.name();
1557 m_newPointDialog->
setFiles(images);
1558 m_newPointDialog->show();
1562 m_newPointDialog->highlightFile(current);
1581 void MatchTool::addMeasure(
MdiCubeViewport *cvp,
double sample,
double line) {
1585 m_newPointDialog->highlightFile(current);
1586 m_newPointDialog->raise();
1606 void MatchTool::doneWithMeasures() {
1608 m_lastUsedPointId = m_newPointDialog->pointId();
1609 m_newPoint->
SetId(m_lastUsedPointId);
1620 QString message =
"This is a coreg network which needs the cube with serial number " +
1621 m_coregReferenceSN +
" as the reference measure. This new control point does "
1622 "not have a measure for that serial number, so this point cannot be created until "
1623 "the cube listed above is added (Right-click on cube).";
1624 QMessageBox::critical(m_matchTool,
"Error", message);
1625 m_newPointDialog->show();
1633 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1637 m_editPoint = m_newPoint;
1640 delete m_newPointDialog;
1641 m_newPointDialog = NULL;
1645 m_matchTool->setVisible(
true);
1646 m_matchTool->raise();
1648 emit editPointChanged();
1654 void MatchTool::cancelNewPoint() {
1656 delete m_newPointDialog;
1657 m_newPointDialog = NULL;
1689 if (mCubes.size() > 0) {
1690 QString msgTitle =
"Missing Cubes";
1691 QString message =
"This point is missing cubes for the following measures and cannot be ";
1692 message +=
"loaded into the editor. Do you still want to delete this point?\n\n";
1693 for (
int i=0; i<mCubes.size(); i++) {
1694 message += mCubes.at(i) +
"\n";
1696 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1698 QPushButton *yesButton = msgBox.addButton(
"Yes", QMessageBox::AcceptRole);
1699 QPushButton *noButton = msgBox.addButton(
"No", QMessageBox::RejectRole);
1700 msgBox.setDefaultButton(yesButton);
1702 if (msgBox.clickedButton() == noButton) {
1706 m_matchTool->setVisible(
false);
1713 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1718 *m_editPoint = *point;
1721 if (mCubes.size() == 0) {
1727 emit editPointChanged();
1731 QString CPId = m_editPoint->
GetId();
1732 deletePointDialog->pointIdValue->setText(CPId);
1734 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1743 deletePointDialog->fileList->addItem(file);
1746 if (deletePointDialog->exec()) {
1748 int numDeleted = deletePointDialog->fileList->selectedItems().count();
1751 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1752 numDeleted == m_editPoint->GetNumMeasures()) {
1755 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1756 QString message =
"You have selected all measures in this point to be deleted. This "
1757 "control point will be deleted. Do you want to delete this control point?";
1758 int response = QMessageBox::question(m_matchTool,
1759 "Delete control point", message,
1760 QMessageBox::Yes | QMessageBox::No,
1763 if (response == QMessageBox::No) {
1768 m_matchTool->setVisible(
false);
1771 QMessageBox::information(m_matchTool,
"EditLocked Point",
1772 "This point is EditLocked and cannot be deleted.");
1775 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1784 int lockedMeasures = 0;
1785 for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
1786 QListWidgetItem *item = deletePointDialog->fileList->item(i);
1787 if (!deletePointDialog->fileList->isItemSelected(item))
continue;
1792 (*m_editPoint)[i]->GetCubeSerialNumber())) {
1793 QString message =
"You are trying to delete the Reference measure."
1794 " Do you really want to delete the Reference measure?";
1795 switch (QMessageBox::question(m_matchTool,
1796 "Delete Reference measure?", message,
1797 "&Yes",
"&No", 0, 0)) {
1805 if (numDeleted == 1) {
1812 if (m_editPoint->
Delete(i) == ControlMeasure::MeasureLocked) {
1817 if (lockedMeasures > 0) {
1818 QMessageBox::information(m_matchTool,
"EditLocked Measures",
1819 QString::number(lockedMeasures) +
" / "
1821 deletePointDialog->fileList->selectedItems().size()) +
1822 " measures are EditLocked and were not deleted.");
1825 if (mCubes.size() == 0) {
1827 m_matchTool->setVisible(
true);
1828 m_matchTool->raise();
1831 m_pointEditor->templateFileName());
1839 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1848 m_netChanged =
true;
1853 emit editPointChanged();
1870 if (point->GetNumMeasures() == 0) {
1871 QString message =
"This point has no measures.";
1872 QMessageBox::warning(m_matchTool,
"Warning", message);
1873 emit editPointChanged();
1879 if (mCubes.size() > 0) {
1880 QString msgTitle =
"Missing Cubes";
1881 QString message =
"This point is missing cubes and cannot be loaded into the editor. Open ";
1882 message +=
"the cubes for the following measures before selecting this point.\n\n";
1883 for (
int i=0; i<mCubes.size(); i++) {
1884 message += mCubes.at(i) +
"\n";
1886 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1894 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1899 *m_editPoint = *point;
1902 m_matchTool->setVisible(
true);
1903 m_matchTool->raise();
1905 m_pointEditor->templateFileName());
1908 emit editPointChanged();
1911 m_savePoint->setPalette(m_saveDefaultPalette);
1936 QString CPId = m_editPoint->
GetId();
1937 QString ptId(
"Point ID: ");
1938 ptId += (QString) CPId;
1939 m_ptIdValue->setText(ptId);
1942 QString ptsize =
"Number of Measures: " +
1943 QString::number(m_editPoint->GetNumMeasures());
1944 m_numMeasures->setText(ptsize);
1947 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
1950 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1953 m_leftCombo->clear();
1954 m_rightCombo->clear();
1955 m_pointFiles.clear();
1958 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1962 QString tempFileName =
FileName(file).name();
1963 m_leftCombo->addItem(tempFileName);
1964 m_rightCombo->addItem(tempFileName);
1967 m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1968 m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1987 if (!m_leftFile.isEmpty()) {
1988 leftIndex = m_leftCombo->findText(
FileName(m_leftFile).name());
1990 if (leftIndex < 0 ) leftIndex = 0;
1995 if (leftIndex == 0) {
2004 if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
2005 m_rightCombo->setCurrentIndex(rightIndex);
2006 m_leftCombo->setCurrentIndex(leftIndex);
2024 if (m_measureWindow == NULL) {
2026 m_measureTable =
new QTableWidget();
2027 m_measureTable->setMinimumWidth(1600);
2028 m_measureTable->setAlternatingRowColors(
true);
2029 m_measureWindow->setCentralWidget(m_measureTable);
2032 m_measureTable->clear();
2033 m_measureTable->setSortingEnabled(
false);
2035 m_measureTable->setRowCount(m_editPoint->GetNumMeasures());
2036 m_measureTable->setColumnCount(NUMCOLUMNS);
2039 for (
int i=0; i<NUMCOLUMNS; i++) {
2040 labels<<measureColumnToString((MeasureColumns)i);
2042 m_measureTable->setHorizontalHeaderLabels(labels);
2045 for (
int row=0; row<m_editPoint->GetNumMeasures(); row++) {
2050 QTableWidgetItem *tableItem =
new QTableWidgetItem(QString(file));
2051 m_measureTable->setItem(row,column++,tableItem);
2054 m_measureTable->setItem(row,column++,tableItem);
2056 tableItem =
new QTableWidgetItem();
2057 tableItem->setData(0,m.GetSample());
2058 m_measureTable->setItem(row,column++,tableItem);
2060 tableItem =
new QTableWidgetItem();
2061 tableItem->setData(0,m.GetLine());
2062 m_measureTable->setItem(row,column++,tableItem);
2064 if (m.GetAprioriSample() ==
Null) {
2065 tableItem =
new QTableWidgetItem(
"Null");
2068 tableItem =
new QTableWidgetItem();
2069 tableItem->setData(0,m.GetAprioriSample());
2071 m_measureTable->setItem(row,column++,tableItem);
2073 if (m.GetAprioriLine() ==
Null) {
2074 tableItem =
new QTableWidgetItem(
"Null");
2077 tableItem =
new QTableWidgetItem();
2078 tableItem->setData(0,m.GetAprioriLine());
2080 m_measureTable->setItem(row,column++,tableItem);
2082 if (m.GetSampleResidual() ==
Null) {
2083 tableItem =
new QTableWidgetItem(QString(
"Null"));
2086 tableItem =
new QTableWidgetItem();
2087 tableItem->setData(0,m.GetSampleResidual());
2089 m_measureTable->setItem(row,column++,tableItem);
2091 if (m.GetLineResidual() ==
Null) {
2092 tableItem =
new QTableWidgetItem(QString(
"Null"));
2095 tableItem =
new QTableWidgetItem();
2096 tableItem->setData(0,m.GetLineResidual());
2098 m_measureTable->setItem(row,column++,tableItem);
2101 tableItem =
new QTableWidgetItem(QString(
"Null"));
2104 tableItem =
new QTableWidgetItem();
2107 m_measureTable->setItem(row,column++,tableItem);
2109 double sampleShift = m.GetSampleShift();
2110 if (sampleShift ==
Null) {
2111 tableItem =
new QTableWidgetItem(QString(
"Null"));
2114 tableItem =
new QTableWidgetItem();
2115 tableItem->setData(0,sampleShift);
2117 m_measureTable->setItem(row,column++,tableItem);
2119 double lineShift = m.GetLineShift();
2120 if (lineShift ==
Null) {
2121 tableItem =
new QTableWidgetItem(QString(
"Null"));
2124 tableItem =
new QTableWidgetItem();
2125 tableItem->setData(0,lineShift);
2127 m_measureTable->setItem(row,column++,tableItem);
2129 double pixelShift = m.GetPixelShift();
2130 if (pixelShift ==
Null) {
2131 tableItem =
new QTableWidgetItem(QString(
"Null"));
2134 tableItem =
new QTableWidgetItem();
2135 tableItem->setData(0,pixelShift);
2137 m_measureTable->setItem(row,column++,tableItem);
2139 double goodnessOfFit = m.GetLogData(
2141 if (goodnessOfFit ==
Null) {
2142 tableItem =
new QTableWidgetItem(QString(
"Null"));
2145 tableItem =
new QTableWidgetItem();
2146 tableItem->setData(0,goodnessOfFit);
2148 m_measureTable->setItem(row,column++,tableItem);
2150 if (m.IsIgnored()) tableItem =
new QTableWidgetItem(
"True");
2151 if (!m.IsIgnored()) tableItem =
new QTableWidgetItem(
"False");
2152 m_measureTable->setItem(row,column++,tableItem);
2155 tableItem =
new QTableWidgetItem(
"True");
2157 tableItem =
new QTableWidgetItem(
"False");
2158 m_measureTable->setItem(row,column++,tableItem);
2160 tableItem =
new QTableWidgetItem(
2162 m_measureTable->setItem(row,column,tableItem);
2170 for (
int col=0; col<m_measureTable->columnCount(); col++)
2171 m_measureTable->item(row, col)->setFont(font);
2176 m_measureTable->resizeColumnsToContents();
2177 m_measureTable->resizeRowsToContents();
2178 m_measureTable->setSortingEnabled(
true);
2179 m_measureWindow->show();
2184 QString MatchTool::measureColumnToString(MatchTool::MeasureColumns column) {
2194 case SAMPLERESIDUAL:
2195 return "Sample Residual";
2197 return "Line Residual";
2198 case RESIDUALMAGNITUDE:
2199 return "Residual Magnitude";
2201 return "Sample Shift";
2203 return "Line Shift";
2205 return "Pixel Shift";
2207 return "Goodness of Fit";
2213 return "Measure Type";
2215 return "Apriori Sample";
2217 return "Apriori Line";
2220 "Invalid measure column passed to measureColumnToString",
_FILEINFO_);
2235 int curIndex = m_rightCombo->currentIndex();
2236 if (curIndex < m_rightCombo->count() - 1) {
2238 m_rightCombo->setCurrentIndex(curIndex + 1);
2254 int curIndex = m_rightCombo->currentIndex();
2257 m_rightCombo->setCurrentIndex(curIndex - 1);
2278 QString file = m_pointFiles[index];
2285 QString message =
"Make sure the correct cube is opened.\n\n";
2287 QMessageBox::critical(m_matchTool,
"Error", message);
2292 int i = m_leftCombo->findText(
FileName(file).name());
2294 m_leftCombo->setCurrentIndex(i);
2300 if (m_leftMeasure != NULL) {
2301 delete m_leftMeasure;
2302 m_leftMeasure = NULL;
2306 *m_leftMeasure = *((*m_editPoint)[serial]);
2309 if (m_leftCube != NULL)
delete m_leftCube;
2310 m_leftCube =
new Cube();
2311 m_leftCube->
open(file);
2315 m_editPoint->
GetId());
2334 QString file = m_pointFiles[index];
2341 QString message =
"Make sure the correct cube is opened.\n\n";
2343 QMessageBox::critical(m_matchTool,
"Error", message);
2348 int i = m_rightCombo->findText(
FileName(file).name());
2350 m_rightCombo->setCurrentIndex(i);
2356 if (m_rightMeasure != NULL) {
2357 delete m_rightMeasure;
2358 m_rightMeasure = NULL;
2362 *m_rightMeasure = *((*m_editPoint)[serial]);
2365 if (m_rightCube != NULL)
delete m_rightCube;
2366 m_rightCube =
new Cube();
2367 m_rightCube->
open(file);
2371 m_editPoint->
GetId());
2400 m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
2402 QString s =
"Reference: ";
2410 m_leftReference->setText(s);
2412 s =
"Measure Type: ";
2417 m_leftMeasureType->setText(s);
2419 if (m_leftMeasure->GetSampleShift() ==
Null) {
2420 s =
"Sample Shift: Null";
2423 s =
"Sample Shift: " + QString::number(m_leftMeasure->GetSampleShift());
2425 m_leftSampShift->setText(s);
2427 if (m_leftMeasure->GetLineShift() ==
Null) {
2428 s =
"Line Shift: Null";
2431 s =
"Line Shift: " + QString::number(m_leftMeasure->GetLineShift());
2433 m_leftLineShift->setText(s);
2435 double goodnessOfFit = m_leftMeasure->GetLogData(
2437 if (goodnessOfFit ==
Null) {
2438 s =
"Goodness of Fit: Null";
2441 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2443 m_leftGoodness->setText(s);
2473 m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
2475 QString s =
"Reference: ";
2484 m_rightReference->setText(s);
2486 s =
"Measure Type: ";
2491 m_rightMeasureType->setText(s);
2493 if (m_rightMeasure->GetSampleShift() ==
Null) {
2494 s =
"Sample Shift: Null";
2497 s =
"Sample Shift: " + QString::number(m_rightMeasure->GetSampleShift());
2499 m_rightSampShift->setText(s);
2501 if (m_rightMeasure->GetLineShift() ==
Null) {
2502 s =
"Line Shift: Null";
2505 s =
"Line Shift: " + QString::number(m_rightMeasure->GetLineShift());
2507 m_rightLineShift->setText(s);
2509 double goodnessOfFit = m_rightMeasure->GetLogData(
2511 if (goodnessOfFit ==
Null) {
2512 s =
"Goodness of Fit: Null";
2515 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2517 m_rightGoodness->setText(s);
2534 if(e->type() != QEvent::Leave)
return false;
2535 if(o == m_leftCombo->view()) {
2537 m_leftCombo->hidePopup();
2539 if (o == m_rightCombo->view()) {
2541 m_rightCombo->hidePopup();
2581 mvp->viewport()->update();
2610 if ( (m_controlNet == NULL || m_controlNet->GetNumPoints() == 0) && m_newPoint == NULL &&
2611 m_editPoint == NULL)
2614 QString sn = serialNumber(mvp);
2618 if (m_newPoint != NULL) {
2622 double samp = (*m_newPoint)[sn]->GetSample();
2623 double line = (*m_newPoint)[sn]->GetLine();
2627 QBrush brush(Qt::red);
2631 painter->setPen(pen);
2632 painter->drawLine(x - 5, y, x + 5, y);
2633 painter->drawLine(x, y - 5, x, y + 5);
2638 if (!m_controlNet->GetCubeSerials().contains(
2646 m_controlNet->GetMeasuresInCube(sn);
2648 for (
int i = 0; i < measures.count(); i++) {
2651 double samp = m->GetSample();
2652 double line = m->GetLine();
2656 if (m->Parent()->IsIgnored()) {
2657 painter->setPen(QColor(255, 255, 0));
2660 else if (m->IsIgnored()) {
2661 painter->setPen(QColor(255, 255, 0));
2664 painter->setPen(Qt::green);
2667 painter->drawLine(x - 5, y, x + 5, y);
2668 painter->drawLine(x, y - 5, x, y + 5);
2671 if (m_editPoint != NULL && m_newPoint == NULL) {
2675 double samp = (*m_editPoint)[sn]->GetSample();
2676 double line = (*m_editPoint)[sn]->GetLine();
2680 QBrush brush(Qt::red);
2684 painter->setPen(pen);
2685 painter->drawLine(x - 5, y, x + 5, y);
2686 painter->drawLine(x, y - 5, x, y + 5);
2708 if (m_templateModified) {
2709 int r = QMessageBox::warning(m_matchTool, tr(
"OK to continue?"),
2710 tr(
"The currently opened registration template has been modified.\n"
2712 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2715 if (r == QMessageBox::Yes)
2717 else if (r == QMessageBox::Cancel)
2736 QString filename = QFileDialog::getOpenFileName(m_matchTool,
2737 "Select a registration template",
".",
2738 "Registration template files (*.def *.pvl);;All files (*)");
2740 if (filename.isEmpty())
2757 QFile file(
FileName((QString) fn).expanded());
2758 if (!file.open(QIODevice::ReadOnly)) {
2759 QString msg =
"Failed to open template file \"" + fn +
"\"";
2760 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2764 QTextStream stream(&file);
2765 m_templateEditor->setText(stream.readAll());
2768 QScrollBar * sb = m_templateEditor->verticalScrollBar();
2769 sb->setValue(sb->minimum());
2771 m_templateModified =
false;
2772 m_saveTemplateFile->setEnabled(
false);
2773 m_templateFileNameLabel->setText(
"Template File: " + fn);
2780 m_templateModified =
true;
2781 m_saveTemplateFile->setEnabled(
true);
2789 if (!m_templateModified)
2793 m_pointEditor->templateFileName();
2803 QString filename = QFileDialog::getSaveFileName(m_matchTool,
2804 "Save registration template",
".",
2805 "Registration template files (*.def *.pvl);;All files (*)");
2807 if (filename.isEmpty())
2822 QString contents = m_templateEditor->toPlainText();
2833 QMessageBox::warning(m_matchTool,
"Error", message);
2837 QString expandedFileName(
2838 FileName((QString) fn).expanded());
2840 QFile file(expandedFileName);
2842 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2843 QString msg =
"Failed to save template file to \"" + fn +
"\"\nDo you "
2845 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2850 QTextStream stream(&file);
2855 m_templateModified =
false;
2856 m_saveTemplateFile->setEnabled(
false);
2857 m_templateFileNameLabel->setText(
"Template File: " + fn);
2879 Pvl templatePvl(m_pointEditor->templateFileName());
2883 registrationDialog.setWindowTitle(
"View or Edit Template File: "
2884 + templatePvl.fileName());
2885 registrationDialog.resize(550,360);
2886 registrationDialog.exec();
2890 QMessageBox::information(m_matchTool,
"Error", message);
2908 void MatchTool::showHideTemplateEditor() {
2910 if (!m_templateEditorWidget)
2913 m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
2931 if (m_editPoint == NULL)
return;
2932 if (pointId != m_editPoint->
GetId())
return;
2937 ControlPoint *updatedPoint = m_controlNet->GetPoint(pointId);
2938 m_editPoint->
SetEditLock(updatedPoint->IsEditLocked());
2939 m_editPoint->
SetIgnored(updatedPoint->IsIgnored());
2942 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
2945 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
2970 if (m_editPoint != NULL) {
2972 QString
id = m_ptIdValue->text().remove(
"Point ID: ");
2973 m_controlNet->GetPoint(
id);
2978 emit editPointChanged();
2996 QColor qc = Qt::red;
2997 QPalette p = m_savePoint->palette();
2998 p.setColor(QPalette::ButtonText,qc);
2999 m_savePoint->setPalette(p);
3019 if (m_editPoint == NULL)
return false;
3041 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
3042 QSettings settings(config.expanded(),
3043 QSettings::NativeFormat);
3044 QPoint pos = settings.value(
"pos", QPoint(300, 100)).toPoint();
3045 QSize size = settings.value(
"size", QSize(900, 500)).toSize();
3046 m_matchTool->resize(size);
3047 m_matchTool->move(pos);
3060 if (!m_matchTool->isVisible())
return;
3061 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
3062 QSettings settings(config.expanded(),
3063 QSettings::NativeFormat);
3064 settings.setValue(
"pos", m_matchTool->pos());
3065 settings.setValue(
"size", m_matchTool->size());
3070 void MatchTool::enterWhatsThisMode() {
3071 QWhatsThis::enterWhatsThisMode();
3075 void MatchTool::clearEditPoint() {
3081 void MatchTool::showHelp() {
3084 helpDialog->setWindowTitle(
"Match Tool Help");
3086 QVBoxLayout *mainLayout =
new QVBoxLayout;
3087 helpDialog->setLayout(mainLayout);
3089 QLabel *matchTitle =
new QLabel(
"<h2>Match Tool</h2>");
3090 mainLayout->addWidget(matchTitle);
3092 QLabel *matchSubtitle =
new QLabel(
"A tool for interactively measuring and editing sample/line "
3093 "registration points between cubes. These "
3094 "points contain sample, line postions only, no latitude or "
3095 "longitude values are used or recorded.");
3096 matchSubtitle->setWordWrap(
true);
3097 mainLayout->addWidget(matchSubtitle);
3099 QTabWidget *tabArea =
new QTabWidget;
3100 tabArea->setDocumentMode(
true);
3101 mainLayout->addWidget(tabArea);
3104 QScrollArea *overviewTab =
new QScrollArea;
3105 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3106 overviewTab->setWidgetResizable(
true);
3108 QVBoxLayout *overviewLayout =
new QVBoxLayout;
3109 overviewContainer->setLayout(overviewLayout);
3111 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
3112 overviewLayout->addWidget(purposeTitle);
3114 QLabel *purposeText =
new QLabel(
"<p>This tool is for recording and editing registration "
3115 "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The "
3116 "recorded registration points are sample and line pixel coordinates only. Therefore, this "
3117 "tool can be used on any images including ones that do not contain a camera model "
3118 "(i.e, The existence of the Isis Instrument Group on the image labels is not required). "
3119 "This also means that the tool differs from the <i>qnet</i> control point network "
3120 "application in that no latitude or longitude values are ever used or recorded "
3121 "(regardless if the image has a camera model in Isis).</p>"
3122 "<p>The output control point network that this tool generates is primarily used 1) as "
3123 "input for an image-wide sample/line translation to register one image to another by "
3124 "'moving' pixel locations - refer to the documentation for applications such as "
3125 "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded "
3126 "measurements in other spreadsheet or plotting packages to visualize magnitude "
3127 "and direction of varying translations of the images relative to one another.</p> "
3128 "<p>An automated version of this match tool is the <i>coreg</i> application. This tool "
3129 "can be used to visually evaluate and edit the control point network created by "
3130 "<i>coreg</i>.</p> "
3131 "<p>The format of the output point network file is binary. This tool uses the Isis control "
3132 " network framework to create, co-register and save all control points and pixel "
3133 "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to "
3134 "a readable PVL format."
3135 "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> "
3136 "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>"
3137 "<p>Control Points are drawn on the associated displayed cubes with the following colors: "
3138 "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
3139 purposeText->setWordWrap(
true);
3140 overviewLayout->addWidget(purposeText);
3142 overviewTab->setWidget(overviewContainer);
3145 QScrollArea *quickTab =
new QScrollArea;
3146 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3147 quickTab->setWidgetResizable(
true);
3149 QVBoxLayout *quickLayout =
new QVBoxLayout;
3150 quickContainer->setLayout(quickLayout);
3152 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
3153 quickLayout->addWidget(quickTitle);
3155 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
3156 quickLayout->addWidget(quickSubTitle);
3158 QLabel *quickPrep =
new QLabel(
"<p><ul>"
3159 "<li>Open the cubes with overlapping areas for choosing control points</li>"
3160 "<li>Choose the match tool <img src=\"" +
toolIconDir() +
3161 "/stock_draw-connector-with-arrows.png\" width=22 height=22> "
3162 "from the toolpad on the right side of the <i>qview</i> main window</li>");
3163 quickPrep->setWordWrap(
true);
3164 quickLayout->addWidget(quickPrep);
3166 QLabel *morePrep =
new QLabel(
"<p>Once the Match tool is activated the tool bar at the top "
3167 "of the main window contains file action buttons and a help button:");
3168 morePrep->setWordWrap(
true);
3169 quickLayout->addWidget(morePrep);
3171 QLabel *fileButtons =
new QLabel(
"<p><ul>"
3172 "<li><img src=\"" +
toolIconDir() +
"/fileopen.png\" width=22 height=22> Open an existing "
3173 "control network <b>Note:</b> If you do not open an existing network, a new one will "
3175 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSaveAs.png\" width=22 height=22> Save "
3176 "control network as ...</li>"
3177 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSave.png\" width=22 height=22> Save "
3178 "control network to current file</li>"
3179 "<li><img src=\"" +
toolIconDir() +
"/help-contents.png\" width=22 height=22> Show Help "
3181 fileButtons->setWordWrap(
true);
3182 quickLayout->addWidget(fileButtons);
3184 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
3185 quickLayout->addWidget(quickFunctionTitle);
3187 QLabel *quickFunction =
new QLabel(
3188 "The match tool window will be shown once "
3189 "you click in a cube viewport window using one of the following "
3190 "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
3191 quickFunction->setWordWrap(
true);
3192 quickLayout->addWidget(quickFunction);
3194 QLabel *quickDesc =
new QLabel(
"<p><ul>"
3195 "<li>Left Click - Modify the control point closest to the click <b>Note:</b> "
3196 "All cubes in the control point must be displayed before loading the point</li>"
3197 "<li>Middle Click - Delete the control point closest to the click</li>"
3198 "<li>Right Click - Create a new control point at the click location</li></ul></p>");
3199 quickDesc->setWordWrap(
true);
3200 quickDesc->setOpenExternalLinks(
true);
3201 quickLayout->addWidget(quickDesc);
3203 quickTab->setWidget(quickContainer);
3206 QScrollArea *controlPointTab =
new QScrollArea;
3207 controlPointTab->setWidgetResizable(
true);
3208 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3210 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
3211 controlPointContainer->setLayout(controlPointLayout);
3213 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
3214 controlPointLayout->addWidget(controlPointTitle);
3216 QLabel *mouseLabel =
new QLabel(
"<p><h3>When the \"Match\" tool "
3217 "is activated, the mouse buttons have the following function in the "
3218 "cube viewports of the main qview window:</h3>");
3219 mouseLabel->setWordWrap(
true);
3220 mouseLabel->setScaledContents(
true);
3221 controlPointLayout->addWidget(mouseLabel);
3223 QLabel *controlPointDesc =
new QLabel(
"<ul>"
3224 "<li>Left click - Edit the closest control point <b>Note:</b> "
3225 "All cubes in the control point must be displayed before loading the point</li>"
3226 "<li>Middle click - Delete the closest control point</li>"
3227 "<li>Right click - Create new control point at cursor location. This will bring up a new "
3228 "point dialog which allows you to enter a point id and will list all cube viewports, "
3229 "highlighting cubes where the point has been chosen by clicking on the cube's viewport. "
3230 "When the desired cubes have been chosen, select the \"Done\" button which will load the "
3231 "control point into the control point editor window which will allow the control measure "
3232 "positions to be refined.</li>");
3233 controlPointDesc->setWordWrap(
true);
3234 controlPointLayout->addWidget(controlPointDesc);
3236 QLabel *controlPointEditing =
new QLabel(
3237 "<h4>Changing Control Measure Locations</h4>"
3238 "<p>Both the left and right control measure positions can be adjusted by:"
3240 "<li>Move the cursor location under the crosshair by clicking the left mouse "
3242 "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
3243 "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>"
3245 "<h4>Other Point Editor Functions</h4>"
3246 "<p>Along the right border of the window:</p>"
3248 "<li><strong>Link Zoom</strong> This will link the two small viewports together when "
3249 "zooming (ie. If this is checked, if the left view is zoomed, the right view will "
3250 "match the left view's zoom factor. "
3251 "<b>Note:</b> Zooming is controlled from the left view.</li>"
3252 "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to "
3253 "its original orientation</li>"
3254 "<li><strong>Rotate:</strong> Rotate the right view using either the dial "
3255 "or entering degrees </li>"
3256 "<li><strong>Show control points:</strong> Draw crosshairs at all control "
3257 "point locations visible within the view</li>"
3258 "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire "
3260 "<li><strong>Circle:</strong> Draw circle which may help center measure "
3261 "on a crater</li></ul"
3262 "<p>Below the left view:</p>"
3263 "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the "
3264 "left view window using the \"Blink Start\" button <img src=\"" +
toolIconDir() +
3265 "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
3266 toolIconDir() +
"/blinkStop.png\" width=22 height=22>. The arrow keys above the left "
3267 "and right views and the keyboard arrow keys may be used to move the both views while "
3269 "<li><strong>Register:</strong> Sub-pixel register the right view to "
3270 "the left view. A default registration template is used for setting parameters "
3271 "passed to the sub-pixel registration tool. The user may load in a predefined "
3272 "template or edit the current loaded template to influence successful "
3273 "co-registration results. For more information regarding the pattern matching "
3274 "functionlity or how to create a parameter template, refer to the Isis PatternMatch "
3275 "document and the <i>autoregtemplate</i> application. <strong>Shortcut: R.</strong>"
3277 "<li><strong>Save Measures:</strong> Save the two control measures using the sample, "
3278 "line positions under the crosshairs. <strong>Shortcut: M.</strong></li>"
3279 "<li><strong>Save Point:</strong> Save the control point to the control network. "
3280 "<strong>Shortcut: P.</strong></li>"
3282 controlPointEditing->setWordWrap(
true);
3283 controlPointLayout->addWidget(controlPointEditing);
3285 controlPointTab->setWidget(controlPointContainer);
3288 QScrollArea *coregTab =
new QScrollArea;
3289 coregTab->setWidgetResizable(
true);
3290 coregTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3292 QVBoxLayout *coregLayout =
new QVBoxLayout;
3293 coregContainer->setLayout(coregLayout);
3295 QLabel *coregTitle =
new QLabel(
"<h2>Coreg Guidance</h2>");
3296 coregLayout->addWidget(coregTitle);
3298 QLabel *coregDesc =
new QLabel(
"<p>When opening control networks created by <i>coreg</i>, "
3299 "there are some things to keep in mind. First, all control points must have the same "
3300 "reference measure (this is the image filename passed to the <i>coreg</i> 'match' parameter)."
3301 "<p>In order to retain the integrity of the input <i>coreg</i> network, you cannot change "
3302 "which image is the reference measure on any of the existing points. "
3303 "<p>When creating a new control point to add to the <i>coreg</i> network, this tool will "
3304 "automatically set the reference measure to the same image as the other control points in "
3305 "the network as long as the reference image was one of the images selected with "
3306 "the right mouse button from the new point dialog. If this image was not selected when "
3307 "creating a new point, it "
3308 "does not contain a required measurement, therefore, you will get an error and the new "
3309 "point will not be created.</p> <p>The reference measure is always loaded on the left side "
3310 "of the control point editor. If you load a measure that is not the reference measure "
3311 "on the left side and try to save the point, you will receive an error message. You will "
3312 "need to move the reference measure back to the left side before saving the control point."
3313 "</p><p><b>Note:</b> This error checking will not happen on control networks created by "
3314 "<i>coreg</i> prior to Isis3.4.2. For older <i>coreg</i> control networks the user must be "
3315 "aware and make sure the correct image is set to the same <i>coreg</i> reference measure.");
3316 coregDesc->setWordWrap(
true);
3317 coregDesc->setScaledContents(
true);
3318 coregLayout->addWidget(coregDesc);
3320 coregTab->setWidget(coregContainer);
3322 tabArea->addTab(overviewTab,
"&Overview");
3323 tabArea->addTab(quickTab,
"&Quick Start");
3324 tabArea->addTab(controlPointTab,
"&Control Point Editing");
3325 tabArea->addTab(coregTab,
"&Coreg Guidance");
3327 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
3329 buttonsLayout->addStretch();
3331 QPushButton *closeButton =
new QPushButton(
"&Close");
3332 closeButton->setIcon(QPixmap(
toolIconDir() +
"/guiStop.png"));
3333 closeButton->setDefault(
true);
3334 connect(closeButton, SIGNAL(clicked()),
3335 helpDialog, SLOT(close()));
3336 buttonsLayout->addWidget(closeButton);
3338 mainLayout->addLayout(buttonsLayout);
3357 if ( m_controlNet->GetNumPoints() == 0 ||
3358 !m_controlNet->ContainsPoint(m_editPoint->
GetId())) {
3359 QString message =
"\n\nDo you want to save the point in the editor?";
3360 int response = QMessageBox::question(m_matchTool,
"Save point in editor", message,
3361 QMessageBox::Yes | QMessageBox::No,
3363 if (response == QMessageBox::Yes) {
3369 if (m_controlNet && m_controlNet->GetNumPoints() != 0 && m_netChanged) {
3370 QString message =
"The currently open control net has changed. Do you want to save?";
3371 int response = QMessageBox::question(m_matchTool,
"Save current control net?",
3373 QMessageBox::Yes | QMessageBox::No,
3376 if (response == QMessageBox::Yes) {
Status SetType(MeasureType type)
Set how the coordinate was obtained.
Cube display widget for certain Isis MDI applications.
void Delete(const QString &sn)
Remove the specified serial number from the list.
const double Null
Value for an Isis Null pixel.
void Add(ControlMeasure *measure)
Add a measurement to the control point, taking ownership of the measure in the process.
(e.g., autoseed, interest) AKA predicted, unmeasured, unverified
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
File name manipulation and expansion.
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
double GetResidualMagnitude() const
Return Residual magnitude.
Status SetIgnored(bool newIgnoreStatus)
Set whether to ignore or use control point.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
double GetNumericalValue() const
Get the value associated with this log data.
Status SetChooserName(QString name)
Set the point's chooser name.
void saveChips()
Slot to save registration chips to files and fire off qview.
Widget to display Isis cubes for qt apps.
Registered to whole pixel (e.g.,pointreg)
Registered to sub-pixel (e.g., pointreg)
This error is for when a programmer made an API call that was illegal.
Status SetEditLock(bool editLock)
Set the EditLock state.
const ControlMeasure * GetRefMeasure() const
Get the reference control measure.
QString GetReferenceSN() const
const char * what() const
Returns a string representation of this exception in its current state.
A Free point is a Control Point that identifies common measurements between two or more cubes...
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
bool HasSerialNumber(QString serialNumber) const
Return true if given serial number exists in point.
QString fileName(const QString &sn)
Return a filename given a serial number.
This was called the Qisis MainWindow.
void setRightMeasure(ControlMeasure *rightMeasure, Cube *rightCube, QString pointId)
Set the measure displayed in the right ChipViewport.
Cube * cube() const
Return the cube associated with viewport.
bool setTemplateFile(QString)
Allows user to choose a new template file by opening a window from which to select a filename...
QString GetId() const
Return the Id of the control point.
Hand Measured (e.g., qnet)
#define _FILEINFO_
Macro for the filename and line number.
Status SetRefMeasure(ControlMeasure *cm)
Set the point's reference measure.
void open(const QString &cfile, QString access="r")
This method will open an isis cube for reading or reading/writing.
void viewportToCube(int x, int y, double &sample, double &line) const
Convert a viewport x/y to a cube sample/line (may be outside the cube)
Container for cube-like labels.
bool IsReferenceExplicit() const
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
Status SetType(PointType newType)
Updates the control point's type.
Status SetId(QString id)
Sets the Id of the control point.
Status
This is a return status for many of the mutating (setter) method calls.
GoodnessOfFit is pointreg information for reference measures.
void cubeToViewport(double sample, double line, int &x, int &y) const
Convert a cube sample/line to a viewport x/y (may be outside the viewport)
QString toString() const
Returns a string representation of this exception.
static QString UserName()
Returns the user name.
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
PvlEditDialog creates a QDialog window in which a QTextEdit box displays the contents of a pvl file...
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
Status SetCubeSerialNumber(QString newSerialNumber)
Set cube serial number.
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
QString fileName() const
Returns the opened cube's filename.
int Delete(ControlMeasure *measure)
Remove a measurement from the control point, deleting reference measure is allowed.
Status SetDateTime()
Date Time - Creation Time.
Serial Number list generator.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube's serial number.
int IndexOfRefMeasure() const
static QString MeasureTypeToString(MeasureType type)
Return the String Control Measure type.
void setLeftMeasure(ControlMeasure *leftMeasure, Cube *leftCube, QString pointId)
Set the measure displayed in the left ChipViewport.
This is returned when the operation requires Edit Lock to be false but it is currently true...
IO Handler for Isis Cubes.