13 #include <QMessageBox>
17 #include <QTableWidget>
18 #include <QTableWidgetItem>
22 #include "Application.h"
23 #include "ControlMeasure.h"
24 #include "ControlMeasureLogData.h"
25 #include "ControlNet.h"
26 #include "ControlPoint.h"
27 #include "ControlPointEdit.h"
29 #include "IException.h"
30 #include "MainWindow.h"
31 #include "MatchToolDeletePointDialog.h"
32 #include "MatchToolNewPointDialog.h"
33 #include "MdiCubeViewport.h"
36 #include "PvlEditDialog.h"
37 #include "SerialNumber.h"
38 #include "SerialNumberList.h"
39 #include "SpecialPixel.h"
41 #include "ViewportMainWindow.h"
42 #include "Workspace.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();
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());
1402 QString fn = QFileDialog::getSaveFileName(m_matchTool,
1403 "Choose filename to save under",
1405 "Control Files (*.net)");
1410 m_controlNet->Write(fn);
1411 m_netChanged =
false;
1414 QMessageBox::critical(m_matchTool, tr(
"Error Writing Control Net"), e.
what());
1417 m_cnetFileName = fn;
1418 m_matchTool->setWindowTitle(
"Match Tool - Control Network File: " + m_cnetFileName);
1419 m_cnetFileNameLabel->setText(
"Control Network: " + m_cnetFileName);
1459 if (mvp == NULL)
return;
1467 if (s == Qt::LeftButton) {
1469 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1470 QString message =
"No points exist for editing. Create points ";
1471 message +=
"using the right mouse button.";
1472 QMessageBox::warning(m_matchTool,
"Warning", message);
1480 point = m_controlNet->FindClosest(sn, samp, line);
1483 QString message =
"Cannot find point for editing.";
1485 QMessageBox::warning(m_matchTool,
"Warning", message);
1491 else if (s == Qt::MidButton) {
1492 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1493 QString message =
"No points exist for deleting. Create points ";
1494 message +=
"using the right mouse button.";
1495 QMessageBox::warning(m_matchTool,
"Warning", message);
1500 ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
1502 if (point == NULL) {
1503 QString message =
"No points exist for deleting. Create points ";
1504 message +=
"using the right mouse button.";
1505 QMessageBox::warning(m_matchTool,
"Warning", message);
1511 else if (s == Qt::RightButton) {
1512 if (m_newPointDialog) {
1513 addMeasure(mvp, samp, line);
1521 QString message =
"Cannot create control point.\n\n";
1523 QMessageBox::critical(m_matchTool,
"Error", message);
1536 for (
int i=0; i<point->GetNumMeasures(); i++) {
1542 return missingCubes;
1556 connect(m_newPointDialog, SIGNAL(measuresFinished()),
this, SLOT(doneWithMeasures()));
1557 connect(m_newPointDialog, SIGNAL(newPointCanceled()),
this, SLOT(cancelNewPoint()));
1562 images<<cubeFile.
name();
1564 m_newPointDialog->
setFiles(images);
1565 m_newPointDialog->show();
1569 m_newPointDialog->highlightFile(current);
1588 void MatchTool::addMeasure(
MdiCubeViewport *cvp,
double sample,
double line) {
1592 m_newPointDialog->highlightFile(current);
1593 m_newPointDialog->raise();
1613 void MatchTool::doneWithMeasures() {
1615 m_lastUsedPointId = m_newPointDialog->pointId();
1616 m_newPoint->
SetId(m_lastUsedPointId);
1627 QString message =
"This is a coreg network which needs the cube with serial number " +
1628 m_coregReferenceSN +
" as the reference measure. This new control point does "
1629 "not have a measure for that serial number, so this point cannot be created until "
1630 "the cube listed above is added (Right-click on cube).";
1631 QMessageBox::critical(m_matchTool,
"Error", message);
1632 m_newPointDialog->show();
1640 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1644 m_editPoint = m_newPoint;
1647 delete m_newPointDialog;
1648 m_newPointDialog = NULL;
1652 m_matchTool->setVisible(
true);
1653 m_matchTool->raise();
1655 emit editPointChanged();
1661 void MatchTool::cancelNewPoint() {
1663 delete m_newPointDialog;
1664 m_newPointDialog = NULL;
1696 if (mCubes.size() > 0) {
1697 QString msgTitle =
"Missing Cubes";
1698 QString message =
"This point is missing cubes for the following measures and cannot be ";
1699 message +=
"loaded into the editor. Do you still want to delete this point?\n\n";
1700 for (
int i=0; i<mCubes.size(); i++) {
1701 message += mCubes.at(i) +
"\n";
1703 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1705 QPushButton *yesButton = msgBox.addButton(
"Yes", QMessageBox::AcceptRole);
1706 QPushButton *noButton = msgBox.addButton(
"No", QMessageBox::RejectRole);
1707 msgBox.setDefaultButton(yesButton);
1709 if (msgBox.clickedButton() == noButton) {
1713 m_matchTool->setVisible(
false);
1720 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1725 *m_editPoint = *point;
1728 if (mCubes.size() == 0) {
1734 emit editPointChanged();
1737 MatchToolDeletePointDialog *deletePointDialog =
new MatchToolDeletePointDialog;
1738 QString CPId = m_editPoint->
GetId();
1739 deletePointDialog->pointIdValue->setText(CPId);
1741 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1750 deletePointDialog->fileList->addItem(file);
1753 if (deletePointDialog->exec()) {
1755 int numDeleted = deletePointDialog->fileList->selectedItems().count();
1758 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1759 numDeleted == m_editPoint->GetNumMeasures()) {
1762 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1763 QString message =
"You have selected all measures in this point to be deleted. This "
1764 "control point will be deleted. Do you want to delete this control point?";
1765 int response = QMessageBox::question(m_matchTool,
1766 "Delete control point", message,
1767 QMessageBox::Yes | QMessageBox::No,
1770 if (response == QMessageBox::No) {
1775 m_matchTool->setVisible(
false);
1778 QMessageBox::information(m_matchTool,
"EditLocked Point",
1779 "This point is EditLocked and cannot be deleted.");
1782 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1791 int lockedMeasures = 0;
1792 for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
1793 QListWidgetItem *item = deletePointDialog->fileList->item(i);
1794 if (!deletePointDialog->fileList->isItemSelected(item))
continue;
1799 (*m_editPoint)[i]->GetCubeSerialNumber())) {
1800 QString message =
"You are trying to delete the Reference measure."
1801 " Do you really want to delete the Reference measure?";
1802 switch (QMessageBox::question(m_matchTool,
1803 "Delete Reference measure?", message,
1804 "&Yes",
"&No", 0, 0)) {
1812 if (numDeleted == 1) {
1819 if (m_editPoint->
Delete(i) == ControlMeasure::MeasureLocked) {
1824 if (lockedMeasures > 0) {
1825 QMessageBox::information(m_matchTool,
"EditLocked Measures",
1826 QString::number(lockedMeasures) +
" / "
1828 deletePointDialog->fileList->selectedItems().size()) +
1829 " measures are EditLocked and were not deleted.");
1832 if (mCubes.size() == 0) {
1834 m_matchTool->setVisible(
true);
1835 m_matchTool->raise();
1838 m_pointEditor->templateFileName());
1846 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1855 m_netChanged =
true;
1860 emit editPointChanged();
1877 if (point->GetNumMeasures() == 0) {
1878 QString message =
"This point has no measures.";
1879 QMessageBox::warning(m_matchTool,
"Warning", message);
1880 emit editPointChanged();
1886 if (mCubes.size() > 0) {
1887 QString msgTitle =
"Missing Cubes";
1888 QString message =
"This point is missing cubes and cannot be loaded into the editor. Open ";
1889 message +=
"the cubes for the following measures before selecting this point.\n\n";
1890 for (
int i=0; i<mCubes.size(); i++) {
1891 message += mCubes.at(i) +
"\n";
1893 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1901 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1906 *m_editPoint = *point;
1909 m_matchTool->setVisible(
true);
1910 m_matchTool->raise();
1912 m_pointEditor->templateFileName());
1915 emit editPointChanged();
1918 m_savePoint->setPalette(m_saveDefaultPalette);
1943 QString CPId = m_editPoint->
GetId();
1944 QString ptId(
"Point ID: ");
1945 ptId += (QString) CPId;
1946 m_ptIdValue->setText(ptId);
1949 QString ptsize =
"Number of Measures: " +
1950 QString::number(m_editPoint->GetNumMeasures());
1951 m_numMeasures->setText(ptsize);
1954 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
1957 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1960 m_leftCombo->clear();
1961 m_rightCombo->clear();
1962 m_pointFiles.clear();
1965 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1970 m_leftCombo->addItem(tempFileName);
1971 m_rightCombo->addItem(tempFileName);
1974 m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1975 m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1994 if (!m_leftFile.isEmpty()) {
1995 leftIndex = m_leftCombo->findText(
FileName(m_leftFile).name());
1997 if (leftIndex < 0 ) leftIndex = 0;
2002 if (leftIndex == 0) {
2011 if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
2012 m_rightCombo->setCurrentIndex(rightIndex);
2013 m_leftCombo->setCurrentIndex(leftIndex);
2031 if (m_measureWindow == NULL) {
2033 m_measureTable =
new QTableWidget();
2034 m_measureTable->setMinimumWidth(1600);
2035 m_measureTable->setAlternatingRowColors(
true);
2036 m_measureWindow->setCentralWidget(m_measureTable);
2039 m_measureTable->clear();
2040 m_measureTable->setSortingEnabled(
false);
2042 m_measureTable->setRowCount(m_editPoint->GetNumMeasures());
2043 m_measureTable->setColumnCount(NUMCOLUMNS);
2046 for (
int i=0; i<NUMCOLUMNS; i++) {
2047 labels<<measureColumnToString((MeasureColumns)i);
2049 m_measureTable->setHorizontalHeaderLabels(labels);
2052 for (
int row=0; row<m_editPoint->GetNumMeasures(); row++) {
2057 QTableWidgetItem *tableItem =
new QTableWidgetItem(QString(file));
2058 m_measureTable->setItem(row,column++,tableItem);
2061 m_measureTable->setItem(row,column++,tableItem);
2063 tableItem =
new QTableWidgetItem();
2064 tableItem->setData(0,m.GetSample());
2065 m_measureTable->setItem(row,column++,tableItem);
2067 tableItem =
new QTableWidgetItem();
2068 tableItem->setData(0,m.GetLine());
2069 m_measureTable->setItem(row,column++,tableItem);
2071 if (m.GetAprioriSample() ==
Null) {
2072 tableItem =
new QTableWidgetItem(
"Null");
2075 tableItem =
new QTableWidgetItem();
2076 tableItem->setData(0,m.GetAprioriSample());
2078 m_measureTable->setItem(row,column++,tableItem);
2080 if (m.GetAprioriLine() ==
Null) {
2081 tableItem =
new QTableWidgetItem(
"Null");
2084 tableItem =
new QTableWidgetItem();
2085 tableItem->setData(0,m.GetAprioriLine());
2087 m_measureTable->setItem(row,column++,tableItem);
2089 if (m.GetSampleResidual() ==
Null) {
2090 tableItem =
new QTableWidgetItem(QString(
"Null"));
2093 tableItem =
new QTableWidgetItem();
2094 tableItem->setData(0,m.GetSampleResidual());
2096 m_measureTable->setItem(row,column++,tableItem);
2098 if (m.GetLineResidual() ==
Null) {
2099 tableItem =
new QTableWidgetItem(QString(
"Null"));
2102 tableItem =
new QTableWidgetItem();
2103 tableItem->setData(0,m.GetLineResidual());
2105 m_measureTable->setItem(row,column++,tableItem);
2108 tableItem =
new QTableWidgetItem(QString(
"Null"));
2111 tableItem =
new QTableWidgetItem();
2114 m_measureTable->setItem(row,column++,tableItem);
2116 double sampleShift = m.GetSampleShift();
2117 if (sampleShift ==
Null) {
2118 tableItem =
new QTableWidgetItem(QString(
"Null"));
2121 tableItem =
new QTableWidgetItem();
2122 tableItem->setData(0,sampleShift);
2124 m_measureTable->setItem(row,column++,tableItem);
2126 double lineShift = m.GetLineShift();
2127 if (lineShift ==
Null) {
2128 tableItem =
new QTableWidgetItem(QString(
"Null"));
2131 tableItem =
new QTableWidgetItem();
2132 tableItem->setData(0,lineShift);
2134 m_measureTable->setItem(row,column++,tableItem);
2136 double pixelShift = m.GetPixelShift();
2137 if (pixelShift ==
Null) {
2138 tableItem =
new QTableWidgetItem(QString(
"Null"));
2141 tableItem =
new QTableWidgetItem();
2142 tableItem->setData(0,pixelShift);
2144 m_measureTable->setItem(row,column++,tableItem);
2146 double goodnessOfFit = m.GetLogData(
2148 if (goodnessOfFit ==
Null) {
2149 tableItem =
new QTableWidgetItem(QString(
"Null"));
2152 tableItem =
new QTableWidgetItem();
2153 tableItem->setData(0,goodnessOfFit);
2155 m_measureTable->setItem(row,column++,tableItem);
2157 if (m.IsIgnored()) tableItem =
new QTableWidgetItem(
"True");
2158 if (!m.IsIgnored()) tableItem =
new QTableWidgetItem(
"False");
2159 m_measureTable->setItem(row,column++,tableItem);
2162 tableItem =
new QTableWidgetItem(
"True");
2164 tableItem =
new QTableWidgetItem(
"False");
2165 m_measureTable->setItem(row,column++,tableItem);
2167 tableItem =
new QTableWidgetItem(
2169 m_measureTable->setItem(row,column,tableItem);
2177 for (
int col=0; col<m_measureTable->columnCount(); col++)
2178 m_measureTable->item(row, col)->setFont(font);
2183 m_measureTable->resizeColumnsToContents();
2184 m_measureTable->resizeRowsToContents();
2185 m_measureTable->setSortingEnabled(
true);
2186 m_measureWindow->show();
2191 QString MatchTool::measureColumnToString(MatchTool::MeasureColumns column) {
2201 case SAMPLERESIDUAL:
2202 return "Sample Residual";
2204 return "Line Residual";
2205 case RESIDUALMAGNITUDE:
2206 return "Residual Magnitude";
2208 return "Sample Shift";
2210 return "Line Shift";
2212 return "Pixel Shift";
2214 return "Goodness of Fit";
2220 return "Measure Type";
2222 return "Apriori Sample";
2224 return "Apriori Line";
2227 "Invalid measure column passed to measureColumnToString", _FILEINFO_);
2242 int curIndex = m_rightCombo->currentIndex();
2243 if (curIndex < m_rightCombo->count() - 1) {
2245 m_rightCombo->setCurrentIndex(curIndex + 1);
2261 int curIndex = m_rightCombo->currentIndex();
2264 m_rightCombo->setCurrentIndex(curIndex - 1);
2285 QString file = m_pointFiles[index];
2292 QString message =
"Make sure the correct cube is opened.\n\n";
2294 QMessageBox::critical(m_matchTool,
"Error", message);
2299 int i = m_leftCombo->findText(
FileName(file).name());
2301 m_leftCombo->setCurrentIndex(i);
2307 if (m_leftMeasure != NULL) {
2308 delete m_leftMeasure;
2309 m_leftMeasure = NULL;
2313 *m_leftMeasure = *((*m_editPoint)[serial]);
2316 if (m_leftCube != NULL)
delete m_leftCube;
2317 m_leftCube =
new Cube();
2318 m_leftCube->
open(file);
2322 m_editPoint->
GetId());
2341 QString file = m_pointFiles[index];
2348 QString message =
"Make sure the correct cube is opened.\n\n";
2350 QMessageBox::critical(m_matchTool,
"Error", message);
2355 int i = m_rightCombo->findText(
FileName(file).name());
2357 m_rightCombo->setCurrentIndex(i);
2363 if (m_rightMeasure != NULL) {
2364 delete m_rightMeasure;
2365 m_rightMeasure = NULL;
2369 *m_rightMeasure = *((*m_editPoint)[serial]);
2372 if (m_rightCube != NULL)
delete m_rightCube;
2373 m_rightCube =
new Cube();
2374 m_rightCube->
open(file);
2378 m_editPoint->
GetId());
2407 m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
2409 QString s =
"Reference: ";
2417 m_leftReference->setText(s);
2419 s =
"Measure Type: ";
2424 m_leftMeasureType->setText(s);
2426 if (m_leftMeasure->GetSampleShift() ==
Null) {
2427 s =
"Sample Shift: Null";
2430 s =
"Sample Shift: " + QString::number(m_leftMeasure->GetSampleShift());
2432 m_leftSampShift->setText(s);
2434 if (m_leftMeasure->GetLineShift() ==
Null) {
2435 s =
"Line Shift: Null";
2438 s =
"Line Shift: " + QString::number(m_leftMeasure->GetLineShift());
2440 m_leftLineShift->setText(s);
2442 double goodnessOfFit = m_leftMeasure->GetLogData(
2444 if (goodnessOfFit ==
Null) {
2445 s =
"Goodness of Fit: Null";
2448 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2450 m_leftGoodness->setText(s);
2480 m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
2482 QString s =
"Reference: ";
2491 m_rightReference->setText(s);
2493 s =
"Measure Type: ";
2498 m_rightMeasureType->setText(s);
2500 if (m_rightMeasure->GetSampleShift() ==
Null) {
2501 s =
"Sample Shift: Null";
2504 s =
"Sample Shift: " + QString::number(m_rightMeasure->GetSampleShift());
2506 m_rightSampShift->setText(s);
2508 if (m_rightMeasure->GetLineShift() ==
Null) {
2509 s =
"Line Shift: Null";
2512 s =
"Line Shift: " + QString::number(m_rightMeasure->GetLineShift());
2514 m_rightLineShift->setText(s);
2516 double goodnessOfFit = m_rightMeasure->GetLogData(
2518 if (goodnessOfFit ==
Null) {
2519 s =
"Goodness of Fit: Null";
2522 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2524 m_rightGoodness->setText(s);
2541 if(e->type() != QEvent::Leave)
return false;
2542 if(o == m_leftCombo->view()) {
2544 m_leftCombo->hidePopup();
2546 if (o == m_rightCombo->view()) {
2548 m_rightCombo->hidePopup();
2588 mvp->viewport()->update();
2617 if ( (m_controlNet == NULL || m_controlNet->GetNumPoints() == 0) && m_newPoint == NULL &&
2618 m_editPoint == NULL)
2621 QString sn = serialNumber(mvp);
2625 if (m_newPoint != NULL) {
2629 double samp = (*m_newPoint)[sn]->GetSample();
2630 double line = (*m_newPoint)[sn]->GetLine();
2634 QBrush brush(Qt::red);
2638 painter->setPen(pen);
2639 painter->drawLine(x - 5, y, x + 5, y);
2640 painter->drawLine(x, y - 5, x, y + 5);
2645 if (!m_controlNet->GetCubeSerials().contains(
2653 m_controlNet->GetMeasuresInCube(sn);
2655 for (
int i = 0; i < measures.count(); i++) {
2658 double samp = m->GetSample();
2659 double line = m->GetLine();
2663 if (m->Parent()->IsIgnored()) {
2664 painter->setPen(QColor(255, 255, 0));
2667 else if (m->IsIgnored()) {
2668 painter->setPen(QColor(255, 255, 0));
2671 painter->setPen(Qt::green);
2674 painter->drawLine(x - 5, y, x + 5, y);
2675 painter->drawLine(x, y - 5, x, y + 5);
2678 if (m_editPoint != NULL && m_newPoint == NULL) {
2682 double samp = (*m_editPoint)[sn]->GetSample();
2683 double line = (*m_editPoint)[sn]->GetLine();
2687 QBrush brush(Qt::red);
2691 painter->setPen(pen);
2692 painter->drawLine(x - 5, y, x + 5, y);
2693 painter->drawLine(x, y - 5, x, y + 5);
2715 if (m_templateModified) {
2716 int r = QMessageBox::warning(m_matchTool, tr(
"OK to continue?"),
2717 tr(
"The currently opened registration template has been modified.\n"
2719 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2722 if (r == QMessageBox::Yes)
2724 else if (r == QMessageBox::Cancel)
2743 QString filename = QFileDialog::getOpenFileName(m_matchTool,
2744 "Select a registration template",
".",
2745 "Registration template files (*.def *.pvl);;All files (*)");
2747 if (filename.isEmpty())
2764 QFile file(
FileName((QString) fn).expanded());
2765 if (!file.open(QIODevice::ReadOnly)) {
2766 QString msg =
"Failed to open template file \"" + fn +
"\"";
2767 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2771 QTextStream stream(&file);
2772 m_templateEditor->setText(stream.readAll());
2775 QScrollBar * sb = m_templateEditor->verticalScrollBar();
2776 sb->setValue(sb->minimum());
2778 m_templateModified =
false;
2779 m_saveTemplateFile->setEnabled(
false);
2780 m_templateFileNameLabel->setText(
"Template File: " + fn);
2787 m_templateModified =
true;
2788 m_saveTemplateFile->setEnabled(
true);
2796 if (!m_templateModified)
2800 m_pointEditor->templateFileName();
2810 QString filename = QFileDialog::getSaveFileName(m_matchTool,
2811 "Save registration template",
".",
2812 "Registration template files (*.def *.pvl);;All files (*)");
2814 if (filename.isEmpty())
2829 QString contents = m_templateEditor->toPlainText();
2840 QMessageBox::warning(m_matchTool,
"Error", message);
2844 QString expandedFileName(
2845 FileName((QString) fn).expanded());
2847 QFile file(expandedFileName);
2849 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2850 QString msg =
"Failed to save template file to \"" + fn +
"\"\nDo you "
2852 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2857 QTextStream stream(&file);
2862 m_templateModified =
false;
2863 m_saveTemplateFile->setEnabled(
false);
2864 m_templateFileNameLabel->setText(
"Template File: " + fn);
2886 Pvl templatePvl(m_pointEditor->templateFileName());
2890 registrationDialog.setWindowTitle(
"View or Edit Template File: "
2892 registrationDialog.resize(550,360);
2893 registrationDialog.exec();
2897 QMessageBox::information(m_matchTool,
"Error", message);
2915 void MatchTool::showHideTemplateEditor() {
2917 if (!m_templateEditorWidget)
2920 m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
2938 if (m_editPoint == NULL)
return;
2939 if (pointId != m_editPoint->
GetId())
return;
2944 ControlPoint *updatedPoint = m_controlNet->GetPoint(pointId);
2945 m_editPoint->
SetEditLock(updatedPoint->IsEditLocked());
2946 m_editPoint->
SetIgnored(updatedPoint->IsIgnored());
2949 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
2952 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
2977 if (m_editPoint != NULL) {
2979 QString
id = m_ptIdValue->text().remove(
"Point ID: ");
2980 m_controlNet->GetPoint(
id);
2985 emit editPointChanged();
3003 QColor qc = Qt::red;
3004 QPalette p = m_savePoint->palette();
3005 p.setColor(QPalette::ButtonText,qc);
3006 m_savePoint->setPalette(p);
3026 if (m_editPoint == NULL)
return false;
3048 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
3049 QSettings settings(config.
expanded(),
3050 QSettings::NativeFormat);
3051 QPoint pos = settings.value(
"pos", QPoint(300, 100)).toPoint();
3052 QSize size = settings.value(
"size", QSize(900, 500)).toSize();
3053 m_matchTool->resize(size);
3054 m_matchTool->move(pos);
3067 if (!m_matchTool->isVisible())
return;
3068 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
3069 QSettings settings(config.
expanded(),
3070 QSettings::NativeFormat);
3071 settings.setValue(
"pos", m_matchTool->pos());
3072 settings.setValue(
"size", m_matchTool->size());
3077 void MatchTool::enterWhatsThisMode() {
3078 QWhatsThis::enterWhatsThisMode();
3082 void MatchTool::clearEditPoint() {
3088 void MatchTool::showHelp() {
3091 helpDialog->setWindowTitle(
"Match Tool Help");
3093 QVBoxLayout *mainLayout =
new QVBoxLayout;
3094 helpDialog->setLayout(mainLayout);
3096 QLabel *matchTitle =
new QLabel(
"<h2>Match Tool</h2>");
3097 mainLayout->addWidget(matchTitle);
3099 QLabel *matchSubtitle =
new QLabel(
"A tool for interactively measuring and editing sample/line "
3100 "registration points between cubes. These "
3101 "points contain sample, line postions only, no latitude or "
3102 "longitude values are used or recorded.");
3103 matchSubtitle->setWordWrap(
true);
3104 mainLayout->addWidget(matchSubtitle);
3106 QTabWidget *tabArea =
new QTabWidget;
3107 tabArea->setDocumentMode(
true);
3108 mainLayout->addWidget(tabArea);
3111 QScrollArea *overviewTab =
new QScrollArea;
3112 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3113 overviewTab->setWidgetResizable(
true);
3115 QVBoxLayout *overviewLayout =
new QVBoxLayout;
3116 overviewContainer->setLayout(overviewLayout);
3118 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
3119 overviewLayout->addWidget(purposeTitle);
3121 QLabel *purposeText =
new QLabel(
"<p>This tool is for recording and editing registration "
3122 "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The "
3123 "recorded registration points are sample and line pixel coordinates only. Therefore, this "
3124 "tool can be used on any images including ones that do not contain a camera model "
3125 "(i.e, The existence of the Isis Instrument Group on the image labels is not required). "
3126 "This also means that the tool differs from the <i>qnet</i> control point network "
3127 "application in that no latitude or longitude values are ever used or recorded "
3128 "(regardless if the image has a camera model in Isis).</p>"
3129 "<p>The output control point network that this tool generates is primarily used 1) as "
3130 "input for an image-wide sample/line translation to register one image to another by "
3131 "'moving' pixel locations - refer to the documentation for applications such as "
3132 "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded "
3133 "measurements in other spreadsheet or plotting packages to visualize magnitude "
3134 "and direction of varying translations of the images relative to one another.</p> "
3135 "<p>An automated version of this match tool is the <i>coreg</i> application. This tool "
3136 "can be used to visually evaluate and edit the control point network created by "
3137 "<i>coreg</i>.</p> "
3138 "<p>The format of the output point network file is binary. This tool uses the Isis control "
3139 " network framework to create, co-register and save all control points and pixel "
3140 "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to "
3141 "a readable PVL format."
3142 "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> "
3143 "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>"
3144 "<p>Control Points are drawn on the associated displayed cubes with the following colors: "
3145 "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
3146 purposeText->setWordWrap(
true);
3147 overviewLayout->addWidget(purposeText);
3149 overviewTab->setWidget(overviewContainer);
3152 QScrollArea *quickTab =
new QScrollArea;
3153 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3154 quickTab->setWidgetResizable(
true);
3156 QVBoxLayout *quickLayout =
new QVBoxLayout;
3157 quickContainer->setLayout(quickLayout);
3159 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
3160 quickLayout->addWidget(quickTitle);
3162 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
3163 quickLayout->addWidget(quickSubTitle);
3165 QLabel *quickPrep =
new QLabel(
"<p><ul>"
3166 "<li>Open the cubes with overlapping areas for choosing control points</li>"
3167 "<li>Choose the match tool <img src=\"" +
toolIconDir() +
3168 "/stock_draw-connector-with-arrows.png\" width=22 height=22> "
3169 "from the toolpad on the right side of the <i>qview</i> main window</li>");
3170 quickPrep->setWordWrap(
true);
3171 quickLayout->addWidget(quickPrep);
3173 QLabel *morePrep =
new QLabel(
"<p>Once the Match tool is activated the tool bar at the top "
3174 "of the main window contains file action buttons and a help button:");
3175 morePrep->setWordWrap(
true);
3176 quickLayout->addWidget(morePrep);
3178 QLabel *fileButtons =
new QLabel(
"<p><ul>"
3179 "<li><img src=\"" +
toolIconDir() +
"/fileopen.png\" width=22 height=22> Open an existing "
3180 "control network <b>Note:</b> If you do not open an existing network, a new one will "
3182 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSaveAs.png\" width=22 height=22> Save "
3183 "control network as ...</li>"
3184 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSave.png\" width=22 height=22> Save "
3185 "control network to current file</li>"
3186 "<li><img src=\"" +
toolIconDir() +
"/help-contents.png\" width=22 height=22> Show Help "
3188 fileButtons->setWordWrap(
true);
3189 quickLayout->addWidget(fileButtons);
3191 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
3192 quickLayout->addWidget(quickFunctionTitle);
3194 QLabel *quickFunction =
new QLabel(
3195 "The match tool window will be shown once "
3196 "you click in a cube viewport window using one of the following "
3197 "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
3198 quickFunction->setWordWrap(
true);
3199 quickLayout->addWidget(quickFunction);
3201 QLabel *quickDesc =
new QLabel(
"<p><ul>"
3202 "<li>Left Click - Modify the control point closest to the click <b>Note:</b> "
3203 "All cubes in the control point must be displayed before loading the point</li>"
3204 "<li>Middle Click - Delete the control point closest to the click</li>"
3205 "<li>Right Click - Create a new control point at the click location</li></ul></p>");
3206 quickDesc->setWordWrap(
true);
3207 quickDesc->setOpenExternalLinks(
true);
3208 quickLayout->addWidget(quickDesc);
3210 quickTab->setWidget(quickContainer);
3213 QScrollArea *controlPointTab =
new QScrollArea;
3214 controlPointTab->setWidgetResizable(
true);
3215 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3217 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
3218 controlPointContainer->setLayout(controlPointLayout);
3220 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
3221 controlPointLayout->addWidget(controlPointTitle);
3223 QLabel *mouseLabel =
new QLabel(
"<p><h3>When the \"Match\" tool "
3224 "is activated, the mouse buttons have the following function in the "
3225 "cube viewports of the main qview window:</h3>");
3226 mouseLabel->setWordWrap(
true);
3227 mouseLabel->setScaledContents(
true);
3228 controlPointLayout->addWidget(mouseLabel);
3230 QLabel *controlPointDesc =
new QLabel(
"<ul>"
3231 "<li>Left click - Edit the closest control point <b>Note:</b> "
3232 "All cubes in the control point must be displayed before loading the point</li>"
3233 "<li>Middle click - Delete the closest control point</li>"
3234 "<li>Right click - Create new control point at cursor location. This will bring up a new "
3235 "point dialog which allows you to enter a point id and will list all cube viewports, "
3236 "highlighting cubes where the point has been chosen by clicking on the cube's viewport. "
3237 "When the desired cubes have been chosen, select the \"Done\" button which will load the "
3238 "control point into the control point editor window which will allow the control measure "
3239 "positions to be refined.</li>");
3240 controlPointDesc->setWordWrap(
true);
3241 controlPointLayout->addWidget(controlPointDesc);
3243 QLabel *controlPointEditing =
new QLabel(
3244 "<h4>Changing Control Measure Locations</h4>"
3245 "<p>Both the left and right control measure positions can be adjusted by:"
3247 "<li>Move the cursor location under the crosshair by clicking the left mouse "
3249 "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
3250 "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>"
3252 "<h4>Other Point Editor Functions</h4>"
3253 "<p>Along the right border of the window:</p>"
3255 "<li><strong>Link Zoom</strong> This will link the two small viewports together when "
3256 "zooming (ie. If this is checked, if the left view is zoomed, the right view will "
3257 "match the left view's zoom factor. "
3258 "<b>Note:</b> Zooming is controlled from the left view.</li>"
3259 "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to "
3260 "its original orientation</li>"
3261 "<li><strong>Rotate:</strong> Rotate the right view using either the dial "
3262 "or entering degrees </li>"
3263 "<li><strong>Show control points:</strong> Draw crosshairs at all control "
3264 "point locations visible within the view</li>"
3265 "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire "
3267 "<li><strong>Circle:</strong> Draw circle which may help center measure "
3268 "on a crater</li></ul"
3269 "<p>Below the left view:</p>"
3270 "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the "
3271 "left view window using the \"Blink Start\" button <img src=\"" +
toolIconDir() +
3272 "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
3273 toolIconDir() +
"/blinkStop.png\" width=22 height=22>. The arrow keys above the left "
3274 "and right views and the keyboard arrow keys may be used to move the both views while "
3276 "<li><strong>Register:</strong> Sub-pixel register the right view to "
3277 "the left view. A default registration template is used for setting parameters "
3278 "passed to the sub-pixel registration tool. The user may load in a predefined "
3279 "template or edit the current loaded template to influence successful "
3280 "co-registration results. For more information regarding the pattern matching "
3281 "functionlity or how to create a parameter template, refer to the Isis PatternMatch "
3282 "document and the <i>autoregtemplate</i> application. <strong>Shortcut: R.</strong>"
3284 "<li><strong>Save Measures:</strong> Save the two control measures using the sample, "
3285 "line positions under the crosshairs. <strong>Shortcut: M.</strong></li>"
3286 "<li><strong>Save Point:</strong> Save the control point to the control network. "
3287 "<strong>Shortcut: P.</strong></li>"
3289 controlPointEditing->setWordWrap(
true);
3290 controlPointLayout->addWidget(controlPointEditing);
3292 controlPointTab->setWidget(controlPointContainer);
3295 QScrollArea *coregTab =
new QScrollArea;
3296 coregTab->setWidgetResizable(
true);
3297 coregTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3299 QVBoxLayout *coregLayout =
new QVBoxLayout;
3300 coregContainer->setLayout(coregLayout);
3302 QLabel *coregTitle =
new QLabel(
"<h2>Coreg Guidance</h2>");
3303 coregLayout->addWidget(coregTitle);
3305 QLabel *coregDesc =
new QLabel(
"<p>When opening control networks created by <i>coreg</i>, "
3306 "there are some things to keep in mind. First, all control points must have the same "
3307 "reference measure (this is the image filename passed to the <i>coreg</i> 'match' parameter)."
3308 "<p>In order to retain the integrity of the input <i>coreg</i> network, you cannot change "
3309 "which image is the reference measure on any of the existing points. "
3310 "<p>When creating a new control point to add to the <i>coreg</i> network, this tool will "
3311 "automatically set the reference measure to the same image as the other control points in "
3312 "the network as long as the reference image was one of the images selected with "
3313 "the right mouse button from the new point dialog. If this image was not selected when "
3314 "creating a new point, it "
3315 "does not contain a required measurement, therefore, you will get an error and the new "
3316 "point will not be created.</p> <p>The reference measure is always loaded on the left side "
3317 "of the control point editor. If you load a measure that is not the reference measure "
3318 "on the left side and try to save the point, you will receive an error message. You will "
3319 "need to move the reference measure back to the left side before saving the control point."
3320 "</p><p><b>Note:</b> This error checking will not happen on control networks created by "
3321 "<i>coreg</i> prior to Isis3.4.2. For older <i>coreg</i> control networks the user must be "
3322 "aware and make sure the correct image is set to the same <i>coreg</i> reference measure.");
3323 coregDesc->setWordWrap(
true);
3324 coregDesc->setScaledContents(
true);
3325 coregLayout->addWidget(coregDesc);
3327 coregTab->setWidget(coregContainer);
3329 tabArea->addTab(overviewTab,
"&Overview");
3330 tabArea->addTab(quickTab,
"&Quick Start");
3331 tabArea->addTab(controlPointTab,
"&Control Point Editing");
3332 tabArea->addTab(coregTab,
"&Coreg Guidance");
3334 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
3336 buttonsLayout->addStretch();
3338 QPushButton *closeButton =
new QPushButton(
"&Close");
3339 closeButton->setIcon(QPixmap(
toolIconDir() +
"/guiStop.png"));
3340 closeButton->setDefault(
true);
3341 connect(closeButton, SIGNAL(clicked()),
3342 helpDialog, SLOT(close()));
3343 buttonsLayout->addWidget(closeButton);
3345 mainLayout->addLayout(buttonsLayout);
3364 if ( m_controlNet->GetNumPoints() == 0 ||
3365 !m_controlNet->ContainsPoint(m_editPoint->
GetId())) {
3366 QString message =
"\n\nDo you want to save the point in the editor?";
3367 int response = QMessageBox::question(m_matchTool,
"Save point in editor", message,
3368 QMessageBox::Yes | QMessageBox::No,
3370 if (response == QMessageBox::Yes) {
3376 if (m_controlNet && m_controlNet->GetNumPoints() != 0 && m_netChanged) {
3377 QString message =
"The currently open control net has changed. Do you want to save?";
3378 int response = QMessageBox::question(m_matchTool,
"Save current control net?",
3380 QMessageBox::Yes | QMessageBox::No,
3383 if (response == QMessageBox::Yes) {