Isis 3.0 Programmer Reference
Back | Home
EditTool.cpp
Go to the documentation of this file.
1 
23 #include "EditTool.h"
24 
25 #include <QAction>
26 #include <QApplication>
27 #include <QComboBox>
28 #include <QDebug>
29 #include <QHBoxLayout>
30 #include <QLine>
31 #include <QLineEdit>
32 #include <QMenuBar>
33 #include <QMessageBox>
34 #include <QPixmap>
35 #include <QStackedWidget>
36 #include <QToolButton>
37 
38 #include "Brick.h"
39 #include "Cube.h"
40 #include "MdiCubeViewport.h"
41 #include "RubberBandTool.h"
42 #include "SpecialPixel.h"
43 #include "ToolPad.h"
44 #include "Workspace.h"
45 
46 
47 namespace Isis {
55  EditTool::EditTool(QWidget *parent) : Tool(parent) {
56  p_dn = Null;
57  }
58 
59  void EditTool::addTo(Workspace *workspace) {
60  Tool::addTo(workspace);
61 
62  connect(workspace, SIGNAL(cubeViewportAdded(MdiCubeViewport *)),
63  this, SLOT(listenToViewport(MdiCubeViewport *)));
64  }
65 
74  QAction *action = new QAction(pad);
75  action->setIcon(QPixmap(toolIconDir() + "/color_line.png"));
76  action->setToolTip("Image Edit (E)");
77  action->setShortcut(Qt::Key_E);
78 
79  QString text =
80  "<b>Function:</b> Edit active viewport \
81  <p><b>Shortcut:</b> E</p> ";
82  action->setWhatsThis(text);
83 
84  return action;
85  }
86 
98  QWidget *EditTool::createToolBarWidget(QStackedWidget *active) {
99  QWidget *container = new QWidget(active);
100  container->setObjectName("EditToolActiveToolBarWidget");
101 
103  p_shapeComboBox->setEditable(false);
104  p_shapeComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
105  p_shapeComboBox->addItem("Point");
106  p_shapeComboBox->addItem("Horizontal Line");
107  p_shapeComboBox->addItem("Vertical Line");
108  p_shapeComboBox->addItem("Start/End Line");
109  p_shapeComboBox->addItem("Rectangle");
110  p_shapeComboBox->setToolTip("Select shape to edit");
111  QString text =
112  "<b>Function:</b> The shape in the image that will be replaced with \
113  a new value. If Horizontal line is chosen, clicking anywhere on the \
114  image will cause all samples on that line of the cube to be replaced \
115  with the replacement value. If Vertical Line is chosen, a v ...";
116  p_shapeComboBox->setWhatsThis(text);
117  p_shapeComboBox->setCurrentIndex(1);
118  connect(p_shapeComboBox, SIGNAL(activated(int)), this, SLOT(enableRubberBandTool()));
119 
121  p_valTypeComboBox->setEditable(false);
122  p_valTypeComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
123  p_valTypeComboBox->addItem("Dn", UserDnComboValue);
124  p_valTypeComboBox->addItem("Null", NullComboValue);
125  p_valTypeComboBox->addItem("Hrs", HrsComboValue);
126  p_valTypeComboBox->addItem("Lrs", LrsComboValue);
127  p_valTypeComboBox->addItem("His", HisComboValue);
128  p_valTypeComboBox->addItem("Lis", LisComboValue);
129  p_valTypeComboBox->setToolTip("Value used to replace image data");
130  text =
131  "<b>Function:</b> The value which will be used to replace image data. ";
132  p_valTypeComboBox->setWhatsThis(text);
133  p_valTypeComboBox->setCurrentIndex(
134  p_valTypeComboBox->findData(NullComboValue));
135  connect(p_valTypeComboBox, SIGNAL(activated(int)), this,
136  SLOT(selectValType(int)));
137 
138  p_dnLineEdit = new QLineEdit;
139  p_dnLineEdit->setToolTip("Dn value");
140  text =
141  "<b>Function:</b> This is the dn used to replace image data";
142  p_dnLineEdit->setWhatsThis(text);
143  p_dnLineEdit->setEnabled(false);
144  connect(p_dnLineEdit, SIGNAL(editingFinished()), this, SLOT(changeDn()));
145 
146  p_undoButton = new QToolButton;
147  p_undoButton->setIcon(QPixmap(toolIconDir() + "/undo.png"));
148  p_undoButton->setToolTip("Undo");
149  text =
150  "<b>Function:</b> Undo last edit operation";
151  p_undoButton->setWhatsThis(text);
152  connect(p_undoButton, SIGNAL(clicked()), this, SLOT(undoEdit()));
153  p_undoButton->setAutoRaise(true);
154  p_undoButton->setIconSize(QSize(22, 22));
155 
156  p_redoButton = new QToolButton;
157  p_redoButton->setIcon(QPixmap(toolIconDir() + "/redo.png"));
158  p_redoButton->setToolTip("Redo");
159  text =
160  "<b>Function:</b> Redo last undo operation";
161  p_redoButton->setWhatsThis(text);
162  p_redoButton->setEnabled(false);
163  connect(p_redoButton, SIGNAL(clicked()), this, SLOT(redoEdit()));
164  p_redoButton->setAutoRaise(true);
165  p_redoButton->setIconSize(QSize(22, 22));
166 
167  p_saveButton = new QToolButton;
168  p_saveButton->setIcon(QPixmap(toolIconDir() + "/filesave.png"));
169  p_saveButton->setToolTip("Save");
170  text =
171  "<b>Function:</b> Save any changes made, these changes are finalized";
172  p_saveButton->setWhatsThis(text);
173  p_saveButton->setEnabled(false);
174  connect(p_saveButton, SIGNAL(clicked()), this, SIGNAL(save()));
175  p_saveButton->setAutoRaise(true);
176  p_saveButton->setIconSize(QSize(22, 22));
177 
178  p_saveAsButton = new QToolButton;
179  p_saveAsButton->setIcon(QPixmap(toolIconDir() + "/filesaveas.png"));
180  p_saveAsButton->setToolTip("Save As");
181  text =
182  "<b>Function:</b> Save any changes made to the file specified, these changes are finalized";
183  p_saveAsButton->setWhatsThis(text);
184  connect(p_saveAsButton, SIGNAL(clicked()), this, SIGNAL(saveAs()));
185  p_saveAsButton->setAutoRaise(true);
186  p_saveAsButton->setIconSize(QSize(22, 22));
187 
188  QHBoxLayout *layout = new QHBoxLayout;
189  layout->setMargin(0);
190  layout->addWidget(p_shapeComboBox);
191  layout->addWidget(p_valTypeComboBox);
192  layout->addWidget(p_dnLineEdit);
193  layout->addWidget(p_undoButton);
194  layout->addWidget(p_redoButton);
195  layout->addWidget(p_saveButton);
196  layout->addWidget(p_saveAsButton);
197  layout->addStretch(1);
198  container->setLayout(layout);
199 
200 m_container = container;
201  return container;
202  }
203 
211  void EditTool::selectValType(int index) {
212  if (p_valTypeComboBox->itemData(index) == UserDnComboValue) {
213  p_dnLineEdit->setEnabled(true);
214  }
215  else {
216  p_dnLineEdit->setEnabled(false);
217 
218  if (p_valTypeComboBox->itemData(index) == NullComboValue) p_dn = Null;
219  if (p_valTypeComboBox->itemData(index) == HrsComboValue) p_dn = Hrs;
220  if (p_valTypeComboBox->itemData(index) == LrsComboValue) p_dn = Lrs;
221  if (p_valTypeComboBox->itemData(index) == HisComboValue) p_dn = His;
222  if (p_valTypeComboBox->itemData(index) == LisComboValue) p_dn = Lis;
223  }
224  }
225 
232  p_dn = p_dnLineEdit->text().toDouble();
233  }
234 
245 
246  if (vp != NULL) {
247  //If the current viewport has no undo history
248  if (!p_undoEdit.contains(cubeViewport()) || p_undoEdit.value(vp)->empty()) {
249  p_undoButton->setEnabled(false);
250  p_saveButton->setEnabled(false);
251  }
252  //Otherwise enable the undo button and save button
253  else {
254  p_undoButton->setEnabled(true);
255  p_saveButton->setEnabled(true);
256  }
257  //If the current viewport has no redo history
258  if (!p_redoEdit.contains(cubeViewport()) || p_redoEdit.value(vp)->empty()) {
259  p_redoButton->setEnabled(false);
260  }
261  //Otherwise enable the redo button and save button
262  else {
263  p_redoButton->setEnabled(true);
264  p_saveButton->setEnabled(true);
265  }
266  }
267  }
268 
279  if (vp == NULL) return;
280 
281  if (vp->cube()->isReadOnly()) {
282  // ReOpen cube as read/write
283  // If cube readonly print error
284  try {
285  vp->cube()->reopen("rw");
286  }
287  catch(IException &) {
288  QMessageBox::information((QWidget *)parent(), "Error", "Cannot open cube read/write");
289  return;
290  }
291  }
292  if (vp->isColor()) {
293  QMessageBox::information((QWidget *)parent(),
294  "Error", "Cannot edit in color mode");
295  return;
296  }
297 
298  int issamp, isline, iesamp, ieline;
299  double ssamp, sline, esamp, eline;
300  QList<QPoint *> *linePts = NULL;
301 
302  // Rectangle is selected
303  if (p_shapeComboBox->currentIndex() == Rectangle) {
304 
305  if (!rubberBandTool()->isValid()) return;
306 
307  QRect r = rubberBandTool()->rectangle();
308  if ((r.width() < 1) || (r.height() < 1)) return;
309 
310  vp->viewportToCube(r.left(), r.top(), ssamp, sline);
311  vp->viewportToCube(r.right(), r.bottom(), esamp, eline);
312 
313  issamp = (int)(ssamp + 0.5);
314  isline = (int)(sline + 0.5);
315  iesamp = (int)(esamp + 0.5);
316  ieline = (int)(eline + 0.5);
317 
318  //Clamp the rectangles coordinates to within the cube's dimensions
319  if (issamp < 0) issamp = 0;
320  if (iesamp < 0) iesamp = 0;
321  if (isline < 0) isline = 0;
322  if (ieline < 0) ieline = 0;
323 
324  if (issamp > vp->cubeSamples()) issamp = vp->cubeSamples();
325  if (iesamp > vp->cubeSamples()) iesamp = vp->cubeSamples();
326  if (isline > vp->cubeLines()) isline = vp->cubeLines();
327  if (ieline > vp->cubeLines()) ieline = vp->cubeLines();
328 
329  //If the rectangle is completely out of bounds on either side, display an error and return
330  if (issamp > iesamp || isline > ieline) {
331  QMessageBox::information((QWidget *)parent(),
332  "Error", "Rectangle is out of bounds");
333  return;
334  }
335  }
336  // Line is selected
337  else if (p_shapeComboBox->currentIndex() == StartEndLine) {
338  // Convert rubber band line to cube coordinates
339  if (!rubberBandTool()->isValid()) return;
340  vp->viewportToCube(rubberBandTool()->vertices()[0].rx(), rubberBandTool()->vertices()[0].ry(),
341  ssamp, sline);
342  vp->viewportToCube(rubberBandTool()->vertices()[1].rx(), rubberBandTool()->vertices()[1].ry(),
343  esamp, eline);
344 
345  QLine l((int)ssamp, (int)sline, (int)esamp, (int)eline);
346 
347  linePts = EditTool::LineToPoints(l);
348 
349  //If the line is completely out of bounds, display an error and return
350  if (linePts->empty()) {
351  QMessageBox::information((QWidget *)parent(),
352  "Error", "No points in edit line");
353  return;
354  }
355 
356  // Find bounding rectangle for the line
357  issamp = std::min(linePts->front()->x(), linePts->back()->x());
358  isline = std::min(linePts->front()->y(), linePts->back()->y());
359  iesamp = std::max(linePts->front()->x(), linePts->back()->x());
360  ieline = std::max(linePts->front()->y(), linePts->back()->y());
361  }
362  // Neither mode is selected, so this is an incorrect mode for this RubberBandTool
363  else {
364  return;
365  }
366 
367  // Write the data to the cube
368  writeToCube(iesamp, issamp, ieline, isline, linePts);
369  if (linePts) delete linePts;
370  }
371 
372  void EditTool::listenToViewport(MdiCubeViewport *newViewport) {
373  connect(newViewport, SIGNAL(saveChanges(CubeViewport *)),
374  this, SLOT(save(CubeViewport *)));
375  connect(newViewport, SIGNAL(discardChanges(CubeViewport *)),
376  this, SLOT(undoAll(CubeViewport *)));
377  connect(newViewport, SIGNAL(destroyed(QObject *)),
378  this, SLOT(removeViewport(QObject *)));
379  }
380 
381 
404  void EditTool::mouseButtonRelease(QPoint p, Qt::MouseButton m) {
406  if (vp == NULL) return;
407  if (p_valTypeComboBox->itemData(p_valTypeComboBox->currentIndex()) ==
408  UserDnComboValue && p_dnLineEdit->text() == "" && m != Qt::RightButton)
409  return;
410 
411  // If cube readonly try to open read/write
412  if (vp->cube()->isReadOnly()) {
413  // ReOpen cube as read/write
414  // If cube readonly print error
415  try {
416  vp->cube()->reopen("rw");
417  }
418  catch(IException &) {
419  QMessageBox::information((QWidget *)parent(), "Error", "Cannot open cube read/write");
420  return;
421  }
422  }
423  if (vp->isColor()) {
424  QMessageBox::information((QWidget *)parent(),
425  "Error", "Cannot edit in color mode");
426  return;
427  }
428 
429  int issamp, isline, iesamp, ieline;
430  double ssamp, sline;
431 
432  // If right mouse button, pick up dn value under the cursor which will be
433  // used as the edit value.
434  if (m == Qt::RightButton &&
435  p_valTypeComboBox->itemData(p_valTypeComboBox->currentIndex()) ==
437  vp->viewportToCube(p.x(), p.y(), ssamp, sline);
438  issamp = (int)(ssamp + 0.5);
439  isline = (int)(sline + 0.5);
440  Brick *pntBrick = new Brick(1, 1, 1,
441  vp->cube()->pixelType());
442  pntBrick->SetBasePosition(issamp, isline, vp->grayBand());
443  vp->cube()->read(*pntBrick);
444  p_dn = (*pntBrick)[0];
445  p_dnLineEdit->setText(QString::number(p_dn));
446  delete pntBrick;
447  return;
448  }
449 
450  else if (p_shapeComboBox->currentIndex() == Point ||
451  p_shapeComboBox->currentIndex() == HorizLine ||
452  p_shapeComboBox->currentIndex() == VertLine) {
453  vp->viewportToCube(p.x(), p.y(), ssamp, sline);
454  if ((ssamp < 0.5) || (sline < 0.5) ||
455  (ssamp > vp->cubeSamples() + 0.5) || (sline > vp->cubeLines() + 0.5)) {
456  QApplication::beep();
457  return;
458  }
459  issamp = (int)(ssamp + 0.5);
460  isline = (int)(sline + 0.5);
461  iesamp = issamp;
462  ieline = isline;
463  if (p_shapeComboBox->currentIndex() == HorizLine) {
464  issamp = 1;
465  iesamp = vp->cube()->sampleCount();
466  }
467  if (p_shapeComboBox->currentIndex() == VertLine) {
468  isline = 1;
469  ieline = vp->cube()->lineCount();
470  }
471  // Write the changes to the cube.
472  writeToCube(iesamp, issamp, ieline, isline, NULL);
473  }
474  }
475 
487  void EditTool::writeToCube(int iesamp, int issamp, int ieline, int isline, QList<QPoint *> *linePts) {
488  Brick *brick = NULL;
489  try {
491 
492  int nsamps = iesamp - issamp + 1;
493  int nlines = ieline - isline + 1;
494 
495  brick = new Brick(nsamps, nlines, 1, vp->cube()->pixelType());
496  brick->SetBasePosition(issamp, isline, vp->grayBand());
497  vp->cube()->read(*brick);
498 
499  // Save for Undo operation, See if viewport has undo entry. If it
500  // does, get Stack, push new undo and put stack back in hash. If not,
501  // create stack, push new undo and add to hash.
502  QStack<Brick *> *s;
503  if (p_undoEdit.contains(vp)) {
504  s = p_undoEdit.value(vp);
505  }
506  else {
507  s = new QStack<Brick *>;
508  }
509  s->push(brick);
510  p_undoEdit[vp] = s;
511 
512  //Remove any redo stack if it exists
513  if (p_redoEdit.contains(vp)) {
514  QStack<Brick *> *temp = p_redoEdit.value(vp);
515  while(!temp->isEmpty()) {
516  delete temp->pop();
517  }
518  p_redoEdit.remove(vp);
519  p_redoButton->setEnabled(false);
520  }
521 
522  // no deep copy constructor so re-read brick for editing....
523  brick = new Brick(nsamps, nlines, 1, vp->cube()->pixelType());
524  brick->SetBasePosition(issamp, isline, vp->grayBand());
525  vp->cube()->read(*brick);
526 
527  // Now that we have where, do the actual edits
528  if (p_shapeComboBox->currentIndex() == StartEndLine) {
529  for(int i = 0; linePts && i < (int)linePts->size(); i++) {
530  QPoint *pt = (*linePts)[i];
531  int is = pt->x();
532  int il = pt->y();
533  int brickIndex = (il - isline) * nsamps + (is - issamp);
534  (*brick)[brickIndex] = (double)p_dn;
535  }
536  }
537  else {
538  for(int i = 0; i < brick->size(); i++)(*brick)[i] = (double)p_dn;
539  }
540 
541  //Signal that this cube has been changed, enable the undo and save buttons
542  emit cubeChanged(true);
543  p_undoButton->setEnabled(true);
544  p_saveButton->setEnabled(true);
545  vp->cube()->write(*brick);
546  vp->cubeChanged(true);
547  vp->setCaption();
548 
549  // QRect r(issamp,isline,nsamps,nlines);
550  QRect r(brick->Sample(), brick->Line(),
551  brick->SampleDimension(), brick->LineDimension());
552  vp->cubeContentsChanged(r);
553  delete brick;
554  }
555  catch(...) {
556  if (brick) {
557  delete brick;
558  }
559  //If the brick failed to initialize due to insufficient memory
560  QMessageBox::information((QWidget *)parent(), "Error", "Not enough memory to complete this operation.");
561  return;
562  }
563  }
564 
571  Brick *redoBrick = NULL;
572  try {
574  if (vp == NULL) return;
575 
576  // If viewport not in hash, beep
577  if (p_undoEdit.empty() || p_undoEdit.count(vp) == 0) {
578  QApplication::beep();
579  return;
580  }
581 
582  // If cube readonly print error
583  if (vp->cube()->isReadOnly()) {
584  QMessageBox::information((QWidget *)parent(), "Error", "Cube is Read Only");
585  return;
586  }
587 
588 
589  QStack<Brick *> *s = p_undoEdit.value(vp);
590  Brick *brick = s->top();
591 
592  //Write the current cube to the a brick and add it to the redo stack
593  redoBrick = new Brick(brick->SampleDimension(), brick->LineDimension(), 1, vp->cube()->pixelType());
594  redoBrick->SetBasePosition(brick->Sample(), brick->Line(), vp->grayBand());
595  vp->cube()->read(*(redoBrick));
596 
597  QStack<Brick *> *redo;
598  if (p_redoEdit.contains(vp)) {
599  redo = p_redoEdit.value(vp);
600  }
601  else {
602  redo = new QStack<Brick *>;
603  }
604  redo->push(redoBrick);
605  p_redoEdit[vp] = redo;
606 
607  // Write the saved brick to the cube
608  vp->cube()->write(*(brick));
609 
610  // Update the viewport
611  QRect r(brick->Sample(), brick->Line(),
612  brick->SampleDimension(), brick->LineDimension());
613  vp->cubeContentsChanged(r);
614 
615  //Enable the redo button since we have made an undo
616  p_redoButton->setEnabled(true);
617  p_saveButton->setEnabled(true);
618  emit cubeChanged(true);
619  vp->cubeChanged(true);
620  vp->setCaption();
621 
622  //Pop this element off the stack, if the undo stack is empty, disable the undo button
623  s->pop();
624  if (s->empty()) {
625  p_undoButton->setEnabled(false);
626  }
627  delete brick;
628  }
629  catch(...) {
630  if (redoBrick) {
631  delete redoBrick;
632  }
633  //If the brick failed to initialize due to insufficient memory
634  QMessageBox::information((QWidget *)parent(), "Error", "Not enough memory to complete this operation.");
635  return;
636  }
637  }
638 
647  try {
648  if (vp != NULL) {
649  // If cube readonly print error
650  if (vp->cube()->isReadOnly()) {
651  QMessageBox::information((QWidget *)parent(), "Error", "Cube is Read Only");
652  return;
653  }
654 
655  QStack<Brick *> *undo;
656  QStack<Brick *> *redo;
657  int marker = 0;
658  //If edits have been made
659  if (p_undoEdit.contains(vp)) {
660  undo = p_undoEdit.value(vp);
661 
662  //If a save has been made
663  if (p_saveMarker.contains(vp)) {
664  marker = p_saveMarker.value(vp);
665  }
666 
667  //Undo up to the save point
668  for(int i = undo->count() - 1; i >= marker; i--) {
669  Brick *brick = undo->at(i);
670  // Write the saved brick to the cube
671  vp->cube()->write(*(brick));
672  }
673 
674  //If undos have been made past the save point, we need to redo them
675  //Set the marker to the correct index
676  marker = marker - undo->count();
677  }
678 
679  //If undos have been made
680  if (p_redoEdit.contains(vp)) {
681  redo = p_redoEdit.value(vp);
682 
683  //If undos have been made past a save point, we need to redo them
684  for(int i = redo->count() - 1; i >= redo->count() - marker; i--) {
685  Brick *brick = redo->at(i);
686 
687  // Write the saved brick to the cube
688  vp->cube()->write(*(brick));
689  }
690  }
691  }
692  }
693  catch(...) {
694  //If the brick failed to initialize due to insufficient memory
695  QMessageBox::information((QWidget *)parent(), "Error",
696  "Not enough memory to complete this operation.");
697  return;
698  }
699  }
700 
706  Brick *undoBrick = NULL;
707  try {
709  if (vp == NULL) return;
710 
711  // If viewport not in hash, beep
712  if (p_redoEdit.empty() || p_redoEdit.count(vp) == 0) {
713  QApplication::beep();
714  return;
715  }
716 
717  // If cube readonly print error
718  if (vp->cube()->isReadOnly()) {
719  QMessageBox::information((QWidget *)parent(), "Error", "Cube is Read Only");
720  return;
721  }
722 
723  QStack<Brick *> *s = p_redoEdit.value(vp);
724  Brick *brick = s->top();
725 
726  //Write the current cube to the a brick and add it to the undo stack
727  undoBrick = new Brick(brick->SampleDimension(),
728  brick->LineDimension(), 1,
729  vp->cube()->pixelType());
730  undoBrick->SetBasePosition(brick->Sample(), brick->Line(), vp->grayBand());
731  vp->cube()->read(*(undoBrick));
732 
733  QStack<Brick *> *undo;
734  if (p_undoEdit.contains(vp)) {
735  undo = p_undoEdit.value(vp);
736  }
737  else {
738  undo = new QStack<Brick *>;
739  }
740  undo->push(undoBrick);
741  p_undoEdit[vp] = undo;
742 
743  // Write the saved brick to the cube
744  vp->cube()->write(*(brick));
745  // Update the viewport
746 
747  QRect r(brick->Sample(), brick->Line(),
748  brick->SampleDimension(), brick->LineDimension());
749  vp->cubeContentsChanged(r);
750 
751  p_undoButton->setEnabled(true);
752  p_saveButton->setEnabled(true);
753  vp->cubeChanged(true);
754  vp->setCaption();
755  emit cubeChanged(true);
756 
757  //Pop this element off the stack, if the redo stack is empty, disable the redo button
758  s->pop();
759  if (s->empty()) {
760  p_redoButton->setEnabled(false);
761  }
762  delete brick;
763  }
764  catch(...) {
765  if (undoBrick) {
766  delete undoBrick;
767  }
768  //If the brick failed to initialize due to insufficient memory
769  QMessageBox::information((QWidget *)parent(), "Error", "Not enough memory to complete this operation.");
770  return;
771  }
772  }
773 
782  if (vp != NULL) {
783  //Set the 'save point' for this viewport, if we undo discard any changes
784  //We will only discard to this point
785  int marker;
786  if (p_undoEdit.contains(vp)) {
787  marker = p_undoEdit.value(vp)->count();
788  }
789  else {
790  marker = 0;
791  }
792  p_saveMarker[vp] = marker;
793 
794  p_saveButton->setEnabled(false);
795  vp->cubeChanged(false);
796  vp->setCaption();
797  }
798  }
799 
800 
809  // Connect destruction of CubeViewport to Remove slot to remove viewport
810  // from the undo and redo Hashes.
811  if (p_undoEdit.contains((MdiCubeViewport *) vp)) {
812  QStack<Brick *> *temp = p_undoEdit.value((MdiCubeViewport *) vp);
813  while(!temp->isEmpty()) {
814  delete temp->pop();
815  }
816  p_undoEdit.remove((MdiCubeViewport *) vp);
817  }
818  if (p_redoEdit.contains((MdiCubeViewport *) vp)) {
819  QStack<Brick *> *temp = p_redoEdit.value((MdiCubeViewport *) vp);
820  while(!temp->isEmpty()) {
821  delete temp->pop();
822  }
823  p_redoEdit.remove((MdiCubeViewport *) vp);
824  }
825  }
826 
827 
828 
829 
846  if (vp == NULL) return new QList<QPoint *>();
847  double slope;
848  int i;
849  int x, y, xinc, yinc;
850  int xsize, ysize;
851 
852 
853  QList<QPoint *> *points = new QList<QPoint *>;
854 
855  int sx = line.p1().x();
856  int ex = line.p2().x();
857  int sy = line.p1().y();
858  int ey = line.p2().y();
859  if (sx > ex) {
860  xsize = sx - ex + 1;
861  xinc = -1;
862  }
863  else {
864  xsize = ex - sx + 1;
865  xinc = 1;
866  }
867 
868  if (sy > ey) {
869  ysize = sy - ey + 1;
870  yinc = -1;
871  }
872  else {
873  ysize = ey - sy + 1;
874  yinc = 1;
875  }
876 
877  if (ysize > xsize) {
878  slope = (double)(ex - sx) / (double)(ey - sy);
879  y = sy;
880  for(i = 0; i < ysize; i++) {
881  x = (int)(slope * (double)(y - sy) + (double) sx + 0.5);
882 
883  //If the x or y coordinates are not within the cube dimensions, don't add them
884  if (x >= 0 && y >= 0 && x <= vp->cubeSamples() && y <= vp->cubeLines()) {
885  QPoint *pt = new QPoint;
886  pt->setX(x);
887  pt->setY(y);
888  points->push_back(pt);
889  }
890  y += yinc;
891  }
892  }
893  else if (xsize == 1) {
894  //If the x or y coordinates are not within the cube dimensions, don't add them
895  if (sx >= 0 && sy >= 0 && sx <= vp->cubeSamples() && sy <= vp->cubeLines()) {
896  QPoint *pt = new QPoint;
897  pt->setX(sx);
898  pt->setY(sy);
899  points->push_back(pt);
900  }
901  }
902  else {
903  slope = (double)(ey - sy) / (double)(ex - sx);
904  x = sx;
905  for(i = 0; i < xsize; i++) {
906  y = (int)(slope * (double)(x - sx) + (double) sy + 0.5);
907 
908  //If the x or y coordinates are not within the cube dimensions, don't add them
909  if (x >= 0 && y >= 0 && x <= vp->cubeSamples() && y <= vp->cubeLines()) {
910  QPoint *pt = new QPoint;
911  pt->setX(x);
912  pt->setY(y);
913  points->push_back(pt);
914  }
915  x += xinc;
916  }
917  }
918 
919  return points;
920  }
921 
929  int index = p_shapeComboBox->currentIndex();
930  if (index == 3) {
931  rubberBandTool()->enable(RubberBandTool::LineMode);
932  rubberBandTool()->setDrawActiveViewportOnly(true);
933  }
934  else if (index == 4) {
935  rubberBandTool()->enable(RubberBandTool::RectangleMode);
936  rubberBandTool()->setDrawActiveViewportOnly(true);
937  }
938  else {
939  rubberBandTool()->disable();
940  }
941  }
942 }
QMap< CubeViewport *, int > p_saveMarker
Marker for last save.
Definition: EditTool.h:152
Cube display widget for certain Isis MDI applications.
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
Definition: Buffer.cpp:161
void updateTool()
This is a virtual function belonging to the Tool class which is called when the user selects a differ...
Definition: EditTool.cpp:243
QToolButton * p_undoButton
Undo button.
Definition: EditTool.h:143
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:109
QComboBox * p_shapeComboBox
Shape combobox.
Definition: EditTool.h:140
int LineDimension() const
Returns the number of lines in the shape buffer.
Definition: Buffer.h:94
horizontal line
Definition: EditTool.h:89
PixelType pixelType() const
Definition: Cube.cpp:1355
QWidget * createToolBarWidget(QStackedWidget *active)
Creates the toolbar containing the edit tool widgets.
Definition: EditTool.cpp:98
void redoEdit()
This method is called to redo any edit operations that have been undone.
Definition: EditTool.cpp:705
void writeToCube(int iesamp, int issamp, int ieline, int isline, QList< QPoint * > *linePts)
Definition: EditTool.cpp:487
bool isColor() const
Is the viewport shown in 3-band color.
Definition: CubeViewport.h:153
QMap< CubeViewport *, QStack< Brick * > * > p_undoEdit
Viewport to brick map for undo.
Definition: EditTool.h:150
QRect rectangle()
This method returns a rectangle from the vertices set by the RubberBandTool.
High representation saturation DN value.
Definition: EditTool.h:102
void undoAll(CubeViewport *vp)
This method is used to discard any changes made to this viewport.
Definition: EditTool.cpp:646
QToolButton * p_redoButton
Redo button.
Definition: EditTool.h:144
int cubeSamples() const
Return the number of samples in the cube.
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:60
User Selected DN value.
Definition: EditTool.h:100
void SetBasePosition(const int start_sample, const int start_line, const int start_band)
This method is used to set the base position of the shape buffer.
Definition: Brick.h:112
void cubeContentsChanged(QRect rect)
Cube changed, repaint given area.
void addTo(Workspace *)
Adds the given workspace to the cubeviewport list.
Definition: EditTool.cpp:59
void setDrawActiveViewportOnly(bool activeOnly=false)
This called to set whether rubber band is drawn on active viewport only rather than all linked viewpo...
QComboBox * p_valTypeComboBox
Value type combobox.
Definition: EditTool.h:141
Low representation saturation DN value.
Definition: EditTool.h:103
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:121
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:686
int Sample(const int index=0) const
Returns the sample position associated with a shape buffer index.
Definition: Buffer.cpp:143
const double Lis
Value for an Isis Low Instrument Saturation pixel.
Definition: SpecialPixel.h:119
void reopen(QString access="r")
This method will reopen an isis sube for reading or reading/writing.
Definition: Cube.cpp:653
Low instrument satruation DN value.
Definition: EditTool.h:105
void selectValType(int index)
This is a private slot which is called when the user selects a new dn type.
Definition: EditTool.cpp:211
QToolButton * p_saveButton
Save button.
Definition: EditTool.h:145
int sampleCount() const
Definition: Cube.cpp:1404
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
Cube * cube() const
Return the cube associated with viewport.
Definition: CubeViewport.h:228
QList< QPoint * > * LineToPoints(const QLine &line)
Convert rubber band line to points.
Definition: EditTool.cpp:844
int grayBand() const
Return the gray band currently viewed.
Definition: CubeViewport.h:163
double p_dn
DN value.
Definition: EditTool.h:148
High instrument saturation DN value.
Definition: EditTool.h:104
void rubberBandComplete()
This method is called any time the RubberBandTool is complete.
Definition: EditTool.cpp:277
void undoEdit()
This is a private slot called when the user selects the undo button.
Definition: EditTool.cpp:570
QToolButton * p_saveAsButton
Save as button.
Definition: EditTool.h:146
void addTo(ViewportMainWindow *mw)
Adds the tool to the application.
Definition: Tool.cpp:78
void viewportToCube(int x, int y, double &sample, double &line) const
Convert a viewport x/y to a cube sample/line (may be outside the cube)
EditTool(QWidget *parent)
Constructs and EditTool object.
Definition: EditTool.cpp:55
QLineEdit * p_dnLineEdit
DN edit line.
Definition: EditTool.h:142
bool isReadOnly() const
Test if the opened cube is read-only, that is write operations will fail if this is true...
Definition: Cube.cpp:128
void removeViewport(QObject *vp)
This is a private slot called to clean up when a viewport is destroyed.
Definition: EditTool.cpp:808
QMap< CubeViewport *, QStack< Brick * > * > p_redoEdit
Viewport to brick map for redo.
Definition: EditTool.h:151
vertical line
Definition: EditTool.h:90
QAction * toolPadAction(ToolPad *pad)
Adds the EditTool to the tool pad.
Definition: EditTool.cpp:73
void cubeChanged(bool changed)
This method is called when the cube has changed or changes have been finalized.
bool isValid()
This returns true if we can return complete &amp; valid data.
int size() const
Returns the total number of pixels in the shape buffer.
Definition: Buffer.h:112
void cubeChanged(bool)
Emitted when cube changed.
void write(Blob &blob)
This method will write a blob of data (e.g.
Definition: Cube.cpp:725
Isis exception class.
Definition: IException.h:99
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
void disable()
This is called when something is not using me, so turn off events, reset &amp; repaint to clear the clear...
void changeDn()
This is a private slot called when the user hits the enter key after typing a value in the dnLineEdit...
Definition: EditTool.cpp:231
Base class for the Qisis tools.
Definition: Tool.h:81
void setCaption()
Change the caption on the viewport title bar.
const double Lrs
Value for an Isis Low Representation Saturation pixel.
Definition: SpecialPixel.h:113
void save()
Emitted when cube should be saved.
void saveAs()
Emitted when cube should be saved as another file.
int cubeLines() const
Return the number of lines in the cube.
int lineCount() const
Definition: Cube.cpp:1331
virtual void enableRubberBandTool()
This method sets up the RubberBandTool depending on which mode is enabled.
Definition: EditTool.cpp:928
void mouseButtonRelease(QPoint p, Qt::MouseButton m)
This is a slot called when any mouse button is released inside of a viewport.
Definition: EditTool.cpp:404
int SampleDimension() const
Returns the number of samples in the shape buffer.
Definition: Buffer.h:85
const double His
Value for an Isis High Instrument Saturation pixel.
Definition: SpecialPixel.h:125
const double Hrs
Value for an Isis High Representation Saturation pixel.
Definition: SpecialPixel.h:131
void enable(RubberBandMode mode, bool showIndicatorColors=false)
This is called when changing modes or turning on.

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:17:41