Isis 3 Programmer Reference
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 
283  QString fileName = vp->cube()->fileName();
284  // ReOpen cube as read/write
285  // If cube readonly print error
286  try {
287  vp->cube()->reopen("rw");
288  }
289  catch(IException &) {
290  vp->cube()->open(fileName, "r");
291  QMessageBox::information((QWidget *)parent(), "Error", "Cannot open cube read/write");
292  return;
293  }
294  }
295  if (vp->isColor()) {
296  QMessageBox::information((QWidget *)parent(),
297  "Error", "Cannot edit in color mode");
298  return;
299  }
300 
301  int issamp, isline, iesamp, ieline;
302  double ssamp, sline, esamp, eline;
303  QList<QPoint *> *linePts = NULL;
304 
305  // Rectangle is selected
306  if (p_shapeComboBox->currentIndex() == Rectangle) {
307 
308  if (!rubberBandTool()->isValid()) return;
309 
310  QRect r = rubberBandTool()->rectangle();
311  if ((r.width() < 1) || (r.height() < 1)) return;
312 
313  vp->viewportToCube(r.left(), r.top(), ssamp, sline);
314  vp->viewportToCube(r.right(), r.bottom(), esamp, eline);
315 
316  issamp = (int)(ssamp + 0.5);
317  isline = (int)(sline + 0.5);
318  iesamp = (int)(esamp + 0.5);
319  ieline = (int)(eline + 0.5);
320 
321  //Clamp the rectangles coordinates to within the cube's dimensions
322  if (issamp < 0) issamp = 0;
323  if (iesamp < 0) iesamp = 0;
324  if (isline < 0) isline = 0;
325  if (ieline < 0) ieline = 0;
326 
327  if (issamp > vp->cubeSamples()) issamp = vp->cubeSamples();
328  if (iesamp > vp->cubeSamples()) iesamp = vp->cubeSamples();
329  if (isline > vp->cubeLines()) isline = vp->cubeLines();
330  if (ieline > vp->cubeLines()) ieline = vp->cubeLines();
331 
332  //If the rectangle is completely out of bounds on either side, display an error and return
333  if (issamp > iesamp || isline > ieline) {
334  QMessageBox::information((QWidget *)parent(),
335  "Error", "Rectangle is out of bounds");
336  return;
337  }
338  }
339  // Line is selected
340  else if (p_shapeComboBox->currentIndex() == StartEndLine) {
341  // Convert rubber band line to cube coordinates
342  if (!rubberBandTool()->isValid()) return;
343  vp->viewportToCube(rubberBandTool()->vertices()[0].rx(), rubberBandTool()->vertices()[0].ry(),
344  ssamp, sline);
345  vp->viewportToCube(rubberBandTool()->vertices()[1].rx(), rubberBandTool()->vertices()[1].ry(),
346  esamp, eline);
347 
348  QLine l((int)ssamp, (int)sline, (int)esamp, (int)eline);
349 
350  linePts = EditTool::LineToPoints(l);
351 
352  //If the line is completely out of bounds, display an error and return
353  if (linePts->empty()) {
354  QMessageBox::information((QWidget *)parent(),
355  "Error", "No points in edit line");
356  return;
357  }
358 
359  // Find bounding rectangle for the line
360  issamp = std::min(linePts->front()->x(), linePts->back()->x());
361  isline = std::min(linePts->front()->y(), linePts->back()->y());
362  iesamp = std::max(linePts->front()->x(), linePts->back()->x());
363  ieline = std::max(linePts->front()->y(), linePts->back()->y());
364  }
365  // Neither mode is selected, so this is an incorrect mode for this RubberBandTool
366  else {
367  return;
368  }
369 
370  // Write the data to the cube
371  writeToCube(iesamp, issamp, ieline, isline, linePts);
372  if (linePts) delete linePts;
373  }
374 
375  void EditTool::listenToViewport(MdiCubeViewport *newViewport) {
376  connect(newViewport, SIGNAL(saveChanges(CubeViewport *)),
377  this, SLOT(save(CubeViewport *)));
378  connect(newViewport, SIGNAL(discardChanges(CubeViewport *)),
379  this, SLOT(undoAll(CubeViewport *)));
380  connect(newViewport, SIGNAL(destroyed(QObject *)),
381  this, SLOT(removeViewport(QObject *)));
382  }
383 
384 
411  void EditTool::mouseButtonRelease(QPoint p, Qt::MouseButton m) {
413  if (vp == NULL) return;
414  if (p_valTypeComboBox->itemData(p_valTypeComboBox->currentIndex()) ==
415  UserDnComboValue && p_dnLineEdit->text() == "" && m != Qt::RightButton)
416  return;
417 
418  // If cube readonly try to open read/write
419  if (vp->cube()->isReadOnly()) {
420 
421  // Get cube filename to recreate it with "r" privileges if the "rw" access fails.
422  QString fileName = vp->cube()->fileName();
423 
424  // ReOpen cube as read/write
425  // If cube readonly print error
426  try {
427  vp->cube()->reopen("rw");
428  }
429  catch(IException &) {
430  vp->cube()->open(fileName, "r");
431  QMessageBox::information((QWidget *)parent(), "Error", "Cannot open cube read/write");
432  return;
433  }
434  }
435  if (vp->isColor()) {
436  QMessageBox::information((QWidget *)parent(),
437  "Error", "Cannot edit in color mode");
438  return;
439  }
440 
441  int issamp, isline, iesamp, ieline;
442  double ssamp, sline;
443 
444  // If right mouse button, pick up dn value under the cursor which will be
445  // used as the edit value.
446  if (m == Qt::RightButton &&
447  p_valTypeComboBox->itemData(p_valTypeComboBox->currentIndex()) ==
449  vp->viewportToCube(p.x(), p.y(), ssamp, sline);
450  issamp = (int)(ssamp + 0.5);
451  isline = (int)(sline + 0.5);
452  Brick *pntBrick = new Brick(1, 1, 1,
453  vp->cube()->pixelType());
454  pntBrick->SetBasePosition(issamp, isline, vp->grayBand());
455  vp->cube()->read(*pntBrick);
456  p_dn = (*pntBrick)[0];
457  p_dnLineEdit->setText(QString::number(p_dn));
458  delete pntBrick;
459  return;
460  }
461 
462  else if (p_shapeComboBox->currentIndex() == Point ||
463  p_shapeComboBox->currentIndex() == HorizLine ||
464  p_shapeComboBox->currentIndex() == VertLine) {
465  vp->viewportToCube(p.x(), p.y(), ssamp, sline);
466  if ((ssamp < 0.5) || (sline < 0.5) ||
467  (ssamp > vp->cubeSamples() + 0.5) || (sline > vp->cubeLines() + 0.5)) {
468  QApplication::beep();
469  return;
470  }
471  issamp = (int)(ssamp + 0.5);
472  isline = (int)(sline + 0.5);
473  iesamp = issamp;
474  ieline = isline;
475  if (p_shapeComboBox->currentIndex() == HorizLine) {
476  issamp = 1;
477  iesamp = vp->cube()->sampleCount();
478  }
479  if (p_shapeComboBox->currentIndex() == VertLine) {
480  isline = 1;
481  ieline = vp->cube()->lineCount();
482  }
483  // Write the changes to the cube.
484  writeToCube(iesamp, issamp, ieline, isline, NULL);
485  }
486  }
487 
499  void EditTool::writeToCube(int iesamp, int issamp, int ieline, int isline, QList<QPoint *> *linePts) {
500  Brick *brick = NULL;
501  try {
503 
504  int nsamps = iesamp - issamp + 1;
505  int nlines = ieline - isline + 1;
506 
507  brick = new Brick(nsamps, nlines, 1, vp->cube()->pixelType());
508  brick->SetBasePosition(issamp, isline, vp->grayBand());
509  vp->cube()->read(*brick);
510 
511  // Save for Undo operation, See if viewport has undo entry. If it
512  // does, get Stack, push new undo and put stack back in hash. If not,
513  // create stack, push new undo and add to hash.
514  QStack<Brick *> *s;
515  if (p_undoEdit.contains(vp)) {
516  s = p_undoEdit.value(vp);
517  }
518  else {
519  s = new QStack<Brick *>;
520  }
521  s->push(brick);
522  p_undoEdit[vp] = s;
523 
524  //Remove any redo stack if it exists
525  if (p_redoEdit.contains(vp)) {
526  QStack<Brick *> *temp = p_redoEdit.value(vp);
527  while(!temp->isEmpty()) {
528  delete temp->pop();
529  }
530  p_redoEdit.remove(vp);
531  p_redoButton->setEnabled(false);
532  }
533 
534  // no deep copy constructor so re-read brick for editing....
535  brick = new Brick(nsamps, nlines, 1, vp->cube()->pixelType());
536  brick->SetBasePosition(issamp, isline, vp->grayBand());
537  vp->cube()->read(*brick);
538 
539  // Now that we have where, do the actual edits
540  if (p_shapeComboBox->currentIndex() == StartEndLine) {
541  for(int i = 0; linePts && i < (int)linePts->size(); i++) {
542  QPoint *pt = (*linePts)[i];
543  int is = pt->x();
544  int il = pt->y();
545  int brickIndex = (il - isline) * nsamps + (is - issamp);
546  (*brick)[brickIndex] = (double)p_dn;
547  }
548  }
549  else {
550  for(int i = 0; i < brick->size(); i++)(*brick)[i] = (double)p_dn;
551  }
552 
553  //Signal that this cube has been changed, enable the undo and save buttons
554  emit cubeChanged(true);
555  p_undoButton->setEnabled(true);
556  p_saveButton->setEnabled(true);
557  vp->cube()->write(*brick);
558  vp->cubeChanged(true);
559  vp->setCaption();
560 
561  // QRect r(issamp,isline,nsamps,nlines);
562  QRect r(brick->Sample(), brick->Line(),
563  brick->SampleDimension(), brick->LineDimension());
564  vp->cubeContentsChanged(r);
565  delete brick;
566  }
567  catch(...) {
568  if (brick) {
569  delete brick;
570  }
571  //If the brick failed to initialize due to insufficient memory
572  QMessageBox::information((QWidget *)parent(), "Error", "Not enough memory to complete this operation.");
573  return;
574  }
575  }
576 
583  Brick *redoBrick = NULL;
584  try {
586  if (vp == NULL) return;
587 
588  // If viewport not in hash, beep
589  if (p_undoEdit.empty() || p_undoEdit.count(vp) == 0) {
590  QApplication::beep();
591  return;
592  }
593 
594  // If cube readonly print error
595  if (vp->cube()->isReadOnly()) {
596  QMessageBox::information((QWidget *)parent(), "Error", "Cube is Read Only");
597  return;
598  }
599 
600 
601  QStack<Brick *> *s = p_undoEdit.value(vp);
602  Brick *brick = s->top();
603 
604  //Write the current cube to the a brick and add it to the redo stack
605  redoBrick = new Brick(brick->SampleDimension(), brick->LineDimension(), 1, vp->cube()->pixelType());
606  redoBrick->SetBasePosition(brick->Sample(), brick->Line(), vp->grayBand());
607  vp->cube()->read(*(redoBrick));
608 
609  QStack<Brick *> *redo;
610  if (p_redoEdit.contains(vp)) {
611  redo = p_redoEdit.value(vp);
612  }
613  else {
614  redo = new QStack<Brick *>;
615  }
616  redo->push(redoBrick);
617  p_redoEdit[vp] = redo;
618 
619  // Write the saved brick to the cube
620  vp->cube()->write(*(brick));
621 
622  // Update the viewport
623  QRect r(brick->Sample(), brick->Line(),
624  brick->SampleDimension(), brick->LineDimension());
625  vp->cubeContentsChanged(r);
626 
627  //Enable the redo button since we have made an undo
628  p_redoButton->setEnabled(true);
629  p_saveButton->setEnabled(true);
630  emit cubeChanged(true);
631  vp->cubeChanged(true);
632  vp->setCaption();
633 
634  //Pop this element off the stack, if the undo stack is empty, disable the undo button
635  s->pop();
636  if (s->empty()) {
637  p_undoButton->setEnabled(false);
638  }
639  delete brick;
640  }
641  catch(...) {
642  if (redoBrick) {
643  delete redoBrick;
644  }
645  //If the brick failed to initialize due to insufficient memory
646  QMessageBox::information((QWidget *)parent(), "Error", "Not enough memory to complete this operation.");
647  return;
648  }
649  }
650 
659  try {
660  if (vp != NULL) {
661  // If cube readonly print error
662  if (vp->cube()->isReadOnly()) {
663  QMessageBox::information((QWidget *)parent(), "Error", "Cube is Read Only");
664  return;
665  }
666 
667  QStack<Brick *> *undo;
668  QStack<Brick *> *redo;
669  int marker = 0;
670  //If edits have been made
671  if (p_undoEdit.contains(vp)) {
672  undo = p_undoEdit.value(vp);
673 
674  //If a save has been made
675  if (p_saveMarker.contains(vp)) {
676  marker = p_saveMarker.value(vp);
677  }
678 
679  //Undo up to the save point
680  for(int i = undo->count() - 1; i >= marker; i--) {
681  Brick *brick = undo->at(i);
682  // Write the saved brick to the cube
683  vp->cube()->write(*(brick));
684  }
685 
686  //If undos have been made past the save point, we need to redo them
687  //Set the marker to the correct index
688  marker = marker - undo->count();
689  }
690 
691  //If undos have been made
692  if (p_redoEdit.contains(vp)) {
693  redo = p_redoEdit.value(vp);
694 
695  //If undos have been made past a save point, we need to redo them
696  for(int i = redo->count() - 1; i >= redo->count() - marker; i--) {
697  Brick *brick = redo->at(i);
698 
699  // Write the saved brick to the cube
700  vp->cube()->write(*(brick));
701  }
702  }
703  }
704  }
705  catch(...) {
706  //If the brick failed to initialize due to insufficient memory
707  QMessageBox::information((QWidget *)parent(), "Error",
708  "Not enough memory to complete this operation.");
709  return;
710  }
711  }
712 
718  Brick *undoBrick = NULL;
719  try {
721  if (vp == NULL) return;
722 
723  // If viewport not in hash, beep
724  if (p_redoEdit.empty() || p_redoEdit.count(vp) == 0) {
725  QApplication::beep();
726  return;
727  }
728 
729  // If cube readonly print error
730  if (vp->cube()->isReadOnly()) {
731  QMessageBox::information((QWidget *)parent(), "Error", "Cube is Read Only");
732  return;
733  }
734 
735  QStack<Brick *> *s = p_redoEdit.value(vp);
736  Brick *brick = s->top();
737 
738  //Write the current cube to the a brick and add it to the undo stack
739  undoBrick = new Brick(brick->SampleDimension(),
740  brick->LineDimension(), 1,
741  vp->cube()->pixelType());
742  undoBrick->SetBasePosition(brick->Sample(), brick->Line(), vp->grayBand());
743  vp->cube()->read(*(undoBrick));
744 
745  QStack<Brick *> *undo;
746  if (p_undoEdit.contains(vp)) {
747  undo = p_undoEdit.value(vp);
748  }
749  else {
750  undo = new QStack<Brick *>;
751  }
752  undo->push(undoBrick);
753  p_undoEdit[vp] = undo;
754 
755  // Write the saved brick to the cube
756  vp->cube()->write(*(brick));
757  // Update the viewport
758 
759  QRect r(brick->Sample(), brick->Line(),
760  brick->SampleDimension(), brick->LineDimension());
761  vp->cubeContentsChanged(r);
762 
763  p_undoButton->setEnabled(true);
764  p_saveButton->setEnabled(true);
765  vp->cubeChanged(true);
766  vp->setCaption();
767  emit cubeChanged(true);
768 
769  //Pop this element off the stack, if the redo stack is empty, disable the redo button
770  s->pop();
771  if (s->empty()) {
772  p_redoButton->setEnabled(false);
773  }
774  delete brick;
775  }
776  catch(...) {
777  if (undoBrick) {
778  delete undoBrick;
779  }
780  //If the brick failed to initialize due to insufficient memory
781  QMessageBox::information((QWidget *)parent(), "Error", "Not enough memory to complete this operation.");
782  return;
783  }
784  }
785 
794  if (vp != NULL) {
795  //Set the 'save point' for this viewport, if we undo discard any changes
796  //We will only discard to this point
797  int marker;
798  if (p_undoEdit.contains(vp)) {
799  marker = p_undoEdit.value(vp)->count();
800  }
801  else {
802  marker = 0;
803  }
804  p_saveMarker[vp] = marker;
805 
806  p_saveButton->setEnabled(false);
807  vp->cubeChanged(false);
808  vp->setCaption();
809  }
810  }
811 
812 
821  // Connect destruction of CubeViewport to Remove slot to remove viewport
822  // from the undo and redo Hashes.
823  if (p_undoEdit.contains((MdiCubeViewport *) vp)) {
824  QStack<Brick *> *temp = p_undoEdit.value((MdiCubeViewport *) vp);
825  while(!temp->isEmpty()) {
826  delete temp->pop();
827  }
828  p_undoEdit.remove((MdiCubeViewport *) vp);
829  }
830  if (p_redoEdit.contains((MdiCubeViewport *) vp)) {
831  QStack<Brick *> *temp = p_redoEdit.value((MdiCubeViewport *) vp);
832  while(!temp->isEmpty()) {
833  delete temp->pop();
834  }
835  p_redoEdit.remove((MdiCubeViewport *) vp);
836  }
837  }
838 
839 
840 
841 
858  if (vp == NULL) return new QList<QPoint *>();
859  double slope;
860  int i;
861  int x, y, xinc, yinc;
862  int xsize, ysize;
863 
864 
865  QList<QPoint *> *points = new QList<QPoint *>;
866 
867  int sx = line.p1().x();
868  int ex = line.p2().x();
869  int sy = line.p1().y();
870  int ey = line.p2().y();
871  if (sx > ex) {
872  xsize = sx - ex + 1;
873  xinc = -1;
874  }
875  else {
876  xsize = ex - sx + 1;
877  xinc = 1;
878  }
879 
880  if (sy > ey) {
881  ysize = sy - ey + 1;
882  yinc = -1;
883  }
884  else {
885  ysize = ey - sy + 1;
886  yinc = 1;
887  }
888 
889  if (ysize > xsize) {
890  slope = (double)(ex - sx) / (double)(ey - sy);
891  y = sy;
892  for(i = 0; i < ysize; i++) {
893  x = (int)(slope * (double)(y - sy) + (double) sx + 0.5);
894 
895  //If the x or y coordinates are not within the cube dimensions, don't add them
896  if (x >= 0 && y >= 0 && x <= vp->cubeSamples() && y <= vp->cubeLines()) {
897  QPoint *pt = new QPoint;
898  pt->setX(x);
899  pt->setY(y);
900  points->push_back(pt);
901  }
902  y += yinc;
903  }
904  }
905  else if (xsize == 1) {
906  //If the x or y coordinates are not within the cube dimensions, don't add them
907  if (sx >= 0 && sy >= 0 && sx <= vp->cubeSamples() && sy <= vp->cubeLines()) {
908  QPoint *pt = new QPoint;
909  pt->setX(sx);
910  pt->setY(sy);
911  points->push_back(pt);
912  }
913  }
914  else {
915  slope = (double)(ey - sy) / (double)(ex - sx);
916  x = sx;
917  for(i = 0; i < xsize; i++) {
918  y = (int)(slope * (double)(x - sx) + (double) sy + 0.5);
919 
920  //If the x or y coordinates are not within the cube dimensions, don't add them
921  if (x >= 0 && y >= 0 && x <= vp->cubeSamples() && y <= vp->cubeLines()) {
922  QPoint *pt = new QPoint;
923  pt->setX(x);
924  pt->setY(y);
925  points->push_back(pt);
926  }
927  x += xinc;
928  }
929  }
930 
931  return points;
932  }
933 
941  int index = p_shapeComboBox->currentIndex();
942  if (index == 3) {
943  rubberBandTool()->enable(RubberBandTool::LineMode);
944  rubberBandTool()->setDrawActiveViewportOnly(true);
945  }
946  else if (index == 4) {
947  rubberBandTool()->enable(RubberBandTool::RectangleMode);
948  rubberBandTool()->setDrawActiveViewportOnly(true);
949  }
950  else {
951  rubberBandTool()->disable();
952  }
953  }
954 }
QMap< CubeViewport *, int > p_saveMarker
Marker for last save.
Definition: EditTool.h:156
Cube display widget for certain Isis MDI applications.
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:147
int cubeLines() const
Return the number of lines in the cube.
QString toolIconDir() const
returns the path to the icon directory.
Definition: Tool.h:127
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
QComboBox * p_shapeComboBox
Shape combobox.
Definition: EditTool.h:144
Cube * cube() const
Definition: CubeViewport.h:348
horizontal line
Definition: EditTool.h:93
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:717
int sampleCount() const
Definition: Cube.cpp:1452
QMap< CubeViewport *, QStack< Brick * > * > p_undoEdit
Viewport to brick map for undo.
Definition: EditTool.h:154
QRect rectangle()
This method returns a rectangle from the vertices set by the RubberBandTool.
High representation saturation DN value.
Definition: EditTool.h:106
void undoAll(CubeViewport *vp)
This method is used to discard any changes made to this viewport.
Definition: EditTool.cpp:658
QToolButton * p_redoButton
Redo button.
Definition: EditTool.h:148
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:61
User Selected DN value.
Definition: EditTool.h:104
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:136
void cubeContentsChanged(QRect rect)
Calle dhwen the contents of the cube changes.
void addTo(Workspace *)
Adds the given workspace to the cubeviewport list.
Definition: EditTool.cpp:59
bool isColor() const
Definition: CubeViewport.h:194
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:145
Low representation saturation DN value.
Definition: EditTool.h:107
Widget to display Isis cubes for qt apps.
Definition: CubeViewport.h:132
int LineDimension() const
Returns the number of lines in the shape buffer.
Definition: Buffer.h:95
const double Lis
Value for an Isis Low Instrument Saturation pixel.
Definition: SpecialPixel.h:120
int size() const
Returns the total number of pixels in the shape buffer.
Definition: Buffer.h:113
void reopen(QString access="r")
This method will reopen an isis sube for reading or reading/writing.
Definition: Cube.cpp:691
Low instrument satruation DN value.
Definition: EditTool.h:109
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:149
int Sample(const int index=0) const
Returns the sample position associated with a shape buffer index.
Definition: Buffer.cpp:143
QList< QPoint * > * LineToPoints(const QLine &line)
Convert rubber band line to points.
Definition: EditTool.cpp:856
double p_dn
DN value.
Definition: EditTool.h:152
High instrument saturation DN value.
Definition: EditTool.h:108
void rubberBandComplete()
This method is called any time the RubberBandTool is complete.
Definition: EditTool.cpp:277
int grayBand() const
Definition: CubeViewport.h:204
void undoEdit()
This is a private slot called when the user selects the undo button.
Definition: EditTool.cpp:582
QToolButton * p_saveAsButton
Save as button.
Definition: EditTool.h:150
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
Definition: Buffer.cpp:161
bool isReadOnly() const
Test if the opened cube is read-only, that is write operations will fail if this is true...
Definition: Cube.cpp:130
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:724
void open(const QString &cfile, QString access="r")
This method will open an isis cube for reading or reading/writing.
Definition: Cube.cpp:544
void addTo(ViewportMainWindow *mw)
Adds the tool to the application.
Definition: Tool.cpp:78
EditTool(QWidget *parent)
Constructs and EditTool object.
Definition: EditTool.cpp:55
QLineEdit * p_dnLineEdit
DN edit line.
Definition: EditTool.h:146
PixelType pixelType() const
Definition: Cube.cpp:1403
void writeToCube(int iesamp, int issamp, int ieline, int isline, QList< QPoint *> *linePts)
Definition: EditTool.cpp:499
void removeViewport(QObject *vp)
This is a private slot called to clean up when a viewport is destroyed.
Definition: EditTool.cpp:820
QMap< CubeViewport *, QStack< Brick * > * > p_redoEdit
Viewport to brick map for redo.
Definition: EditTool.h:155
int cubeSamples() const
Return the number of samples in the cube.
int SampleDimension() const
Returns the number of samples in the shape buffer.
Definition: Buffer.h:86
vertical line
Definition: EditTool.h:94
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 & valid data.
void cubeChanged(bool)
Emitted when cube changed.
virtual QString fileName() const
Returns the opened cube&#39;s filename.
Definition: Cube.cpp:1208
int lineCount() const
Definition: Cube.cpp:1379
void write(Blob &blob)
This method will write a blob of data (e.g.
Definition: Cube.cpp:763
Isis exception class.
Definition: IException.h:107
void disable()
This is called when something is not using me, so turn off events, reset & 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
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
Base class for the Qisis tools.
Definition: Tool.h:81
MdiCubeViewport * cubeViewport() const
Return the current cubeviewport.
Definition: Tool.h:211
void setCaption()
Change the caption on the viewport title bar.
const double Lrs
Value for an Isis Low Representation Saturation pixel.
Definition: SpecialPixel.h:114
void save()
Emitted when cube should be saved.
void saveAs()
Emitted when cube should be saved as another file.
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
virtual void enableRubberBandTool()
This method sets up the RubberBandTool depending on which mode is enabled.
Definition: EditTool.cpp:940
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:411
const double His
Value for an Isis High Instrument Saturation pixel.
Definition: SpecialPixel.h:126
const double Hrs
Value for an Isis High Representation Saturation pixel.
Definition: SpecialPixel.h:132
void enable(RubberBandMode mode, bool showIndicatorColors=false)
This is called when changing modes or turning on.