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