USGS

Isis 3.0 Object Programmers' Reference

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 }