Isis 3 Programmer Reference
ControlMeasureEditWidget.cpp
1 #include "ControlMeasureEditWidget.h"
2 
3 #include <QApplication>
4 #include <QButtonGroup>
5 #include <QCheckBox>
6 #include <QColor>
7 #include <QDial>
8 #include <QDoubleSpinBox>
9 #include <QFileDialog>
10 #include <QGridLayout>
11 #include <QHBoxLayout>
12 #include <QLCDNumber>
13 #include <QListWidget>
14 #include <QMessageBox>
15 #include <QPalette>
16 #include <QPushButton>
17 #include <QRadioButton>
18 #include <QScrollBar>
19 #include <QSize>
20 #include <QString>
21 #include <QTimer>
22 #include <QToolButton>
23 
24 #include "Application.h"
25 #include "AutoReg.h"
26 #include "AutoRegFactory.h"
27 #include "ChipViewport.h"
28 #include "ControlMeasure.h"
29 #include "ControlMeasureLogData.h"
30 #include "ControlPoint.h"
31 #include "FileName.h"
32 #include "IString.h"
33 #include "ProgramLauncher.h"
34 #include "Pvl.h"
35 #include "SerialNumberList.h"
36 #include "UniversalGroundMap.h"
37 
38 namespace Isis {
39 
41  const int VIEWSIZE = 301;
42 
57  bool allowLeftMouse,
58  bool useGeometry) : QWidget(parent) {
59 
60  m_rotation = 0;
61  m_timerOn = false;
62  m_timerOnRight = false;
63  m_autoRegFact = NULL;
65  m_useGeometry = useGeometry;
66 
67  // Initialize some pointers
68  m_leftCube = 0;
69  m_rightCube = 0;
70  m_leftGroundMap = 0;
71  m_rightGroundMap = 0;
72 
73  m_templateFileName = "$base/templates/autoreg/qnetReg.def";
74 
75  createMeasureEditor(parent);
76  }
77 
78 
83 
84  delete m_leftChip;
85  m_leftChip = NULL;
86  delete m_rightChip;
87  m_rightChip = NULL;
88  }
89 
90 
114  // Place everything in a grid
115  QGridLayout *gridLayout = new QGridLayout();
116  gridLayout->setSizeConstraint(QLayout::SetFixedSize);
117  // grid row
118  int row = 0;
119 
120  QString tempFileName = FileName("$base/icons").expanded();
121  QString toolIconDir = tempFileName;
122 
123  QSize isize(27, 27);
124  // Add zoom buttons
125  QToolButton *leftZoomIn = new QToolButton();
126  leftZoomIn->setIcon(QPixmap(toolIconDir + "/viewmag+.png"));
127  leftZoomIn->setIconSize(isize);
128  leftZoomIn->setToolTip("Zoom In 2x");
129  leftZoomIn->setWhatsThis("Zoom In 2x on left measure.");
130 
131  QToolButton *leftZoomOut = new QToolButton();
132  leftZoomOut->setIcon(QPixmap(toolIconDir + "/viewmag-.png"));
133  leftZoomOut->setIconSize(isize);
134  leftZoomOut->setToolTip("Zoom Out 2x");
135  leftZoomOut->setWhatsThis("Zoom Out 2x on left measure.");
136 
137  QToolButton *leftZoom1 = new QToolButton();
138  leftZoom1->setIcon(QPixmap(toolIconDir + "/viewmag1.png"));
139  leftZoom1->setIconSize(isize);
140  leftZoom1->setToolTip("Zoom 1:1");
141  leftZoom1->setWhatsThis("Show left measure at full resolution.");
142 
143  QHBoxLayout *leftZoomPan = new QHBoxLayout;
144  leftZoomPan->addWidget(leftZoomIn);
145  leftZoomPan->addWidget(leftZoomOut);
146  leftZoomPan->addWidget(leftZoom1);
147 
148  // These buttons only used if allow mouse events in leftViewport
149  QToolButton *leftPanUp = 0;
150  QToolButton *leftPanDown = 0;
151  QToolButton *leftPanLeft = 0;
152  QToolButton *leftPanRight = 0;
153  if ( m_allowLeftMouse ) {
154  // Add arrows for panning
155  leftPanUp = new QToolButton(parent);
156  leftPanUp->setIcon(QIcon(FileName("$base/icons/up.png").
157  expanded()));
158  leftPanUp->setIconSize(isize);
159  leftPanUp->setToolTip("Move up 1 screen pixel");
160  leftPanUp->setStatusTip("Move up 1 screen pixel");
161  leftPanUp->setWhatsThis("Move the left measure up 1 screen pixel.");
162 
163  leftPanDown = new QToolButton(parent);
164  leftPanDown->setIcon(QIcon(FileName("$base/icons/down.png").
165  expanded()));
166  leftPanDown->setIconSize(isize);
167  leftPanDown->setToolTip("Move down 1 screen pixel");
168  leftPanDown->setStatusTip("Move down 1 screen pixel");
169  leftPanDown->setWhatsThis("Move the left measure down 1 screen pixel.");
170 
171  leftPanLeft = new QToolButton(parent);
172  leftPanLeft->setIcon(QIcon(FileName("$base/icons/back.png").
173  expanded()));
174  leftPanLeft->setIconSize(isize);
175  leftPanLeft->setToolTip("Move left 1 screen pixel");
176  leftPanLeft->setWhatsThis("Move the left measure to the left by 1 screen"
177  "pixel.");
178 
179  leftPanRight = new QToolButton(parent);
180  leftPanRight->setIcon(QIcon(FileName("$base/icons/forward.png").
181  expanded()));
182  leftPanRight->setIconSize(isize);
183  leftPanRight->setToolTip("Move right 1 screen pixel");
184  leftPanRight->setWhatsThis("Move the left measure to the right by 1"
185  "screen pixel.");
186 
187  leftZoomPan->addWidget(leftPanUp);
188  leftZoomPan->addWidget(leftPanDown);
189  leftZoomPan->addWidget(leftPanLeft);
190  leftZoomPan->addWidget(leftPanRight);
191  }
192 
193  leftZoomPan->addStretch();
194  gridLayout->addLayout(leftZoomPan, row, 0);
195 
196  m_rightZoomIn = new QToolButton();
197  m_rightZoomIn->setIcon(QPixmap(toolIconDir + "/viewmag+.png"));
198  m_rightZoomIn->setIconSize(isize);
199  m_rightZoomIn->setToolTip("Zoom In 2x");
200  m_rightZoomIn->setWhatsThis("Zoom In 2x on right measure.");
201 
202  m_rightZoomOut = new QToolButton();
203  m_rightZoomOut->setIcon(QIcon(FileName("$base/icons/viewmag-.png").
204  expanded()));
205  m_rightZoomOut->setIconSize(isize);
206  m_rightZoomOut->setToolTip("Zoom Out 2x");
207  m_rightZoomOut->setWhatsThis("Zoom Out 2x on right measure.");
208 
209  m_rightZoom1 = new QToolButton();
210  m_rightZoom1->setIcon(QPixmap(toolIconDir + "/viewmag1.png"));
211  m_rightZoom1->setIconSize(isize);
212  m_rightZoom1->setToolTip("Zoom 1:1");
213  m_rightZoom1->setWhatsThis("Show right measure at full resolution.");
214 
215  QHBoxLayout *rightZoomPan = new QHBoxLayout;
216  rightZoomPan->addWidget(m_rightZoomIn);
217  rightZoomPan->addWidget(m_rightZoomOut);
218  rightZoomPan->addWidget(m_rightZoom1);
219 
220  // Add arrows for panning
221  QToolButton *rightPanUp = new QToolButton(parent);
222  rightPanUp->setIcon(QIcon(FileName("$base/icons/up.png").
223  expanded()));
224  rightPanUp->setIconSize(isize);
225  rightPanUp->setToolTip("Move up 1 screen pixel");
226  rightPanUp->setWhatsThis("Move the right measure up 1 screen pixel.");
227 
228  QToolButton *rightPanDown = new QToolButton(parent);
229  rightPanDown->setIcon(QIcon(FileName("$base/icons/down.png").
230  expanded()));
231  rightPanDown->setIconSize(isize);
232  rightPanDown->setToolTip("Move down 1 screen pixel");
233  rightPanUp->setWhatsThis("Move the right measure down 1 screen pixel.");
234 
235  QToolButton *rightPanLeft = new QToolButton(parent);
236  rightPanLeft->setIcon(QIcon(FileName("$base/icons/back.png").
237  expanded()));
238  rightPanLeft->setIconSize(isize);
239  rightPanLeft->setToolTip("Move left 1 screen pixel");
240  rightPanLeft->setWhatsThis("Move the right measure to the left by 1 screen"
241  "pixel.");
242 
243  QToolButton *rightPanRight = new QToolButton(parent);
244  rightPanRight->setIcon(QIcon(FileName("$base/icons/forward.png").
245  expanded()));
246  rightPanRight->setIconSize(isize);
247  rightPanRight->setToolTip("Move right 1 screen pixel");
248  rightPanRight->setWhatsThis("Move the right measure to the right by 1"
249  "screen pixel.");
250 
251  rightZoomPan->addWidget(rightPanUp);
252  rightZoomPan->addWidget(rightPanDown);
253  rightZoomPan->addWidget(rightPanLeft);
254  rightZoomPan->addWidget(rightPanRight);
255  rightZoomPan->addStretch();
256 
257  gridLayout->addLayout(rightZoomPan, row++, 1);
258 
259  // Add zoom factor label and stretch locking checkbox
260  m_leftZoomFactor = new QLabel();
261  QCheckBox *leftLockStretch = new QCheckBox("lock stretch");
262  // there are two "lock stretch" checkboxes (left and right)
263  // use same whats this text for both
264  QString whatsThisTextForStretchLocking = "If checked then a new stretch "
265  "will NOT be calculated for each pan or zoom change. Note that stretch"
266  " changes made using the stretch tool will ALWAYS take effect, "
267  "regardless of the state of this checkbox.";
268  leftLockStretch->setWhatsThis(whatsThisTextForStretchLocking);
269  QHBoxLayout *leftzflsLayout = new QHBoxLayout;
270  leftzflsLayout->addWidget(m_leftZoomFactor);
271  leftzflsLayout->addWidget(leftLockStretch);
272  gridLayout->addLayout(leftzflsLayout, row, 0);
273 
274  m_rightZoomFactor = new QLabel();
275  QCheckBox *rightLockStretch = new QCheckBox("lock stretch");
276  rightLockStretch->setWhatsThis(whatsThisTextForStretchLocking);
277  QHBoxLayout *rightzflsLayout = new QHBoxLayout;
278  rightzflsLayout->addWidget(m_rightZoomFactor);
279  rightzflsLayout->addWidget(rightLockStretch);
280  gridLayout->addLayout(rightzflsLayout, row++, 1);
281 
282 
284  // Do not want to accept mouse/keyboard events
285  if ( !m_allowLeftMouse ) m_leftView->setDisabled(true);
286 
287  gridLayout->addWidget(m_leftView, row, 0);
288 
289  connect(this, SIGNAL(newControlNetwork(ControlNet *)),
290  m_leftView, SLOT(setControlNet(ControlNet *)));
291 
292  connect(this,
293  SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
294  m_leftView,
295  SLOT(stretchFromCubeViewport(Stretch *, CubeViewport *)));
296 
297  connect(leftLockStretch, SIGNAL(stateChanged(int)),
298  m_leftView,
299  SLOT(changeStretchLock(int)));
300  leftLockStretch->setChecked(false);
301 
302 
303  // Connect left zoom buttons to ChipViewport's zoom slots
304  connect(leftZoomIn, SIGNAL(clicked()), m_leftView, SLOT(zoomIn()));
305  connect(leftZoomOut, SIGNAL(clicked()), m_leftView, SLOT(zoomOut()));
306  connect(leftZoom1, SIGNAL(clicked()), m_leftView, SLOT(zoom1()));
307 
308  // If zoom on left, need to re-geom right
309  connect(leftZoomIn, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
310  connect(leftZoomOut, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
311  connect(leftZoom1, SIGNAL(clicked()), this, SLOT(updateRightGeom()));
312 
313  // Connect the ChipViewport tackPointChanged signal to
314  // the update sample/line label
315  connect(m_leftView, SIGNAL(tackPointChanged(double)),
316  this, SLOT(updateLeftPositionLabel(double)));
317 
318  // we want to allow this connection so that if a changed point is saved
319  // and the same image is showing in both viewports, the left will refresh.
320  connect(this, SIGNAL(updateLeftView(double, double)),
321  m_leftView, SLOT(refreshView(double, double)));
322 
323  connect (m_leftView, SIGNAL(userMovedTackPoint()),
324  this, SLOT(colorizeSaveButton()));
325 
326  if ( m_allowLeftMouse ) {
327  // Connect pan buttons to ChipViewport
328  connect(leftPanUp, SIGNAL(clicked()), m_leftView, SLOT(panUp()));
329  connect(leftPanDown, SIGNAL(clicked()), m_leftView, SLOT(panDown()));
330  connect(leftPanLeft, SIGNAL(clicked()), m_leftView, SLOT(panLeft()));
331  connect(leftPanRight, SIGNAL(clicked()), m_leftView, SLOT(panRight()));
332 
333  connect(leftPanUp, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
334  connect(leftPanDown, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
335  connect(leftPanLeft, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
336  connect(leftPanRight, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
337  }
338 
340  gridLayout->addWidget(m_rightView, row, 1);
341 
342  connect(this, SIGNAL(newControlNetwork(ControlNet *)),
343  m_rightView, SLOT(setControlNet(ControlNet *)));
344  connect(this, SIGNAL(stretchChipViewport(Stretch *, CubeViewport *)),
345  m_rightView, SLOT(stretchFromCubeViewport(Stretch *, CubeViewport *)));
346  connect(rightLockStretch, SIGNAL(stateChanged(int)),
347  m_rightView, SLOT(changeStretchLock(int)));
348  rightLockStretch->setChecked(false);
349 
350  // Connect the ChipViewport tackPointChanged signal to
351  // the update sample/line label
352  connect(m_rightView, SIGNAL(tackPointChanged(double)),
353  this, SLOT(updateRightPositionLabel(double)));
354  connect(this, SIGNAL(updateRightView(double, double)),
355  m_rightView, SLOT(refreshView(double, double)));
356 
357  connect (m_rightView, SIGNAL(userMovedTackPoint()),
358  this, SLOT(colorizeSaveButton()));
359 
360  connect(m_rightZoomIn, SIGNAL(clicked()), m_rightView, SLOT(zoomIn()));
361  connect(m_rightZoomOut, SIGNAL(clicked()), m_rightView, SLOT(zoomOut()));
362  connect(m_rightZoom1, SIGNAL(clicked()), m_rightView, SLOT(zoom1()));
363 
364  // Connect pan buttons to ChipViewport
365  connect(rightPanUp, SIGNAL(clicked()), m_rightView, SLOT(panUp()));
366  connect(rightPanDown, SIGNAL(clicked()), m_rightView, SLOT(panDown()));
367  connect(rightPanLeft, SIGNAL(clicked()), m_rightView, SLOT(panLeft()));
368  connect(rightPanRight, SIGNAL(clicked()), m_rightView, SLOT(panRight()));
369 
370  connect(rightPanUp, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
371  connect(rightPanDown, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
372  connect(rightPanLeft, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
373  connect(rightPanRight, SIGNAL(clicked()), this, SLOT(colorizeSaveButton()));
374 
375  // Create chips for left and right
378 
379  QButtonGroup *bgroup = new QButtonGroup();
380  m_nogeom = new QRadioButton();
381  m_nogeom->setChecked(true);
382  connect(m_nogeom, SIGNAL(clicked()), this, SLOT(setNoGeom()));
383 
384  QCheckBox *linkZoom = NULL;
385  if (m_useGeometry) {
386  m_nogeom->setText("No geom/rotate");
387  m_nogeom->setToolTip("Reset right measure to it's native geometry.");
388  m_nogeom->setWhatsThis("Reset right measure to it's native geometry. "
389  "If measure was rotated, set rotation back to 0. "
390  "If measure was geomed to match the left measure, "
391  "reset the geometry back to it's native state.");
392  m_geom = new QRadioButton("Geom");
393  m_geom->setToolTip("Geom right measure to match geometry of left measure.");
394  m_geom->setWhatsThis("Using an affine transform, geom the right measure to match the "
395  "geometry of the left measure.");
396  bgroup->addButton(m_geom);
397  connect(m_geom, SIGNAL(clicked()), this, SLOT(setGeom()));
398  }
399  else {
400  linkZoom = new QCheckBox("Link Zoom");
401  linkZoom->setToolTip("Link zooming between the left and right views.");
402  linkZoom->setWhatsThis("When zooming in the left view, the right view will "
403  "be set to the same zoom factor as the left view.");
404  connect(linkZoom, SIGNAL(toggled(bool)), this, SLOT(setZoomLink(bool)));
405 
406  m_nogeom->setText("No rotate");
407  m_nogeom->setToolTip("Reset right measure to it's native geometry.");
408  m_nogeom->setWhatsThis("Reset right measure to it's native geometry. "
409  "If measure was rotated, set rotation back to 0.");
410  }
411  bgroup->addButton(m_nogeom);
412 
413  QRadioButton *rotate = new QRadioButton("Rotate");
414  bgroup->addButton(rotate);
415  // TODO: ?? Don't think we need this connection
416  connect(rotate, SIGNAL(clicked()), this, SLOT(setRotate()));
417 
418  // Set some defaults
419  m_geomIt = false;
420  m_rotation = 0;
421  m_linkZoom = false;
422 
423  m_dial = new QDial();
424  m_dial->setRange(0, 360);
425  m_dial->setWrapping(false);
426  m_dial->setNotchesVisible(true);
427  m_dial->setNotchTarget(5.);
428  m_dial->setEnabled(false);
429  m_dial->setToolTip("Rotate right measure");
430  m_dial->setWhatsThis("Rotate the right measure by degrees.");
431 
432  m_dialNumber = new QLCDNumber();
433  m_dialNumber->setEnabled(false);
434  m_dialNumber->setToolTip("Rotate right measure");
435  m_dialNumber->setWhatsThis("Rotate the right measure by given number"
436  " of degrees.");
437  connect(m_dial, SIGNAL(valueChanged(int)), m_dialNumber, SLOT(display(int)));
438  connect(m_dial, SIGNAL(valueChanged(int)), m_rightView, SLOT(rotateChip(int)));
439 
440  QCheckBox *showPoints = new QCheckBox("Show control points");
441  showPoints->setToolTip("Draw control point crosshairs");
442  showPoints->setWhatsThis("This will toggle whether crosshairs are drawn"
443  " for the control points located within the measure''s"
444  " view. For areas of dense measurements, turning this"
445  " off will allow easier viewing of features.");
446  connect(showPoints, SIGNAL(toggled(bool)), m_leftView, SLOT(setPoints(bool)));
447  connect(showPoints, SIGNAL(toggled(bool)), m_rightView, SLOT(setPoints(bool)));
448  showPoints->setChecked(true);
449 
450  QCheckBox *cross = new QCheckBox("Show crosshair");
451  connect(cross, SIGNAL(toggled(bool)), m_leftView, SLOT(setCross(bool)));
452  connect(cross, SIGNAL(toggled(bool)), m_rightView, SLOT(setCross(bool)));
453  cross->setChecked(true);
454  cross->setToolTip("Show the red crosshair across measure view");
455  cross->setWhatsThis("This will toggle whether the crosshair across the"
456  " measure view will be shown");
457 
458  QCheckBox *circle = new QCheckBox("Circle");
459  circle->setChecked(false);
460  circle->setToolTip("Draw circle");
461  circle->setWhatsThis("Draw circle on measure view. This can aid in"
462  " centering a crater under the crosshair.");
463  connect(circle, SIGNAL(toggled(bool)), this, SLOT(setCircle(bool)));
464 
465  m_slider = new QScrollBar(Qt::Horizontal);
466  m_slider->setRange(1, 100);
467  m_slider->setSingleStep(1);
468  connect(m_slider, SIGNAL(valueChanged(int)), m_leftView, SLOT(setCircleSize(int)));
469  connect(m_slider, SIGNAL(valueChanged(int)), m_rightView, SLOT(setCircleSize(int)));
470  m_slider->setValue(20);
471  m_slider->setDisabled(true);
472  m_slider->hide();
473  m_slider->setToolTip("Adjust circle size");
474  m_slider->setWhatsThis("This allows the cirle size to be adjusted.");
475 
476  QVBoxLayout *vlayout = new QVBoxLayout();
477  if (!m_useGeometry) {
478  vlayout->addWidget(linkZoom);
479  }
480  vlayout->addWidget(m_nogeom);
481  if (m_useGeometry) {
482  vlayout->addWidget(m_geom);
483  }
484  vlayout->addWidget(rotate);
485  vlayout->addWidget(m_dial);
486  vlayout->addWidget(m_dialNumber);
487  vlayout->addWidget(showPoints);
488  vlayout->addWidget(cross);
489  vlayout->addWidget(circle);
490  vlayout->addWidget(m_slider);
491  gridLayout->addLayout(vlayout, row++, 2);
492 
493  // Show sample / line for measure of chips shown
494  m_leftSampLinePosition = new QLabel();
495  m_leftSampLinePosition->setToolTip("Sample/Line under the crosshair");
496  gridLayout->addWidget(m_leftSampLinePosition, row, 0);
497  m_rightSampLinePosition = new QLabel();
498  m_rightSampLinePosition->setToolTip("Sample/Line under the crosshair");
499  gridLayout->addWidget(m_rightSampLinePosition, row++, 1);
500 
501  if (m_useGeometry) {
502  // Show lat / lon for measure of chips shown
503  m_leftLatLonPosition = new QLabel();
504  m_leftLatLonPosition->setToolTip("Latitude/Longitude under the crosshair");
505  gridLayout->addWidget(m_leftLatLonPosition, row, 0);
506  m_rightLatLonPosition = new QLabel();
507  m_rightLatLonPosition->setToolTip("Latitude/Longitude under the crosshair");
508  gridLayout->addWidget(m_rightLatLonPosition, row++, 1);
509  }
510 
511  // Add auto registration extension
513  m_oldPosition = new QLabel;
514  m_oldPosition->setToolTip("Measure Sample/Line before sub-pixel "
515  "registration");
516  m_oldPosition->setWhatsThis("Original Sample/Line of the right measure "
517  "before the sub-pixel registration. If you select the \"Undo\" "
518  "button, the measure will revert back to this Sample/Line.");
519  m_goodFit = new QLabel;
520  m_goodFit->setToolTip("Goodness of Fit result from sub-pixel registration.");
521  m_goodFit->setWhatsThis("Resulting Goodness of Fit from sub-pixel "
522  "registration.");
523  QVBoxLayout *autoRegLayout = new QVBoxLayout;
524  autoRegLayout->setMargin(0);
525  autoRegLayout->addWidget(m_oldPosition);
526  autoRegLayout->addWidget(m_goodFit);
527  m_autoRegExtension->setLayout(autoRegLayout);
528  m_autoRegShown = false;
529  m_autoRegAttempted = false;
530  gridLayout->addWidget(m_autoRegExtension, row++, 1);
531 
532 
533  QHBoxLayout *leftLayout = new QHBoxLayout();
534  QToolButton *stop = new QToolButton();
535  stop->setIcon(QPixmap(toolIconDir + "/blinkStop.png"));
536  stop->setIconSize(QSize(22, 22));
537  stop->setToolTip("Blink Stop");
538  QString text = "<b>Function:</b> Stop automatic timed blinking";
539  stop->setWhatsThis(text);
540  connect(stop, SIGNAL(released()), this, SLOT(blinkStop()));
541 
542  QToolButton *start = new QToolButton();
543  start->setIcon(QPixmap(toolIconDir + "/blinkStart.png"));
544  start->setIconSize(QSize(22, 22));
545  start->setToolTip("Blink Start");
546  text = "<b>Function:</b> Start automatic timed blinking. Cycles \
547  through linked viewports at variable rate";
548  start->setWhatsThis(text);
549  connect(start, SIGNAL(released()), this, SLOT(blinkStart()));
550 
551  m_blinkTimeBox = new QDoubleSpinBox();
552  m_blinkTimeBox->setMinimum(0.1);
553  m_blinkTimeBox->setMaximum(5.0);
554  m_blinkTimeBox->setDecimals(1);
555  m_blinkTimeBox->setSingleStep(0.1);
556  m_blinkTimeBox->setValue(0.5);
557  m_blinkTimeBox->setToolTip("Blink Time Delay");
558  text = "<b>Function:</b> Change automatic blink rate between " +
559  QString::number(m_blinkTimeBox->minimum()) + " and " +
560  QString::number(m_blinkTimeBox->maximum()) + " seconds";
561  m_blinkTimeBox->setWhatsThis(text);
562  connect(m_blinkTimeBox, SIGNAL(valueChanged(double)),
563  this, SLOT(changeBlinkTime(double)));
564 
565  leftLayout->addWidget(stop);
566  leftLayout->addWidget(start);
567  leftLayout->addWidget(m_blinkTimeBox);
568 
569  if (m_useGeometry) {
570  QPushButton *find = new QPushButton("Find");
571  find->setShortcut(Qt::Key_F);
572  find->setToolTip("Move right measure to same Latitude/Longitude as left. "
573  "<strong>Shortcut: F</strong>");
574  find->setWhatsThis("Find the Latitude/Longitude under the crosshair in the "
575  "left measure and move the right measure to the same "
576  "latitude/longitude.");
577  leftLayout->addWidget(find);
578  connect(find, SIGNAL(clicked()), this, SLOT(findPoint()));
579  }
580 
581  leftLayout->addStretch();
582  gridLayout->addLayout(leftLayout, row, 0);
583 
584  QHBoxLayout *rightLayout = new QHBoxLayout();
585  m_autoReg = new QPushButton("Register");
586  m_autoReg->setShortcut(Qt::Key_R);
587  m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
588  "<strong>Shortcut: R</strong>");
589  m_autoReg->setWhatsThis("Sub-pixel register the right measure to the left "
590  "and move the result under the crosshair. After "
591  "viewing the results, the option exists to move the "
592  "measure back to the original position by selecting "
593  "<strong>\"Undo Registration\"</strong>.");
594  if (m_allowLeftMouse) {
595  m_saveMeasure = new QPushButton("Save Measures");
596  m_saveMeasure->setToolTip("Save the both the left and right measure to the edit control "
597  "point (control point currently being edited). "
598  "<strong>Shortcut: M</strong>. "
599  " <strong>Note: The edit control point "
600  "will not be saved to the network until you select "
601  "<strong>\"Save Point\"</strong>");
602  }
603  else {
604  m_saveMeasure = new QPushButton("Save Measure");
605  m_saveMeasure->setToolTip("Save the right measure to the edit control "
606  "point (control point currently being edited). "
607  "<strong>Shortcut: M</strong>. "
608  " <strong>Note: The edit control point "
609  "will not be saved to the network until you select "
610  "<strong>\"Save Point\"</strong>");
611  }
612  m_saveMeasure->setShortcut(Qt::Key_M);
613  m_saveDefaultPalette = m_saveMeasure->palette();
614 
615  // Blink extension allows all measures in the current control point to be blinked and gives
616  // user ability to select which measures and the order for blinking
618 
619  QPushButton *blinkButton = new QPushButton("Advanced Blink");
620  blinkButton->setCheckable(true);
621  connect(blinkButton, &QAbstractButton::toggled, m_blinkExtension, &QWidget::setVisible);
622  connect(blinkButton, SIGNAL(clicked()), this, SLOT(showBlinkExtension()));
623 
624  QHBoxLayout *rightBlinkLayout = new QHBoxLayout();
625  QToolButton *stopRight = new QToolButton();
626  stopRight->setIcon(QPixmap(toolIconDir + "/blinkStop.png"));
627  stopRight->setIconSize(QSize(22, 22));
628  stopRight->setToolTip("Blink Stop");
629  text = "<b>Function:</b> Stop automatic timed blinking";
630  stopRight->setWhatsThis(text);
631  connect(stopRight, SIGNAL(released()), this, SLOT(blinkStopRight()));
632 
633  QToolButton *startRight = new QToolButton();
634  startRight->setIcon(QPixmap(toolIconDir + "/blinkStart.png"));
635  startRight->setIconSize(QSize(22, 22));
636  startRight->setToolTip("Blink Start");
637  text = "<b>Function:</b> Start automatic timed blinking. Cycles \
638  through linked viewports at variable rate";
639  startRight->setWhatsThis(text);
640  connect(startRight, SIGNAL(released()), this, SLOT(blinkStartRight()));
641 
642  m_blinkTimeBoxRight = new QDoubleSpinBox();
643  m_blinkTimeBoxRight->setMinimum(0.1);
644  m_blinkTimeBoxRight->setMaximum(5.0);
645  m_blinkTimeBoxRight->setDecimals(1);
646  m_blinkTimeBoxRight->setSingleStep(0.1);
647  m_blinkTimeBoxRight->setValue(0.5);
648  m_blinkTimeBoxRight->setToolTip("Blink Time Delay");
649  text = "<b>Function:</b> Change automatic blink rate between " +
650  QString::number(m_blinkTimeBox->minimum()) + " and " +
651  QString::number(m_blinkTimeBox->maximum()) + " seconds";
652  m_blinkTimeBoxRight->setWhatsThis(text);
653  connect(m_blinkTimeBoxRight, SIGNAL(valueChanged(double)),
654  this, SLOT(changeBlinkTimeRight(double)));
655 
656  rightBlinkLayout->addWidget(stopRight);
657  rightBlinkLayout->addWidget(startRight);
658  rightBlinkLayout->addWidget(m_blinkTimeBoxRight);
659 
660  m_blinkListWidget = new QListWidget(m_blinkExtension);
661  m_blinkListWidget->setMinimumHeight(100);
662  m_blinkListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
663  m_blinkListWidget->setDragEnabled(true);
664  m_blinkListWidget->setAcceptDrops(true);
665  m_blinkListWidget->setDropIndicatorShown(true);
666  m_blinkListWidget->setDragDropMode(QAbstractItemView::InternalMove);
667 // connect(m_blinkListWidget, SIGNAL(itemActivated(QListWidgetItem *)),
668 // this, SLOT(toggleBlink(QListWidgetItem *)));
669 // connect(m_blinkListWidget, SIGNAL(currentRowChanged(int)),
670 // this, SLOT(updateWindow()));
671 
672  rightBlinkLayout->addWidget(m_blinkListWidget);
673 
674  m_blinkExtension->setLayout(rightBlinkLayout);
675 
676 
677 
678 
679 
680 
681  rightLayout->addWidget(m_autoReg);
682  rightLayout->addWidget(m_saveMeasure);
683  rightLayout->addWidget(blinkButton);
684  rightLayout->addStretch();
685  gridLayout->addLayout(rightLayout, row++, 1);
686  gridLayout->addWidget(m_blinkExtension, row, 1);
687  connect(m_autoReg, SIGNAL(clicked()), this, SLOT(registerPoint()));
688  connect(m_saveMeasure, SIGNAL(clicked()), this, SLOT(saveMeasure()));
689 
690  setLayout(gridLayout);
691 
692  //m_pointEditor->setCentralWidget(cw);
693  m_autoRegExtension->hide();
694  m_blinkExtension->hide();
695 
696  //m_pointEditor->setVisible(true);
697  //m_pointEditor->raise();
698  }
699 
700 
724  Cube *leftCube, QString pointId) {
725 
726  // Make sure registration is turned off
727  if ( m_autoRegShown ) {
728  // Undo Registration
729  m_autoRegShown = false;
730  m_autoRegExtension->hide();
731  m_autoReg->setText("Register");
732  m_autoReg->setToolTip("Sub-pixel register the right measure to the left."
733  "<strong>Shortcut: R</strong>");
734  m_autoReg->setShortcut(Qt::Key_R);
735  }
736 
737  m_leftMeasure = leftMeasure;
738 
739  if (m_useGeometry) {
740  // get new ground map
741  if ( m_leftGroundMap != 0 ) delete m_leftGroundMap;
742  m_leftGroundMap = new UniversalGroundMap(*leftCube);
743  }
744  m_leftCube = leftCube;
745 
746  m_leftChip->TackCube(m_leftMeasure->GetSample(), m_leftMeasure->GetLine());
748 
749  // Dump into left chipViewport
751 
752  // Only update right if not loading a new point. If it's a new point, right measure
753  // hasn't been loaded yet.
754  if (pointId == m_pointId && m_geomIt) updateRightGeom();
755  m_pointId = pointId;
756  }
757 
758 
766  void ControlMeasureEditWidget::setLeftPosition(double sample, double line) {
767 
768  m_leftChip->TackCube(sample, line);
769  emit updateLeftView(sample, line);
770  }
771 
772 
780  void ControlMeasureEditWidget::setRightPosition(double sample, double line) {
781 
782  m_rightChip->TackCube(sample, line);
783  emit updateRightView(sample, line);
784  }
785 
786 
814  Cube *rightCube, QString pointId) {
815 
816  // Make sure registration is turned off
817  if ( m_autoRegShown ) {
818  // Undo Registration
819  m_autoRegShown = false;
820  m_autoRegExtension->hide();
821  m_autoReg->setText("Register");
822  m_autoReg->setShortcut(Qt::Key_R);
823  m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
824  "<strong>Shortcut: R</strong>");
825  }
826  m_autoRegAttempted = false;
827 
828  m_rightMeasure = rightMeasure;
829  m_pointId = pointId;
830 
831  if (m_useGeometry) {
832  // get new ground map
833  if ( m_rightGroundMap != 0 ) delete m_rightGroundMap;
834  m_rightGroundMap = new UniversalGroundMap(*rightCube);
835  }
836  m_rightCube = rightCube;
837 
838  m_rightChip->TackCube(m_rightMeasure->GetSample(),
839  m_rightMeasure->GetLine());
840  if ( m_geomIt == false ) {
842  }
843  else {
844  try {
846 
847  }
848  catch (IException &e) {
849  IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
850  QString message = fullError.toString();
851  QMessageBox::information((QWidget *)parent(), "Error", message);
853  m_geomIt = false;
854  m_nogeom->setChecked(true);
855  m_geom->setChecked(false);
856  }
857  }
858 
859  // Dump into left chipViewport
861 
862  updateRightGeom();
863 
864  // New right measure, make sure Save Measure Button text is default
865  m_saveMeasure->setPalette(m_saveDefaultPalette);
866  }
867 
868 
883  QString pos = "Sample: " + QString::number(m_leftView->tackSample()) +
884  " Line: " + QString::number(m_leftView->tackLine());
885  m_leftSampLinePosition->setText(pos);
886 
887  if (m_useGeometry) {
888  // Get lat/lon from point in left
890  double lat = m_leftGroundMap->UniversalLatitude();
891  double lon = m_leftGroundMap->UniversalLongitude();
892 
893  pos = "Latitude: " + QString::number(lat) +
894  " Longitude: " + QString::number(lon);
895  m_leftLatLonPosition->setText(pos);
896  }
897 
898  // Print zoom scale factor
899  pos = "Zoom Factor: " + QString::number(zoomFactor);
900  m_leftZoomFactor->setText(pos);
901 
902  // If zooms are linked, make right match left
903  if (m_linkZoom) {
905  }
906  }
907 
908 
920 
921  // If registration Info is on, turn off
922  if (m_autoRegShown) {
923  // Undo Registration
924  m_autoRegShown = false;
925  m_autoRegExtension->hide();
926  m_autoReg->setText("Register");
927  m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
928  "<strong>Shortcut: R</strong>");
929  m_autoReg->setShortcut(Qt::Key_R);
930  }
931 
932  QString pos = "Sample: " + QString::number(m_rightView->tackSample()) +
933  " Line: " + QString::number(m_rightView->tackLine());
934  m_rightSampLinePosition->setText(pos);
935 
936  if (m_useGeometry) {
937  // Get lat/lon from point in right
939  double lat = m_rightGroundMap->UniversalLatitude();
940  double lon = m_rightGroundMap->UniversalLongitude();
941 
942  pos = "Latitude: " + QString::number(lat) +
943  " Longitude: " + QString::number(lon);
944  m_rightLatLonPosition->setText(pos);
945  }
946 
947  // Print zoom scale factor
948  pos = "Zoom Factor: " + QString::number(zoomFactor);
949  m_rightZoomFactor->setText(pos);
950 
951  }
952 
953 
960 
961  QColor qc = Qt::red;
962  QPalette p = m_saveMeasure->palette();
963  p.setColor(QPalette::ButtonText,qc);
964  m_saveMeasure->setPalette(p);
965 
966  }
967 
968 
979 
980  // Get lat/lon from point in left
982  double lat = m_leftGroundMap->UniversalLatitude();
983  double lon = m_leftGroundMap->UniversalLongitude();
984 
985  // Reload right chipViewport with this new tack point.
986  if ( m_rightGroundMap->SetUniversalGround(lat, lon) ) {
987  emit updateRightView(m_rightGroundMap->Sample(), m_rightGroundMap->Line());
988 
989  // If moving from saved measure, turn save button to red
990  if (m_rightGroundMap->Sample() != m_rightMeasure->GetSample() ||
991  m_rightGroundMap->Line() != m_rightMeasure->GetLine())
993  }
994  else {
995  QString message = "Latitude: " + QString::number(lat) + " Longitude: " +
996  QString::number(lon) + " is not on the right image. Right measure " +
997  "was not moved.";
998  QMessageBox::warning((QWidget *)parent(),"Warning",message);
999  }
1000 
1001  }
1002 
1003 
1034 
1035  // if the auto registration factory has not been initialized, do it here
1036  if (m_autoRegFact == NULL) {
1037  try {
1038  Pvl pvl(m_templateFileName);
1040  }
1041  catch (IException &e) {
1042  m_autoRegFact = NULL;
1043  IException fullError(e, IException::Io,
1044  "Cannot create AutoRegFactory. As a result, "
1045  "sub-pixel registration will not work.",
1046  _FILEINFO_);
1047  QString message = fullError.toString();
1048  QMessageBox::information((QWidget *)parent(), "Error", message);
1049  return;
1050  }
1051  }
1052 
1053  if ( m_autoRegShown ) {
1054  // Undo Registration
1055  m_autoRegShown = false;
1056  m_autoRegExtension->hide();
1057  m_autoReg->setText("Register");
1058  m_autoReg->setShortcut(Qt::Key_R);
1059  m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
1060  "<strong>Shortcut: R</strong>");
1061 
1062  // Reload chip with original measure
1063  emit updateRightView(m_rightMeasure->GetSample(),
1064  m_rightMeasure->GetLine());
1065  // Since un-doing registration, make sure save button not red
1066  m_saveMeasure->setPalette(m_saveDefaultPalette);
1067  return;
1068 
1069  }
1070  m_autoRegAttempted = true;
1071 
1072  try {
1074  m_leftMeasure->GetSample(), m_leftMeasure->GetLine());
1077  m_rightMeasure->GetSample(),
1078  m_rightMeasure->GetLine());
1079  if (m_useGeometry) {
1082  }
1083  else {
1085  }
1086  }
1087  catch (IException &e) {
1088  QString msg = "Cannot register this point, unable to Load chips.\n";
1089  msg += e.toString();
1090  QMessageBox::information((QWidget *)parent(), "Error", msg);
1091  return;
1092  }
1093 
1094  try {
1096  if ( !m_autoRegFact->Success() ) {
1097  QString msg = "Cannot sub-pixel register this point.\n";
1098  if ( status == AutoReg::PatternChipNotEnoughValidData ) {
1099  msg += "\n\nNot enough valid data in Pattern Chip.\n";
1100  msg += " PatternValidPercent = ";
1101  msg += QString::number(m_autoRegFact->PatternValidPercent()) + "%";
1102  }
1103  else if ( status == AutoReg::FitChipNoData ) {
1104  msg += "\n\nNo valid data in Fit Chip.";
1105  }
1106  else if ( status == AutoReg::FitChipToleranceNotMet ) {
1107  msg += "\n\nGoodness of Fit Tolerance not met.\n";
1108  msg += "\nGoodnessOfFit = " + QString::number(m_autoRegFact->GoodnessOfFit());
1109  msg += "\nGoodnessOfFitTolerance = ";
1110  msg += QString::number(m_autoRegFact->Tolerance());
1111  }
1112  else if ( status == AutoReg::SurfaceModelNotEnoughValidData ) {
1113  msg += "\n\nNot enough valid points in the fit chip window for sub-pixel ";
1114  msg += "accuracy. Probably too close to edge.\n";
1115  }
1116  else if ( status == AutoReg::SurfaceModelSolutionInvalid ) {
1117  msg += "\n\nCould not model surface for sub-pixel accuracy.\n";
1118  }
1119  else if ( status == AutoReg::SurfaceModelDistanceInvalid ) {
1120  double sampDist, lineDist;
1121  m_autoRegFact->Distance(sampDist, lineDist);
1122  msg += "\n\nSub pixel algorithm moves registration more than tolerance.\n";
1123  msg += "\nSampleMovement = " + QString::number(sampDist) +
1124  " LineMovement = " + QString::number(lineDist);
1125  msg += "\nDistanceTolerance = " +
1126  QString::number(m_autoRegFact->DistanceTolerance());
1127  }
1128  else if ( status == AutoReg::PatternZScoreNotMet ) {
1129  double score1, score2;
1130  m_autoRegFact->ZScores(score1, score2);
1131  msg += "\n\nPattern data max or min does not pass z-score test.\n";
1132  msg += "\nMinimumZScore = " + QString::number(m_autoRegFact->MinimumZScore());
1133  msg += "\nCalculatedZscores = " + QString::number(score1) + ", " + QString::number(score2);
1134  }
1135  else if ( status == AutoReg::AdaptiveAlgorithmFailed ) {
1136  msg += "\n\nError occured in Adaptive algorithm.";
1137  }
1138  else {
1139  msg += "\n\nUnknown registration error.";
1140  }
1141 
1142  QMessageBox::information((QWidget *)parent(), "Error", msg);
1143  return;
1144  }
1145  }
1146  catch (IException &e) {
1147  QString msg = "Cannot register this point.\n";
1148  msg += e.toString();
1149  QMessageBox::information((QWidget *)parent(), "Error", msg);
1150  return;
1151  }
1152 
1153 
1154 
1155  // Load chip with new registered point
1156  emit updateRightView(m_autoRegFact->CubeSample(), m_autoRegFact->CubeLine());
1157  // If registered pt different from measure, colorize the save button
1158  if (m_autoRegFact->CubeSample() != m_rightMeasure->GetSample() ||
1159  m_autoRegFact->CubeLine() != m_rightMeasure->GetLine()) {
1161  }
1162 
1163  QString oldPos = "Original Sample: " +
1164  QString::number(m_rightMeasure->GetSample()) + " Original Line: " +
1165  QString::number(m_rightMeasure->GetLine());
1166  m_oldPosition->setText(oldPos);
1167 
1168  QString goodFit = "Goodness of Fit: " +
1169  QString::number(m_autoRegFact->GoodnessOfFit());
1170  m_goodFit->setText(goodFit);
1171 
1172  m_autoRegExtension->show();
1173  m_autoRegShown = true;
1174  m_autoReg->setText("Undo Registration");
1175  m_autoReg->setToolTip("Undo sub-pixel registration. "
1176  "<strong>Shortcut: U</strong>");
1177  m_autoReg->setShortcut(Qt::Key_U);
1178  }
1179 
1180 
1219 
1220  if ( m_rightMeasure != NULL ) {
1221 
1222  if (m_rightMeasure->IsEditLocked()) {
1223  QString message = "The right measure is locked. You must first unlock the measure by ";
1224  message += "clicking the check box above labeled \"Edit Lock Measure\".";
1225  QMessageBox::warning((QWidget *)parent(),"Warning",message);
1226  return;
1227  }
1228 
1229  if ( m_autoRegShown ) {
1230  try {
1231  // Save autoreg parameters to the right measure log entry
1232  // Eccentricity may be invalid, check before writing.
1236  double minZScore, maxZScore;
1237  m_autoRegFact->ZScores(minZScore,maxZScore);
1240  minZScore));
1243  maxZScore));
1244  }
1245  // need to handle exception that SetLogData throws if our data is invalid -
1246  // unhandled exceptions thrown in Qt signal and slot connections produce undefined behavior
1247  catch (IException &e) {
1248  QString message = e.toString();
1249  QMessageBox::critical((QWidget *)parent(), "Error", message);
1250  return;
1251  }
1252 
1253  // Reset AprioriSample/Line to the current coordinate, before the
1254  // coordinate is updated with the registered coordinate.
1255  m_rightMeasure->SetAprioriSample(m_rightMeasure->GetSample());
1256  m_rightMeasure->SetAprioriLine(m_rightMeasure->GetLine());
1257 
1258  m_rightMeasure->SetChooserName("Application qnet");
1260 
1261  m_autoRegShown = false;
1262  m_autoRegExtension->hide();
1263  m_autoReg->setText("Register");
1264  m_autoReg->setToolTip("Sub-pixel register the right measure to the left. "
1265  "<strong>Shortcut: R</strong>");
1266  m_autoReg->setShortcut(Qt::Key_R);
1267  }
1268  else {
1277  }
1278 
1279  // Get cube position at right chipViewport crosshair
1281  m_rightView->tackLine());
1283 
1284  }
1285 
1286  if ( m_allowLeftMouse ) {
1287  if ( m_leftMeasure != NULL ) {
1288  if (m_leftMeasure->IsEditLocked()) {
1289  QString message = "The left measure is locked. You must first unlock the measure by ";
1290  message += "clicking the check box above labeled \"Edit Lock Measure\".";
1291  QMessageBox::warning((QWidget *)parent(),"Warning",message);
1292  return;
1293  }
1294 
1299  }
1300  }
1301 
1302  // If the right chip is the same as the left chip, copy right into left and
1303  // re-load the left.
1306 
1309  }
1310 
1311  // Change Save Measure button text back to default palette
1312  m_saveMeasure->setPalette(m_saveDefaultPalette);
1313 
1314  // Redraw measures on viewports
1315  emit measureSaved();
1316  }
1317 
1318 
1328 
1329  if ( m_geomIt ) {
1330  try {
1332 
1333  }
1334  catch (IException &e) {
1335  IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1336  QString message = fullError.toString();
1337  QMessageBox::information((QWidget *)parent(), "Error", message);
1338  m_geomIt = false;
1339  m_nogeom->setChecked(true);
1340  m_geom->setChecked(false);
1341  }
1342  }
1343  }
1344 
1345 
1346 
1348 // * Slot to update the right ChipViewport for zoom
1349 // * operations
1350 // *
1351 // * @author 2012-07-26 Tracie Sucharski
1352 // *
1353 // * @internal
1354 // */
1355 //void ControlMeasureEditWidget::updateRightZoom() {
1356 //
1357 // if ( m_linkZoom ) {
1358 // try {
1359 // m_rightView->geomChip(m_leftChip, m_leftCube);
1360 //
1361 // }
1362 // catch (IException &e) {
1363 // IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1364 // QString message = fullError.toString();
1365 // QMessageBox::information((QWidget *)parent(), "Error", message);
1366 // m_geomIt = false;
1367 // m_nogeom->setChecked(true);
1368 // m_geom->setChecked(false);
1369 // }
1370 // }
1371 //}
1372 
1373 
1381  QApplication::setOverrideCursor(Qt::WaitCursor);
1382 
1383  // Text needs to be reset because it was changed to
1384  // indicate why it's greyed out
1385  QString text = "Zoom in 2X";
1386  m_rightZoomIn->setEnabled(true);
1387  m_rightZoomIn->setWhatsThis(text);
1388  m_rightZoomIn->setToolTip("Zoom In");
1389  text = "Zoom out 2X";
1390  m_rightZoomOut->setEnabled(true);
1391  m_rightZoomOut->setWhatsThis(text);
1392  m_rightZoomOut->setToolTip("Zoom Out");
1393  text = "Zoom 1:1";
1394  m_rightZoom1->setEnabled(true);
1395  m_rightZoom1->setWhatsThis(text);
1396  m_rightZoom1->setToolTip("Zoom 1:1");
1397 
1398  m_geomIt = false;
1400 
1401  QApplication::restoreOverrideCursor();
1402 
1403  m_dial->setEnabled(true);
1404  m_dialNumber->setEnabled(true);
1405  m_dial->setNotchesVisible(true);
1406 
1407  }
1408 
1409 
1420 
1421  if ( m_geomIt == true ) return;
1422 
1423  QApplication::setOverrideCursor(Qt::WaitCursor);
1424 
1425  // Grey right view zoom buttons
1426  QString text = "Zoom functions disabled when Geom is set";
1427  m_rightZoomIn->setEnabled(false);
1428  m_rightZoomIn->setWhatsThis(text);
1429  m_rightZoomIn->setToolTip(text);
1430  m_rightZoomOut->setEnabled(false);
1431  m_rightZoomOut->setWhatsThis(text);
1432  m_rightZoomOut->setToolTip(text);
1433  m_rightZoom1->setEnabled(false);
1434  m_rightZoom1->setWhatsThis(text);
1435  m_rightZoom1->setToolTip(text);
1436 
1437 
1438  // Reset dial to 0 before disabling
1439  m_dial->setValue(0);
1440  m_dial->setEnabled(false);
1441  m_dialNumber->setEnabled(false);
1442 
1443  m_geomIt = true;
1444 
1445  try {
1447 
1448  }
1449  catch (IException &e) {
1450  IException fullError(e, IException::User, "Geom failed.", _FILEINFO_);
1451  QString message = fullError.toString();
1452  QMessageBox::information((QWidget *)parent(), "Error", message);
1453  m_geomIt = false;
1454  m_nogeom->setChecked(true);
1455  m_geom->setChecked(false);
1456  }
1457 
1458  QApplication::restoreOverrideCursor();
1459  }
1460 
1461 
1469 
1470  QApplication::setOverrideCursor(Qt::WaitCursor);
1471 
1472  QString text = "Zoom in 2X";
1473  m_rightZoomIn->setEnabled(true);
1474  m_rightZoomIn->setWhatsThis(text);
1475  m_rightZoomIn->setToolTip("Zoom In");
1476  text = "Zoom out 2X";
1477  m_rightZoomOut->setEnabled(true);
1478  m_rightZoomOut->setWhatsThis(text);
1479  m_rightZoomOut->setToolTip("Zoom Out");
1480  text = "Zoom 1:1";
1481  m_rightZoom1->setEnabled(true);
1482  m_rightZoom1->setWhatsThis(text);
1483  m_rightZoom1->setToolTip("Zoom 1:1");
1484 
1485  // Reset dial to 0 before disabling
1486  m_dial->setValue(0);
1487  m_dial->setEnabled(false);
1488  m_dialNumber->setEnabled(false);
1489 
1490  m_geomIt = false;
1492 
1493  QApplication::restoreOverrideCursor();
1494  }
1495 
1496 
1505 
1506  if ( checked == m_circle ) return;
1507 
1508  m_circle = checked;
1509  if ( m_circle ) {
1510  // Turn on slider bar
1511  m_slider->setDisabled(false);
1512  m_slider->show();
1513  m_slider->setValue(20);
1514  m_leftView->setCircle(true);
1515  m_rightView->setCircle(true);
1516  }
1517  else {
1518  m_slider->setDisabled(true);
1519  m_slider->hide();
1520  m_leftView->setCircle(false);
1521  m_rightView->setCircle(false);
1522  }
1523  }
1524 
1525 
1534 
1535  if ( checked == m_linkZoom ) return;
1536 
1537  m_linkZoom = checked;
1538  if ( m_linkZoom ) {
1540  }
1541  }
1542 
1543 
1548  if ( m_timerOn ) return;
1549 
1550  // Set up blink list
1551  m_blinkList.push_back(m_leftView);
1552  m_blinkList.push_back(m_rightView);
1553  m_blinkIndex = 0;
1554 
1555  m_timerOn = true;
1556  int msec = (int)(m_blinkTimeBox->value() * 1000.0);
1557  m_timer = new QTimer(this);
1558  connect(m_timer, SIGNAL(timeout()), this, SLOT(updateBlink()));
1559  m_timer->start(msec);
1560  }
1561 
1562 
1567  m_timer->stop();
1568  m_timerOn = false;
1569  m_blinkList.clear();
1570 
1571  // Reload left chipViewport with original chip
1572  m_leftView->repaint();
1573 
1574  }
1575 
1576 
1584  if ( m_timerOn ) m_timer->setInterval((int)(interval * 1000.));
1585  }
1586 
1587 
1592 
1595  }
1596 
1597 
1617 
1618  AutoReg *reg = NULL;
1619  // save original template filename
1620  QString temp = m_templateFileName;
1621  try {
1622  // set template filename to user chosen pvl file
1623  m_templateFileName = fn;
1624 
1625  // Create PVL object with this file
1626  Pvl pvl(fn);
1627 
1628  // try to register file
1629  reg = AutoRegFactory::Create(pvl);
1630  if ( m_autoRegFact != NULL )
1631  delete m_autoRegFact;
1632  m_autoRegFact = reg;
1633 
1634  m_templateFileName = fn;
1635  return true;
1636  }
1637  catch (IException &e) {
1638  // set templateFileName back to its original value
1639  m_templateFileName = temp;
1640  IException fullError(e, IException::Io,
1641  "Cannot create AutoRegFactory for " +
1642  fn +
1643  ". As a result, current template file will remain set to " +
1645  QString message = fullError.toString();
1646  QMessageBox::information((QWidget *)parent(), "Error", message);
1647  emit setTemplateFailed(m_templateFileName);
1648  return false;
1649  }
1650  }
1651 
1652 
1661  m_allowLeftMouse = allowMouse;
1662 
1663  if (m_allowLeftMouse) {
1664  m_saveMeasure = new QPushButton("Save Measures");
1665  m_saveMeasure->setToolTip("Save the both the left and right measure to the edit control "
1666  "point (control point currently being edited). "
1667  " <strong>Note: The edit control point "
1668  "will not be saved to the network until you select "
1669  "<strong>\"Save Point\"</strong>");
1670  }
1671  else {
1672  m_saveMeasure = new QPushButton("Save Measure");
1673  m_saveMeasure->setToolTip("Save the right measure to the edit control "
1674  "point (control point currently being edited). "
1675  " <strong>Note: The edit control point "
1676  "will not be saved to the network until you select "
1677  "<strong>\"Save Point\"</strong>");
1678  }
1679  }
1680 
1681 
1682  void ControlMeasureEditWidget::refreshChips() {
1683  m_leftView->update();
1684  m_rightView->update();
1685  }
1686 
1687 
1698 
1699 // if (!m_autoRegShown) {
1700  if ( !m_autoRegAttempted ) {
1701  QString message = "Point must be Registered before chips can be saved.";
1702  QMessageBox::warning((QWidget *)parent(), "Warning", message);
1703  return;
1704  }
1705 
1706  // Save chips - pattern, search and fit
1707  QString baseFile = m_pointId.replace(" ", "_") + "_" +
1708  toString((int)(m_leftMeasure ->GetSample())) + "_" +
1709  toString((int)(m_leftMeasure ->GetLine())) + "_" +
1710  toString((int)(m_rightMeasure->GetSample())) + "_" +
1711  toString((int)(m_rightMeasure->GetLine())) + "_";
1712  QString fname = baseFile + "Search.cub";
1713  QString command = "$ISISROOT/bin/qview \'" + fname + "\'";
1715  fname = baseFile + "Pattern.cub";
1716  command += " \'" + fname + "\'";
1718  fname = baseFile + "Fit.cub";
1719  command += " \'" + fname + "\' &";
1720  m_autoRegFact->FitChip()->Write(fname);
1722  }
1723 
1724 
1733 
1734  m_editPoint = editPoint;
1735  m_serialNumberList = snList;
1736 
1737 
1738  m_blinkListWidget->clear();
1739  }
1740 
1741 
1742  void ControlMeasureEditWidget::showBlinkExtension() {
1743  m_blinkListWidget->clear();
1744  // Get all measure filenames for ListWidget
1745  for (int i=0; i<m_editPoint->GetNumMeasures(); i++) {
1746  ControlMeasure &m = *(*m_editPoint)[i];
1747  QString file = m_serialNumberList->fileName(m.GetCubeSerialNumber());
1748  // TODO Ipce TLS Look at QnetNavTool for how selectedItems is used so don't need map
1749  // between full cubename and base name.
1750 // QString tempFileName = FileName(file).name();
1751  m_blinkListWidget->addItem(file);
1752 
1753 
1754 
1755 // if (m_editPoint->IsReferenceExplicit() &&
1756 // (QString)m.GetCubeSerialNumber() == m_editPoint->GetReferenceSN()) {
1757 // m_blinkListWidget->setItemData(i,QFont("DejaVu Sans", 12, QFont::Bold), Qt::FontRole);
1758 // }
1759  }
1760  }
1761 
1762 
1765 
1766  if ( m_timerOnRight ) return;
1767 
1768  // Set up blink list. Create ChipViewport for each cube active in the ListWidget, using the
1769  // correct zoom and geom selections
1770  QList<QListWidgetItem *> selected = m_blinkListWidget->selectedItems();
1771  if (selected.size() < 1) {
1772  QMessageBox::information((QWidget *)parent(), "Error", "No files selected for blinking.");
1773  return;
1774  }
1775 
1776  // Find measure for each selected file, create cube, chip and chipViewport
1777  for (int i=0; i<selected.size(); i++) {
1778  QString file = selected.at(i)->text();
1779  QString serial = m_serialNumberList->serialNumber(file);
1780  Cube *blinkCube = new Cube(selected.at(i)->text());
1781  Chip *blinkChip = new Chip(VIEWSIZE, VIEWSIZE);
1782  ControlMeasure *blinkMeasure = m_editPoint->GetMeasure(serial);
1783  blinkChip->TackCube(blinkMeasure->GetSample(), blinkMeasure->GetLine());
1784  blinkChip->Load(*blinkCube);
1785  ChipViewport *blinkViewport = new ChipViewport(VIEWSIZE, VIEWSIZE, this);
1786  blinkViewport->setChip(blinkChip, blinkCube);
1787  if (m_geomIt) {
1788  blinkViewport->geomChip(m_leftChip, m_leftCube);
1789  }
1790  else {
1791  blinkViewport->zoom(m_leftView->zoomFactor());
1792  }
1793  m_blinkChipViewportListRight.append(blinkViewport);
1794  }
1795 
1796  m_blinkIndexRight = 0;
1797 
1798  m_timerOnRight = true;
1799  int msec = (int)(m_blinkTimeBoxRight->value() * 1000.0);
1800  m_timerRight = new QTimer(this);
1801  connect(m_timerRight, SIGNAL(timeout()), this, SLOT(updateBlinkRight()));
1802  m_timerRight->start(msec);
1803  }
1804 
1805 
1808 
1809  m_timerRight->stop();
1810  m_timerOnRight = false;
1812  // Reload left chipViewport with original chip
1813  m_rightView->repaint();
1814  }
1815 
1816 
1824  if ( m_timerOnRight ) m_timerRight->setInterval((int)(interval * 1000.));
1825  }
1826 
1827 
1830 
1833  m_blinkIndexRight = 0;
1834  }
1836  }
1837 }
Status SetType(MeasureType type)
Set how the coordinate was obtained.
ControlPoint * m_editPoint
The control point currently being edited.
Error occured in Adaptive algorithm.
Definition: AutoReg.h:205
double MinimumZScore() const
Return minimumPatternZScore.
Definition: AutoReg.h:366
void zoom(double zoomFactor)
Zoom by a specified factor.
void setLeftPosition(double sample, double line)
Set the tack position of the measure in the left ChipViewport.
SerialNumberList * m_serialNumberList
The serial numbers for each measure of m_editpoint.
double Line() const
Returns the current line value of the camera model or projection.
void blinkStartRight()
Slot to start blink function for advanced blink functionality.
File name manipulation and expansion.
Definition: FileName.h:116
Universal Ground Map.
void setCircle(bool)
Turn circle widgets on/off.
void updateBlinkRight()
Slot to cause the blink to happen coinciding with the timer.
QLabel * m_rightSampLinePosition
Label for right chip viewport&#39;s current sample/line.
void blinkStart()
Slot to start blink function.
QListWidget * m_blinkListWidget
List of images being blinked through.
const ControlMeasure * GetMeasure(QString serialNumber) const
Get a control measure based on its cube&#39;s serial number.
QDoubleSpinBox * m_blinkTimeBoxRight
Input for time between image blinks.
A small chip of data used for pattern matching.
Definition: Chip.h:102
Chip * RegistrationSearchChip()
Return pointer to search chip used in registration.
Definition: AutoReg.h:243
Not enough valid data in pattern chip.
Definition: AutoReg.h:198
Not enough points to fit a surface model for sub-pixel accuracy.
Definition: AutoReg.h:201
void updateRightPositionLabel(double zoomFactor)
Update sample/line, lat/lon and zoom factor of right measure.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
Chip * RegistrationPatternChip()
Return pointer to pattern chip used in registration.
Definition: AutoReg.h:233
QTimer * m_timer
Timer on the blinking.
Surface model moves registration more than one pixel.
Definition: AutoReg.h:203
Statistical and similar ControlMeasure associated information.
QLabel * m_leftZoomFactor
Label for left chip viewport&#39;s zoom factor.
double DistanceTolerance() const
Return distance tolerance.
Definition: AutoReg.h:316
void TackCube(const double cubeSample, const double cubeLine)
This sets which cube position will be located at the chip tack position.
Definition: Chip.cpp:204
QPushButton * m_autoReg
Button to auto-register the measure.
AutoReg::RegisterStatus Register()
Walk the pattern chip through the search chip to find the best registration.
Definition: AutoReg.cpp:600
bool m_linkZoom
Link zoom factors between chip viewports.
Chip * SearchChip()
Return pointer to search chip.
Definition: AutoReg.h:223
ChipViewport * m_leftView
Left ChipViewport.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:132
ControlMeasureEditWidget(QWidget *parent=0, bool allowLeftMouse=false, bool useGeometry=true)
Constructs a ControlMeasureEditWidget widget.
Registered to sub-pixel (e.g., pointreg)
double GoodnessOfFit() const
Return the goodness of fit of the match algorithm.
Definition: AutoReg.h:339
void setNoGeom()
Slot to turn off geom.
QLabel * m_rightZoomFactor
Label for right chip viewport&#39;s zoom factor.
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
double tackLine()
Returns tack line.
void changeBlinkTime(double interval)
Set blink rate.
void colorizeSaveButton()
Turn "Save Measure" button text to red.
bool m_circle
Whether or not to draw circle in center of the right chip viewport.
bool m_timerOnRight
Timer is on for right viewport.
double tackSample()
Return the position of cube under cross hair.
Control measures store z-scores in pairs.
bool m_useGeometry
Whether or not to allow geometry/rotation on right chip viewport.
double CubeSample() const
Return the search chip cube sample that best matched.
Definition: AutoReg.h:356
QString fileName(const QString &sn)
Return a filename given a serial number.
void ZScores(double &score1, double &score2) const
Return the ZScores of the pattern chip.
Definition: AutoReg.h:376
QLCDNumber * m_dialNumber
The current amount of rotation (in degrees)
static void RunSystemCommand(QString commandLine)
This runs arbitrary system commands.
void setPoint(ControlPoint *editPoint, SerialNumberList *snList)
Set the Control Point for this widget.
void saveChips()
Slot to save registration chips to files and fire off qview.
void updateBlink()
Slot to cause the blink to happen coinciding with the timer.
void updateLeftPositionLabel(double zoomFactor)
Update sample/line, lat/lon and zoom factor of left measure.
UniversalGroundMap * m_leftGroundMap
UniversalGroundMap for left cube.
QWidget * m_blinkExtension
Widget for selecting images and timing to blink through them.
void saveMeasure()
Save control measure under the crosshair in right ChipViewport.
void setRotate()
Slot to update the right ChipViewport for zoom operations.
void findPoint()
Find point from left ChipViewport in the right ChipViewport.
a control network
Definition: ControlNet.h:271
Hand Measured (e.g., qnet)
double Tolerance() const
Return match algorithm tolerance.
Definition: AutoReg.h:306
bool m_geomIt
Apply geometry to the right chip viewport.
void blinkStop()
Slot to stop blink function.
Pixel value mapper.
Definition: Stretch.h:72
Chip * PatternChip()
Return pointer to pattern chip.
Definition: AutoReg.h:218
void Write(const QString &filename)
Writes the contents of the Chip to a cube.
Definition: Chip.cpp:1007
unsigned char m_blinkIndexRight
Index of image being blinked.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
void setRightPosition(double sample, double line)
Set the tack position of the measure in the right ChipViewport.
void changeBlinkTimeRight(double interval)
Set blink rate.
void SetLogData(ControlMeasureLogData)
This adds or updates the log data information associated with data&#39;s type.
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
QScrollBar * m_slider
Slider that controls the size of the center circle.
AutoReg * m_autoRegFact
Created AutoReg.
double UniversalLatitude() const
Returns the universal latitude of the camera model or projection.
double CubeLine() const
Return the search chip cube line that best matched.
Definition: AutoReg.h:361
double PatternValidPercent() const
Return pattern chip valid percent. The default value is.
Definition: AutoReg.h:296
bool m_allowLeftMouse
Whether or not to allow mouse events on left chip viewport.
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:212
void geomChip(Chip *matchChip, Cube *matchChipCube)
Slot to geom chip (apply geometry transformation)
A single control point.
Definition: ControlPoint.h:369
QTimer * m_timerRight
Timer for tracking image blink time.
QLabel * m_rightLatLonPosition
Label for right chip viewport&#39;s current lat/lon.
QRadioButton * m_geom
Radio button to apply geometry/rotation to right chip viewport.
bool m_autoRegAttempted
Whether or not auto-registration has been attempted.
void setLeftMeasure(ControlMeasure *leftMeasure, Cube *leftCube, QString pointId)
Set the measure displayed in the left ChipViewport.
QRadioButton * m_nogeom
Radio button to remove geometry/rotation for right chip viewport.
double zoomFactor()
Return the zoom factor.
ControlMeasure * m_rightMeasure
Right ControlMeasure.
bool Success() const
Return whether the match algorithm succeeded or not.
Definition: AutoReg.h:334
Fit chip did not have any valid data.
Definition: AutoReg.h:199
void setRightMeasure(ControlMeasure *rightMeasure, Cube *rightCube, QString pointId)
Set the measure displayed in the right ChipViewport.
QString m_templateFileName
Registration template filename.
Container for cube-like labels.
Definition: Pvl.h:135
void Load(Cube &cube, const double rotation=0.0, const double scale=1.0, const int band=1)
Load cube data into the Chip.
Definition: Chip.cpp:225
QLabel * m_goodFit
The goodness of fit value after registering.
QToolButton * m_rightZoomOut
Button for zooming out right chip viewport.
void createMeasureEditor(QWidget *parent)
Design the MeasureEdit widget.
Auto Registration class.
Definition: AutoReg.h:183
bool SetImage(double sample, double line)
Returns whether the sample/line postion was set successfully in the camera model or projection...
static AutoReg * Create(Pvl &pvl)
Create an AutoReg object using a PVL specification.
GoodnessOfFit is pointreg information for reference measures.
int m_rotation
Amount to rotate right chip viewport TODO Is this used??
QToolButton * m_rightZoomIn
Button for zooming in right chip viewport.
Goodness of fit tolerance not satisfied.
Definition: AutoReg.h:200
QString toString() const
Returns a string representation of this exception.
Definition: IException.cpp:553
Viewport for Isis Chips.
Definition: ChipViewport.h:85
void registerPoint()
Sub-pixel register point in right chipViewport with point in left.
RegisterStatus
Enumeration of the Register() method&#39;s return status.
Definition: AutoReg.h:195
void Distance(double &sampDistance, double &lineDistance)
Return the distance point moved.
Definition: AutoReg.h:326
Cube * m_leftCube
Left chip viewport&#39;s Cube.
QDoubleSpinBox * m_blinkTimeBox
The current blink step (in seconds)
void setChip(Chip *chip, Cube *chipCube)
Set chip.
ChipViewport * m_rightView
Right ChipViewport.
static QString UserName()
Returns the user name.
Isis exception class.
Definition: IException.h:107
ControlMeasure * m_leftMeasure
Left ControlMeasure.
QLabel * m_oldPosition
The old sample and line before registering.
Status SetChooserName()
Set chooser name to a user who last changed the coordinate.
QPalette m_saveDefaultPalette
Default color palette for the Save button.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
QList< ChipViewport * > m_blinkList
List of chip viewports to blink.
void updateRightGeom()
Slot to update the geomed right ChipViewport for zoom operations.
bool IsEditLocked() const
Return value for p_editLock or implicit lock on reference measure.
bool SetUniversalGround(double lat, double lon)
Returns whether the lat/lon position was set successfully in the camera model or projection.
a control measurement
Status SetCoordinate(double sample, double line)
Set the coordinate of the measurement.
bool m_timerOn
Indicates if the blink timer is on.
QString m_pointId
Associated control point id of the right measure.
QPushButton * m_saveMeasure
Button to save the current measure.
Chip * FitChip()
Return pointer to fit chip.
Definition: AutoReg.h:228
bool m_autoRegShown
Whether or not the auto-reg extension is shown.
void DeleteLogData(long dataType)
This deletes log data of the specified type.
Status SetDateTime()
Date Time - Creation Time.
QLabel * m_leftLatLonPosition
Label for left chip viewport&#39;s current lat/lon.
Could not model surface for sub-pixel accuracy.
Definition: AutoReg.h:202
Pattern data max or min does not pass the z-score test.
Definition: AutoReg.h:204
double Sample() const
Returns the current line value of the camera model or projection.
Cube * m_rightCube
Right chip viewport&#39;s Cube.
void setCircle(bool checked)
Slot to change state of circle.
QToolButton * m_rightZoom1
Button for 1:1 zoom on right chip viewport.
const int VIEWSIZE
Constant representing the length and width of the chip viewports.
QLabel * m_leftSampLinePosition
Label for left chip viewport&#39;s current sample/line.
Serial Number list generator.
QWidget * m_autoRegExtension
Widget that shows after registering a measure.
double UniversalLongitude() const
Returns the universal longitude of the camera model or projection.
void allowLeftMouse(bool allowMouse)
Set the option that allows mouse movements in the left ChipViewport.
void loadView(ChipViewport &newView)
Load with another ChipViewport, used for blinking.
unsigned char m_blinkIndex
Index of the chip to load in the left chip viewport.
UniversalGroundMap * m_rightGroundMap
UniversalGroundMap for right cube.
QList< ChipViewport * > m_blinkChipViewportListRight
List of viewports to blink through.
bool setTemplateFile(QString)
Allows user to choose a new template file by opening a window from which to select a filename...
void nogeomChip()
Slot to un-geom chip (revert geometry transformation)
void setZoomLink(bool)
Turn linking of zoom on or off.
QString GetCubeSerialNumber() const
Return the serial number of the cube containing the coordinate.
void blinkStopRight()
Slot to stop blink function.
IO Handler for Isis Cubes.
Definition: Cube.h:170