diff --git a/isis/src/base/objs/Stretch/Stretch.cpp b/isis/src/base/objs/Stretch/Stretch.cpp index 24458fd21e..a16f37379b 100644 --- a/isis/src/base/objs/Stretch/Stretch.cpp +++ b/isis/src/base/objs/Stretch/Stretch.cpp @@ -38,7 +38,7 @@ namespace Isis { * Constructs a Stretch object with default mapping of special pixel values to * themselves. */ - Stretch::Stretch() { + Stretch::Stretch() : Blob("ImageStretch", "Stretch") { p_null = Isis::NULL8; p_lis = Isis::LOW_INSTR_SAT8; p_lrs = Isis::LOW_REPR_SAT8; @@ -47,8 +47,29 @@ namespace Isis { p_minimum = p_lrs; p_maximum = p_hrs; p_pairs = 0; + p_type = "None"; } + + /** + * Constructs a Stretch object with default mapping of special pixel values to + * themselves and a provided name. + * + * @param name Name to use for Stretch + */ + Stretch::Stretch(QString name) : Blob(name, "Stretch") { + p_null = Isis::NULL8; + p_lis = Isis::LOW_INSTR_SAT8; + p_lrs = Isis::LOW_REPR_SAT8; + p_his = Isis::HIGH_INSTR_SAT8; + p_hrs = Isis::HIGH_REPR_SAT8; + p_minimum = p_lrs; + p_maximum = p_hrs; + p_pairs = 0; + p_type = "None"; + } + + /** * Adds a stretch pair to the list of pairs. Note that all input pairs must be * in ascending order. @@ -410,6 +431,89 @@ namespace Isis { this->p_output = other.p_output; } + + /** + * Read saved Stretch data from a Cube into this object. + * + * This is called by Blob::Read() and is the actual data reading function + * ultimately called when running something like cube->read(stretch); + * + * @param is input stream containing the saved Stretch information + */ + void Stretch::ReadData(std::istream &is) { + // Set the Stretch Type + p_type = p_blobPvl["StretchType"][0]; + + // Read in the Stretch Pairs + streampos sbyte = p_startByte - 1; + is.seekg(sbyte, std::ios::beg); + if (!is.good()) { + QString msg = "Error preparing to read data from " + p_type + + " [" + p_blobName + "]"; + throw IException(IException::Io, msg, _FILEINFO_); + } + + char *buf = new char[p_nbytes+1]; + memset(buf, 0, p_nbytes + 1); + + is.read(buf, p_nbytes); + + // Read buffer data into a QString so we can call Parse() + std::string stringFromBuffer(buf); + QString qStringFromBuffer = QString::fromStdString(stringFromBuffer); + Parse(qStringFromBuffer); + + delete [] buf; + + if (!is.good()) { + QString msg = "Error reading data from " + p_type + " [" + + p_blobName + "]"; + throw IException(IException::Io, msg, _FILEINFO_); + } + } + + + /** + * Get the Type of Stretch. This is only used by the AdvancedStretchTool. + * + * @return QString Type of Stretch. + */ + QString Stretch::getType(){ + return p_type; + } + + + /** + * Set the Type of Stretch. This is only used by the AdvancedStretchTool. + * + * @param stretchType The type of stretch. + */ + void Stretch::setType(QString stretchType){ + // check to see if valid input + p_type = stretchType; + } + + + /** + * Initializes for writing stretch to cube blob + */ + void Stretch::WriteInit() { + p_nbytes = Text().toStdString().size(); + } + + + /** + * Writes the stretch information to a cube. + * + * This is called by Blob::write() and is ultimately the function + * called when running something like cube->write(stretch); + * + * @param os output stream to write the stretch data to. + */ + void Stretch::WriteData(std::fstream &os) { + os.write(Text().toStdString().c_str(), p_nbytes); + } + } // end namespace isis diff --git a/isis/src/base/objs/Stretch/Stretch.h b/isis/src/base/objs/Stretch/Stretch.h index 144bb41251..5da48bbe74 100644 --- a/isis/src/base/objs/Stretch/Stretch.h +++ b/isis/src/base/objs/Stretch/Stretch.h @@ -26,6 +26,7 @@ #include #include "Pvl.h" #include "Histogram.h" +#include "Blob.h" namespace Isis { /** @@ -67,9 +68,10 @@ namespace Isis { * Created second Parse method for handling pairs where the * input side is a perentage. Fixed Input and Output getters * to check both sides of boundry condition for valid data - * + * @history 2020-02-27 Kristin Berry - Updated to inherit from Blob so Stretches can be + * saved and restored from cubes. */ - class Stretch { + class Stretch : public Isis::Blob { private: std::vector p_input; //!< Array for input side of stretch pairs std::vector p_output; //!< Array for output side of stretch pairs @@ -88,10 +90,13 @@ namespace Isis { double p_minimum; //! NextPair(QString &pairs); public: Stretch(); + Stretch(QString name); //! Destroys the Stretch object ~Stretch() {}; @@ -177,6 +182,9 @@ namespace Isis { return p_pairs; }; + QString getType(); + void setType(QString type); + double Input(const int index) const; double Output(const int index) const; @@ -188,6 +196,11 @@ namespace Isis { }; void CopyPairs(const Stretch &other); + + protected: + void WriteInit(); + void ReadData(std::istream &is); + void WriteData(std::fstream &os); }; }; diff --git a/isis/src/qisis/objs/StretchTool/AdvancedStretch.cpp b/isis/src/qisis/objs/StretchTool/AdvancedStretch.cpp index ae237ddd05..6b41d0b892 100644 --- a/isis/src/qisis/objs/StretchTool/AdvancedStretch.cpp +++ b/isis/src/qisis/objs/StretchTool/AdvancedStretch.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "Stretch.h" #include "IString.h" @@ -35,40 +36,52 @@ namespace Isis { typeSelectionArea->setLayout(new QHBoxLayout()); typeSelectionArea->layout()->addWidget(new QLabel("Stretch Type")); - QComboBox *stretchTypeSelection = new QComboBox(); - stretchTypeSelection->addItem("Linear", 0); - stretchTypeSelection->addItem("Sawtooth", 1); - stretchTypeSelection->addItem("Binary", 2); - stretchTypeSelection->addItem("Manual", 3); + p_stretchTypeSelection = new QComboBox(); + p_stretchTypeSelection->addItem("Linear", 0); + p_stretchTypeSelection->addItem("Sawtooth", 1); + p_stretchTypeSelection->addItem("Binary", 2); + p_stretchTypeSelection->addItem("Manual", 3); - typeSelectionArea->layout()->addWidget(stretchTypeSelection); + typeSelectionArea->layout()->addWidget(p_stretchTypeSelection); layout()->addWidget(typeSelectionArea); p_stretchTypeStack = new QStackedWidget(); LinearStretchType *linear = new LinearStretchType(hist, curStretch, name, color); connect(linear, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); + connect(linear, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); + connect(linear, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); + connect(linear, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); p_stretchTypeStack->addWidget(linear); SawtoothStretchType *sawtooth = new SawtoothStretchType(hist, curStretch, name, color); connect(sawtooth, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); + connect(sawtooth, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); + connect(sawtooth, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); + connect(sawtooth, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); p_stretchTypeStack->addWidget(sawtooth); BinaryStretchType *binary = new BinaryStretchType(hist, curStretch, name, color); connect(binary, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); + connect(binary, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); + connect(binary, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); + connect(binary, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); p_stretchTypeStack->addWidget(binary); ManualStretchType *manual = new ManualStretchType(hist, curStretch, name, color); connect(manual, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); + connect(manual, SIGNAL(saveToCube()), this, SIGNAL(saveToCube())); + connect(manual, SIGNAL(deleteFromCube()), this, SIGNAL(deleteFromCube())); + connect(manual, SIGNAL(loadStretch()), this, SIGNAL(loadStretch())); p_stretchTypeStack->addWidget(manual); layout()->addWidget(p_stretchTypeStack); - connect(stretchTypeSelection, SIGNAL(currentIndexChanged(int)), + connect(p_stretchTypeSelection, SIGNAL(currentIndexChanged(int)), p_stretchTypeStack, SLOT(setCurrentIndex(int))); - connect(stretchTypeSelection, SIGNAL(currentIndexChanged(int)), + connect(p_stretchTypeSelection, SIGNAL(currentIndexChanged(int)), this, SIGNAL(stretchChanged())); } @@ -105,6 +118,38 @@ namespace Isis { } + /** + * Used to restore a saved Stretch from a cube. This function is + * distinct from setStretch in that setStretch deliberately _does not_ + * change the stretch type, and this function does change the stretch type. + * + * @param newStretch saved stretch to restore + */ + void AdvancedStretch::restoreSavedStretch(Stretch newStretch) { + QString stretchTypeName = newStretch.getType(); + + int index = 0; + if (stretchTypeName.compare("LinearStretch") == 0 ) { + index = 0; + } + else if (stretchTypeName.compare("SawtoothStretch") == 0 ) { + index = 1; + } + else if (stretchTypeName.compare("BinaryStretch") == 0) { + index = 2; + } + else if (stretchTypeName.compare("ManualStretch") == 0) { + index = 3; + } + // Fail by defaulting to Linear + + p_stretchTypeSelection->setCurrentIndex(index); + StretchType *stretchType = (StretchType *) + p_stretchTypeStack->currentWidget(); + stretchType->setStretch(newStretch); + } + + /** * This is called when the visible area changes, so that the * histogram can be updated. It is essential that the stretch diff --git a/isis/src/qisis/objs/StretchTool/AdvancedStretch.h b/isis/src/qisis/objs/StretchTool/AdvancedStretch.h index acd80e8f32..3f49826e3c 100644 --- a/isis/src/qisis/objs/StretchTool/AdvancedStretch.h +++ b/isis/src/qisis/objs/StretchTool/AdvancedStretch.h @@ -4,6 +4,7 @@ #include class QStackedWidget; +class QComboBox; class QLayout; class QString; class QColor; @@ -36,16 +37,19 @@ namespace Isis { ~AdvancedStretch(); Stretch getStretch(); void setStretch(Stretch newStretch); + void restoreSavedStretch(Stretch newStretch); void setHistogram(const Histogram &newHist); signals: //! Emitted when a new stretch is available void stretchChanged(); - - protected: + void saveToCube(); + void deleteFromCube(); + void loadStretch(); private: QStackedWidget *p_stretchTypeStack; //!< StretchType's + QComboBox *p_stretchTypeSelection; //!< ComboBox of StretchTypes }; }; diff --git a/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.cpp b/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.cpp index 7055a49a2c..63a05e2fa2 100644 --- a/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.cpp +++ b/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.cpp @@ -21,7 +21,10 @@ namespace Isis { p_bluStretch = NULL; p_enabled = false; + setWindowTitle("Advanced Stretch Tool"); + QHBoxLayout *layout = new QHBoxLayout(); + setLayout(layout); } @@ -124,6 +127,22 @@ namespace Isis { connect(p_grayStretch, SIGNAL(stretchChanged()), this, SIGNAL(stretchChanged())); + connect(p_grayStretch, SIGNAL(saveToCube()), + this, SIGNAL(saveToCube())); + connect(p_grayStretch, SIGNAL(deleteFromCube()), + this, SIGNAL(deleteFromCube())); + connect(p_grayStretch, SIGNAL(loadStretch()), + this, SIGNAL(loadStretch())); + } + + + /** + * Restores a saved stretch from the cube + * + * @param stretch + */ + void AdvancedStretchDialog::restoreSavedStretch(Stretch stretch){ + p_grayStretch->restoreSavedStretch(stretch); } @@ -213,7 +232,7 @@ namespace Isis { /** - * This calls setHistogram on the gray advanced stretche. This + * This calls setHistogram on the gray advanced stretches. This * should be called every time the visible area changes. * * @param grayHist Histogram of visible area on gray band diff --git a/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.h b/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.h index 2799f5a15f..24a41f331e 100644 --- a/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.h +++ b/isis/src/qisis/objs/StretchTool/AdvancedStretchDialog.h @@ -48,6 +48,7 @@ namespace Isis { Histogram &grayHist); void updateHistogram(const Histogram &grayHist); bool isRgbMode() const; + void restoreSavedStretch(Stretch stretch); Stretch getGrayStretch(); Stretch getRedStretch(); @@ -77,6 +78,9 @@ namespace Isis { void stretchChanged(); //! Emitted when this dialog is shown or hidden void visibilityChanged(); + void saveToCube(); + void deleteFromCube(); + void loadStretch(); public slots: void updateStretch(CubeViewport *); diff --git a/isis/src/qisis/objs/StretchTool/BinaryStretchType.cpp b/isis/src/qisis/objs/StretchTool/BinaryStretchType.cpp index d3c7b7e3f5..2e67c7011e 100644 --- a/isis/src/qisis/objs/StretchTool/BinaryStretchType.cpp +++ b/isis/src/qisis/objs/StretchTool/BinaryStretchType.cpp @@ -73,6 +73,8 @@ namespace Isis { sliderWidget->setLayout(sliderLayout); p_mainLayout->addWidget(sliderWidget, 1, 0); + p_stretch->setType("BinaryStretch"); + setLayout(p_mainLayout); setStretch(calculateNewStretch()); } diff --git a/isis/src/qisis/objs/StretchTool/LinearStretchType.cpp b/isis/src/qisis/objs/StretchTool/LinearStretchType.cpp index a1211598ed..66953c5320 100644 --- a/isis/src/qisis/objs/StretchTool/LinearStretchType.cpp +++ b/isis/src/qisis/objs/StretchTool/LinearStretchType.cpp @@ -71,6 +71,7 @@ namespace Isis { sliderWidget->setLayout(sliderLayout); p_mainLayout->addWidget(sliderWidget, 1, 0); + p_stretch->setType("LinearStretch"); setLayout(p_mainLayout); setStretch(stretch); @@ -254,8 +255,8 @@ namespace Isis { } } - Stretch LinearStretchType::getStretch() { return *p_stretch; } + } diff --git a/isis/src/qisis/objs/StretchTool/LinearStretchType.h b/isis/src/qisis/objs/StretchTool/LinearStretchType.h index 1ca66618ec..b41d46b8ef 100644 --- a/isis/src/qisis/objs/StretchTool/LinearStretchType.h +++ b/isis/src/qisis/objs/StretchTool/LinearStretchType.h @@ -36,7 +36,6 @@ namespace Isis { virtual Stretch getStretch(); virtual void setStretch(Stretch); - private slots: void startSliderMoved(int); void startEditChanged(const QString &); diff --git a/isis/src/qisis/objs/StretchTool/ManualStretchType.cpp b/isis/src/qisis/objs/StretchTool/ManualStretchType.cpp index 4ae247c0c5..2c8d20f697 100644 --- a/isis/src/qisis/objs/StretchTool/ManualStretchType.cpp +++ b/isis/src/qisis/objs/StretchTool/ManualStretchType.cpp @@ -55,6 +55,8 @@ namespace Isis { this, SLOT(readTable())); disconnect(this, SIGNAL(stretchChanged()), this, SLOT(updateTable())); + p_stretch->setType("ManualStretch"); + setLayout(p_mainLayout); setStretch(stretch); } diff --git a/isis/src/qisis/objs/StretchTool/SawtoothStretchType.cpp b/isis/src/qisis/objs/StretchTool/SawtoothStretchType.cpp index 5b1e46589c..2e97c93ed1 100644 --- a/isis/src/qisis/objs/StretchTool/SawtoothStretchType.cpp +++ b/isis/src/qisis/objs/StretchTool/SawtoothStretchType.cpp @@ -71,6 +71,8 @@ namespace Isis { sliderWidget->setLayout(sliderLayout); p_mainLayout->addWidget(sliderWidget, 1, 0); + p_stretch->setType("SawtoothStretch"); + setLayout(p_mainLayout); p_widthEdit->setText(QString::number( diff --git a/isis/src/qisis/objs/StretchTool/SawtoothStretchType.h b/isis/src/qisis/objs/StretchTool/SawtoothStretchType.h index 1da8bda35b..7801f8b114 100644 --- a/isis/src/qisis/objs/StretchTool/SawtoothStretchType.h +++ b/isis/src/qisis/objs/StretchTool/SawtoothStretchType.h @@ -39,7 +39,6 @@ namespace Isis { virtual void setStretch(Stretch); - private slots: void offsetSliderMoved(int); void offsetEditChanged(const QString &); diff --git a/isis/src/qisis/objs/StretchTool/StretchTool.cpp b/isis/src/qisis/objs/StretchTool/StretchTool.cpp index 09660aecdb..466ade83fc 100644 --- a/isis/src/qisis/objs/StretchTool/StretchTool.cpp +++ b/isis/src/qisis/objs/StretchTool/StretchTool.cpp @@ -1,5 +1,7 @@ #include "StretchTool.h" +#include + #include #include #include @@ -13,9 +15,11 @@ #include #include #include +#include #include "AdvancedStretchDialog.h" #include "Brick.h" +#include "Blob.h" #include "CubeViewport.h" #include "Histogram.h" #include "IException.h" @@ -51,6 +55,12 @@ namespace Isis { this, SLOT(advancedStretchChanged())); connect(m_advancedStretch, SIGNAL(visibilityChanged()), this, SLOT(updateTool())); + connect(m_advancedStretch, SIGNAL(saveToCube()), + this, SLOT(saveStretchToCube())); + connect(m_advancedStretch, SIGNAL(deleteFromCube()), + this, SLOT(deleteFromCube())); + connect(m_advancedStretch, SIGNAL(loadStretch()), + this, SLOT(loadStretchFromCube())); QPushButton *hiddenButton = new QPushButton(); hiddenButton->setVisible(false); @@ -370,6 +380,177 @@ namespace Isis { } } + + /** + * Restores a saved stretch from the cube + */ + void StretchTool::loadStretchFromCube(){ + MdiCubeViewport *cvp = cubeViewport(); + Cube* icube = cvp->cube(); + Pvl* lab = icube->label(); + + // Create a list of existing Stretch names + QStringList namelist; + PvlObject::PvlObjectIterator objIter; + for (objIter=lab->beginObject(); objIterendObject(); objIter++) { + if (objIter->name() == "Stretch") { + PvlKeyword tempKeyword = objIter->findKeyword("Name"); + QString tempName = tempKeyword[0]; + namelist.append(tempName); + } + } + + bool ok; + QString stretchName = QInputDialog::getItem(m_advancedStretch, tr("Load Stretch"), + tr("Name of Stretch to Load:"), namelist, 0, + false, &ok); + + if (ok) { + Stretch stretch(stretchName); + icube->read(stretch); + m_advancedStretch->restoreSavedStretch(stretch); + } + } + + + /** + * Deletes a saved stretch from the cube + */ + void StretchTool::deleteFromCube() { + MdiCubeViewport *cvp = cubeViewport(); + Cube* icube = cvp->cube(); + Pvl* lab = icube->label(); + + // Create a list of existing Stretch names + QStringList namelist; + PvlObject::PvlObjectIterator objIter; + for (objIter=lab->beginObject(); objIterendObject(); objIter++) { + if (objIter->name() == "Stretch") { + PvlKeyword tempKeyword = objIter->findKeyword("Name"); + QString tempName = tempKeyword[0]; + namelist.append(tempName); + } + } + + bool ok; + QString toDelete = QInputDialog::getItem(m_advancedStretch, tr("Delete Stretch"), + tr("Name of Stretch to Delete:"), namelist, 0, + false, &ok); + if (ok) { + if (icube->isReadOnly()) { + try { + cvp->cube()->reopen("rw"); + } + catch(IException &) { + cvp->cube()->reopen("r"); + QMessageBox::information((QWidget *)parent(), "Error", + "Cannot open cube read/write to delete stretch"); + return; + } + } + + bool cubeDeleted = icube->deleteBlob("Stretch", toDelete); + + if (!cubeDeleted) { + QMessageBox msgBox; + msgBox.setText("Stretch Could Not Be Deleted!"); + msgBox.setInformativeText("A stretch with name: \"" + toDelete + + "\" Could not be found, so there was nothing to delete from the Cube."); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setIcon(QMessageBox::Critical); + msgBox.exec(); + } + + // Don't leave open rw -- not optimal. + cvp->cube()->reopen("r"); + } + } + + + /** + * Saves a strech to the cube. + */ + void StretchTool::saveStretchToCube() { + MdiCubeViewport *cvp = cubeViewport(); + Cube* icube = cvp->cube(); + Pvl* lab = icube->label(); + + // Create a list of existing Stretch names + QStringList namelist; + PvlObject::PvlObjectIterator objIter; + for (objIter=lab->beginObject(); objIterendObject(); objIter++) { + if (objIter->name() == "Stretch") { + PvlKeyword tempKeyword = objIter->findKeyword("Name"); + QString tempName = tempKeyword[0]; + namelist.append(tempName); + } + } + + bool ok; + QString name; + + // "Get the name for the stretch" dialog + QString text = QInputDialog::getText(m_advancedStretch, tr("Save Stretch"), + tr("Enter a name to save the stretch as:"), QLineEdit::Normal, + "stretch", &ok); + + if (ok) { + // Stretch Name Already Exists Dialog! + if (namelist.contains(text)) { + QMessageBox msgBox; + msgBox.setText(tr("Stretch Name Already Exists!")); + msgBox.setInformativeText("A stretch pair with name: \"" + text + "\" already exists and " + "the existing saved data will be overwritten. Are you sure you " + "wish to proceed?"); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setDefaultButton(QMessageBox::Cancel); + int ret = msgBox.exec(); + + switch (ret) { + case QMessageBox::Save: + break; + case QMessageBox::Cancel: + // Cancel was clicked, exit this function + return; + break; + default: + // should never be reached + return; + break; + } + } + + if (icube->isReadOnly()) { + // ReOpen cube as read/write + // If cube readonly print error + try { + cvp->cube()->reopen("rw"); + } + catch(IException &) { + cvp->cube()->reopen("r"); + QMessageBox::information((QWidget *)parent(), "Error", "Cannot open cube read/write to save stretch"); + return; + } + } + + Stretch stretch = m_advancedStretch->getGrayStretch(); + + // consider moving into Stretch::WriteInit() + stretch.Label()["Name"] = text; + stretch.Label() += PvlKeyword("StretchType", stretch.getType()); + + // Greyscale is only available option for now + stretch.Label() += PvlKeyword("Color", "Greyscale"); + + icube->write(stretch); + + // Don't leave open rw -- not optimal. + cvp->cube()->reopen("r"); + } + } + + /** * This is called when the visible area changes. */ diff --git a/isis/src/qisis/objs/StretchTool/StretchTool.h b/isis/src/qisis/objs/StretchTool/StretchTool.h index cfa9cb0f40..13a5e938ec 100644 --- a/isis/src/qisis/objs/StretchTool/StretchTool.h +++ b/isis/src/qisis/objs/StretchTool/StretchTool.h @@ -171,6 +171,9 @@ namespace Isis { protected slots: void mouseButtonRelease(QPoint p, Qt::MouseButton s); + void saveStretchToCube(); + void deleteFromCube(); + void loadStretchFromCube(); void enableRubberBandTool(); void screenPixelsChanged(); void updateHistograms(); diff --git a/isis/src/qisis/objs/StretchTool/StretchType.cpp b/isis/src/qisis/objs/StretchTool/StretchType.cpp index 87a93dba2e..2e69622a04 100644 --- a/isis/src/qisis/objs/StretchTool/StretchType.cpp +++ b/isis/src/qisis/objs/StretchTool/StretchType.cpp @@ -55,10 +55,25 @@ namespace Isis { connect(this, SIGNAL(stretchChanged()), this, SLOT(updateTable())); p_mainLayout->addWidget(p_table, 2, 0); - QPushButton *saveAsButton = new QPushButton("Save Stretch Pairs..."); + QPushButton *saveAsButton = new QPushButton("Save Stretch Pairs to File..."); connect(saveAsButton, SIGNAL(clicked(bool)), this, SLOT(savePairs())); p_mainLayout->addWidget(saveAsButton, 3, 0); + // Save/Restore strech only supported for Grayscale images. Hide buttons if in RGB. + if (name.compare("Gray") == 0) { + QPushButton *saveToCubeButton = new QPushButton("Save Stretch Pairs to Cube..."); + connect(saveToCubeButton, SIGNAL(clicked(bool)), this, SIGNAL(saveToCube())); + p_mainLayout->addWidget(saveToCubeButton, 4, 0); + + QPushButton *deleteFromCubeButton = new QPushButton("Delete Stretch Pairs from Cube..."); + connect(deleteFromCubeButton, SIGNAL(clicked(bool)), this, SIGNAL(deleteFromCube())); + p_mainLayout->addWidget(deleteFromCubeButton, 5, 0); + + QPushButton *loadStretchButton = new QPushButton("Load Saved Stretch from Cube..."); + connect(loadStretchButton, SIGNAL(clicked(bool)), this, SIGNAL(loadStretch())); + p_mainLayout->addWidget(loadStretchButton, 6, 0); + } + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); sizePolicy.setHeightForWidth(true); p_graph->setSizePolicy(sizePolicy); diff --git a/isis/src/qisis/objs/StretchTool/StretchType.h b/isis/src/qisis/objs/StretchTool/StretchType.h index 00808f2677..d54979dfa5 100644 --- a/isis/src/qisis/objs/StretchTool/StretchType.h +++ b/isis/src/qisis/objs/StretchTool/StretchType.h @@ -45,6 +45,7 @@ namespace Isis { virtual ~StretchType(); virtual Stretch getStretch(); + /** * Children must re-implement this to update their stretch pairs and GUI * elements appropriately. This could be called with a @@ -72,11 +73,14 @@ namespace Isis { signals: //! Emitted when a new Stretch object is available + void saveToCube(); + void deleteFromCube(); void stretchChanged(); - + void loadStretch(); private slots: void savePairs(); + }; };