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;
159 m_matchTool->setWindowTitle(
"Match Tool");
160 m_matchTool->setObjectName(
"MatchTool");
161 connect(m_matchTool, SIGNAL(destroyed(
QObject *)),
this, SLOT(clearEditPoint()));
170 connect(
this, SIGNAL(newControlNetwork(
ControlNet *)),
171 m_pointEditor, SIGNAL(newControlNetwork(
ControlNet *)));
175 connect(
this, SIGNAL(measureChanged()),
178 m_savePoint =
new QPushButton (
"Save Point");
179 m_savePoint->setShortcut(Qt::Key_P);
180 m_savePoint->setToolTip(
"Save the edit control point to the control network. "
181 "<strong>Shortcut: P</strong>");
182 m_savePoint->setWhatsThis(
"Save the edit control point to the control "
183 "network which is loaded into memory in its entirety. "
184 "When a control point is selected for editing, "
185 "a copy of the point is made so that the original control "
186 "point remains in the network.");
187 m_saveDefaultPalette = m_savePoint->palette();
188 connect (m_savePoint,SIGNAL(clicked()),
this,SLOT(
savePoint()));
190 QHBoxLayout * addMeasureLayout =
new QHBoxLayout;
191 addMeasureLayout->addStretch();
192 addMeasureLayout->addWidget(m_savePoint);
195 m_cnetFileNameLabel =
new QLabel(
"Control Network: " + m_cnetFileName);
196 m_cnetFileNameLabel->setToolTip(
"Name of opened control network file.");
197 m_cnetFileNameLabel->setWhatsThis(
"Name of opened control network file.");
199 m_templateFileNameLabel =
new QLabel(
"Template File: " +
200 m_pointEditor->templateFileName());
201 m_templateFileNameLabel->setToolTip(
"Sub-pixel registration template File.");
205 m_templateFileNameLabel->setWhatsThis(
"FileName of the sub-pixel "
206 "registration template. Refer to $ISISROOT/doc/documents/"
207 "PatternMatch/PatternMatch.html for a description of the "
208 "contents of this file.");
210 QVBoxLayout * centralLayout =
new QVBoxLayout;
212 centralLayout->addWidget(m_cnetFileNameLabel);
213 centralLayout->addWidget(m_templateFileNameLabel);
215 centralLayout->addStretch();
216 centralLayout->addWidget(m_pointEditor);
217 centralLayout->addLayout(addMeasureLayout);
219 centralWidget->setLayout(centralLayout);
221 QScrollArea *scrollArea =
new QScrollArea();
222 scrollArea->setObjectName(
"MatchToolScroll");
223 scrollArea->setWidget(centralWidget);
224 scrollArea->setWidgetResizable(
true);
225 centralWidget->adjustSize();
226 m_matchTool->setCentralWidget(scrollArea);
230 connect(
this, SIGNAL(editPointChanged()),
240 QHBoxLayout * measureLayout =
new QHBoxLayout;
244 QVBoxLayout * groupBoxesLayout =
new QVBoxLayout;
246 groupBoxesLayout->addStretch();
247 groupBoxesLayout->addLayout(measureLayout);
250 groupBoxesWidget->setLayout(groupBoxesLayout);
254 QSplitter * topSplitter =
new QSplitter;
255 topSplitter->addWidget(groupBoxesWidget);
256 topSplitter->addWidget(m_templateEditorWidget);
257 topSplitter->setStretchFactor(0, 4);
258 topSplitter->setStretchFactor(1, 3);
260 m_templateEditorWidget->hide();
270 m_ptIdValue =
new QLabel;
271 m_numMeasures =
new QLabel;
272 QVBoxLayout * leftLayout =
new QVBoxLayout;
273 leftLayout->addWidget(m_ptIdValue);
274 leftLayout->addWidget(m_numMeasures);
277 m_lockPoint =
new QCheckBox(
"Edit Lock Point");
278 connect(m_lockPoint, SIGNAL(clicked(
bool)),
this, SLOT(
setLockPoint(
bool)));
279 m_ignorePoint =
new QCheckBox(
"Ignore Point");
280 connect(m_ignorePoint, SIGNAL(clicked(
bool)),
282 connect(
this, SIGNAL(ignorePointChanged()), m_ignorePoint, SLOT(toggle()));
284 QVBoxLayout * rightLayout =
new QVBoxLayout;
285 rightLayout->addWidget(m_lockPoint);
286 rightLayout->addWidget(m_ignorePoint);
288 QHBoxLayout * mainLayout =
new QHBoxLayout;
289 mainLayout->addLayout(leftLayout);
290 mainLayout->addStretch();
291 mainLayout->addLayout(rightLayout);
294 QGroupBox * groupBox =
new QGroupBox(
"Control Point");
295 groupBox->setLayout(mainLayout);
305 m_leftCombo->view()->installEventFilter(
this);
306 m_leftCombo->setToolTip(
"Choose left control measure");
307 m_leftCombo->setWhatsThis(
"Choose left control measure identified by "
309 connect(m_leftCombo, SIGNAL(activated(
int)),
311 m_lockLeftMeasure =
new QCheckBox(
"Edit Lock Measure");
312 connect(m_lockLeftMeasure, SIGNAL(clicked(
bool)),
314 m_ignoreLeftMeasure =
new QCheckBox(
"Ignore Measure");
315 connect(m_ignoreLeftMeasure, SIGNAL(clicked(
bool)),
317 connect(
this, SIGNAL(ignoreLeftChanged()),
318 m_ignoreLeftMeasure, SLOT(toggle()));
319 m_leftReference =
new QLabel();
320 m_leftMeasureType =
new QLabel();
321 m_leftSampShift =
new QLabel();
322 m_leftSampShift->setToolTip(
"Sample shift between apriori and current");
323 m_leftSampShift->setWhatsThis(
"The shift between the apriori sample and "
324 "the current sample. The apriori sample is set "
325 "when creating a new measure.");
326 m_leftLineShift =
new QLabel();
327 m_leftLineShift->setToolTip(
"Line shift between apriori and current");
328 m_leftLineShift->setWhatsThis(
"The shift between the apriori line and "
329 "the current line. The apriori line is set "
330 "when creating a new measure.");
331 m_leftGoodness =
new QLabel();
332 m_leftGoodness->setToolTip(
"Goodness of Fit result from sub-pixel "
334 m_leftGoodness->setWhatsThis(
"Resulting Goodness of Fit from sub-pixel "
336 QVBoxLayout * leftLayout =
new QVBoxLayout;
337 leftLayout->addWidget(m_leftCombo);
338 leftLayout->addWidget(m_lockLeftMeasure);
339 leftLayout->addWidget(m_ignoreLeftMeasure);
340 leftLayout->addWidget(m_leftReference);
341 leftLayout->addWidget(m_leftMeasureType);
342 leftLayout->addWidget(m_leftSampShift);
343 leftLayout->addWidget(m_leftLineShift);
344 leftLayout->addWidget(m_leftGoodness);
346 QGroupBox * leftGroupBox =
new QGroupBox(
"Left Measure");
347 leftGroupBox->setLayout(leftLayout);
366 m_rightCombo->view()->installEventFilter(
this);
370 QShortcut *nextMeasure =
new QShortcut(Qt::Key_PageDown, m_matchTool);
372 QShortcut *prevMeasure =
new QShortcut(Qt::Key_PageUp, m_matchTool);
375 m_rightCombo->setToolTip(
"Choose right control measure. "
376 "<strong>Shorcuts: PageUp/PageDown</strong>");
377 m_rightCombo->setWhatsThis(
"Choose right control measure identified by "
379 "Note: PageUp selects previous measure; "
380 "PageDown selects next measure.");
381 connect(m_rightCombo, SIGNAL(activated(
int)),
383 m_lockRightMeasure =
new QCheckBox(
"Edit Lock Measure");
384 connect(m_lockRightMeasure, SIGNAL(clicked(
bool)),
386 m_ignoreRightMeasure =
new QCheckBox(
"Ignore Measure");
387 connect(m_ignoreRightMeasure, SIGNAL(clicked(
bool)),
389 connect(
this, SIGNAL(ignoreRightChanged()),
390 m_ignoreRightMeasure, SLOT(toggle()));
391 m_rightReference =
new QLabel();
392 m_rightMeasureType =
new QLabel();
393 m_rightSampShift =
new QLabel();
394 m_rightSampShift->setToolTip(m_leftSampShift->toolTip());
395 m_rightSampShift->setWhatsThis(m_leftSampShift->whatsThis());
396 m_rightLineShift =
new QLabel();
397 m_rightLineShift->setToolTip(m_leftLineShift->toolTip());
398 m_rightLineShift->setWhatsThis(m_leftLineShift->whatsThis());
399 m_rightGoodness =
new QLabel();
400 m_rightGoodness->setToolTip(m_leftGoodness->toolTip());
401 m_rightGoodness->setWhatsThis(m_leftGoodness->whatsThis());
404 QVBoxLayout * rightLayout =
new QVBoxLayout;
405 rightLayout->addWidget(m_rightCombo);
406 rightLayout->addWidget(m_lockRightMeasure);
407 rightLayout->addWidget(m_ignoreRightMeasure);
408 rightLayout->addWidget(m_rightReference);
409 rightLayout->addWidget(m_rightMeasureType);
410 rightLayout->addWidget(m_rightSampShift);
411 rightLayout->addWidget(m_rightLineShift);
412 rightLayout->addWidget(m_rightGoodness);
414 QGroupBox * rightGroupBox =
new QGroupBox(
"Right Measure");
415 rightGroupBox->setLayout(rightLayout);
417 return rightGroupBox;
426 toolBar->addAction(m_openTemplateFile);
427 toolBar->addSeparator();
428 toolBar->addAction(m_saveTemplateFile);
429 toolBar->addAction(m_saveTemplateFileAs);
431 m_templateEditor =
new QTextEdit;
432 connect(m_templateEditor, SIGNAL(textChanged()),
this,
435 QVBoxLayout *mainLayout =
new QVBoxLayout;
436 mainLayout->addWidget(toolBar);
437 mainLayout->addWidget(m_templateEditor);
439 m_templateEditorWidget =
new QWidget;
440 m_templateEditorWidget->setLayout(mainLayout);
454 "Save Control Network ...",
456 m_saveNet->setShortcut(Qt::CTRL + Qt::Key_S);
457 m_saveNet->setToolTip(
"Save current control network");
458 m_saveNet->setStatusTip(
"Save current control network");
459 QString whatsThis =
"<b>Function:</b> Saves the current <i>"
460 "control network</i>";
461 m_saveNet->setWhatsThis(whatsThis);
462 connect(m_saveNet, SIGNAL(activated()),
this, SLOT(
saveNet()));
465 "Save Control Network &As...",
467 m_saveAsNet->setToolTip(
"Save current control network to chosen file");
468 m_saveAsNet->setStatusTip(
"Save current control network to chosen file");
469 whatsThis =
"<b>Function:</b> Saves the current <i>"
470 "control network</i> under chosen filename";
471 m_saveAsNet->setWhatsThis(whatsThis);
472 connect(m_saveAsNet, SIGNAL(activated()),
this, SLOT(
saveAsNet()));
477 m_closeMatchTool->setToolTip(
"Close this window");
478 m_closeMatchTool->setStatusTip(
"Close this window");
479 m_closeMatchTool->setShortcut(Qt::ALT + Qt::Key_F4);
480 whatsThis =
"<b>Function:</b> Closes the Match Tool window for this point "
481 "<p><b>Shortcut:</b> Alt+F4 </p>";
482 m_closeMatchTool->setWhatsThis(whatsThis);
483 connect(m_closeMatchTool, SIGNAL(activated()), m_matchTool, SLOT(close()));
486 "&View/edit registration template",
488 m_showHideTemplateEditor->setCheckable(
true);
489 m_showHideTemplateEditor->setToolTip(
"View and/or edit the registration template");
490 m_showHideTemplateEditor->setStatusTip(
"View and/or edit the registration template");
491 whatsThis =
"<b>Function:</b> Displays the curent registration template. "
492 "The user may edit and save changes under a chosen filename.";
493 m_showHideTemplateEditor->setWhatsThis(whatsThis);
494 connect(m_showHideTemplateEditor, SIGNAL(activated()),
this,
495 SLOT(showHideTemplateEditor()));
498 "Save registration chips",
500 m_saveChips->setToolTip(
"Save registration chips");
501 m_saveChips->setStatusTip(
"Save registration chips");
502 whatsThis =
"<b>Function:</b> Save registration chips to file. "
503 "Each chip: pattern, search, fit will be saved to a separate file.";
504 m_saveChips->setWhatsThis(whatsThis);
505 connect(m_saveChips, SIGNAL(activated()),
this, SLOT(
saveChips()));
508 "&Open registration template",
510 m_openTemplateFile->setToolTip(
"Set registration template");
511 m_openTemplateFile->setStatusTip(
"Set registration template");
512 whatsThis =
"<b>Function:</b> Allows user to select a new file to set as "
513 "the registration template";
514 m_openTemplateFile->setWhatsThis(whatsThis);
515 connect(m_openTemplateFile, SIGNAL(activated()),
this, SLOT(
openTemplateFile()));
518 "&Save template file",
520 m_saveTemplateFile->setToolTip(
"Save the template file");
521 m_saveTemplateFile->setStatusTip(
"Save the template file");
522 m_saveTemplateFile->setWhatsThis(
"Save the registration template file");
523 connect(m_saveTemplateFile, SIGNAL(triggered()),
this,
527 "&Save template as...",
529 m_saveTemplateFileAs->setToolTip(
"Save the template file as");
530 m_saveTemplateFileAs->setStatusTip(
"Save the template file as");
531 m_saveTemplateFileAs->setWhatsThis(
"Save the registration template file as");
532 connect(m_saveTemplateFileAs, SIGNAL(triggered()),
this,
538 m_whatsThis->setShortcut(Qt::SHIFT | Qt::Key_F1);
539 m_whatsThis->setToolTip(
"Activate What's This and click on items on "
540 "user interface to see more information.");
541 connect(m_whatsThis, SIGNAL(activated()),
this, SLOT(enterWhatsThisMode()));
543 m_showHelp =
new QAction(QPixmap(
toolIconDir() +
"/help-contents.png"),
"Help", m_matchTool);
544 m_showHelp->setToolTip(
"Help");
545 connect(m_showHelp, SIGNAL(activated()),
this, SLOT(showHelp()));
562 QMenu *fileMenu = m_matchTool->menuBar()->addMenu(
"&File");
563 fileMenu->addAction(m_saveNet);
564 fileMenu->addAction(m_saveAsNet);
565 fileMenu->addAction(m_closeMatchTool);
567 QMenu * regMenu = m_matchTool->menuBar()->addMenu(
"&Registration");
568 regMenu->addAction(m_openTemplateFile);
569 regMenu->addAction(m_showHideTemplateEditor);
570 regMenu->addAction(m_saveChips);
572 QMenu *helpMenu = m_matchTool->menuBar()->addMenu(
"&Help");
573 helpMenu->addAction(m_whatsThis);
577 void MatchTool::createToolBars() {
580 toolBar->setObjectName(
"TemplateEditorToolBar");
581 toolBar->setFloatable(
false);
582 toolBar->addAction(m_saveNet);
583 toolBar->addSeparator();
584 toolBar->addAction(m_showHideTemplateEditor);
585 toolBar->addAction(m_saveChips);
586 toolBar->addAction(m_showHelp);
587 toolBar->addAction(m_whatsThis);
589 m_matchTool->addToolBar(Qt::TopToolBarArea, toolBar);
607 action->setIcon(QPixmap(
toolIconDir()+
"/stock_draw-connector-with-arrows.png"));
608 action->setToolTip(
"Match Tool - Control Point Editor (T)");
609 action->setShortcut(Qt::Key_T);
615 QWidget *MatchTool::createToolBarWidget(QStackedWidget *parent) {
619 QToolButton *openNetButton =
new QToolButton(hbox);
620 openNetButton->setIcon(QPixmap(
toolIconDir() +
"/fileopen.png"));
621 openNetButton->setIconSize(QSize(22,22));
622 openNetButton->setToolTip(
"Open control network");
623 openNetButton->setEnabled(
true);
624 connect(openNetButton, SIGNAL(clicked()),
this, SLOT(openNet()));
626 QToolButton *saveAsNetButton =
new QToolButton(hbox);
627 saveAsNetButton->setDefaultAction(m_saveAsNet);
628 saveAsNetButton->setIconSize(QSize(22,22));
630 QToolButton *saveNetButton =
new QToolButton(hbox);
631 saveNetButton->setDefaultAction(m_saveNet);
632 saveNetButton->setIconSize(QSize(22,22));
634 QToolButton *helpButton =
new QToolButton(hbox);
635 helpButton->setDefaultAction(m_showHelp);
636 helpButton->setIconSize(QSize(22, 22));
638 QHBoxLayout *layout =
new QHBoxLayout;
639 layout->setMargin(0);
640 layout->addWidget(openNetButton);
641 layout->addWidget(saveAsNetButton);
642 layout->addWidget(saveNetButton);
643 layout->addStretch();
644 layout->addWidget(helpButton);
645 hbox->setLayout(layout);
652 void MatchTool::activateTool() {
655 m_controlNet =
new ControlNet();
686 list.
add(fileName.name(),fileName.expanded());
705 QString serialNumber;
711 catch (IException &e) {
712 serialNumber =
"Unknown";
788 if (*origLeftMeasure == *m_leftMeasure && *origRightMeasure == *m_rightMeasure) {
792 if (m_editPoint->IsIgnored()) {
793 QString message =
"You are saving changes to a measure on an ignored ";
794 message +=
"point. Do you want to set Ignore = False on the point and ";
795 message +=
"both measures?";
796 switch (QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
797 message,
"&Yes",
"&No", 0, 0)) {
801 emit ignorePointChanged();
802 if (m_leftMeasure->IsIgnored()) {
803 m_leftMeasure->SetIgnored(
false);
804 emit ignoreLeftChanged();
806 if (m_rightMeasure->IsIgnored()) {
807 m_rightMeasure->SetIgnored(
false);
808 emit ignoreRightChanged();
816 bool savedAMeasure =
false;
818 bool leftChangeOk = validateMeasureChange(m_leftMeasure);
821 *origLeftMeasure = *m_leftMeasure;
822 savedAMeasure =
true;
824 bool rightChangeOk = validateMeasureChange(m_rightMeasure);
827 *origRightMeasure = *m_rightMeasure;
828 savedAMeasure =
true;
833 *m_leftMeasure = *m_rightMeasure;
836 m_editPoint->
GetId());
844 emit editPointChanged();
865 if (*m == *origMeasure)
return false;
869 QString side =
"right";
882 QString message =
"The " + side +
" measure is editLocked ";
883 message +=
"for editing. Do you want to set EditLock = False for this ";
884 message +=
"measure?";
885 int response = QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
886 message, QMessageBox::Yes | QMessageBox::No);
888 if (response == QMessageBox::Yes) {
889 m->SetEditLock(
false);
890 if (side ==
"left") {
891 m_lockLeftMeasure->setChecked(
false);
894 m_lockRightMeasure->setChecked(
false);
903 if (origMeasure->IsIgnored() && m->IsIgnored()) {
904 QString message =
"The " + side +
"measure is ignored. ";
905 message +=
"Do you want to set Ignore = False on the measure?";
906 switch(QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
907 message,
"&Yes",
"&No", 0, 0)){
910 m->SetIgnored(
false);
911 if (side ==
"left") {
912 emit ignoreLeftChanged();
915 emit ignoreRightChanged();
927 if (m->GetSample() != origMeasure->GetSample() || m->GetLine() != origMeasure->GetLine()) {
928 QString message =
"You are making a change to the reference measure. You ";
929 message +=
"may need to move all of the other measures to match the new ";
930 message +=
" coordinate of the reference measure. Do you really want to ";
931 message +=
" change the reference measure's location? ";
932 switch(QMessageBox::question(m_matchTool,
"Match Tool Save Measure",
933 message,
"&Yes",
"&No", 0, 0)){
945 else if (side ==
"left" && (refMeasure->GetCubeSerialNumber() != m->
GetCubeSerialNumber())) {
947 QString message =
"This control network was created by the <i>coreg</i> program, and the "
948 "reference measure needs to remain the same as what <i>coreg</i> set. "
949 "Therefore, you cannot change which measure is the reference. To "
950 "save this point, move the reference measure (measure in BOLD) back "
952 QMessageBox::information(m_matchTool,
"Cannot change reference", message);
955 QString message =
"This point already contains a reference measure. ";
956 message +=
"Would you like to replace it with the measure on the left?";
957 int response = QMessageBox::question(m_matchTool,
958 "Match Tool Save Measure", message,
959 QMessageBox::Yes | QMessageBox::No,
962 if (response == QMessageBox::Yes) {
966 QString fname = FileName(file).name();
967 int iref = m_leftCombo->findText(fname);
970 QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
971 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
972 iref = m_rightCombo->findText(fname);
973 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
976 fname = FileName(file).name();
977 iref = m_leftCombo->findText(fname);
978 m_leftCombo->setItemData(iref,font,Qt::FontRole);
979 iref = m_rightCombo->findText(fname);
980 m_rightCombo->setItemData(iref,font,Qt::FontRole);
989 if (side ==
"left") {
1011 void MatchTool::checkReference() {
1018 QString message =
"This point already contains a reference measure. ";
1019 message +=
"Would you like to replace it with the measure on the left?";
1020 int response = QMessageBox::question(m_matchTool,
1021 "Match Tool Save Measure", message,
1022 QMessageBox::Yes | QMessageBox::No,
1025 if (response == QMessageBox::Yes) {
1029 QString fname = FileName(file).name();
1030 int iref = m_leftCombo->findText(fname);
1033 QVariant font = m_leftCombo->itemData(iref,Qt::FontRole);
1034 m_leftCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1035 iref = m_rightCombo->findText(fname);
1036 m_rightCombo->setItemData(iref,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1039 fname = FileName(file).name();
1040 iref = m_leftCombo->findText(fname);
1041 m_leftCombo->setItemData(iref,font,Qt::FontRole);
1042 iref = m_rightCombo->findText(fname);
1043 m_rightCombo->setItemData(iref,font,Qt::FontRole);
1075 *updatePoint = *m_editPoint;
1079 if (m_controlNet->ContainsPoint(updatePoint->
GetId())) {
1081 p = m_controlNet->GetPoint(QString(updatePoint->
GetId()));
1087 m_controlNet->AddPoint(updatePoint);
1091 m_savePoint->setPalette(m_saveDefaultPalette);
1094 emit editPointChanged();
1096 m_netChanged =
true;
1098 m_pointEditor->refreshChips();
1113 if (m_editPoint == NULL)
return;
1132 if (m_editPoint == NULL)
return;
1136 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1137 QString message =
"Unable to change Ignored on point. Set EditLock ";
1138 message +=
" to False.";
1139 QMessageBox::critical(m_matchTool,
"Error", message);
1165 if (m_editPoint->IsEditLocked()) {
1166 m_lockLeftMeasure->setChecked(m_leftMeasure->
IsEditLocked());
1167 QMessageBox::warning(m_matchTool,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1168 " before changing a measure.");
1169 m_lockLeftMeasure->setChecked(m_leftMeasure->
IsEditLocked());
1173 if (m_leftMeasure != NULL) m_leftMeasure->SetEditLock(lock);
1177 if (m_rightMeasure != NULL) {
1179 m_rightMeasure->SetEditLock(lock);
1180 m_lockRightMeasure->setChecked(lock);
1183 emit measureChanged();
1205 if (m_leftMeasure != NULL) m_leftMeasure->SetIgnored(ignore);
1209 if (m_rightMeasure != NULL) {
1211 m_rightMeasure->SetIgnored(ignore);
1212 m_ignoreRightMeasure->setChecked(ignore);
1215 emit measureChanged();
1236 if (m_editPoint->IsEditLocked()) {
1237 m_lockRightMeasure->setChecked(m_rightMeasure->
IsEditLocked());
1238 QMessageBox::warning(m_matchTool,
"Point Locked",
"Point is Edit Locked. You must un-lock point"
1239 " before changing a measure.");
1240 m_lockRightMeasure->setChecked(m_rightMeasure->
IsEditLocked());
1244 if (m_rightMeasure != NULL) m_rightMeasure->SetEditLock(lock);
1247 if (m_leftMeasure != NULL) {
1249 m_leftMeasure->SetEditLock(lock);
1250 m_lockLeftMeasure->setChecked(lock);
1253 emit measureChanged();
1275 if (m_rightMeasure != NULL) m_rightMeasure->SetIgnored(ignore);
1279 if (m_leftMeasure != NULL) {
1281 m_leftMeasure->SetIgnored(ignore);
1282 m_ignoreLeftMeasure->setChecked(ignore);
1285 emit measureChanged();
1290 void MatchTool::openNet() {
1293 if (m_controlNet->GetNumPoints() != 0 && m_netChanged) {
1294 QString message =
"A control net has already been created. Do you want to save before "
1295 "opening a new control net?";
1296 int response = QMessageBox::question(m_matchTool,
"Save current control net?",
1298 QMessageBox::Yes | QMessageBox::No,
1301 if (response == QMessageBox::Yes) {
1304 m_matchTool->setShown(
false);
1306 delete m_controlNet;
1307 m_controlNet = NULL;
1310 m_newPointDialog = NULL;
1314 m_netChanged =
false;
1316 QApplication::restoreOverrideCursor();
1317 QString filter =
"Control net (*.net *.cnet *.ctl);;";
1318 filter +=
"Pvl file (*.pvl);;";
1319 filter +=
"Text file (*.txt);;";
1320 filter +=
"All (*)";
1321 m_cnetFileName = QFileDialog::getOpenFileName((
QWidget *)parent(),
1322 "Select a control network",
1325 QApplication::setOverrideCursor(Qt::WaitCursor);
1326 if (!m_cnetFileName.isEmpty()) {
1329 m_controlNet =
new ControlNet(m_cnetFileName, &progress);
1331 m_coregReferenceSN =
"";
1332 if (m_controlNet->GetNetworkId() ==
"Coreg") {
1336 m_coregReferenceSN = m_controlNet->GetPoint(0)->GetReferenceSN();
1339 catch (IException &e) {
1340 QApplication::restoreOverrideCursor();
1341 QString message =
"Invalid control network. \n";
1342 message += e.toString();
1343 QMessageBox::critical(m_matchTool,
"Error", message);
1344 m_cnetFileName.clear();
1345 delete m_controlNet;
1346 m_controlNet = NULL;
1350 QApplication::restoreOverrideCursor();
1351 m_matchTool->setWindowTitle(
"Match Tool - Control Network File: " + m_cnetFileName);
1352 m_cnetFileNameLabel->setText(
"Control Network: " + m_cnetFileName);
1365 if (m_cnetFileName.isEmpty()) {
1366 QString message =
"This is a new network, you must select "
1367 "\"Save As\" under the File Menu or on the toolbar.";
1368 QMessageBox::critical(m_matchTool,
"Error", message);
1372 m_controlNet->Write(m_cnetFileName);
1373 m_netChanged =
false;
1376 QMessageBox::critical(m_matchTool, tr(
"Error Writing Control Net"), e.
what());
1388 QString fn = QFileDialog::getSaveFileName(m_matchTool,
1389 "Choose filename to save under",
1391 "Control Files (*.net)");
1396 m_controlNet->Write(fn);
1397 m_netChanged =
false;
1400 QMessageBox::critical(m_matchTool, tr(
"Error Writing Control Net"), e.
what());
1403 m_cnetFileName = fn;
1443 if (mvp == NULL)
return;
1451 if (s == Qt::LeftButton) {
1453 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1454 QString message =
"No points exist for editing. Create points ";
1455 message +=
"using the right mouse button.";
1456 QMessageBox::warning(m_matchTool,
"Warning", message);
1464 point = m_controlNet->FindClosest(sn, samp, line);
1467 QString message =
"Cannot find point for editing.";
1469 QMessageBox::warning(m_matchTool,
"Warning", message);
1475 else if (s == Qt::MidButton) {
1476 if (!m_controlNet || m_controlNet->GetNumPoints() == 0) {
1477 QString message =
"No points exist for deleting. Create points ";
1478 message +=
"using the right mouse button.";
1479 QMessageBox::warning(m_matchTool,
"Warning", message);
1484 ControlPoint *point = m_controlNet->FindClosest(sn, samp, line);
1486 if (point == NULL) {
1487 QString message =
"No points exist for deleting. Create points ";
1488 message +=
"using the right mouse button.";
1489 QMessageBox::warning(m_matchTool,
"Warning", message);
1495 else if (s == Qt::RightButton) {
1496 if (m_newPointDialog) {
1497 addMeasure(mvp, samp, line);
1505 QString message =
"Cannot create control point.\n\n";
1507 QMessageBox::critical(m_matchTool,
"Error", message);
1520 for (
int i=0; i<point->GetNumMeasures(); i++) {
1526 return missingCubes;
1540 connect(m_newPointDialog, SIGNAL(measuresFinished()),
this, SLOT(doneWithMeasures()));
1541 connect(m_newPointDialog, SIGNAL(newPointCanceled()),
this, SLOT(cancelNewPoint()));
1546 images<<cubeFile.name();
1548 m_newPointDialog->
setFiles(images);
1549 m_newPointDialog->show();
1553 m_newPointDialog->highlightFile(current);
1572 void MatchTool::addMeasure(
MdiCubeViewport *cvp,
double sample,
double line) {
1576 m_newPointDialog->highlightFile(current);
1577 m_newPointDialog->raise();
1597 void MatchTool::doneWithMeasures() {
1599 m_lastUsedPointId = m_newPointDialog->pointId();
1600 m_newPoint->
SetId(m_lastUsedPointId);
1611 QString message =
"This is a coreg network which needs the cube with serial number " +
1612 m_coregReferenceSN +
" as the reference measure. This new control point does "
1613 "not have a measure for that serial number, so this point cannot be created until "
1614 "the cube listed above is added (Right-click on cube).";
1615 QMessageBox::critical(m_matchTool,
"Error", message);
1616 m_newPointDialog->show();
1624 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1628 m_editPoint = m_newPoint;
1631 delete m_newPointDialog;
1632 m_newPointDialog = NULL;
1636 m_matchTool->setShown(
true);
1637 m_matchTool->raise();
1639 emit editPointChanged();
1645 void MatchTool::cancelNewPoint() {
1647 delete m_newPointDialog;
1648 m_newPointDialog = NULL;
1680 if (mCubes.size() > 0) {
1681 QString msgTitle =
"Missing Cubes";
1682 QString message =
"This point is missing cubes for the following measures and cannot be ";
1683 message +=
"loaded into the editor. Do you still want to delete this point?\n\n";
1684 for (
int i=0; i<mCubes.size(); i++) {
1685 message += mCubes.at(i) +
"\n";
1687 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1689 QPushButton *yesButton = msgBox.addButton(
"Yes", QMessageBox::AcceptRole);
1690 QPushButton *noButton = msgBox.addButton(
"No", QMessageBox::RejectRole);
1691 msgBox.setDefaultButton(yesButton);
1693 if (msgBox.clickedButton() == noButton) {
1697 m_matchTool->setShown(
false);
1704 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1709 *m_editPoint = *point;
1712 if (mCubes.size() == 0) {
1718 emit editPointChanged();
1722 QString CPId = m_editPoint->
GetId();
1723 deletePointDialog->pointIdValue->setText(CPId);
1725 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1734 deletePointDialog->fileList->addItem(file);
1737 if (deletePointDialog->exec()) {
1739 int numDeleted = deletePointDialog->fileList->selectedItems().count();
1742 if (deletePointDialog->deleteAllCheckBox->isChecked() ||
1743 numDeleted == m_editPoint->GetNumMeasures()) {
1746 if (!deletePointDialog->deleteAllCheckBox->isChecked()) {
1747 QString message =
"You have selected all measures in this point to be deleted. This "
1748 "control point will be deleted. Do you want to delete this control point?";
1749 int response = QMessageBox::question(m_matchTool,
1750 "Delete control point", message,
1751 QMessageBox::Yes | QMessageBox::No,
1754 if (response == QMessageBox::No) {
1759 m_matchTool->setShown(
false);
1762 QMessageBox::information(m_matchTool,
"EditLocked Point",
1763 "This point is EditLocked and cannot be deleted.");
1766 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1775 int lockedMeasures = 0;
1776 for (
int i=0; i<deletePointDialog->fileList->count(); i++) {
1777 QListWidgetItem *item = deletePointDialog->fileList->item(i);
1778 if (!deletePointDialog->fileList->isItemSelected(item))
continue;
1783 (*m_editPoint)[i]->GetCubeSerialNumber())) {
1784 QString message =
"You are trying to delete the Reference measure."
1785 " Do you really want to delete the Reference measure?";
1786 switch (QMessageBox::question(m_matchTool,
1787 "Delete Reference measure?", message,
1788 "&Yes",
"&No", 0, 0)) {
1796 if (numDeleted == 1) {
1803 if (m_editPoint->
Delete(i) == ControlMeasure::MeasureLocked) {
1808 if (lockedMeasures > 0) {
1809 QMessageBox::information(m_matchTool,
"EditLocked Measures",
1810 QString::number(lockedMeasures) +
" / "
1812 deletePointDialog->fileList->selectedItems().size()) +
1813 " measures are EditLocked and were not deleted.");
1816 if (mCubes.size() == 0) {
1818 m_matchTool->setShown(
true);
1819 m_matchTool->raise();
1822 m_pointEditor->templateFileName());
1830 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1839 m_netChanged =
true;
1844 emit editPointChanged();
1861 if (point->GetNumMeasures() == 0) {
1862 QString message =
"This point has no measures.";
1863 QMessageBox::warning(m_matchTool,
"Warning", message);
1864 emit editPointChanged();
1870 if (mCubes.size() > 0) {
1871 QString msgTitle =
"Missing Cubes";
1872 QString message =
"This point is missing cubes and cannot be loaded into the editor. Open ";
1873 message +=
"the cubes for the following measures before selecting this point.\n\n";
1874 for (
int i=0; i<mCubes.size(); i++) {
1875 message += mCubes.at(i) +
"\n";
1877 QMessageBox msgBox(QMessageBox::Critical, msgTitle, message, 0, m_matchTool,
1885 if (m_editPoint != NULL && m_editPoint->Parent() == NULL) {
1890 *m_editPoint = *point;
1893 m_matchTool->setShown(
true);
1894 m_matchTool->raise();
1896 m_pointEditor->templateFileName());
1899 emit editPointChanged();
1902 m_savePoint->setPalette(m_saveDefaultPalette);
1927 QString CPId = m_editPoint->
GetId();
1928 QString ptId(
"Point ID: ");
1929 ptId += (QString) CPId;
1930 m_ptIdValue->setText(ptId);
1933 QString ptsize =
"Number of Measures: " +
1934 QString::number(m_editPoint->GetNumMeasures());
1935 m_numMeasures->setText(ptsize);
1938 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
1941 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
1944 m_leftCombo->clear();
1945 m_rightCombo->clear();
1946 m_pointFiles.clear();
1949 for (
int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1953 QString tempFileName =
FileName(file).name();
1954 m_leftCombo->addItem(tempFileName);
1955 m_rightCombo->addItem(tempFileName);
1958 m_leftCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1959 m_rightCombo->setItemData(i,QFont(
"DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1978 if (!m_leftFile.isEmpty()) {
1979 leftIndex = m_leftCombo->findText(
FileName(m_leftFile).name());
1981 if (leftIndex < 0 ) leftIndex = 0;
1986 if (leftIndex == 0) {
1995 if (rightIndex > m_editPoint->GetNumMeasures()-1) rightIndex = 0;
1996 m_rightCombo->setCurrentIndex(rightIndex);
1997 m_leftCombo->setCurrentIndex(leftIndex);
2015 if (m_measureWindow == NULL) {
2017 m_measureTable =
new QTableWidget();
2018 m_measureTable->setMinimumWidth(1600);
2019 m_measureTable->setAlternatingRowColors(
true);
2020 m_measureWindow->setCentralWidget(m_measureTable);
2023 m_measureTable->clear();
2024 m_measureTable->setSortingEnabled(
false);
2026 m_measureTable->setRowCount(m_editPoint->GetNumMeasures());
2027 m_measureTable->setColumnCount(NUMCOLUMNS);
2030 for (
int i=0; i<NUMCOLUMNS; i++) {
2031 labels<<measureColumnToString((MeasureColumns)i);
2033 m_measureTable->setHorizontalHeaderLabels(labels);
2036 for (
int row=0; row<m_editPoint->GetNumMeasures(); row++) {
2041 QTableWidgetItem *tableItem =
new QTableWidgetItem(QString(file));
2042 m_measureTable->setItem(row,column++,tableItem);
2045 m_measureTable->setItem(row,column++,tableItem);
2047 tableItem =
new QTableWidgetItem();
2048 tableItem->setData(0,m.GetSample());
2049 m_measureTable->setItem(row,column++,tableItem);
2051 tableItem =
new QTableWidgetItem();
2052 tableItem->setData(0,m.GetLine());
2053 m_measureTable->setItem(row,column++,tableItem);
2055 if (m.GetAprioriSample() ==
Null) {
2056 tableItem =
new QTableWidgetItem(
"Null");
2059 tableItem =
new QTableWidgetItem();
2060 tableItem->setData(0,m.GetAprioriSample());
2062 m_measureTable->setItem(row,column++,tableItem);
2064 if (m.GetAprioriLine() ==
Null) {
2065 tableItem =
new QTableWidgetItem(
"Null");
2068 tableItem =
new QTableWidgetItem();
2069 tableItem->setData(0,m.GetAprioriLine());
2071 m_measureTable->setItem(row,column++,tableItem);
2073 if (m.GetSampleResidual() ==
Null) {
2074 tableItem =
new QTableWidgetItem(QString(
"Null"));
2077 tableItem =
new QTableWidgetItem();
2078 tableItem->setData(0,m.GetSampleResidual());
2080 m_measureTable->setItem(row,column++,tableItem);
2082 if (m.GetLineResidual() ==
Null) {
2083 tableItem =
new QTableWidgetItem(QString(
"Null"));
2086 tableItem =
new QTableWidgetItem();
2087 tableItem->setData(0,m.GetLineResidual());
2089 m_measureTable->setItem(row,column++,tableItem);
2092 tableItem =
new QTableWidgetItem(QString(
"Null"));
2095 tableItem =
new QTableWidgetItem();
2098 m_measureTable->setItem(row,column++,tableItem);
2100 double sampleShift = m.GetSampleShift();
2101 if (sampleShift ==
Null) {
2102 tableItem =
new QTableWidgetItem(QString(
"Null"));
2105 tableItem =
new QTableWidgetItem();
2106 tableItem->setData(0,sampleShift);
2108 m_measureTable->setItem(row,column++,tableItem);
2110 double lineShift = m.GetLineShift();
2111 if (lineShift ==
Null) {
2112 tableItem =
new QTableWidgetItem(QString(
"Null"));
2115 tableItem =
new QTableWidgetItem();
2116 tableItem->setData(0,lineShift);
2118 m_measureTable->setItem(row,column++,tableItem);
2120 double pixelShift = m.GetPixelShift();
2121 if (pixelShift ==
Null) {
2122 tableItem =
new QTableWidgetItem(QString(
"Null"));
2125 tableItem =
new QTableWidgetItem();
2126 tableItem->setData(0,pixelShift);
2128 m_measureTable->setItem(row,column++,tableItem);
2130 double goodnessOfFit = m.GetLogData(
2132 if (goodnessOfFit ==
Null) {
2133 tableItem =
new QTableWidgetItem(QString(
"Null"));
2136 tableItem =
new QTableWidgetItem();
2137 tableItem->setData(0,goodnessOfFit);
2139 m_measureTable->setItem(row,column++,tableItem);
2141 if (m.IsIgnored()) tableItem =
new QTableWidgetItem(
"True");
2142 if (!m.IsIgnored()) tableItem =
new QTableWidgetItem(
"False");
2143 m_measureTable->setItem(row,column++,tableItem);
2146 tableItem =
new QTableWidgetItem(
"True");
2148 tableItem =
new QTableWidgetItem(
"False");
2149 m_measureTable->setItem(row,column++,tableItem);
2151 tableItem =
new QTableWidgetItem(
2153 m_measureTable->setItem(row,column,tableItem);
2161 for (
int col=0; col<m_measureTable->columnCount(); col++)
2162 m_measureTable->item(row, col)->setFont(font);
2167 m_measureTable->resizeColumnsToContents();
2168 m_measureTable->resizeRowsToContents();
2169 m_measureTable->setSortingEnabled(
true);
2170 m_measureWindow->show();
2175 QString MatchTool::measureColumnToString(MatchTool::MeasureColumns column) {
2185 case SAMPLERESIDUAL:
2186 return "Sample Residual";
2188 return "Line Residual";
2189 case RESIDUALMAGNITUDE:
2190 return "Residual Magnitude";
2192 return "Sample Shift";
2194 return "Line Shift";
2196 return "Pixel Shift";
2198 return "Goodness of Fit";
2204 return "Measure Type";
2206 return "Apriori Sample";
2208 return "Apriori Line";
2211 "Invalid measure column passed to measureColumnToString",
_FILEINFO_);
2226 int curIndex = m_rightCombo->currentIndex();
2227 if (curIndex < m_rightCombo->count() - 1) {
2229 m_rightCombo->setCurrentIndex(curIndex + 1);
2245 int curIndex = m_rightCombo->currentIndex();
2248 m_rightCombo->setCurrentIndex(curIndex - 1);
2269 QString file = m_pointFiles[index];
2276 QString message =
"Make sure the correct cube is opened.\n\n";
2278 QMessageBox::critical(m_matchTool,
"Error", message);
2283 int i = m_leftCombo->findText(
FileName(file).name());
2285 m_leftCombo->setCurrentIndex(i);
2291 if (m_leftMeasure != NULL) {
2292 delete m_leftMeasure;
2293 m_leftMeasure = NULL;
2297 *m_leftMeasure = *((*m_editPoint)[serial]);
2300 if (m_leftCube != NULL)
delete m_leftCube;
2301 m_leftCube =
new Cube();
2302 m_leftCube->
open(file);
2306 m_editPoint->
GetId());
2325 QString file = m_pointFiles[index];
2332 QString message =
"Make sure the correct cube is opened.\n\n";
2334 QMessageBox::critical(m_matchTool,
"Error", message);
2339 int i = m_rightCombo->findText(
FileName(file).name());
2341 m_rightCombo->setCurrentIndex(i);
2347 if (m_rightMeasure != NULL) {
2348 delete m_rightMeasure;
2349 m_rightMeasure = NULL;
2353 *m_rightMeasure = *((*m_editPoint)[serial]);
2356 if (m_rightCube != NULL)
delete m_rightCube;
2357 m_rightCube =
new Cube();
2358 m_rightCube->
open(file);
2362 m_editPoint->
GetId());
2391 m_ignoreLeftMeasure->setChecked(m_leftMeasure->IsIgnored());
2393 QString s =
"Reference: ";
2401 m_leftReference->setText(s);
2403 s =
"Measure Type: ";
2408 m_leftMeasureType->setText(s);
2410 if (m_leftMeasure->GetSampleShift() ==
Null) {
2411 s =
"Sample Shift: Null";
2414 s =
"Sample Shift: " + QString::number(m_leftMeasure->GetSampleShift());
2416 m_leftSampShift->setText(s);
2418 if (m_leftMeasure->GetLineShift() ==
Null) {
2419 s =
"Line Shift: Null";
2422 s =
"Line Shift: " + QString::number(m_leftMeasure->GetLineShift());
2424 m_leftLineShift->setText(s);
2426 double goodnessOfFit = m_leftMeasure->GetLogData(
2428 if (goodnessOfFit ==
Null) {
2429 s =
"Goodness of Fit: Null";
2432 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2434 m_leftGoodness->setText(s);
2464 m_ignoreRightMeasure->setChecked(m_rightMeasure->IsIgnored());
2466 QString s =
"Reference: ";
2475 m_rightReference->setText(s);
2477 s =
"Measure Type: ";
2482 m_rightMeasureType->setText(s);
2484 if (m_rightMeasure->GetSampleShift() ==
Null) {
2485 s =
"Sample Shift: Null";
2488 s =
"Sample Shift: " + QString::number(m_rightMeasure->GetSampleShift());
2490 m_rightSampShift->setText(s);
2492 if (m_rightMeasure->GetLineShift() ==
Null) {
2493 s =
"Line Shift: Null";
2496 s =
"Line Shift: " + QString::number(m_rightMeasure->GetLineShift());
2498 m_rightLineShift->setText(s);
2500 double goodnessOfFit = m_rightMeasure->GetLogData(
2502 if (goodnessOfFit ==
Null) {
2503 s =
"Goodness of Fit: Null";
2506 s =
"Goodness of Fit: " + QString::number(goodnessOfFit);
2508 m_rightGoodness->setText(s);
2525 if(e->type() != QEvent::Leave)
return false;
2526 if(o == m_leftCombo->view()) {
2528 m_leftCombo->hidePopup();
2530 if (o == m_rightCombo->view()) {
2532 m_rightCombo->hidePopup();
2572 mvp->viewport()->update();
2601 if ( (m_controlNet == NULL || m_controlNet->GetNumPoints() == 0) && m_newPoint == NULL &&
2602 m_editPoint == NULL)
2605 QString sn = serialNumber(mvp);
2609 if (m_newPoint != NULL) {
2613 double samp = (*m_newPoint)[sn]->GetSample();
2614 double line = (*m_newPoint)[sn]->GetLine();
2618 QBrush brush(Qt::red);
2622 painter->setPen(pen);
2623 painter->drawLine(x - 5, y, x + 5, y);
2624 painter->drawLine(x, y - 5, x, y + 5);
2629 if (!m_controlNet->GetCubeSerials().contains(
2637 m_controlNet->GetMeasuresInCube(sn);
2639 for (
int i = 0; i < measures.count(); i++) {
2642 double samp = m->GetSample();
2643 double line = m->GetLine();
2647 if (m->Parent()->IsIgnored()) {
2648 painter->setPen(QColor(255, 255, 0));
2651 else if (m->IsIgnored()) {
2652 painter->setPen(QColor(255, 255, 0));
2655 painter->setPen(Qt::green);
2658 painter->drawLine(x - 5, y, x + 5, y);
2659 painter->drawLine(x, y - 5, x, y + 5);
2662 if (m_editPoint != NULL && m_newPoint == NULL) {
2666 double samp = (*m_editPoint)[sn]->GetSample();
2667 double line = (*m_editPoint)[sn]->GetLine();
2671 QBrush brush(Qt::red);
2675 painter->setPen(pen);
2676 painter->drawLine(x - 5, y, x + 5, y);
2677 painter->drawLine(x, y - 5, x, y + 5);
2699 if (m_templateModified) {
2700 int r = QMessageBox::warning(m_matchTool, tr(
"OK to continue?"),
2701 tr(
"The currently opened registration template has been modified.\n"
2703 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
2706 if (r == QMessageBox::Yes)
2708 else if (r == QMessageBox::Cancel)
2727 QString filename = QFileDialog::getOpenFileName(m_matchTool,
2728 "Select a registration template",
".",
2729 "Registration template files (*.def *.pvl);;All files (*)");
2731 if (filename.isEmpty())
2748 QFile file(
FileName((QString) fn).expanded());
2749 if (!file.open(QIODevice::ReadOnly)) {
2750 QString msg =
"Failed to open template file \"" + fn +
"\"";
2751 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2755 QTextStream stream(&file);
2756 m_templateEditor->setText(stream.readAll());
2759 QScrollBar * sb = m_templateEditor->verticalScrollBar();
2760 sb->setValue(sb->minimum());
2762 m_templateModified =
false;
2763 m_saveTemplateFile->setEnabled(
false);
2764 m_templateFileNameLabel->setText(
"Template File: " + fn);
2771 m_templateModified =
true;
2772 m_saveTemplateFile->setEnabled(
true);
2780 if (!m_templateModified)
2784 m_pointEditor->templateFileName();
2794 QString filename = QFileDialog::getSaveFileName(m_matchTool,
2795 "Save registration template",
".",
2796 "Registration template files (*.def *.pvl);;All files (*)");
2798 if (filename.isEmpty())
2813 QString contents = m_templateEditor->toPlainText();
2824 QMessageBox::warning(m_matchTool,
"Error", message);
2828 QString expandedFileName(
2829 FileName((QString) fn).expanded());
2831 QFile file(expandedFileName);
2833 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
2834 QString msg =
"Failed to save template file to \"" + fn +
"\"\nDo you "
2836 QMessageBox::warning(m_matchTool,
"IO Error", msg);
2841 QTextStream stream(&file);
2846 m_templateModified =
false;
2847 m_saveTemplateFile->setEnabled(
false);
2848 m_templateFileNameLabel->setText(
"Template File: " + fn);
2870 Pvl templatePvl(m_pointEditor->templateFileName());
2874 registrationDialog.setWindowTitle(
"View or Edit Template File: "
2875 + templatePvl.fileName());
2876 registrationDialog.resize(550,360);
2877 registrationDialog.exec();
2881 QMessageBox::information(m_matchTool,
"Error", message);
2899 void MatchTool::showHideTemplateEditor() {
2901 if (!m_templateEditorWidget)
2904 m_templateEditorWidget->setVisible(!m_templateEditorWidget->isVisible());
2922 if (m_editPoint == NULL)
return;
2923 if (pointId != m_editPoint->
GetId())
return;
2928 ControlPoint *updatedPoint = m_controlNet->GetPoint(pointId);
2929 m_editPoint->
SetEditLock(updatedPoint->IsEditLocked());
2930 m_editPoint->
SetIgnored(updatedPoint->IsIgnored());
2933 m_lockPoint->setChecked(m_editPoint->IsEditLocked());
2936 m_ignorePoint->setChecked(m_editPoint->IsIgnored());
2961 if (m_editPoint != NULL) {
2963 QString
id = m_ptIdValue->text().remove(
"Point ID: ");
2964 m_controlNet->GetPoint(
id);
2969 emit editPointChanged();
2987 QColor qc = Qt::red;
2988 QPalette p = m_savePoint->palette();
2989 p.setColor(QPalette::ButtonText,qc);
2990 m_savePoint->setPalette(p);
3010 if (m_editPoint == NULL)
return false;
3032 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
3033 QSettings settings(config.expanded(),
3034 QSettings::NativeFormat);
3035 QPoint pos = settings.value(
"pos", QPoint(300, 100)).toPoint();
3036 QSize size = settings.value(
"size", QSize(900, 500)).toSize();
3037 m_matchTool->resize(size);
3038 m_matchTool->move(pos);
3051 if (!m_matchTool->isVisible())
return;
3052 FileName config(
"$HOME/.Isis/qview/MatchTool.config");
3053 QSettings settings(config.expanded(),
3054 QSettings::NativeFormat);
3055 settings.setValue(
"pos", m_matchTool->pos());
3056 settings.setValue(
"size", m_matchTool->size());
3061 void MatchTool::enterWhatsThisMode() {
3062 QWhatsThis::enterWhatsThisMode();
3066 void MatchTool::clearEditPoint() {
3072 void MatchTool::showHelp() {
3075 helpDialog->setWindowTitle(
"Match Tool Help");
3077 QVBoxLayout *mainLayout =
new QVBoxLayout;
3078 helpDialog->setLayout(mainLayout);
3080 QLabel *matchTitle =
new QLabel(
"<h2>Match Tool</h2>");
3081 mainLayout->addWidget(matchTitle);
3083 QLabel *matchSubtitle =
new QLabel(
"A tool for interactively measuring and editing sample/line "
3084 "registration points between cubes. These "
3085 "points contain sample, line postions only, no latitude or "
3086 "longitude values are used or recorded.");
3087 matchSubtitle->setWordWrap(
true);
3088 mainLayout->addWidget(matchSubtitle);
3090 QTabWidget *tabArea =
new QTabWidget;
3091 tabArea->setDocumentMode(
true);
3092 mainLayout->addWidget(tabArea);
3095 QScrollArea *overviewTab =
new QScrollArea;
3096 overviewTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3097 overviewTab->setWidgetResizable(
true);
3099 QVBoxLayout *overviewLayout =
new QVBoxLayout;
3100 overviewContainer->setLayout(overviewLayout);
3102 QLabel *purposeTitle =
new QLabel(
"<h2>Purpose</h2>");
3103 overviewLayout->addWidget(purposeTitle);
3105 QLabel *purposeText =
new QLabel(
"<p>This tool is for recording and editing registration "
3106 "points measured between cubes displayed in the <i>qview</i> main window.</p> <p>The "
3107 "recorded registration points are sample and line pixel coordinates only. Therefore, this "
3108 "tool can be used on any images including ones that do not contain a camera model "
3109 "(i.e, The existence of the Isis Instrument Group on the image labels is not required). "
3110 "This also means that the tool differs from the <i>qnet</i> control point network "
3111 "application in that no latitude or longitude values are ever used or recorded "
3112 "(regardless if the image has a camera model in Isis).</p>"
3113 "<p>The output control point network that this tool generates is primarily used 1) as "
3114 "input for an image-wide sample/line translation to register one image to another by "
3115 "'moving' pixel locations - refer to the documentation for applications such as "
3116 "<i>translate</i> and <i>warp</i>, or 2) to export the file and use the recorded "
3117 "measurements in other spreadsheet or plotting packages to visualize magnitude "
3118 "and direction of varying translations of the images relative to one another.</p> "
3119 "<p>An automated version of this match tool is the <i>coreg</i> application. This tool "
3120 "can be used to visually evaluate and edit the control point network created by "
3121 "<i>coreg</i>.</p> "
3122 "<p>The format of the output point network file is binary. This tool uses the Isis control "
3123 " network framework to create, co-register and save all control points and pixel "
3124 "measurements. The application <i>cnetbin2pvl</i> can be used to convert from binary to "
3125 "a readable PVL format."
3126 "<p>The Mouse Button functions are: (same as <i>qnet</i>)<ul><li>Modify Point=Left</li> "
3127 "<li>Delete Point=Middle</li><li>Create New Point=Right</li></ul></p>"
3128 "<p>Control Points are drawn on the associated displayed cubes with the following colors: "
3129 "Green=Valid registration point; Yellow=Ignored point; Red=Active point being edited");
3130 purposeText->setWordWrap(
true);
3131 overviewLayout->addWidget(purposeText);
3133 overviewTab->setWidget(overviewContainer);
3136 QScrollArea *quickTab =
new QScrollArea;
3137 quickTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3138 quickTab->setWidgetResizable(
true);
3140 QVBoxLayout *quickLayout =
new QVBoxLayout;
3141 quickContainer->setLayout(quickLayout);
3143 QLabel *quickTitle =
new QLabel(
"<h2>Quick Start</h2>");
3144 quickLayout->addWidget(quickTitle);
3146 QLabel *quickSubTitle =
new QLabel(
"<h3>Preparation:</h3>");
3147 quickLayout->addWidget(quickSubTitle);
3149 QLabel *quickPrep =
new QLabel(
"<p><ul>"
3150 "<li>Open the cubes with overlapping areas for choosing control points</li>"
3151 "<li>Choose the match tool <img src=\"" +
toolIconDir() +
3152 "/stock_draw-connector-with-arrows.png\" width=22 height=22> "
3153 "from the toolpad on the right side of the <i>qview</i> main window</li>");
3154 quickPrep->setWordWrap(
true);
3155 quickLayout->addWidget(quickPrep);
3157 QLabel *morePrep =
new QLabel(
"<p>Once the Match tool is activated the tool bar at the top "
3158 "of the main window contains file action buttons and a help button:");
3159 morePrep->setWordWrap(
true);
3160 quickLayout->addWidget(morePrep);
3162 QLabel *fileButtons =
new QLabel(
"<p><ul>"
3163 "<li><img src=\"" +
toolIconDir() +
"/fileopen.png\" width=22 height=22> Open an existing "
3164 "control network <b>Note:</b> If you do not open an existing network, a new one will "
3166 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSaveAs.png\" width=22 height=22> Save "
3167 "control network as ...</li>"
3168 "<li><img src=\"" +
toolIconDir() +
"/mActionFileSave.png\" width=22 height=22> Save "
3169 "control network to current file</li>"
3170 "<li><img src=\"" +
toolIconDir() +
"/help-contents.png\" width=22 height=22> Show Help "
3172 fileButtons->setWordWrap(
true);
3173 quickLayout->addWidget(fileButtons);
3175 QLabel *quickFunctionTitle =
new QLabel(
"<h3>Cube Viewport Functions:</h3>");
3176 quickLayout->addWidget(quickFunctionTitle);
3178 QLabel *quickFunction =
new QLabel(
3179 "The match tool window will be shown once "
3180 "you click in a cube viewport window using one of the following "
3181 "mouse functions. <b>Note:</b> Existing control points are drawn on the cube viewports");
3182 quickFunction->setWordWrap(
true);
3183 quickLayout->addWidget(quickFunction);
3185 QLabel *quickDesc =
new QLabel(
"<p><ul>"
3186 "<li>Left Click - Modify the control point closest to the click <b>Note:</b> "
3187 "All cubes in the control point must be displayed before loading the point</li>"
3188 "<li>Middle Click - Delete the control point closest to the click</li>"
3189 "<li>Right Click - Create a new control point at the click location</li></ul></p>");
3190 quickDesc->setWordWrap(
true);
3191 quickDesc->setOpenExternalLinks(
true);
3192 quickLayout->addWidget(quickDesc);
3194 quickTab->setWidget(quickContainer);
3197 QScrollArea *controlPointTab =
new QScrollArea;
3198 controlPointTab->setWidgetResizable(
true);
3199 controlPointTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3201 QVBoxLayout *controlPointLayout =
new QVBoxLayout;
3202 controlPointContainer->setLayout(controlPointLayout);
3204 QLabel *controlPointTitle =
new QLabel(
"<h2>Control Point Editing</h2>");
3205 controlPointLayout->addWidget(controlPointTitle);
3207 QLabel *mouseLabel =
new QLabel(
"<p><h3>When the \"Match\" tool "
3208 "is activated, the mouse buttons have the following function in the "
3209 "cube viewports of the main qview window:</h3>");
3210 mouseLabel->setWordWrap(
true);
3211 mouseLabel->setScaledContents(
true);
3212 controlPointLayout->addWidget(mouseLabel);
3214 QLabel *controlPointDesc =
new QLabel(
"<ul>"
3215 "<li>Left click - Edit the closest control point <b>Note:</b> "
3216 "All cubes in the control point must be displayed before loading the point</li>"
3217 "<li>Middle click - Delete the closest control point</li>"
3218 "<li>Right click - Create new control point at cursor location. This will bring up a new "
3219 "point dialog which allows you to enter a point id and will list all cube viewports, "
3220 "highlighting cubes where the point has been chosen by clicking on the cube's viewport. "
3221 "When the desired cubes have been chosen, select the \"Done\" button which will load the "
3222 "control point into the control point editor window which will allow the control measure "
3223 "positions to be refined.</li>");
3224 controlPointDesc->setWordWrap(
true);
3225 controlPointLayout->addWidget(controlPointDesc);
3227 QLabel *controlPointEditing =
new QLabel(
3228 "<h4>Changing Control Measure Locations</h4>"
3229 "<p>Both the left and right control measure positions can be adjusted by:"
3231 "<li>Move the cursor location under the crosshair by clicking the left mouse "
3233 "<li>Move 1 pixel at a time by using arrow keys on the keyboard</li>"
3234 "<li>Move 1 pixel at a time by using arrow buttons above the right and left views</li>"
3236 "<h4>Other Point Editor Functions</h4>"
3237 "<p>Along the right border of the window:</p>"
3239 "<li><strong>Link Zoom</strong> This will link the two small viewports together when "
3240 "zooming (ie. If this is checked, if the left view is zoomed, the right view will "
3241 "match the left view's zoom factor. "
3242 "<b>Note:</b> Zooming is controlled from the left view.</li>"
3243 "<li><strong>No Rotate:</strong> Turn off the rotation and bring right view back to "
3244 "its original orientation</li>"
3245 "<li><strong>Rotate:</strong> Rotate the right view using either the dial "
3246 "or entering degrees </li>"
3247 "<li><strong>Show control points:</strong> Draw crosshairs at all control "
3248 "point locations visible within the view</li>"
3249 "<li><strong>Show crosshair:</strong> Show a red crosshair across the entire "
3251 "<li><strong>Circle:</strong> Draw circle which may help center measure "
3252 "on a crater</li></ul"
3253 "<p>Below the left view:</p>"
3254 "<ul><li><strong>Blink controls:</strong> Blink the left and right view in the "
3255 "left view window using the \"Blink Start\" button <img src=\"" +
toolIconDir() +
3256 "/blinkStart.png\" width=22 height=22> and \"Blink Stop\" button <img src=\"" +
3257 toolIconDir() +
"/blinkStop.png\" width=22 height=22>. The arrow keys above the left "
3258 "and right views and the keyboard arrow keys may be used to move the both views while "
3260 "<li><strong>Register:</strong> Sub-pixel register the right view to "
3261 "the left view. A default registration template is used for setting parameters "
3262 "passed to the sub-pixel registration tool. The user may load in a predefined "
3263 "template or edit the current loaded template to influence successful "
3264 "co-registration results. For more information regarding the pattern matching "
3265 "functionlity or how to create a parameter template, refer to the Isis PatternMatch "
3266 "document and the <i>autoregtemplate</i> application. <strong>Shortcut: R.</strong>"
3268 "<li><strong>Save Measures:</strong> Save the two control measures using the sample, "
3269 "line positions under the crosshairs. <strong>Shortcut: M.</strong></li>"
3270 "<li><strong>Save Point:</strong> Save the control point to the control network. "
3271 "<strong>Shortcut: P.</strong></li>"
3273 controlPointEditing->setWordWrap(
true);
3274 controlPointLayout->addWidget(controlPointEditing);
3276 controlPointTab->setWidget(controlPointContainer);
3279 QScrollArea *coregTab =
new QScrollArea;
3280 coregTab->setWidgetResizable(
true);
3281 coregTab->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
3283 QVBoxLayout *coregLayout =
new QVBoxLayout;
3284 coregContainer->setLayout(coregLayout);
3286 QLabel *coregTitle =
new QLabel(
"<h2>Coreg Guidance</h2>");
3287 coregLayout->addWidget(coregTitle);
3289 QLabel *coregDesc =
new QLabel(
"<p>When opening control networks created by <i>coreg</i>, "
3290 "there are some things to keep in mind. First, all control points must have the same "
3291 "reference measure (this is the image filename passed to the <i>coreg</i> 'match' parameter)."
3292 "<p>In order to retain the integrity of the input <i>coreg</i> network, you cannot change "
3293 "which image is the reference measure on any of the existing points. "
3294 "<p>When creating a new control point to add to the <i>coreg</i> network, this tool will "
3295 "automatically set the reference measure to the same image as the other control points in "
3296 "the network as long as the reference image was one of the images selected with "
3297 "the right mouse button from the new point dialog. If this image was not selected when "
3298 "creating a new point, it "
3299 "does not contain a required measurement, therefore, you will get an error and the new "
3300 "point will not be created.</p> <p>The reference measure is always loaded on the left side "
3301 "of the control point editor. If you load a measure that is not the reference measure "
3302 "on the left side and try to save the point, you will receive an error message. You will "
3303 "need to move the reference measure back to the left side before saving the control point."
3304 "</p><p><b>Note:</b> This error checking will not happen on control networks created by "
3305 "<i>coreg</i> prior to Isis3.4.2. For older <i>coreg</i> control networks the user must be "
3306 "aware and make sure the correct image is set to the same <i>coreg</i> reference measure.");
3307 coregDesc->setWordWrap(
true);
3308 coregDesc->setScaledContents(
true);
3309 coregLayout->addWidget(coregDesc);
3311 coregTab->setWidget(coregContainer);
3313 tabArea->addTab(overviewTab,
"&Overview");
3314 tabArea->addTab(quickTab,
"&Quick Start");
3315 tabArea->addTab(controlPointTab,
"&Control Point Editing");
3316 tabArea->addTab(coregTab,
"&Coreg Guidance");
3318 QHBoxLayout *buttonsLayout =
new QHBoxLayout;
3320 buttonsLayout->addStretch();
3322 QPushButton *closeButton =
new QPushButton(
"&Close");
3323 closeButton->setIcon(QPixmap(
toolIconDir() +
"/guiStop.png"));
3324 closeButton->setDefault(
true);
3325 connect(closeButton, SIGNAL(clicked()),
3326 helpDialog, SLOT(close()));
3327 buttonsLayout->addWidget(closeButton);
3329 mainLayout->addLayout(buttonsLayout);
3348 if ( m_controlNet->GetNumPoints() == 0 ||
3349 !m_controlNet->ContainsPoint(m_editPoint->
GetId())) {
3350 QString message =
"\n\nDo you want to save the point in the editor?";
3351 int response = QMessageBox::question(m_matchTool,
"Save point in editor", message,
3352 QMessageBox::Yes | QMessageBox::No,
3354 if (response == QMessageBox::Yes) {
3360 if (m_controlNet && m_controlNet->GetNumPoints() != 0 && m_netChanged) {
3361 QString message =
"The currently open control net has changed. Do you want to save?";
3362 int response = QMessageBox::question(m_matchTool,
"Save current control net?",
3364 QMessageBox::Yes | QMessageBox::No,
3367 if (response == QMessageBox::Yes) {