15 #include "ControlPointEdit.h"
18 #include "MainWindow.h"
19 #include "MatchToolDeletePointDialog.h"
20 #include "MatchToolNewPointDialog.h"
23 #include "PvlEditDialog.h"
28 #include "ViewportMainWindow.h"
35 const int VIEWSIZE = 301;
36 const int CHIPVIEWPORT_WIDTH = 310;
53 m_newPointDialog = NULL;
67 m_leftReference = NULL;
68 m_leftMeasureType = NULL;
69 m_leftGoodness = NULL;
70 m_rightReference = NULL;
71 m_rightMeasureType = NULL;
72 m_rightGoodness = NULL;
73 m_lockLeftMeasure = NULL;
74 m_ignoreLeftMeasure = NULL;
75 m_lockRightMeasure = NULL;
76 m_ignoreRightMeasure = NULL;
80 m_rightMeasure = NULL;
81 m_templateModified =
false;
82 m_measureWindow = NULL;
83 m_measureTable = NULL;
93 connect(
this, SIGNAL(toolActivated()),
this, SLOT(activateTool()));
99 if (parentMainWindow) {
100 connect(parent, SIGNAL(closeWindow()),
this, SLOT(
exiting()));
108 MatchTool::~MatchTool () {
114 delete m_pointEditor;
115 m_pointEditor = NULL;
116 delete m_newPointDialog;
117 m_newPointDialog = NULL;
120 delete m_leftMeasure;
121 m_leftMeasure = NULL;
122 delete m_rightMeasure;
123 m_rightMeasure = NULL;
158 m_matchTool->setWindowTitle(
"Match Tool");
159 m_matchTool->setObjectName(
"MatchTool");
160 connect(m_matchTool, SIGNAL(destroyed(
QObject *)),
this, SLOT(clearEditPoint()));
169 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
170 m_pointEditor, SIGNAL(newControlNetwork(
ControlNet *)));
174 connect(
this, SIGNAL(measureChanged()),
177 m_savePoint =
new QPushButton (
"Save Point");
178 m_savePoint->setToolTip(
"Save the edit control point to the control "
180 m_savePoint->setWhatsThis(
"Save the edit control point to the control "
181 "network which is loaded into memory in its entirety. "
182 "When a control point is selected for editing, "
183 "a copy of the point is made so that the original control "
184 "point remains in the network.");
185 m_saveDefaultPalette = m_savePoint->palette();
186 connect (m_savePoint,SIGNAL(clicked()),
this,SLOT(
savePoint()));
188 QHBoxLayout * addMeasureLayout =
new QHBoxLayout;
189 addMeasureLayout->addStretch();
190 addMeasureLayout->addWidget(m_savePoint);
193 m_cnetFileNameLabel =
new QLabel(
"Control Network: " + m_cnetFileName);
194 m_cnetFileNameLabel->setToolTip(
"Name of opened control network file.");
195 m_cnetFileNameLabel->setWhatsThis(
"Name of opened control network file.");
197 m_templateFileNameLabel =
new QLabel(
"Template File: " +
198 m_pointEditor->templateFileName());
199 m_templateFileNameLabel->setToolTip(
"Sub-pixel registration template File.");
203 m_templateFileNameLabel->setWhatsThis(
"FileName of the sub-pixel "
204 "registration template. Refer to $ISISROOT/doc/documents/"
205 "PatternMatch/PatternMatch.html for a description of the "
206 "contents of this file.");
208 QVBoxLayout * centralLayout =
new QVBoxLayout;
210 centralLayout->addWidget(m_cnetFileNameLabel);
211 centralLayout->addWidget(m_templateFileNameLabel);
213 centralLayout->addStretch();
214 centralLayout->addWidget(m_pointEditor);
215 centralLayout->addLayout(addMeasureLayout);
217 centralWidget->setLayout(centralLayout);
219 QScrollArea *scrollArea =
new QScrollArea();
220 scrollArea->setObjectName(
"MatchToolScroll");
221 scrollArea->setWidget(centralWidget);
222 scrollArea->setWidgetResizable(
true);
223 centralWidget->adjustSize();
224 m_matchTool->setCentralWidget(scrollArea);
228 connect(
this, SIGNAL(editPointChanged()),
238 QHBoxLayout * measureLayout =
new QHBoxLayout;
242 QVBoxLayout * groupBoxesLayout =
new QVBoxLayout;
244 groupBoxesLayout->addStretch();
245 groupBoxesLayout->addLayout(measureLayout);
248 groupBoxesWidget->setLayout(groupBoxesLayout);
252 QSplitter * topSplitter =
new QSplitter;
253 topSplitter->addWidget(groupBoxesWidget);
254 topSplitter->addWidget(m_templateEditorWidget);
255 topSplitter->setStretchFactor(0, 4);
256 topSplitter->setStretchFactor(1, 3);
258 m_templateEditorWidget->hide();
268 m_ptIdValue =
new QLabel;
269 m_numMeasures =
new QLabel;
270 QVBoxLayout * leftLayout =
new QVBoxLayout;
271 leftLayout->addWidget(m_ptIdValue);
272 leftLayout->addWidget(m_numMeasures);
275 m_lockPoint =
new QCheckBox(
"Edit Lock Point");
276 connect(m_lockPoint, SIGNAL(clicked(
bool)),
this, SLOT(
setLockPoint(
bool)));
277 m_ignorePoint =
new QCheckBox(
"Ignore Point");
278 connect(m_ignorePoint, SIGNAL(clicked(
bool)),
280 connect(
this, SIGNAL(ignorePointChanged()), m_ignorePoint, SLOT(toggle()));
282 QVBoxLayout * rightLayout =
new QVBoxLayout;
283 rightLayout->addWidget(m_lockPoint);
284 rightLayout->addWidget(m_ignorePoint);
286 QHBoxLayout * mainLayout =
new QHBoxLayout;
287 mainLayout->addLayout(leftLayout);
288 mainLayout->addStretch();
289 mainLayout->addLayout(rightLayout);
292 QGroupBox * groupBox =
new QGroupBox(
"Control Point");
293 groupBox->setLayout(mainLayout);
303 m_leftCombo->view()->installEventFilter(
this);
304 m_leftCombo->setToolTip(
"Choose left control measure");
305 m_leftCombo->setWhatsThis(
"Choose left control measure identified by "
307 connect(m_leftCombo, SIGNAL(activated(
int)),
309 m_lockLeftMeasure =
new QCheckBox(
"Edit Lock Measure");
310 connect(m_lockLeftMeasure, SIGNAL(clicked(
bool)),
312 m_ignoreLeftMeasure =
new QCheckBox(
"Ignore Measure");
313 connect(m_ignoreLeftMeasure, SIGNAL(clicked(
bool)),
315 connect(
this, SIGNAL(ignoreLeftChanged()),
316 m_ignoreLeftMeasure, SLOT(toggle()));
317 m_leftReference =
new QLabel();
318 m_leftMeasureType =
new QLabel();
319 m_leftSampShift =
new QLabel();
320 m_leftSampShift->setToolTip(
"Sample shift between apriori and current");
321 m_leftSampShift->setWhatsThis(
"The shift between the apriori sample and "
322 "the current sample. The apriori sample is set "
323 "when creating a new measure.");
324 m_leftLineShift =
new QLabel();
325 m_leftLineShift->setToolTip(
"Line shift between apriori and current");
326 m_leftLineShift->setWhatsThis(
"The shift between the apriori line and "
327 "the current line. The apriori line is set "
328 "when creating a new measure.");
329 m_leftGoodness =
new QLabel();
330 m_leftGoodness->setToolTip(
"Goodness of Fit result from sub-pixel "
332 m_leftGoodness->setWhatsThis(
"Resulting Goodness of Fit from sub-pixel "
334 QVBoxLayout * leftLayout =
new QVBoxLayout;
335 leftLayout->addWidget(m_leftCombo);
336 leftLayout->addWidget(m_lockLeftMeasure);
337 leftLayout->addWidget(m_ignoreLeftMeasure);
338 leftLayout->addWidget(m_leftReference);
339 leftLayout->addWidget(m_leftMeasureType);
340 leftLayout->addWidget(m_leftSampShift);
341 leftLayout->addWidget(m_leftLineShift);
342 leftLayout->addWidget(m_leftGoodness);
344 QGroupBox * leftGroupBox =
new QGroupBox(
"Left Measure");
345 leftGroupBox->setLayout(leftLayout);
356 m_rightCombo->view()->installEventFilter(
this);
357 m_rightCombo->setToolTip(
"Choose right control measure");
358 m_rightCombo->setWhatsThis(
"Choose right control measure identified by "
360 connect(m_rightCombo, SIGNAL(activated(
int)),
362 m_lockRightMeasure =
new QCheckBox(
"Edit Lock Measure");
363 connect(m_lockRightMeasure, SIGNAL(clicked(
bool)),
365 m_ignoreRightMeasure =
new QCheckBox(
"Ignore Measure");
366 connect(m_ignoreRightMeasure, SIGNAL(clicked(
bool)),
368 connect(
this, SIGNAL(ignoreRightChanged()),
369 m_ignoreRightMeasure, SLOT(toggle()));
370 m_rightReference =
new QLabel();
371 m_rightMeasureType =
new QLabel();
372 m_rightSampShift =
new QLabel();
373 m_rightSampShift->setToolTip(m_leftSampShift->toolTip());
374 m_rightSampShift->setWhatsThis(m_leftSampShift->whatsThis());
375 m_rightLineShift =
new QLabel();
376 m_rightLineShift->setToolTip(m_leftLineShift->toolTip());
377 m_rightLineShift->setWhatsThis(m_leftLineShift->whatsThis());
378 m_rightGoodness =
new QLabel();
379 m_rightGoodness->setToolTip(m_leftGoodness->toolTip());
380 m_rightGoodness->setWhatsThis(m_leftGoodness->whatsThis());
383 QVBoxLayout * rightLayout =
new QVBoxLayout;
384 rightLayout->addWidget(m_rightCombo);
385 rightLayout->addWidget(m_lockRightMeasure);
386 rightLayout->addWidget(m_ignoreRightMeasure);
387 rightLayout->addWidget(m_rightReference);
388 rightLayout->addWidget(m_rightMeasureType);
389 rightLayout->addWidget(m_rightSampShift);
390 rightLayout->addWidget(m_rightLineShift);
391 rightLayout->addWidget(m_rightGoodness);
393 QGroupBox * rightGroupBox =
new QGroupBox(
"Right Measure");
394 rightGroupBox->setLayout(rightLayout);
396 return rightGroupBox;
405 toolBar->addAction(m_openTemplateFile);
406 toolBar->addSeparator();
407 toolBar->addAction(m_saveTemplateFile);
408 toolBar->addAction(m_saveTemplateFileAs);
410 m_templateEditor =
new QTextEdit;
411 connect(m_templateEditor, SIGNAL(textChanged()),
this,
414 QVBoxLayout *mainLayout =
new QVBoxLayout;
415 mainLayout->addWidget(toolBar);
416 mainLayout->addWidget(m_templateEditor);
418 m_templateEditorWidget =
new QWidget;
419 m_templateEditorWidget->setLayout(mainLayout);
424 void MatchTool::createActions() {
427 "Save Control Network ...",
429 m_saveNet->setToolTip(
"Save current control network");
430 m_saveNet->setStatusTip(
"Save current control network");
431 QString whatsThis =
"<b>Function:</b> Saves the current <i>"
432 "control network</i>";
433 m_saveNet->setWhatsThis(whatsThis);
434 connect(m_saveNet, SIGNAL(activated()),
this, SLOT(
saveNet()));
437 "Save Control Network &As...",
439 m_saveAsNet->setToolTip(
"Save current control network to chosen file");
440 m_saveAsNet->setStatusTip(
"Save current control network to chosen file");
441 whatsThis =
"<b>Function:</b> Saves the current <i>"
442 "control network</i> under chosen filename";
443 m_saveAsNet->setWhatsThis(whatsThis);
444 connect(m_saveAsNet, SIGNAL(activated()),
this, SLOT(
saveAsNet()));
449 m_closeMatchTool->setToolTip(
"Close this window");
450 m_closeMatchTool->setStatusTip(
"Close this window");
451 m_closeMatchTool->setShortcut(Qt::ALT + Qt::Key_F4);
452 whatsThis =
"<b>Function:</b> Closes the Match Tool window for this point "
453 "<p><b>Shortcut:</b> Alt+F4 </p>";
454 m_closeMatchTool->setWhatsThis(whatsThis);
455 connect(m_closeMatchTool, SIGNAL(activated()), m_matchTool, SLOT(close()));
458 "&View/edit registration template",
460 m_showHideTemplateEditor->setCheckable(
true);
461 m_showHideTemplateEditor->setToolTip(
"View and/or edit the registration template");
462 m_showHideTemplateEditor->setStatusTip(
"View and/or edit the registration template");
463 whatsThis =
"<b>Function:</b> Displays the curent registration template. "
464 "The user may edit and save changes under a chosen filename.";
465 m_showHideTemplateEditor->setWhatsThis(whatsThis);
466 connect(m_showHideTemplateEditor, SIGNAL(activated()),
this,
467 SLOT(showHideTemplateEditor()));
470 "Save registration chips",
472 m_saveChips->setToolTip(
"Save registration chips");
473 m_saveChips->setStatusTip(
"Save registration chips");
474 whatsThis =
"<b>Function:</b> Save registration chips to file. "
475 "Each chip: pattern, search, fit will be saved to a separate file.";
476 m_saveChips->setWhatsThis(whatsThis);
477 connect(m_saveChips, SIGNAL(activated()),
this, SLOT(
saveChips()));
480 "&Open registration template",
482 m_openTemplateFile->setToolTip(
"Set registration template");
483 m_openTemplateFile->setStatusTip(
"Set registration template");
484 whatsThis =
"<b>Function:</b> Allows user to select a new file to set as "
485 "the registration template";
486 m_openTemplateFile->setWhatsThis(whatsThis);
487 connect(m_openTemplateFile, SIGNAL(activated()),
this, SLOT(
openTemplateFile()));
490 "&Save template file",
492 m_saveTemplateFile->setToolTip(
"Save the template file");
493 m_saveTemplateFile->setStatusTip(
"Save the template file");
494 m_saveTemplateFile->setWhatsThis(
"Save the registration template file");
495 connect(m_saveTemplateFile, SIGNAL(triggered()),
this,
499 "&Save template as...",
501 m_saveTemplateFileAs->setToolTip(
"Save the template file as");
502 m_saveTemplateFileAs->setStatusTip(
"Save the template file as");
503 m_saveTemplateFileAs->setWhatsThis(
"Save the registration template file as");
504 connect(m_saveTemplateFileAs, SIGNAL(triggered()),
this,
510 m_whatsThis->setShortcut(Qt::SHIFT | Qt::Key_F1);
511 m_whatsThis->setToolTip(
"Activate What's This and click on items on "
512 "user interface to see more information.");
513 connect(m_whatsThis, SIGNAL(activated()),
this, SLOT(enterWhatsThisMode()));
515 m_showHelp =
new QAction(QPixmap(
toolIconDir() +
"/help-contents.png"),
"Help", m_matchTool);
516 m_showHelp->setToolTip(
"Help");
517 connect(m_showHelp, SIGNAL(activated()),
this, SLOT(showHelp()));
534 QMenu *fileMenu = m_matchTool->menuBar()->addMenu(
"&File");
535 fileMenu->addAction(m_saveNet);
536 fileMenu->addAction(m_saveAsNet);
537 fileMenu->addAction(m_closeMatchTool);
539 QMenu * regMenu = m_matchTool->menuBar()->addMenu(
"&Registration");
540 regMenu->addAction(m_openTemplateFile);
541 regMenu->addAction(m_showHideTemplateEditor);
542 regMenu->addAction(m_saveChips);
544 QMenu *helpMenu = m_matchTool->menuBar()->addMenu(
"&Help");
545 helpMenu->addAction(m_whatsThis);
549 void MatchTool::createToolBars() {
552 toolBar->setObjectName(
"TemplateEditorToolBar");
553 toolBar->setFloatable(
false);
554 toolBar->addAction(m_saveNet);
555 toolBar->addSeparator();
556 toolBar->addAction(m_showHideTemplateEditor);
557 toolBar->addAction(m_saveChips);
558 toolBar->addAction(m_showHelp);
559 toolBar->addAction(m_whatsThis);
561 m_matchTool->addToolBar(Qt::TopToolBarArea, toolBar);
579 action->setIcon(QPixmap(
toolIconDir()+
"/stock_draw-connector-with-arrows.png"));
580 action->setToolTip(
"Match Tool - Control Point Editor (T)");
581 action->setShortcut(Qt::Key_T);
587 QWidget *MatchTool::createToolBarWidget(QStackedWidget *parent) {
591 QToolButton *openNetButton =
new QToolButton(hbox);
592 openNetButton->setIcon(QPixmap(
toolIconDir() +
"/fileopen.png"));
593 openNetButton->setIconSize(QSize(22,22));
594 openNetButton->setToolTip(
"Open control network");
595 openNetButton->setEnabled(
true);
596 connect(openNetButton, SIGNAL(clicked()),
this, SLOT(openNet()));
598 QToolButton *saveAsNetButton =
new QToolButton(hbox);
599 saveAsNetButton->setDefaultAction(m_saveAsNet);
600 saveAsNetButton->setIconSize(QSize(22,22));
602 QToolButton *saveNetButton =
new QToolButton(hbox);
603 saveNetButton->setDefaultAction(m_saveNet);
604 saveNetButton->setIconSize(QSize(22,22));
606 QToolButton *helpButton =
new QToolButton(hbox);
607 helpButton->setDefaultAction(m_showHelp);
608 helpButton->setIconSize(QSize(22, 22));
610 QHBoxLayout *layout =
new QHBoxLayout;
611 layout->setMargin(0);
612 layout->addWidget(openNetButton);
613 layout->addWidget(saveAsNetButton);
614 layout->addWidget(saveNetButton);
615 layout->addStretch();
616 layout->addWidget(helpButton);
617 hbox->setLayout(layout);
624 void MatchTool::activateTool() {
627 m_controlNet =
new ControlNet();
658 list.
Add(fileName.name(),fileName.expanded());
677 QString serialNumber;
683 catch (IException &e) {
684 serialNumber =
"Unknown";
760 if (*origLeftMeasure == *m_leftMeasure && *origRightMeasure == *m_rightMeasure) {
764 if (m_editPoint->IsIgnored()) {
765 QString message =
"You are saving changes to a measure on an ignored ";
766 message +=
"point. Do you want to set Ignore = False on the point and ";
767 message +=
"both measures?";
768 switch (QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
769 message,
"&Yes",
"&No", 0, 0)) {
773 emit ignorePointChanged();
774 if (m_leftMeasure->IsIgnored()) {
775 m_leftMeasure->SetIgnored(
false);
776 emit ignoreLeftChanged();
778 if (m_rightMeasure->IsIgnored()) {
779 m_rightMeasure->SetIgnored(
false);
780 emit ignoreRightChanged();
788 bool savedAMeasure =
false;
790 bool leftChangeOk = validateMeasureChange(m_leftMeasure);
793 *origLeftMeasure = *m_leftMeasure;
794 savedAMeasure =
true;
796 bool rightChangeOk = validateMeasureChange(m_rightMeasure);
799 *origRightMeasure = *m_rightMeasure;
800 savedAMeasure =
true;
805 *m_leftMeasure = *m_rightMeasure;
808 m_editPoint->
GetId());
816 emit editPointChanged();
837 if (*m == *origMeasure)
return false;
841 QString side =
"right";
854 QString message =
"The " + side +
" measure is editLocked ";
855 message +=
"for editing. Do you want to set EditLock = False for this ";
856 message +=
"measure?";
857 int response = QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
858 message, QMessageBox::Yes | QMessageBox::No);
860 if (response == QMessageBox::Yes) {
861 m->SetEditLock(
false);
862 if (side ==
"left") {
863 m_lockLeftMeasure->setChecked(
false);
866 m_lockRightMeasure->setChecked(
false);
875 if (origMeasure->IsIgnored() && m->IsIgnored()) {
876 QString message =
"The " + side +
"measure is ignored. ";
877 message +=
"Do you want to set Ignore = False on the measure?";
878 switch(QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
879 message,
"&Yes",
"&No", 0, 0)){
882 m->SetIgnored(
false);
883 if (side ==
"left") {
884 emit ignoreLeftChanged();
887 emit ignoreRightChanged();
899 if (m->GetSample() != origMeasure->GetSample() || m->GetLine() != origMeasure->GetLine()) {
900 QString message =
"You are making a change to the reference measure. You ";
901 message +=
"may need to move all of the other measures to match the new ";
902 message +=
" coordinate of the reference measure. Do you really want to ";
903 message +=
" change the reference measure's location? ";
904 switch(QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
905 message,
"&Yes",
"&No", 0, 0)){
917 else if (side ==
"left" && (refMeasure->GetCubeSerialNumber() != m->
GetCubeSerialNumber())) {
919 QString message =
"This control network was created by the <i>coreg</i> program, and the "
920 "reference measure needs to remain the same as what <i>coreg</i> set. "
921 "Therefore, you cannot change which measure is the reference. To "
922 "save this point, move the reference measure (measure in BOLD) back "
924 QMessageBox::information(m_matchTool,
"Cannot change reference", message);
927 QString message =
"This point already contains a reference measure. ";
928 message +=
"Would you like to replace it with the measure on the left?";
929 int response = QMessageBox::question(m_matchTool,
930 "Match Tool Save Measure", message,
931 QMessageBox::Yes | QMessageBox::No,
934 if (response == QMessageBox::Yes) {
938 QString fname = FileName(file).name();
939 int iref = m_leftCombo->findText(fname);
942 QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
943 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
944 iref = m_rightCombo->findText(fname);
945 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
948 fname = FileName(file).name();
949 iref = m_leftCombo->findText(fname);
950 m_leftCombo->setItemData(iref,font,Qt::FontRole);
951 iref = m_rightCombo->findText(fname);
952 m_rightCombo->setItemData(iref,font,Qt::FontRole);
961 if (side ==
"left") {
983 void MatchTool::checkReference() {
990 QString message =
"This point already contains a reference measure. ";
991 message +=
"Would you like to replace it with the measure on the left?";
992 int response = QMessageBox::question(m_matchTool,
993 "Match Tool Save Measure", message,
994 QMessageBox::Yes | QMessageBox::No,
997 if (response == QMessageBox::Yes) {
1001 QString fname = FileName(file).name();
1002 int iref = m_leftCombo->findText(fname);
1005 QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
1006 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1007 iref = m_rightCombo->findText(fname);
1008 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1011 fname = FileName(file).name();
1012 iref = m_leftCombo->findText(fname);
1013 m_leftCombo->setItemData(iref,font,Qt::FontRole);
1014 iref = m_rightCombo->findText(fname);
1015 m_rightCombo->setItemData(iref,font,Qt::FontRole);
1047 *updatePoint = *m_editPoint;
1051 if (m_controlNet->ContainsPoint(updatePoint->
GetId())) {
1053 p = m_controlNet->GetPoint(QString(updatePoint->
GetId()));
1059 m_controlNet->AddPoint(updatePoint);
1063 m_savePoint->setPalette(m_saveDefaultPalette);
1066 emit editPointChanged();
1068 m_netChanged =
true;
1070 m_pointEditor->refreshChips();
1085 if (m_editPoint == NULL)
return;
1104 if (m_editPoint == NULL)
return;
1108 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1109 QString message =
"Unable to change Ignored on point. Set EditLock ";
1110 message +=
" to False.";
1111 QMessageBox::critical(m_matchTool,
"Error", message);
1137 if (m_editPoint->IsEditLocked()) {
1138 m_lockLeftMeasure->setChecked(m_leftMeasure->
IsEditLocked());
1139 QMessageBox::warning(m_matchTool,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1140 " before changing a measure.");
1141 m_lockLeftMeasure->setChecked(m_leftMeasure->
IsEditLocked());
1145 if (m_leftMeasure != NULL) m_leftMeasure->SetEditLock(lock);
1149 if (m_rightMeasure != NULL) {
1151 m_rightMeasure->SetEditLock(lock);
1152 m_lockRightMeasure->setChecked(lock);
1155 emit measureChanged();
1177 if (m_leftMeasure != NULL) m_leftMeasure->SetIgnored(ignore);
1181 if (m_rightMeasure != NULL) {
1183 m_rightMeasure->SetIgnored(ignore);
1184 m_ignoreRightMeasure->setChecked(ignore);
1187 emit measureChanged();
1208 if (m_editPoint->IsEditLocked()) {
1209 m_lockRightMeasure->setChecked(m_rightMeasure->
IsEditLocked());
1210 QMessageBox::warning(m_matchTool,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1211 " before changing a measure.");
1212 m_lockRightMeasure->setChecked(m_rightMeasure->
IsEditLocked());
1216 if (m_rightMeasure != NULL) m_rightMeasure->SetEditLock(lock);
1219 if (m_leftMeasure != NULL) {
1221 m_leftMeasure->SetEditLock(lock);
1222 m_lockLeftMeasure->setChecked(lock);
1225 emit measureChanged();
1247 if (m_rightMeasure != NULL) m_rightMeasure->SetIgnored(ignore);
1251 if (m_leftMeasure != NULL) {
1253 m_leftMeasure->SetIgnored(ignore);
1254 m_ignoreLeftMeasure->setChecked(ignore);
1257 emit measureChanged();
1262 void MatchTool::openNet() {
1265 if (m_controlNet->GetNumPoints() != 0 && m_netChanged) {
1266 QString message =
"A control net has already been created. Do you want to save before "
1267 "opening a new control net?";
1268 int response = QMessageBox::question(m_matchTool,
"Save current control net?",
1270 QMessageBox::Yes | QMessageBox::No,
1273 if (response == QMessageBox::Yes) {
1276 m_matchTool->setShown(
false);
1278 delete m_controlNet;
1279 m_controlNet = NULL;
1282 m_newPointDialog = NULL;
1286 m_netChanged =
false;
1288 QApplication::restoreOverrideCursor();
1289 QString filter =
"Control net (*.net *.cnet *.ctl);;";
1290 filter +=
"Pvl file (*.pvl);;";
1291 filter +=
"Text file (*.txt);;";
1292 filter +=
"All (*)";
1293 m_cnetFileName = QFileDialog::getOpenFileName((
QWidget *)parent(),
1294 "Select a control network",
1297 QApplication::setOverrideCursor(Qt::WaitCursor);
1298 if (!m_cnetFileName.isEmpty()) {
1301 m_controlNet =
new ControlNet(m_cnetFileName, &progress);
1303 m_coregReferenceSN =
"";
1304 if (m_controlNet->GetNetworkId() ==
"Coreg") {
1308 m_coregReferenceSN = m_controlNet->GetPoint(0)->GetReferenceSN();
1311 catch (IException &e) {
1312 QApplication::restoreOverrideCursor();
1313 QString message =
"Invalid control network. \n";
1314 message += e.toString();
1315 QMessageBox::critical(m_matchTool,
"Error", message);
1316 m_cnetFileName.clear();
1317 delete m_controlNet;
1318 m_controlNet = NULL;
1322 QApplication::restoreOverrideCursor();
1323 m_matchTool->setWindowTitle(
"Match Tool - Control Network File: " + m_cnetFileName);
1324 m_cnetFileNameLabel->setText(
"Control Network: " + m_cnetFileName);
1337 if (m_cnetFileName.isEmpty()) {
1338 QString message =
"This is a new network, you must select "
1339 "\"Save As\" under the File Menu or on the toolbar.";
1340 QMessageBox::critical(m_matchTool,
"Error", message);
1344 m_controlNet->Write(m_cnetFileName);
1345 m_netChanged =
false;
1348 QMessageBox::critical(m_matchTool, tr(
"Error Writing Control Net"), e.
what());
1360 QString fn = QFileDialog::getSaveFileName(m_matchTool,
1361 "Choose filename to save under",
1363 "Control Files (*.net)");
1368 m_controlNet->Write(fn);
1369 m_netChanged =
false;
1372 QMessageBox::critical(m_matchTool, tr(
"Error Writing Control Net"), e.
what());
1375 m_cnetFileName = fn;
1415 if (mvp == NULL)
return;
1423 if (s == Qt::LeftButton) {
1425 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1426 QString message =
"No points exist for editing. Create points ";
1427 message +=
"using the right mouse button.";
1428 QMessageBox::warning(m_matchTool,
"Warning", message);
1436 point = m_controlNet->FindClosest(sn, samp, line);
1439 QString message =
"Cannot find point for editing.";
1441 QMessageBox::warning(m_matchTool,
"Warning", message);
1447 else if (s == Qt::MidButton) {
1448 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1449 QString message =
"No points exist for deleting. Create points ";
1450 message +=
"using the right mouse button.";
1451 QMessageBox::warning(m_matchTool,
"Warning", message);
1456 ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
1458 if (point == NULL) {
1459 QString message =
"No points exist for deleting. Create points ";
1460 message +=
"using the right mouse button.";
1461 QMessageBox::warning(m_matchTool,
"Warning", message);
1467 else if (s == Qt::RightButton) {
1468 if (m_newPointDialog) {
1469 addMeasure(mvp, samp, line);
1477 QString message =
"Cannot create control point.\n\n";
1479 QMessageBox::critical(m_matchTool,
"Error", message);
1492 for (
int i=0; i<point->GetNumMeasures(); i++) {
1498 return missingCubes;
1512 connect(m_newPointDialog, SIGNAL(measuresFinished()),
this, SLOT(doneWithMeasures()));
1513 connect(m_newPointDialog, SIGNAL(newPointCanceled()),
this, SLOT(cancelNewPoint()));
1518 images<<cubeFile.name();
1520 m_newPointDialog->
setFiles(images);
1521 m_newPointDialog->show();
1525 m_newPointDialog->highlightFile(current);
1544 void MatchTool::addMeasure(
MdiCubeViewport *cvp,
double sample,
double line) {
1548 m_newPointDialog->highlightFile(current);
1549 m_newPointDialog->raise();
1569 void MatchTool::doneWithMeasures() {
1571 m_lastUsedPointId = m_newPointDialog->pointId();
1572 m_newPoint->
SetId(m_lastUsedPointId);
1583 QString message =
"This is a coreg network which needs the cube with serial number " +
1584 m_coregReferenceSN +
" as the reference measure. This new control point does "
1585 "not have a measure for that serial number, so this point cannot be created until "
1586 "the cube listed above is added (Right-click on cube).";
1587 QMessageBox::critical(m_matchTool,
"Error", message);
1588 m_newPointDialog->show();
1596 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1600 m_editPoint = m_newPoint;
1603 delete m_newPointDialog;
1604 m_newPointDialog = NULL;
1608 m_matchTool->setShown(
true);
1609 m_matchTool->raise();
1611 emit editPointChanged();
1617 void MatchTool::cancelNewPoint() {
1619 delete m_newPointDialog;
1620 m_newPointDialog = NULL;
1652 if (mCubes.size() > 0) {
1653 QString msgTitle =
"Missing Cubes";
1654 QString message =
"This point is missing cubes for the following measures and cannot be ";
1655 message +=
"loaded into the editor. Do you still want to delete this point?\n\n";
1656 for (
int i=0; i<mCubes.size(); i++) {
1657 message += mCubes.at(i) +
"\n";
1659 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1661 QPushButton *yesButton = msgBox.addButton(
"Yes", QMessageBox::AcceptRole);
1662 QPushButton *noButton = msgBox.addButton(
"No", QMessageBox::RejectRole);
1663 msgBox.setDefaultButton(yesButton);
1665 if (msgBox.clickedButton() == noButton) {
1669 m_matchTool->setShown(
false);
1676 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1681 *m_editPoint = *point;
1684 if (mCubes.size() == 0) {
1690 emit editPointChanged();
1694 QString CPId = m_editPoint->
GetId();
1695 deletePointDialog->pointIdValue->setText(CPId);
1697 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1706 deletePointDialog->fileList->addItem(file);
1709 if (deletePointDialog->exec()) {
1711 int numDeleted = deletePointDialog->fileList->selectedItems().count();
1714 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1715 numDeleted == m_editPoint->GetNumMeasures()) {
1718 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1719 QString message =
"You have selected all measures in this point to be deleted. This "
1720 "control point will be deleted. Do you want to delete this control point?";
1721 int response = QMessageBox::question(m_matchTool,
1722 "Delete control point", message,
1723 QMessageBox::Yes | QMessageBox::No,
1726 if (response == QMessageBox::No) {
1731 m_matchTool->setShown(
false);
1734 QMessageBox::information(m_matchTool,
"EditLocked Point",
1735 "This point is EditLocked and cannot be deleted.");
1738 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1747 int lockedMeasures = 0;
1748 for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
1749 QListWidgetItem *item = deletePointDialog->fileList->item(i);
1750 if (!deletePointDialog->fileList->isItemSelected(item))
continue;
1755 (*m_editPoint)[i]->GetCubeSerialNumber())) {
1756 QString message =
"You are trying to delete the Reference measure."
1757 " Do you really want to delete the Reference measure?";
1758 switch (QMessageBox::question(m_matchTool,
1759 "Delete Reference measure?", message,
1760 "&Yes",
"&No", 0, 0)) {
1768 if (numDeleted == 1) {
1775 if (m_editPoint->
Delete(i) == ControlMeasure::MeasureLocked) {
1780 if (lockedMeasures > 0) {
1781 QMessageBox::information(m_matchTool,
"EditLocked Measures",
1782 QString::number(lockedMeasures) +
" / "
1784 deletePointDialog->fileList->selectedItems().size()) +
1785 " measures are EditLocked and were not deleted.");
1788 if (mCubes.size() == 0) {
1790 m_matchTool->setShown(
true);
1791 m_matchTool->raise();
1794 m_pointEditor->templateFileName());
1802 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1811 m_netChanged =
true;
1816 emit editPointChanged();
1833 if (point->GetNumMeasures() == 0) {
1834 QString message =
"This point has no measures.";
1835 QMessageBox::warning(m_matchTool,
"Warning", message);
1836 emit editPointChanged();
1842 if (mCubes.size() > 0) {
1843 QString msgTitle =
"Missing Cubes";
1844 QString message =
"This point is missing cubes and cannot be loaded into the editor. Open ";
1845 message +=
"the cubes for the following measures before selecting this point.\n\n";
1846 for (
int i=0; i<mCubes.size(); i++) {
1847 message += mCubes.at(i) +
"\n";
1849 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1857 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1862 *m_editPoint = *point;
1865 m_matchTool->setShown(
true);
1866 m_matchTool->raise();
1868 m_pointEditor->templateFileName());
1871 emit editPointChanged();
1874 m_savePoint->setPalette(m_saveDefaultPalette);
1899 QString CPId = m_editPoint->
GetId();
1900 QString ptId(
"Point ID: ");
1901 ptId += (QString) CPId;
1902 m_ptIdValue->setText(ptId);
1905 QString ptsize =
"Number of Measures: " +
1906 QString::number(m_editPoint->GetNumMeasures());
1907 m_numMeasures->setText(ptsize);
1910 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
1913 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1916 m_leftCombo->clear();
1917 m_rightCombo->clear();
1918 m_pointFiles.clear();
1921 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1925 QString tempFileName =
FileName(file).name();
1926 m_leftCombo->addItem(tempFileName);
1927 m_rightCombo->addItem(tempFileName);
1930 m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1931 m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1950 if (!m_leftFile.isEmpty()) {
1951 leftIndex = m_leftCombo->findText(
FileName(m_leftFile).name());
1953 if (leftIndex < 0 ) leftIndex = 0;
1958 if (leftIndex == 0) {
1967 if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
1968 m_rightCombo->setCurrentIndex(rightIndex);
1969 m_leftCombo->setCurrentIndex(leftIndex);
1987 if (m_measureWindow == NULL) {
1989 m_measureTable =
new QTableWidget();
1990 m_measureTable->setMinimumWidth(1600);
1991 m_measureTable->setAlternatingRowColors(
true);
1992 m_measureWindow->setCentralWidget(m_measureTable);
1995 m_measureTable->clear();
1996 m_measureTable->setSortingEnabled(
false);
1998 m_measureTable->setRowCount(m_editPoint->GetNumMeasures());
1999 m_measureTable->setColumnCount(NUMCOLUMNS);
2002 for (
int i=0; i<NUMCOLUMNS; i++) {
2003 labels<<measureColumnToString((MeasureColumns)i);
2005 m_measureTable->setHorizontalHeaderLabels(labels);
2008 for (
int row=0; row<m_editPoint->GetNumMeasures(); row++) {
2013 QTableWidgetItem *tableItem =
new QTableWidgetItem(QString(file));
2014 m_measureTable->setItem(row,column++,tableItem);
2017 m_measureTable->setItem(row,column++,tableItem);
2019 tableItem =
new QTableWidgetItem();
2020 tableItem->setData(0,m.GetSample());
2021 m_measureTable->setItem(row,column++,tableItem);
2023 tableItem =
new QTableWidgetItem();
2024 tableItem->setData(0,m.GetLine());
2025 m_measureTable->setItem(row,column++,tableItem);
2027 if (m.GetAprioriSample() ==
Null) {
2028 tableItem =
new QTableWidgetItem(
"Null");
2031 tableItem =
new QTableWidgetItem();
2032 tableItem->setData(0,m.GetAprioriSample());
2034 m_measureTable->setItem(row,column++,tableItem);
2036 if (m.GetAprioriLine() ==
Null) {
2037 tableItem =
new QTableWidgetItem(
"Null");
2040 tableItem =
new QTableWidgetItem();
2041 tableItem->setData(0,m.GetAprioriLine());
2043 m_measureTable->setItem(row,column++,tableItem);
2045 if (m.GetSampleResidual() ==
Null) {
2046 tableItem =
new QTableWidgetItem(QString(
"Null"));
2049 tableItem =
new QTableWidgetItem();
2050 tableItem->setData(0,m.GetSampleResidual());
2052 m_measureTable->setItem(row,column++,tableItem);
2054 if (m.GetLineResidual() ==
Null) {
2055 tableItem =
new QTableWidgetItem(QString(
"Null"));
2058 tableItem =
new QTableWidgetItem();
2059 tableItem->setData(0,m.GetLineResidual());
2061 m_measureTable->setItem(row,column++,tableItem);
2064 tableItem =
new QTableWidgetItem(QString(
"Null"));
2067 tableItem =
new QTableWidgetItem();
2070 m_measureTable->setItem(row,column++,tableItem);
2072 double sampleShift = m.GetSampleShift();
2073 if (sampleShift ==
Null) {
2074 tableItem =
new QTableWidgetItem(QString(
"Null"));
2077 tableItem =
new QTableWidgetItem();
2078 tableItem->setData(0,sampleShift);
2080 m_measureTable->setItem(row,column++,tableItem);
2082 double lineShift = m.GetLineShift();
2083 if (lineShift ==
Null) {
2084 tableItem =
new QTableWidgetItem(QString(
"Null"));
2087 tableItem =
new QTableWidgetItem();
2088 tableItem->setData(0,lineShift);
2090 m_measureTable->setItem(row,column++,tableItem);
2092 double pixelShift = m.GetPixelShift();
2093 if (pixelShift ==
Null) {
2094 tableItem =
new QTableWidgetItem(QString(
"Null"));
2097 tableItem =
new QTableWidgetItem();
2098 tableItem->setData(0,pixelShift);
2100 m_measureTable->setItem(row,column++,tableItem);
2102 double goodnessOfFit = m.GetLogData(
2104 if (goodnessOfFit ==
Null) {
2105 tableItem =
new QTableWidgetItem(QString(
"Null"));
2108 tableItem =
new QTableWidgetItem();
2109 tableItem->setData(0,goodnessOfFit);
2111 m_measureTable->setItem(row,column++,tableItem);
2113 if (m.IsIgnored()) tableItem =
new QTableWidgetItem(
"True");
2114 if (!m.IsIgnored()) tableItem =
new QTableWidgetItem(
"False");
2115 m_measureTable->setItem(row,column++,tableItem);
2118 tableItem =
new QTableWidgetItem(
"True");
2120 tableItem =
new QTableWidgetItem(
"False");
2121 m_measureTable->setItem(row,column++,tableItem);
2123 tableItem =
new QTableWidgetItem(
2125 m_measureTable->setItem(row,column,tableItem);
2133 for (
int col=0; col<m_measureTable->columnCount(); col++)
2134 m_measureTable->item(row, col)->setFont(font);
2139 m_measureTable->resizeColumnsToContents();
2140 m_measureTable->resizeRowsToContents();
2141 m_measureTable->setSortingEnabled(
true);
2142 m_measureWindow->show();
2147 QString MatchTool::measureColumnToString(MatchTool::MeasureColumns column) {
2157 case SAMPLERESIDUAL:
2158 return "Sample Residual";
2160 return "Line Residual";
2161 case RESIDUALMAGNITUDE:
2162 return "Residual Magnitude";
2164 return "Sample Shift";
2166 return "Line Shift";
2168 return "Pixel Shift";
2170 return "Goodness of Fit";
2176 return "Measure Type";
2178 return "Apriori Sample";
2180 return "Apriori Line";
2183 "Invalid measure column passed to measureColumnToString",
_FILEINFO_);
2202 QString file = m_pointFiles[index];
2209 QString message =
"Make sure the correct cube is opened.\n\n";
2211 QMessageBox::critical(m_matchTool,
"Error", message);
2216 int i = m_leftCombo->findText(
FileName(file).name());
2218 m_leftCombo->setCurrentIndex(i);
2224 if (m_leftMeasure != NULL) {
2225 delete m_leftMeasure;
2226 m_leftMeasure = NULL;
2230 *m_leftMeasure = *((*m_editPoint)[serial]);
2233 if (m_leftCube != NULL)
delete m_leftCube;
2234 m_leftCube =
new Cube();
2235 m_leftCube->
open(file);
2239 m_editPoint->
GetId());
2258 QString file = m_pointFiles[index];
2265 QString message =
"Make sure the correct cube is opened.\n\n";
2267 QMessageBox::critical(m_matchTool,
"Error", message);
2272 int i = m_rightCombo->findText(
FileName(file).name());
2274 m_rightCombo->setCurrentIndex(i);
2280 if (m_rightMeasure != NULL) {
2281 delete m_rightMeasure;
2282 m_rightMeasure = NULL;
2286 *m_rightMeasure = *((*m_editPoint)[serial]);
2289 if (m_rightCube != NULL)
delete m_rightCube;
2290 m_rightCube =
new Cube();
2291 m_rightCube->
open(file);
2295 m_editPoint->
GetId());
2324 m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
2326 QString s =
"Reference: ";
2334 m_leftReference->setText(s);
2336 s =
"Measure Type: ";
2341 m_leftMeasureType->setText(s);
2343 if (m_leftMeasure->GetSampleShift() ==
Null) {
2344 s =
"Sample Shift: Null";
2347 s =
"Sample Shift: " + QString::number(m_leftMeasure->GetSampleShift());
2349 m_leftSampShift->setText(s);
2351 if (m_leftMeasure->GetLineShift() ==
Null) {
2352 s =
"Line Shift: Null";
2355 s =
"Line Shift: " + QString::number(m_leftMeasure->GetLineShift());
2357 m_leftLineShift->setText(s);
2359 double goodnessOfFit = m_leftMeasure->GetLogData(
2361 if (goodnessOfFit ==
Null) {
2362 s =
"Goodness of Fit: Null";
2365 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2367 m_leftGoodness->setText(s);
2397 m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
2399 QString s =
"Reference: ";
2408 m_rightReference->setText(s);
2410 s =
"Measure Type: ";
2415 m_rightMeasureType->setText(s);
2417 if (m_rightMeasure->GetSampleShift() ==
Null) {
2418 s =
"Sample Shift: Null";
2421 s =
"Sample Shift: " + QString::number(m_rightMeasure->GetSampleShift());
2423 m_rightSampShift->setText(s);
2425 if (m_rightMeasure->GetLineShift() ==
Null) {
2426 s =
"Line Shift: Null";
2429 s =
"Line Shift: " + QString::number(m_rightMeasure->GetLineShift());
2431 m_rightLineShift->setText(s);
2433 double goodnessOfFit = m_rightMeasure->GetLogData(
2435 if (goodnessOfFit ==
Null) {
2436 s =
"Goodness of Fit: Null";
2439 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2441 m_rightGoodness->setText(s);
2458 if(e->type() != QEvent::Leave)
return false;
2459 if(o == m_leftCombo->view()) {
2461 m_leftCombo->hidePopup();
2463 if (o == m_rightCombo->view()) {
2465 m_rightCombo->hidePopup();
2505 mvp->viewport()->update();
2534 if ( (m_controlNet == NULL || m_controlNet->GetNumPoints() == 0) && m_newPoint == NULL &&
2535 m_editPoint == NULL)
2538 QString sn = serialNumber(mvp);
2542 if (m_newPoint != NULL) {
2546 double samp = (*m_newPoint)[sn]->GetSample();
2547 double line = (*m_newPoint)[sn]->GetLine();
2551 QBrush brush(Qt::red);
2555 painter->setPen(pen);
2556 painter->drawLine(x - 5, y, x + 5, y);
2557 painter->drawLine(x, y - 5, x, y + 5);
2562 if (!m_controlNet->GetCubeSerials().contains(
2570 m_controlNet->GetMeasuresInCube(sn);
2572 for (
int i = 0; i < measures.count(); i++) {
2575 double samp = m->GetSample();
2576 double line = m->GetLine();
2580 if (m->Parent()->IsIgnored()) {
2581 painter->setPen(QColor(255, 255, 0));
2584 else if (m->IsIgnored()) {
2585 painter->setPen(QColor(255, 255, 0));
2588 painter->setPen(Qt::green);
2591 painter->drawLine(x - 5, y, x + 5, y);
2592 painter->drawLine(x, y - 5, x, y + 5);
2595 if (m_editPoint != NULL && m_newPoint == NULL) {
2599 double samp = (*m_editPoint)[sn]->GetSample();
2600 double line = (*m_editPoint)[sn]->GetLine();
2604 QBrush brush(Qt::red);
2608 painter->setPen(pen);
2609 painter->drawLine(x - 5, y, x + 5, y);
2610 painter->drawLine(x, y - 5, x, y + 5);
2632 if (m_templateModified) {
2633 int r = QMessageBox::warning(m_matchTool, tr(
"OK to continue?"),
2634 tr(
"The currently opened registration template has been modified.\n"
2636 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2639 if (r == QMessageBox::Yes)
2641 else if (r == QMessageBox::Cancel)
2660 QString filename = QFileDialog::getOpenFileName(m_matchTool,
2661 "Select a registration template",
".",
2662 "Registration template files (*.def *.pvl);;All files (*)");
2664 if (filename.isEmpty())
2681 QFile file(
FileName((QString) fn).expanded());
2682 if (!file.open(QIODevice::ReadOnly)) {
2683 QString msg =
"Failed to open template file \"" + fn +
"\"";
2684 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2688 QTextStream stream(&file);
2689 m_templateEditor->setText(stream.readAll());
2692 QScrollBar * sb = m_templateEditor->verticalScrollBar();
2693 sb->setValue(sb->minimum());
2695 m_templateModified =
false;
2696 m_saveTemplateFile->setEnabled(
false);
2697 m_templateFileNameLabel->setText(
"Template File: " + fn);
2704 m_templateModified =
true;
2705 m_saveTemplateFile->setEnabled(
true);
2713 if (!m_templateModified)
2717 m_pointEditor->templateFileName();
2727 QString filename = QFileDialog::getSaveFileName(m_matchTool,
2728 "Save registration template",
".",
2729 "Registration template files (*.def *.pvl);;All files (*)");
2731 if (filename.isEmpty())
2746 QString contents = m_templateEditor->toPlainText();
2757 QMessageBox::warning(m_matchTool,
"Error", message);
2761 QString expandedFileName(
2762 FileName((QString) fn).expanded());
2764 QFile file(expandedFileName);
2766 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2767 QString msg =
"Failed to save template file to \"" + fn +
"\"\nDo you "
2769 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2774 QTextStream stream(&file);
2779 m_templateModified =
false;
2780 m_saveTemplateFile->setEnabled(
false);
2781 m_templateFileNameLabel->setText(
"Template File: " + fn);
2803 Pvl templatePvl(m_pointEditor->templateFileName());
2807 registrationDialog.setWindowTitle(
"View or Edit Template File: "
2808 + templatePvl.fileName());
2809 registrationDialog.resize(550,360);
2810 registrationDialog.exec();
2814 QMessageBox::information(m_matchTool,
"Error", message);
2832 void MatchTool::showHideTemplateEditor() {
2834 if (!m_templateEditorWidget)
2837 m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
2855 if (m_editPoint == NULL)
return;
2856 if (pointId != m_editPoint->
GetId())
return;
2861 ControlPoint *updatedPoint = m_controlNet->GetPoint(pointId);
2862 m_editPoint->
SetEditLock(updatedPoint->IsEditLocked());
2863 m_editPoint->
SetIgnored(updatedPoint->IsIgnored());
2866 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
2869 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
2894 if (m_editPoint != NULL) {
2896 QString
id = m_ptIdValue->text().remove(
"Point ID: ");
2897 m_controlNet->GetPoint(
id);
2902 emit editPointChanged();
2920 QColor qc = Qt::red;
2921 QPalette p = m_savePoint->palette();
2922 p.setColor(QPalette::ButtonText,qc);
2923 m_savePoint->setPalette(p);
2943 if (m_editPoint == NULL)
return false;
2965 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
2966 QSettings settings(config.expanded(),
2967 QSettings::NativeFormat);
2968 QPoint pos = settings.value(
"pos", QPoint(300, 100)).toPoint();
2969 QSize size = settings.value(
"size", QSize(900, 500)).toSize();
2970 m_matchTool->resize(size);
2971 m_matchTool->move(pos);
2984 if (!m_matchTool->isVisible())
return;
2985 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
2986 QSettings settings(config.expanded(),
2987 QSettings::NativeFormat);
2988 settings.setValue(
"pos", m_matchTool->pos());
2989 settings.setValue(
"size", m_matchTool->size());
2994 void MatchTool::enterWhatsThisMode() {
2995 QWhatsThis::enterWhatsThisMode();
2999 void MatchTool::clearEditPoint() {
3005 void MatchTool::showHelp() {
3008 helpDialog->setWindowTitle(
"Match Tool Help");
3010 QVBoxLayout *mainLayout =
new QVBoxLayout;
3011 helpDialog->setLayout(mainLayout);
3013 QLabel *matchTitle =
new QLabel(
"<h2>Match Tool</h2>");
3014 mainLayout->addWidget(matchTitle);
3016 QLabel *matchSubtitle =
new QLabel(
"A tool for interactively measuring and editing sample/line "
3017 "registration points between cubes. These "
3018 "points contain sample, line postions only, no latitude or "
3019 "longitude values are used or recorded.");
3020 matchSubtitle->setWordWrap(
true);
3021 mainLayout->addWidget(matchSubtitle);
3023 QTabWidget *tabArea =
new QTabWidget;
3024 tabArea->setDocumentMode(
true);
3025 mainLayout->addWidget(tabArea);
3028 QScrollArea *overviewTab =
new QScrollArea;
3029 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3030 overviewTab->setWidgetResizable(
true);
3032 QVBoxLayout *overviewLayout =
new QVBoxLayout;
3033 overviewContainer->setLayout(overviewLayout);
3035 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
3036 overviewLayout->addWidget(purposeTitle);
3038 QLabel *purposeText =
new QLabel(
"<p>This tool is for recording and editing registration "
3039 "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The "
3040 "recorded registration points are sample and line pixel coordinates only. Therefore, this "
3041 "tool can be used on any images including ones that do not contain a camera model "
3042 "(i.e, The existence of the Isis Instrument Group on the image labels is not required). "
3043 "This also means that the tool differs from the <i>qnet</i> control point network "
3044 "application in that no latitude or longitude values are ever used or recorded "
3045 "(regardless if the image has a camera model in Isis).</p>"
3046 "<p>The output control point network that this tool generates is primarily used 1) as "
3047 "input for an image-wide sample/line translation to register one image to another by "
3048 "'moving' pixel locations - refer to the documentation for applications such as "
3049 "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded "
3050 "measurements in other spreadsheet or plotting packages to visualize magnitude "
3051 "and direction of varying translations of the images relative to one another.</p> "
3052 "<p>An automated version of this match tool is the <i>coreg</i> application. This tool "
3053 "can be used to visually evaluate and edit the control point network created by "
3054 "<i>coreg</i>.</p> "
3055 "<p>The format of the output point network file is binary. This tool uses the Isis control "
3056 " network framework to create, co-register and save all control points and pixel "
3057 "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to "
3058 "a readable PVL format."
3059 "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> "
3060 "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>"
3061 "<p>Control Points are drawn on the associated displayed cubes with the following colors: "
3062 "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
3063 purposeText->setWordWrap(
true);
3064 overviewLayout->addWidget(purposeText);
3066 overviewTab->setWidget(overviewContainer);
3069 QScrollArea *quickTab =
new QScrollArea;
3070 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3071 quickTab->setWidgetResizable(
true);
3073 QVBoxLayout *quickLayout =
new QVBoxLayout;
3074 quickContainer->setLayout(quickLayout);
3076 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
3077 quickLayout->addWidget(quickTitle);
3079 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
3080 quickLayout->addWidget(quickSubTitle);
3082 QLabel *quickPrep =
new QLabel(
"<p><ul>"
3083 "<li>Open the cubes with overlapping areas for choosing control points</li>"
3084 "<li>Choose the match tool <img src=\"" +
toolIconDir() +
3085 "/stock_draw-connector-with-arrows.png\" width=22 height=22> "
3086 "from the toolpad on the right side of the <i>qview</i> main window</li>");
3087 quickPrep->setWordWrap(
true);
3088 quickLayout->addWidget(quickPrep);
3090 QLabel *morePrep =
new QLabel(
"<p>Once the Match tool is activated the tool bar at the top "
3091 "of the main window contains file action buttons and a help button:");
3092 morePrep->setWordWrap(
true);
3093 quickLayout->addWidget(morePrep);
3095 QLabel *fileButtons =
new QLabel(
"<p><ul>"
3096 "<li><img src=\"" +
toolIconDir() +
"/fileopen.png\" width=22 height=22> Open an existing "
3097 "control network <b>Note:</b> If you do not open an existing network, a new one will "
3099 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSaveAs.png\" width=22 height=22> Save "
3100 "control network as ...</li>"
3101 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSave.png\" width=22 height=22> Save "
3102 "control network to current file</li>"
3103 "<li><img src=\"" +
toolIconDir() +
"/help-contents.png\" width=22 height=22> Show Help "
3105 fileButtons->setWordWrap(
true);
3106 quickLayout->addWidget(fileButtons);
3108 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
3109 quickLayout->addWidget(quickFunctionTitle);
3111 QLabel *quickFunction =
new QLabel(
3112 "The match tool window will be shown once "
3113 "you click in a cube viewport window using one of the following "
3114 "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
3115 quickFunction->setWordWrap(
true);
3116 quickLayout->addWidget(quickFunction);
3118 QLabel *quickDesc =
new QLabel(
"<p><ul>"
3119 "<li>Left Click - Modify the control point closest to the click <b>Note:</b> "
3120 "All cubes in the control point must be displayed before loading the point</li>"
3121 "<li>Middle Click - Delete the control point closest to the click</li>"
3122 "<li>Right Click - Create a new control point at the click location</li></ul></p>");
3123 quickDesc->setWordWrap(
true);
3124 quickDesc->setOpenExternalLinks(
true);
3125 quickLayout->addWidget(quickDesc);
3127 quickTab->setWidget(quickContainer);
3130 QScrollArea *controlPointTab =
new QScrollArea;
3131 controlPointTab->setWidgetResizable(
true);
3132 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3134 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
3135 controlPointContainer->setLayout(controlPointLayout);
3137 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
3138 controlPointLayout->addWidget(controlPointTitle);
3140 QLabel *mouseLabel =
new QLabel(
"<p><h3>When the \"Match\" tool "
3141 "is activated, the mouse buttons have the following function in the "
3142 "cube viewports of the main qview window:</h3>");
3143 mouseLabel->setWordWrap(
true);
3144 mouseLabel->setScaledContents(
true);
3145 controlPointLayout->addWidget(mouseLabel);
3147 QLabel *controlPointDesc =
new QLabel(
"<ul>"
3148 "<li>Left click - Edit the closest control point <b>Note:</b> "
3149 "All cubes in the control point must be displayed before loading the point</li>"
3150 "<li>Middle click - Delete the closest control point</li>"
3151 "<li>Right click - Create new control point at cursor location. This will bring up a new "
3152 "point dialog which allows you to enter a point id and will list all cube viewports, "
3153 "highlighting cubes where the point has been chosen by clicking on the cube's viewport. "
3154 "When the desired cubes have been chosen, select the \"Done\" button which will load the "
3155 "control point into the control point editor window which will allow the control measure "
3156 "positions to be refined.</li>");
3157 controlPointDesc->setWordWrap(
true);
3158 controlPointLayout->addWidget(controlPointDesc);
3160 QLabel *controlPointEditing =
new QLabel(
3161 "<h4>Changing Control Measure Locations</h4>"
3162 "<p>Both the left and right control measure positions can be adjusted by:"
3164 "<li>Move the cursor location under the crosshair by clicking the left mouse "
3166 "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
3167 "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>"
3169 "<h4>Other Point Editor Functions</h4>"
3170 "<p>Along the right border of the window:</p>"
3172 "<li><strong>Link Zoom</strong> This will link the two small viewports together when "
3173 "zooming (ie. If this is checked, if the left view is zoomed, the right view will "
3174 "match the left view's zoom factor. "
3175 "<b>Note:</b> Zooming is controlled from the left view.</li>"
3176 "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to "
3177 "its original orientation</li>"
3178 "<li><strong>Rotate:</strong> Rotate the right view using either the dial "
3179 "or entering degrees </li>"
3180 "<li><strong>Show control points:</strong> Draw crosshairs at all control "
3181 "point locations visible within the view</li>"
3182 "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire "
3184 "<li><strong>Circle:</strong> Draw circle which may help center measure "
3185 "on a crater</li></ul"
3186 "<p>Below the left view:</p>"
3187 "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the "
3188 "left view window using the \"Blink Start\" button <img src=\"" +
toolIconDir() +
3189 "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
3190 toolIconDir() +
"/blinkStop.png\" width=22 height=22>. The arrow keys above the left "
3191 "and right views and the keyboard arrow keys may be used to move the both views while "
3193 "<li><strong>Register:</strong> Sub-pixel register the right view to "
3194 "the left view. A default registration template is used for setting parameters "
3195 "passed to the sub-pixel registration tool. The user may load in a predefined "
3196 "template or edit the current loaded template to influence successful "
3197 "co-registration results. For more information regarding the pattern matching "
3198 "functionlity or how to create a parameter template, refer to the Isis PatternMatch "
3199 "document and the <i>autoregtemplate</i> application.</li>"
3200 "<li><strong>Save Measures:</strong> Save the two control measures using the sample, "
3201 "line positions under the crosshairs.</li>"
3202 "<li><strong>Save Point:</strong> Save the control point to the control network.</li>"
3204 controlPointEditing->setWordWrap(
true);
3205 controlPointLayout->addWidget(controlPointEditing);
3207 controlPointTab->setWidget(controlPointContainer);
3210 QScrollArea *coregTab =
new QScrollArea;
3211 coregTab->setWidgetResizable(
true);
3212 coregTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3214 QVBoxLayout *coregLayout =
new QVBoxLayout;
3215 coregContainer->setLayout(coregLayout);
3217 QLabel *coregTitle =
new QLabel(
"<h2>Coreg Guidance</h2>");
3218 coregLayout->addWidget(coregTitle);
3220 QLabel *coregDesc =
new QLabel(
"<p>When opening control networks created by <i>coreg</i>, "
3221 "there are some things to keep in mind. First, all control points must have the same "
3222 "reference measure (this is the image filename passed to the <i>coreg</i> 'match' parameter)."
3223 "<p>In order to retain the integrity of the input <i>coreg</i> network, you cannot change "
3224 "which image is the reference measure on any of the existing points. "
3225 "<p>When creating a new control point to add to the <i>coreg</i> network, this tool will "
3226 "automatically set the reference measure to the same image as the other control points in "
3227 "the network as long as the reference image was one of the images selected with "
3228 "the right mouse button from the new point dialog. If this image was not selected when "
3229 "creating a new point, it "
3230 "does not contain a required measurement, therefore, you will get an error and the new "
3231 "point will not be created.</p> <p>The reference measure is always loaded on the left side "
3232 "of the control point editor. If you load a measure that is not the reference measure "
3233 "on the left side and try to save the point, you will receive an error message. You will "
3234 "need to move the reference measure back to the left side before saving the control point."
3235 "</p><p><b>Note:</b> This error checking will not happen on control networks created by "
3236 "<i>coreg</i> prior to Isis3.4.2. For older <i>coreg</i> control networks the user must be "
3237 "aware and make sure the correct image is set to the same <i>coreg</i> reference measure.");
3238 coregDesc->setWordWrap(
true);
3239 coregDesc->setScaledContents(
true);
3240 coregLayout->addWidget(coregDesc);
3242 coregTab->setWidget(coregContainer);
3244 tabArea->addTab(overviewTab,
"&Overview");
3245 tabArea->addTab(quickTab,
"&Quick Start");
3246 tabArea->addTab(controlPointTab,
"&Control Point Editing");
3247 tabArea->addTab(coregTab,
"&Coreg Guidance");
3249 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
3251 buttonsLayout->addStretch();
3253 QPushButton *closeButton =
new QPushButton(
"&Close");
3254 closeButton->setIcon(QPixmap(
toolIconDir() +
"/guiStop.png"));
3255 closeButton->setDefault(
true);
3256 connect(closeButton, SIGNAL(clicked()),
3257 helpDialog, SLOT(close()));
3258 buttonsLayout->addWidget(closeButton);
3260 mainLayout->addLayout(buttonsLayout);
3279 if ( m_controlNet->GetNumPoints() == 0 ||
3280 !m_controlNet->ContainsPoint(m_editPoint->
GetId())) {
3281 QString message =
"\n\nDo you want to save the point in the editor?";
3282 int response = QMessageBox::question(m_matchTool,
"Save point in editor", message,
3283 QMessageBox::Yes | QMessageBox::No,
3285 if (response == QMessageBox::Yes) {
3291 if (m_controlNet && m_controlNet->GetNumPoints() != 0 && m_netChanged) {
3292 QString message =
"The currently open control net has changed. Do you want to save?";
3293 int response = QMessageBox::question(m_matchTool,
"Save current control net?",
3295 QMessageBox::Yes | QMessageBox::No,
3298 if (response == QMessageBox::Yes) {