USGS

Isis 3.0 Object Programmers' Reference

Home

AdvancedTrackTool.cpp
1 #include "AdvancedTrackTool.h"
2 
3 #include <QApplication>
4 #include <QMenu>
5 #include <QSize>
6 
7 #include "Angle.h"
8 #include "Camera.h"
9 #include "Distance.h"
10 #include "iTime.h"
11 #include "Longitude.h"
12 #include "MdiCubeViewport.h"
13 #include "Projection.h"
14 #include "RingPlaneProjection.h"
15 #include "SerialNumber.h"
16 #include "SpecialPixel.h"
17 #include "TableMainWindow.h"
18 #include "Target.h"
19 #include "TProjection.h"
20 
21 namespace Isis {
22 
23  // For mosaic tracking
24 #define FLOAT_MIN -16777215
25 #define TABLE_MOSAIC_SRC "InputImages"
26 
33  p_tableWin = new TableMainWindow("Advanced Tracking", parent);
35  connect(p_tableWin, SIGNAL(fileLoaded()), this, SLOT(updateID()));
36 
37  p_action = new QAction(parent);
38  p_action->setText("Tracking ...");
39  p_action->setIcon(QPixmap(toolIconDir() + "/goto.png"));
40  p_action->setShortcut(Qt::CTRL + Qt::Key_T);
41  p_action->setWhatsThis("<b>Function: </b> Opens the Advanced Tracking Tool \
42  window. This window will track sample/line positions,\
43  lat/lon positions, and many other pieces of \
44  information. All of the data in the window can be \
45  saved to a text file. <p><b>Shortcut: </b> Ctrl+T</p>");
46  connect(p_action, SIGNAL(triggered()), p_tableWin, SLOT(showTable()));
47  activate(true);
48  connect(p_action, SIGNAL(triggered()), p_tableWin, SLOT(raise()));
49  connect(p_action, SIGNAL(triggered()), p_tableWin, SLOT(syncColumns()));
50  p_tableWin->installEventFilter(this);
51 
52  p_tableWin->addToTable(false, "Id", "Id");
53  p_tableWin->addToTable(true, "Sample:Line", "Sample:Line", -1,
54  Qt::Horizontal, "Sample and Line");
55  p_tableWin->addToTable(false, "Band", "Band");
56  p_tableWin->addToTable(true, "Pixel", "Pixel");
57  p_tableWin->addToTable(true, "Planetocentric Latitude", "Planetocentric Lat");
58  p_tableWin->addToTable(false, "Planetographic Latitude", "Planetographic Lat");
59  p_tableWin->addToTable(true, "360 Positive East Longitude", "360 East Longitude");
60  p_tableWin->addToTable(false, "360 Positive West Longitude", "360 West Longitude");
61  p_tableWin->addToTable(true, "180 Positive East Longitude", "180 East Longitude");
62  p_tableWin->addToTable(false, "180 Positive West Longitude", "180 West Longitude");
63  p_tableWin->addToTable(false, "Projected X:Projected Y", "Projected X:Projected Y", -1,
64  Qt::Horizontal, "X and Y values for a projected image");
65  p_tableWin->addToTable(false, "Local Radius", "Radius");
66  p_tableWin->addToTable(false, "Point X:Point Y:Point Z", "XYZ", -1, Qt::Horizontal,
67  "The X, Y, and Z of surface intersection in body-fixed coordinates");
68  p_tableWin->addToTable(false, "Right Ascension:Declination", "Ra:Dec", -1, Qt::Horizontal,
69  "Right Ascension and Declination");
70  p_tableWin->addToTable(false, "Resolution", "Resolution");
71  p_tableWin->addToTable(false, "Phase", "Phase");
72  p_tableWin->addToTable(false, "Incidence", "Incidence");
73  p_tableWin->addToTable(false, "Emission", "Emission");
74  p_tableWin->addToTable(false, "LocalIncidence", "LocalIncidence");
75  p_tableWin->addToTable(false, "LocalEmission", "LocalEmission");
76  p_tableWin->addToTable(false, "North Azimuth", "North Azimuth");
77  p_tableWin->addToTable(false, "Sun Azimuth", "Sun Azimuth");
78  p_tableWin->addToTable(false, "Solar Longitude", "Solar Longitude");
79  p_tableWin->addToTable(false, "Spacecraft X:Spacecraft Y:Spacecraft Z", "Spacecraft Position",
80  -1, Qt::Horizontal, "The X, Y, and Z of the spacecraft position");
81  p_tableWin->addToTable(false, "Spacecraft Azimuth", "Spacecraft Azimuth");
82  p_tableWin->addToTable(false, "Slant Distance", "Slant Distance");
83  p_tableWin->addToTable(false, "Ephemeris Time", "Ephemeris iTime");
84  p_tableWin->addToTable(false, "Local Solar Time", "Local Solar iTime");
85  p_tableWin->addToTable(false, "UTC", "UTC", -1, Qt::Horizontal, "Internal time in UTC format");
86  p_tableWin->addToTable(false, "Path", "Path");
87  p_tableWin->addToTable(false, "FileName", "FileName");
88  p_tableWin->addToTable(false, "Serial Number", "Serial Number");
89  p_tableWin->addToTable(false, "Track Mosaic Index", "Track Mosaic Index");
90  p_tableWin->addToTable(false, "Track Mosaic FileName", "Track Mosaic FileName");
91  p_tableWin->addToTable(false, "Track Mosaic Serial Number", "Track Mosaic Serial Number");
92  p_tableWin->addToTable(false, "Notes", "Notes");
93  //This variable will keep track of how many times
94  // the user has issued the 'record' command.
95  p_id = 0;
96 
97  // Setup 10 blank rows in the table
98  for(int r = 0; r < 10; r++) {
99  p_tableWin->table()->insertRow(r);
100  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
101  QTableWidgetItem *item = new QTableWidgetItem("");
102  p_tableWin->table()->setItem(r, c, item);
103  }
104  }
105 
106  // Create the action for recording points
107  QAction *recordAction = new QAction(parent);
108  recordAction->setShortcut(Qt::Key_R);
109  parent->addAction(recordAction);
110  connect(recordAction, SIGNAL(activated()), this, SLOT(record()));
111  p_tableWin->setStatusMessage("To record press the R key"
112  " --- Double click on a cell to enable crtl+c (copy) and"
113  " ctrl+v (paste).");
114 
115  // Add a help menu to the menu bar
116  QMenuBar *menuBar = p_tableWin->menuBar();
117  QMenu *helpMenu = menuBar->addMenu("&Help");
118  QAction *help = new QAction(p_tableWin);
119  help->setText("&Tool Help");
120  help->setShortcut(Qt::CTRL + Qt::Key_H);
121  connect(help, SIGNAL(activated()), this, SLOT(helpDialog()));
122  helpMenu->addAction(help);
123  p_tableWin->setMenuBar(menuBar);
124  installEventFilter(p_tableWin);
125 
126  m_showHelpOnStart = true;
127  readSettings();
128  }
129 
139  if(e->type() == QEvent::Show) {
140  activate(true);
141  if (m_showHelpOnStart) {
142  helpDialog();
143  m_showHelpOnStart = false;
144  writeSettings();
145  }
146  }
147  else if(e->type() == QEvent::Hide) {
148  activate(false);
149  }
150  return Tool::eventFilter(o, e);
151  }
152 
153 
159  void AdvancedTrackTool::addTo(QMenu *menu) {
160  menu->addAction(p_action);
161  }
162 
170  perm->addAction(p_action);
171  }
172 
180  updateRow(p);
181  }
182 
189 
190  if(cubeViewport()->isLinked()) {
191  for(int i = 0; i < p_numRows; i++) {
193  }
194  }
195  else {
197  }
198 
199  }
200 
207  MdiCubeViewport *cvp = cubeViewport();
208  if(cvp == NULL) {
210  return;
211  }
212 
213  if(!cubeViewport()->isLinked()) {
214  updateRow(cvp, p, p_tableWin->currentRow());
215  p_numRows = 1;
216  }
217  else {
218  p_numRows = 0;
219  for(int i = 0; i < (int)cubeViewportList()->size(); i++) {
220  MdiCubeViewport *d = (*(cubeViewportList()))[i];
221  if(d->isLinked()) {
223  p_numRows++;
224  }
225  }
226  }
227  }
228 
236  void AdvancedTrackTool::updateRow(MdiCubeViewport *cvp, QPoint p, int row) {
237  // Get the sample line position to report
238  double sample, line;
239  cvp->viewportToCube(p.x(), p.y(), sample, line);
240  int isample = int (sample + 0.5);
241  int iline = int (line + 0.5);
242 
243  /*if there are linked cvp's then we want to highlight (select)
244  the row of the active cvp.*/
245  if(cvp->isLinked()) {
246 
247  if(cvp == cubeViewport()) {
248  p_tableWin->table()->selectRow(row);
249  }
250 
251  }
252 
253 
254  // Do we need more rows?
255  if(row + 1 > p_tableWin->table()->rowCount()) {
256  p_tableWin->table()->insertRow(row);
257  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
258  QTableWidgetItem *item = new QTableWidgetItem("");
259  p_tableWin->table()->setItem(row, c, item);
260  if(c == 0) p_tableWin->table()->scrollToItem(item);
261  }
262  }
263 
264  // Blank out the row to remove stuff left over from previous cvps
265  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
266  p_tableWin->table()->item(row, c)->setText("");
267  }
268 
269  // Don't write anything if we are outside the cube
270  if(sample < 0.5) return;
271  if(line < 0.5) return;
272  if(sample > cvp->cubeSamples() + 0.5) return;
273  if(line > cvp->cubeLines() + 0.5) return;
274 
275  // Write cols 0-2 (id, sample, line)
276  p_tableWin->table()->item(row, ID)->setText(QString::number(p_id));
277  p_tableWin->table()->item(row, SAMPLE)->setText(QString::number(sample));
278  p_tableWin->table()->item(row, LINE)->setText(QString::number(line));
279 
280  // Write col 3 (band)
281  if(cvp->isGray()) {
282  p_tableWin->table()->item(row, BAND)->setText(QString::number(cvp->grayBand()));
283  }
284  else {
285  p_tableWin->table()->item(row, BAND)->setText(QString::number(cvp->redBand()));
286  }
287 
288  // Write out the path, filename, and serial number
289  FileName fname = FileName(cvp->cube()->fileName()).expanded();
290  QString fnamePath = fname.path();
291  QString fnameName = fname.name();
292  p_tableWin->table()->item(row, PATH)->setText(fnamePath);
293  p_tableWin->table()->item(row, FILENAME)->setText(fnameName);
294  //p_tableWin->table()->item(row,34)->setText(SerialNumber::Compose(*cvp->cube()).c_str());
295 
296  // If we are outside of the image then we are done
297  if((sample < 0.5) || (line < 0.5) ||
298  (sample > cvp->cubeSamples() + 0.5) ||
299  (line > cvp->cubeLines() + 0.5)) {
300  return;
301  }
302 
303  // Otherwise write out col 4 (Pixel value)
304  if(cvp->isGray()) {
305  QString grayPixel = PixelToString(cvp->grayPixel(isample, iline));
306  QString p = grayPixel;
307  p_tableWin->table()->item(row, PIXEL)->setText(p);
308  }
309  else {
310  QString redPixel = PixelToString(cvp->redPixel(isample, iline));
311  QString p = redPixel;
312  p_tableWin->table()->item(row, PIXEL)->setText(p);
313  }
314 
315  // Do we have a camera model?
316  if(cvp->camera() != NULL) {
317  if(cvp->camera()->SetImage(sample, line)) {
318  // Write columns ocentric lat/lon, and radius, only if set image succeeds
319  double lat = cvp->camera()->UniversalLatitude();
320  double lon = cvp->camera()->UniversalLongitude();
321 
322  double radius = cvp->camera()->LocalRadius().meters();
323  p_tableWin->table()->item(row, PLANETOCENTRIC_LAT)->setText(QString::number(lat, 'f', 15));
324  p_tableWin->table()->item(row, EAST_LON_360)->setText(QString::number(lon, 'f', 15));
325  p_tableWin->table()->item(row, RADIUS)->setText(QString::number(radius, 'f', 15));
326 
327  /* 180 Positive East Lon. */
328  p_tableWin->table()->item(row, EAST_LON_180)->
329  setText(QString::number(TProjection::To180Domain(lon), 'f', 15));
330 
331  // Write out the planetographic and positive west values, only if set image succeeds
332  lon = -lon;
333  while(lon < 0.0) lon += 360.0;
334  Distance radii[3];
335  cvp->camera()->radii(radii);
336  lat = TProjection::ToPlanetographic(lat, radii[0].meters(), radii[2].meters());
337  p_tableWin->table()->item(row, PLANETOGRAPHIC_LAT)->setText(QString::number(lat, 'f', 15));
338  p_tableWin->table()->item(row, WEST_LON_360)->setText(QString::number(lon, 'f', 15));
339 
340  /*180 Positive West Lon. */
341  p_tableWin->table()->item(row, WEST_LON_180)->setText(
342  QString::number(TProjection::To180Domain(lon), 'f', 15));
343 
344  // Next write out columns, the x/y/z position of the lat/lon, only if set image succeeds
345  double pos[3];
346  cvp->camera()->Coordinate(pos);
347  p_tableWin->table()->item(row, POINT_X)->setText(QString::number(pos[0]));
348  p_tableWin->table()->item(row, POINT_Y)->setText(QString::number(pos[1]));
349  p_tableWin->table()->item(row, POINT_Z)->setText(QString::number(pos[2]));
350 
351  // Write out columns resolution, only if set image succeeds
352  if (cvp->camera()->PixelResolution() != -1.0) {
353  double res = cvp->camera()->PixelResolution();
354  p_tableWin->table()->item(row, RESOLUTION)->setText(QString::number(res));
355  }
356  else {
357  p_tableWin->table()->item(row, RESOLUTION)->setText("");
358  }
359 
360  // Write out columns photometric angle values, only if set image succeeds
361  double phase = cvp->camera()->PhaseAngle();
362  p_tableWin->table()->item(row, PHASE)->setText(QString::number(phase));
363  double incidence = cvp->camera()->IncidenceAngle();
364  p_tableWin->table()->item(row, INCIDENCE)->setText(QString::number(incidence));
365  double emission = cvp->camera()->EmissionAngle();
366  p_tableWin->table()->item(row, EMISSION)->setText(QString::number(emission));
367 
368  // Write out columns local incidence and emission, only if set image
369  // succeeds. This might fail if there are holes in the DEM.
370  // Calculates the angles local to the slope for the DEMs, compare against
371  // the incidence and emission angles calculated for the sphere
372  Angle phaseAngle, incidenceAngle, emissionAngle;
373  bool bSuccess=false;
374  cvp->camera()->LocalPhotometricAngles(phaseAngle, incidenceAngle, emissionAngle, bSuccess);
375  if(bSuccess) {
376  p_tableWin->table()->item(row, LOCAL_INCIDENCE)->
377  setText(QString::number(incidenceAngle.degrees()));
378  p_tableWin->table()->item(row, LOCAL_EMISSION)->
379  setText(QString::number(emissionAngle.degrees()));
380  }
381  else {
382  p_tableWin->table()->item(row, LOCAL_INCIDENCE)->setText("");
383  p_tableWin->table()->item(row, LOCAL_EMISSION)->setText("");
384  }
385 
386  // If set image succeeds, write out columns north azimuth, sun azimuth, solar longitude
387  // north azimuth is meaningless for ring plane projections
388  if (cvp->camera()->target()->shape()->name() != "Plane"
389  && Isis::IsValidPixel(cvp->camera()->NorthAzimuth())) {
390  double northAzi = cvp->camera()->NorthAzimuth();
391  p_tableWin->table()->item(row, NORTH_AZIMUTH)->setText(QString::number(northAzi));
392  }
393  else { // north azimuth is meaningless for ring plane projections
394  p_tableWin->table()->item(row, NORTH_AZIMUTH)->setText("");
395  }
396  if (Isis::IsValidPixel(cvp->camera()->SunAzimuth())) {
397  double sunAzi = cvp->camera()->SunAzimuth();
398  p_tableWin->table()->item(row, SUN_AZIMUTH)->setText(QString::number(sunAzi));
399  }
400  else { // sun azimuth is null
401  p_tableWin->table()->item(row, SUN_AZIMUTH)->setText("");
402  }
404  double spacecraftAzi = cvp->camera()->SpacecraftAzimuth();
405  p_tableWin->table()->item(row, SPACECRAFT_AZIMUTH)->setText(QString::number(spacecraftAzi));
406  }
407  else { // spacecraft azimuth is null
408  p_tableWin->table()->item(row, SPACECRAFT_AZIMUTH)->setText("");
409  }
410 
411  // Write out columns solar lon, slant distance, local solar time
412  double solarLon = cvp->camera()->solarLongitude().degrees();
413  p_tableWin->table()->item(row, SOLAR_LON)->setText(QString::number(solarLon));
414  double slantDistance = cvp->camera()->SlantDistance();
415  p_tableWin->table()->item(row, SLANT)->setText(QString::number(slantDistance));
416  double lst = cvp->camera()->LocalSolarTime();
417  p_tableWin->table()->item(row, SOLAR_TIME)->setText(QString::number(lst));
418  } // end if set image succeeds
419 
420  // Always write out columns ra/dec, regardless of whether set image succeeds
421  double ra = cvp->camera()->RightAscension();
422  p_tableWin->table()->item(row, RIGHT_ASCENSION)->setText(QString::number(ra));
423  double dec = cvp->camera()->Declination();
424  p_tableWin->table()->item(row, DECLINATION)->setText(QString::number(dec));
425 
426  // Always write out columns et and utc, regardless of whether set image succeeds
427  iTime time(cvp->camera()->time());
428  p_tableWin->table()->item(row, EPHEMERIS_TIME)->setText(QString::number(time.Et(), 'f', 15));
429  QString time_utc = time.UTC();
430  p_tableWin->table()->item(row, UTC)->setText(time_utc);
431 
432  // Always out columns spacecraft position, regardless of whether set image succeeds
433  double pos[3];
434  cvp->camera()->instrumentPosition(pos);
435  p_tableWin->table()->item(row, SPACECRAFT_X)->setText(QString::number(pos[0]));
436  p_tableWin->table()->item(row, SPACECRAFT_Y)->setText(QString::number(pos[1]));
437  p_tableWin->table()->item(row, SPACECRAFT_Z)->setText(QString::number(pos[2]));
438  }
439 
440  else if (cvp->projection() != NULL) {
441  // Determine the projection type
443 
444  if (cvp->projection()->SetWorld(sample, line)) {
445  if (projType == Projection::Triaxial) {
446  TProjection *tproj = (TProjection *) cvp->projection();
447  double lat = tproj->UniversalLatitude();
448  double lon = tproj->UniversalLongitude();
449 
450  double glat = tproj->ToPlanetographic(lat);
451  double wlon = -lon;
452  while(wlon < 0.0) wlon += 360.0;
453  if (tproj->IsSky()) {
454  lon = tproj->Longitude();
455  p_tableWin->table()->item(row, RIGHT_ASCENSION)->setText(QString::number(lon, 'f', 15));
456  p_tableWin->table()->item(row, DECLINATION)->setText(QString::number(lat, 'f', 15));
457  }
458  else {
459  double radius = tproj->LocalRadius();
460  p_tableWin->table()->item(row, PLANETOCENTRIC_LAT)->
461  setText(QString::number(lat, 'f', 15));
462  p_tableWin->table()->item(row, PLANETOGRAPHIC_LAT)->
463  setText(QString::number(glat, 'f', 15));
464  p_tableWin->table()->item(row, EAST_LON_360)->
465  setText(QString::number(lon, 'f', 15));
466  p_tableWin->table()->item(row, EAST_LON_180)->
467  setText(QString::number(TProjection::To180Domain(lon), 'f', 15));
468  p_tableWin->table()->item(row, WEST_LON_360)->setText(QString::number(wlon, 'f', 15));
469  p_tableWin->table()->item(row, WEST_LON_180)->
470  setText(QString::number(TProjection::To180Domain(wlon), 'f', 15));
471  p_tableWin->table()->item(row, RADIUS)->setText(QString::number(radius, 'f', 15));
472  }
473  }
474  else { // RingPlane
476  double lat = rproj->UniversalRingRadius();
477  double lon = rproj->UniversalRingLongitude();
478 
479  double wlon = -lon;
480  while(wlon < 0.0) wlon += 360.0;
481  double radius = lat;
482  p_tableWin->table()->item(row, PLANETOCENTRIC_LAT)->setText("0.0");
483  p_tableWin->table()->item(row, PLANETOGRAPHIC_LAT)->setText("0.0");
484  p_tableWin->table()->item(row, EAST_LON_360)->
485  setText(QString::number(lon, 'f', 15));
486  p_tableWin->table()->item(row, EAST_LON_180)->
487  setText(QString::number(RingPlaneProjection::To180Domain(lon), 'f', 15));
488  p_tableWin->table()->item(row, WEST_LON_360)->setText(QString::number(wlon, 'f', 15));
489  p_tableWin->table()->item(row, WEST_LON_180)->
490  setText(QString::number(RingPlaneProjection::To180Domain(wlon), 'f', 15));
491  p_tableWin->table()->item(row, RADIUS)->setText(QString::number(radius, 'f', 15));
492  }
493  }
494  }
495 
496  //If there is a projection add the Projected X and Y coords to the table
497  if(cvp->projection() != NULL) {
498  if(cvp->projection()->SetWorld(sample, line)) {
499  double projX = cvp->projection()->XCoord();
500  double projY = cvp->projection()->YCoord();
501  p_tableWin->table()->item(row, PROJECTED_X)->setText(QString::number(projX, 'f', 15));
502  p_tableWin->table()->item(row, PROJECTED_Y)->setText(QString::number(projY, 'f', 15));
503  }
504  }
505 
506  // Track the Mosaic Origin - Index (Zero based) and FileName
507  int iMosaicOrigin = -1;
508  QString sSrcFileName = "";
509  QString sSrcSerialNum = "";
510  TrackMosaicOrigin(cvp, iline, isample, iMosaicOrigin, sSrcFileName, sSrcSerialNum);
511  p_tableWin->table()->item(row, TRACK_MOSAIC_INDEX)->setText(QString::number(iMosaicOrigin));
512  p_tableWin->table()->item(row, TRACK_MOSAIC_FILENAME)->setText(QString(sSrcFileName));
513  p_tableWin->table()->item(row, TRACK_MOSAIC_SERIAL_NUM)->
514  setText(QString(sSrcSerialNum));
515  }
516 
517 
535  int piSample, int &piOrigin, QString &psSrcFileName,
536  QString &psSrcSerialNum) {
537  Cube *cCube = cvp->cube();
538  int iTrackBand = -1;
539 
540  if(cCube->hasTable(TABLE_MOSAIC_SRC)) {
541  Pvl *cPvl = cCube->label();
542  PvlObject cObjIsisCube = cPvl->findObject("IsisCube");
543  PvlGroup cGrpBandBin = cObjIsisCube.findGroup("BandBin");
544  for(int i = 0; i < cGrpBandBin.keywords(); i++) {
545  PvlKeyword &cKeyTrackBand = cGrpBandBin[i];
546  for(int j = 0; j < cKeyTrackBand.size(); j++) {
547  if(cKeyTrackBand[j] == "TRACKING") {
548  iTrackBand = j;
549  break;
550  }
551  }
552  }
553 
554  if(iTrackBand > 0 && iTrackBand <= cCube->bandCount()) {
555  Portal cOrgPortal(cCube->sampleCount(), 1,
556  cCube->pixelType());
557  cOrgPortal.SetPosition(piSample, piLine, iTrackBand + 1); // 1 based
558  cCube->read(cOrgPortal);
559 
560  piOrigin = (int)cOrgPortal[0];
561  switch(SizeOf(cCube->pixelType())) {
562  case 1:
563  piOrigin -= VALID_MIN1;
564  break;
565 
566  case 2:
567  piOrigin -= VALID_MIN2;
568  break;
569 
570  case 4:
571  piOrigin -= FLOAT_MIN;
572  break;
573  }
574 
575  // Get the input file name and serial number
576  Table cFileTable(TABLE_MOSAIC_SRC);
577  cCube->read(cFileTable);
578  int iRecs = cFileTable.Records();
579  if(piOrigin >= 0 && piOrigin < iRecs) {
580  psSrcFileName = QString(cFileTable[piOrigin][0]);
581  psSrcSerialNum = QString(cFileTable[piOrigin][1]);
582  }
583  }
584  }
585  }
586 
587 
594 
596 
597  QVBoxLayout *dialogLayout = new QVBoxLayout;
598  helpDialog->setLayout(dialogLayout);
599  QLabel *dialogTitle = new QLabel("<h3>Advanced Tracking Tool</h3>");
600  dialogLayout->addWidget(dialogTitle);
601 
602  QTabWidget *tabArea = new QTabWidget;
603  dialogLayout->addWidget(tabArea);
604 
605  QScrollArea *recordTab = new QScrollArea;
606  QWidget *recordContainer = new QWidget;
607  QVBoxLayout *recordLayout = new QVBoxLayout;
608  recordContainer->setLayout(recordLayout);
609  QLabel *recordText = new QLabel("To record, click on the viewport of interest and"
610  " press (r) while the mouse is hovering over the image.");
611  recordText->setWordWrap(true);
612  recordLayout->addWidget(recordText);
613  recordTab->setWidget(recordContainer);
614 
615  QScrollArea *helpTab = new QScrollArea;
616  QWidget *helpContainer = new QWidget;
617  QVBoxLayout *helpLayout = new QVBoxLayout;
618  helpContainer->setLayout(helpLayout);
619  QLabel *helpText = new QLabel("In order to use <i>ctrl+c</i> to copy and <i>ctrl+v</i> to"
620  " paste, you need to double click on the cell you are copying"
621  " from (the text should be highlighted). Then double click on"
622  " the cell you are pasting to (you should see a cursor if the"
623  " cell is blank). When a cell is in this editing mode, most"
624  " keyboard shortcuts work.");
625  helpText->setWordWrap(true);
626  recordText->setWordWrap(true);
627  helpLayout->addWidget(helpText);
628  helpTab->setWidget(helpContainer);
629 
630  tabArea->addTab(recordTab, "Record");
631  tabArea->addTab(helpTab, "Table Help");
632 
633  QPushButton *okButton = new QPushButton("OK");
634  dialogLayout->addStretch();
635  dialogLayout->addWidget(okButton);
636  helpDialog->show();
637  connect(okButton, SIGNAL(clicked()), helpDialog, SLOT(accept()));
638  }
639 
640 
646  if(p_tableWin->table()->isHidden()) return;
647  if(p_tableWin->table()->item(p_tableWin->currentRow(), 0)->text() == "") return;
648 
649  int row = 0;
652  while(p_tableWin->currentRow() >= p_tableWin->table()->rowCount()) {
653  row = p_tableWin->table()->rowCount();
654  p_tableWin->table()->insertRow(row);
655  for(int c = 0; c < p_tableWin->table()->columnCount(); c++) {
656  QTableWidgetItem *item = new QTableWidgetItem("");
657  p_tableWin->table()->setItem(row, c, item);
658  }
659  }
660 
661  QApplication::sendPostedEvents(p_tableWin->table(), 0);
662  p_tableWin->table()->scrollToItem(p_tableWin->table()->item(p_tableWin->currentRow(), 0),
663  QAbstractItemView::PositionAtBottom);
664 
665  //Keep track of number times user presses 'R' (record command)
666  p_id = p_tableWin->table()->item(p_tableWin->currentRow() - 1, 0)->text().toInt() + 1;
667  }
668 
669 
685  void AdvancedTrackTool::record(QPoint p) {
686  updateRow(p);
687  record();
689  }
690 
691 
697  //Check if the current row is 0
698  if(p_tableWin->currentRow() == 0)
699  p_id = 0;
700  else
701  p_id = p_tableWin->table()->item(p_tableWin->currentRow() - 1, ID)->text().toInt() + 1;
702  }
703 
704 
711 
712  QSettings settings(settingsFilePath() , QSettings::NativeFormat);
713 
714  m_showHelpOnStart = settings.value("showHelpOnStart", m_showHelpOnStart).toBool();
715  }
716 
717 
723 
724  QSettings settings(settingsFilePath(), QSettings::NativeFormat);
725 
726  settings.setValue("showHelpOnStart", m_showHelpOnStart);
727  }
728 
729 
736 
737  if (QApplication::applicationName() == "") {
738  throw IException(IException::Programmer, "You must set QApplication's "
739  "application name before using the Isis::MainWindow class. Window "
740  "state and geometry can not be saved and restored", _FILEINFO_);
741  }
742 
743  FileName config(FileName("$HOME/.Isis/" + QApplication::applicationName() + "/").path() + "/" +
744  "advancedTrackTool.config");
745 
746  return config.expanded();
747  }
748 }