diff --git a/DngPropertiesDialog.cpp b/DngPropertiesDialog.cpp index c0b3959..9444d95 100644 --- a/DngPropertiesDialog.cpp +++ b/DngPropertiesDialog.cpp @@ -26,13 +26,15 @@ #include #include #include -#include +#include #include "DngPropertiesDialog.hpp" namespace hdrmerge { DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f), SaveOptions() { + loadDefaultOptions(); + QVBoxLayout * layout = new QVBoxLayout(this); QWidget * bpsSelector = new QWidget(this); @@ -40,14 +42,14 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f) bpsSelectorLayout->setMargin(0); QButtonGroup * bpsGroup = new QButtonGroup(this); const char * buttonLabels[] = { "16", "24", "32" }; + int bpsIndex = (bps - 16) / 8;; for (int i = 0; i < 3; ++i) { QRadioButton * button = new QRadioButton(buttonLabels[i], this); - button->setChecked(i == 0); + button->setChecked(i == bpsIndex); bpsGroup->addButton(button, i); bpsSelectorLayout->addWidget(button); } - connect(bpsGroup, SIGNAL(buttonClicked( int)), this, SLOT(setBps(int))); - bps = 16; + connect(bpsGroup, SIGNAL(buttonClicked(int)), this, SLOT(setBps(int))); QWidget * previewSelector = new QWidget(this); QHBoxLayout * previewSelectorLayout = new QHBoxLayout(previewSelector); @@ -56,12 +58,11 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f) const char * previewLabels[] = { "Full", "Half", "None" }; for (int i = 0; i < 3; ++i) { QRadioButton * button = new QRadioButton(tr(previewLabels[i]), this); - button->setChecked(i == 0); + button->setChecked(i == (2 - previewSize)); previewGroup->addButton(button, 2 - i); previewSelectorLayout->addWidget(button); } connect(previewGroup, SIGNAL(buttonClicked( int)), this, SLOT(setPreviewSize(int))); - previewSize = 2; QCheckBox * saveMaskFile = new QCheckBox(tr("Save"), this); @@ -70,12 +71,19 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f) maskFileSelectorLayout->setMargin(0); maskFileEditor = new QLineEdit(maskFileSelector); maskFileEditor->setMinimumWidth(200); + maskFileEditor->setToolTip(tr("You can use the following tokens:") + "\n" + + "- %if " + tr("for the file name of the least exposed image.") + "\n" + + "- %id " + tr("for the directory name of the least exposed image.") + "\n" + + "- %of " + tr("for the file name of the result image.") + "\n" + + "- %od " + tr("for the directory name of the result image.")); + maskFileEditor->setText(maskFileName.c_str()); QPushButton * showFileDialog = new QPushButton("...", maskFileSelector); connect(showFileDialog, SIGNAL(clicked(bool)), this, SLOT(setMaskFileName())); maskFileSelectorLayout->addWidget(maskFileEditor); maskFileSelectorLayout->addWidget(showFileDialog); connect(saveMaskFile, SIGNAL(stateChanged(int)), this, SLOT(setMaskFileSelectorEnabled(int))); - maskFileSelector->setEnabled(false); + saveMaskFile->setChecked(saveMask); + maskFileSelector->setEnabled(saveMask); QWidget * formWidget = new QWidget(this); QFormLayout * formLayout = new QFormLayout(formWidget); @@ -86,6 +94,9 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f) formWidget->setLayout(formLayout); layout->addWidget(formWidget, 1); + saveOptions = new QCheckBox(tr("Save these options as the default values.")); + layout->addWidget(saveOptions, 0, Qt::AlignLeft); + QWidget * buttons = new QWidget(this); QHBoxLayout * buttonsLayout = new QHBoxLayout(buttons); QPushButton * acceptButton = new QPushButton(tr("Accept"), this); @@ -103,12 +114,28 @@ DngPropertiesDialog::DngPropertiesDialog(QWidget * parent, Qt::WindowFlags f) void DngPropertiesDialog::accept() { - maskFileName = maskFileSelector->isEnabled() ? - QDir::toNativeSeparators(maskFileEditor->text()).toUtf8().constData() : ""; + saveMask = maskFileSelector->isEnabled(); + maskFileName = QDir::toNativeSeparators(maskFileEditor->text()).toUtf8().constData(); + if (saveOptions->isChecked()) { + QSettings settings; + settings.setValue("bps", bps); + settings.setValue("previewSize", previewSize); + settings.setValue("saveMask", saveMask); + settings.setValue("maskFileName", maskFileName.c_str()); + } QDialog::accept(); } +void DngPropertiesDialog::loadDefaultOptions() { + QSettings settings; + bps = settings.value("bps", 16).toInt(); + previewSize = settings.value("previewSize", 2).toInt(); + saveMask = settings.value("saveMask", false).toBool(); + maskFileName = settings.value("maskFileName", "%od/%of_mask.png").toString().toUtf8().constData(); +} + + void DngPropertiesDialog::setBps(int i) { switch (i) { case 0: bps = 16; break; diff --git a/DngPropertiesDialog.hpp b/DngPropertiesDialog.hpp index 18f10e1..41d3349 100644 --- a/DngPropertiesDialog.hpp +++ b/DngPropertiesDialog.hpp @@ -25,6 +25,7 @@ #include #include +#include #include "LoadSaveOptions.hpp" namespace hdrmerge { @@ -50,9 +51,12 @@ private slots: private: Q_OBJECT + + void loadDefaultOptions(); QLineEdit * maskFileEditor; QWidget * maskFileSelector; + QCheckBox * saveOptions; }; } // namespace hdrmerge diff --git a/ImageStack.cpp b/ImageStack.cpp index 526da78..c879047 100644 --- a/ImageStack.cpp +++ b/ImageStack.cpp @@ -106,9 +106,10 @@ int ImageStack::save(const SaveOptions & options, ProgressIndicator & progress) writer.setBitsPerSample(options.bps); writer.setPreviewWidth((options.previewSize * width) / 2); writer.write(options.fileName); - if (!options.maskFileName.empty()) { - Log::msg(Log::DEBUG, "Saving mask to ", options.maskFileName); - mask.writeMaskImage(options.maskFileName); + if (options.saveMask) { + string name = replaceArguments(options.maskFileName, options.fileName); + Log::msg(Log::DEBUG, "Saving mask to ", name); + mask.writeMaskImage(name); } } @@ -222,3 +223,37 @@ string ImageStack::buildOutputFileName() const { } return name; } + + +string ImageStack::replaceArguments(const string & maskFileName, const string & outFileName) { + string result = maskFileName; + const char * specs[4] = { + "%if", + "%id", + "%of", + "%od" + }; + string names[4]; + string inFileName = images.back()->getMetaData().fileName; + size_t index = inFileName.find_last_of('/'); + if (index != string::npos) { + names[1] = inFileName.substr(0, index); + names[0] = inFileName.substr(index + 1); + } else { + names[0] = inFileName; + } + index = outFileName.find_last_of('/'); + if (index != string::npos) { + names[3] = outFileName.substr(0, index); + names[2] = outFileName.substr(index + 1); + } else { + names[2] = outFileName; + } + // Replace specifiers + for (int i = 0; i < 4; ++i) { + while ((index = result.find(specs[i])) != string::npos) { + result.replace(index, 3, names[i]); + } + } + return result; +} diff --git a/ImageStack.hpp b/ImageStack.hpp index 703fa61..5902777 100644 --- a/ImageStack.hpp +++ b/ImageStack.hpp @@ -95,6 +95,8 @@ class ImageStack { size_t width; size_t height; uint8_t toneCurve[65536]; + + std::string replaceArguments(const std::string & maskFileName, const std::string & outFileName); }; } // namespace hdrmerge diff --git a/LoadSaveOptions.hpp b/LoadSaveOptions.hpp index 243a4b1..668a82a 100644 --- a/LoadSaveOptions.hpp +++ b/LoadSaveOptions.hpp @@ -40,8 +40,9 @@ struct SaveOptions { int bps; int previewSize; std::string fileName; + bool saveMask; std::string maskFileName; - SaveOptions() : bps(16), previewSize(0) {} + SaveOptions() : bps(16), previewSize(0), saveMask(false) {} }; } // namespace hdrmerge diff --git a/MainWindow.cpp b/MainWindow.cpp index f9a9d1b..f90fc3b 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -338,7 +338,6 @@ void MainWindow::saveResult() { fileName += ".dng"; } DngPropertiesDialog dpd(this); - dpd.setMaskFileName((images->buildOutputFileName() + "_mask.png").c_str()); if (dpd.exec()) { dpd.fileName = fileName; ProgressDialog pd(this); diff --git a/hdrmerge_es.ts b/hdrmerge_es.ts index c1b6af1..1491b3a 100644 --- a/hdrmerge_es.ts +++ b/hdrmerge_es.ts @@ -207,6 +207,30 @@ Save Guardar + + Save these options as the default values. + Guardar estas opciones como los valores por defecto. + + + You can use the following tokens: + Puede utilizar los siguientes símbolos: + + + for the file name of the least exposed image. + para el nombre de fichero de la imagen menos expuesta. + + + for the directory name of the least exposed image. + para el nombre de directorio de la imagen menos expuesta. + + + for the file name of the result image. + para el nombre de fichero de la imagen resultado. + + + for the directory name of the result image. + para el nombre de directorio de la imagen resultado. + hdrmerge::MainWindow