diff --git a/Grinder/Grinder.pro b/Grinder/Grinder.pro index 6a72011ec3d4670fbd326134745bf1e09f7e5543..2a55167a7c1d4643ecd7685da8ce9cb32590ce31 100644 --- a/Grinder/Grinder.pro +++ b/Grinder/Grinder.pro @@ -434,7 +434,12 @@ SOURCES += \ ui/properties/editors/ImageReferenceSelectionPropertyEditor.cpp \ engine/processors/BatchInputProcessor.cpp \ pipeline/blocks/BatchInputBlock.cpp \ - pipeline/blocks/BatchInputProviderBlock.cpp + pipeline/blocks/BatchInputProviderBlock.cpp \ + common/properties/types/PathProperty.cpp \ + common/properties/types/FileProperty.cpp \ + ui/properties/editors/FilePropertyEditor.cpp \ + ui/properties/editors/PathPropertyEditor.cpp \ + ui/dlg/BrowseDialog.cpp HEADERS += \ ui/mainwnd/GrinderWindow.h \ @@ -931,7 +936,12 @@ HEADERS += \ ui/properties/editors/ImageReferenceSelectionPropertyEditor.h \ engine/processors/BatchInputProcessor.h \ pipeline/blocks/BatchInputBlock.h \ - pipeline/blocks/BatchInputProviderBlock.h + pipeline/blocks/BatchInputProviderBlock.h \ + common/properties/types/PathProperty.h \ + common/properties/types/FileProperty.h \ + ui/properties/editors/FilePropertyEditor.h \ + ui/properties/editors/PathPropertyEditor.h \ + ui/dlg/BrowseDialog.h FORMS += \ ui/mainwnd/GrinderWindow.ui \ @@ -951,7 +961,8 @@ FORMS += \ ui/task/tasks/BaristaTrainingTaskWidget.ui \ ui/task/tasks/BaristaInferenceTaskWidget.ui \ ui/task/tasks/CommandInterfaceTaskWidget.ui \ - ui/task/tasks/CommandInterfaceTestTaskWidget.ui + ui/task/tasks/CommandInterfaceTestTaskWidget.ui \ + ui/dlg/BrowseDialog.ui RESOURCES += \ res/Grinder.qrc diff --git a/Grinder/Version.h b/Grinder/Version.h index c96b8f8c91c415862a725dcd1bef5da997043ddb..5793409e859813d70da158b8f0882edcb053717a 100644 --- a/Grinder/Version.h +++ b/Grinder/Version.h @@ -10,14 +10,14 @@ #define GRNDR_INFO_TITLE "Grinder" #define GRNDR_INFO_COPYRIGHT "Copyright (c) WWU Muenster" -#define GRNDR_INFO_DATE "06.8.2019" +#define GRNDR_INFO_DATE "07.8.2019" #define GRNDR_INFO_COMPANY "WWU Muenster" #define GRNDR_INFO_WEBSITE "http://www.uni-muenster.de" #define GRNDR_VERSION_MAJOR 0 #define GRNDR_VERSION_MINOR 14 #define GRNDR_VERSION_REVISION 0 -#define GRNDR_VERSION_BUILD 366 +#define GRNDR_VERSION_BUILD 367 namespace grndr { diff --git a/Grinder/common/properties/StandardProperties.h b/Grinder/common/properties/StandardProperties.h index 3d87ecc1ef458aac54ca0f700f604f773c1130fd..43d1a231b7b48d4baae5e037370b5b57db2ecf8d 100644 --- a/Grinder/common/properties/StandardProperties.h +++ b/Grinder/common/properties/StandardProperties.h @@ -18,6 +18,8 @@ #include "types/SizeProperty.h" #include "types/ColorProperty.h" #include "types/EnumProperty.h" +#include "types/PathProperty.h" +#include "types/FileProperty.h" #include "constraints/RangeConstraint.h" #include "constraints/EvenOddConstraint.h" diff --git a/Grinder/common/properties/types/FileProperty.cpp b/Grinder/common/properties/types/FileProperty.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01e0e5fc1ee37cad0fb789bbd095084cd14fd64e --- /dev/null +++ b/Grinder/common/properties/types/FileProperty.cpp @@ -0,0 +1,13 @@ +/****************************************************************************** + * File: FileProperty.cpp + * Date: 07.8.2019 + *****************************************************************************/ + +#include "Grinder.h" +#include "FileProperty.h" +#include "ui/properties/editors/FilePropertyEditor.h" + +QWidget* FileProperty::createEditor(QWidget* parent) +{ + return new FilePropertyEditor{this, _saveMode, _fileFilter, parent}; +} diff --git a/Grinder/common/properties/types/FileProperty.h b/Grinder/common/properties/types/FileProperty.h new file mode 100644 index 0000000000000000000000000000000000000000..c2fc11346c40319b5189380eb8ed465c75941ba4 --- /dev/null +++ b/Grinder/common/properties/types/FileProperty.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * File: FileProperty.h + * Date: 07.8.2019 + *****************************************************************************/ + +#ifndef FILEPROPERTY_H +#define FILEPROPERTY_H + +#include "common/properties/Property.h" + +namespace grndr +{ + class FileProperty : public Property<QString> + { + Q_OBJECT + + public: + using Property<value_type>::Property; + + public: + void setSaveMode(bool saveMode = true) { _saveMode = saveMode; } + void setFileFilter(QString fileFilter) { _fileFilter = fileFilter; } + + public: + virtual QWidget* createEditor(QWidget* parent) override; + + private: + bool _saveMode{false}; + QString _fileFilter{"All files (*.*)"}; + }; +} + +#endif diff --git a/Grinder/common/properties/types/PathProperty.cpp b/Grinder/common/properties/types/PathProperty.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d370e6797bd88996106276d5e85d4f99fa2df25b --- /dev/null +++ b/Grinder/common/properties/types/PathProperty.cpp @@ -0,0 +1,13 @@ +/****************************************************************************** + * File: PathProperty.cpp + * Date: 07.8.2019 + *****************************************************************************/ + +#include "Grinder.h" +#include "PathProperty.h" +#include "ui/properties/editors/PathPropertyEditor.h" + +QWidget* PathProperty::createEditor(QWidget* parent) +{ + return new PathPropertyEditor{this, parent}; +} diff --git a/Grinder/common/properties/types/PathProperty.h b/Grinder/common/properties/types/PathProperty.h new file mode 100644 index 0000000000000000000000000000000000000000..09d1c0aad5839d674d77441eb1b9739ff7cc4452 --- /dev/null +++ b/Grinder/common/properties/types/PathProperty.h @@ -0,0 +1,25 @@ +/****************************************************************************** + * File: PathProperty.h + * Date: 07.8.2019 + *****************************************************************************/ + +#ifndef PATHPROPERTY_H +#define PATHPROPERTY_H + +#include "common/properties/Property.h" + +namespace grndr +{ + class PathProperty : public Property<QString> + { + Q_OBJECT + + public: + using Property<value_type>::Property; + + public: + virtual QWidget* createEditor(QWidget* parent) override; + }; +} + +#endif diff --git a/Grinder/pipeline/blocks/SaveImageBlock.cpp b/Grinder/pipeline/blocks/SaveImageBlock.cpp index 997f0193857010961248382b204b8efffc88bc89..541497c1614c6cbe823b3c423e506d68a7aa05ab 100644 --- a/Grinder/pipeline/blocks/SaveImageBlock.cpp +++ b/Grinder/pipeline/blocks/SaveImageBlock.cpp @@ -26,7 +26,7 @@ void SaveImageBlock::createProperties() setPropertyGroup("General"); - _directory = createProperty<StringProperty>(PropertyID::Directory, "Directory", ""); + _directory = createProperty<PathProperty>(PropertyID::Directory, "Directory", ""); directory()->setDescription("The output directory. If using a relative path, images will be written relative to the input image directory; leave empty to use the input image directory."); setPropertyGroup("Image files"); diff --git a/Grinder/pipeline/blocks/SaveImageBlock.h b/Grinder/pipeline/blocks/SaveImageBlock.h index fa658111c125f682a1467ddae2027630e0289f84..d753991674591991923c1b12a837d6b0caf6dae9 100644 --- a/Grinder/pipeline/blocks/SaveImageBlock.h +++ b/Grinder/pipeline/blocks/SaveImageBlock.h @@ -26,8 +26,8 @@ namespace grndr virtual std::unique_ptr<ProcessorBase> createProcessor() const override; public: - auto directory() { return dynamic_cast<StringProperty*>(_directory.get()); } - auto directory() const { return dynamic_cast<const StringProperty*>(_directory.get()); } + auto directory() { return dynamic_cast<PathProperty*>(_directory.get()); } + auto directory() const { return dynamic_cast<const PathProperty*>(_directory.get()); } auto filenamePrefix() { return dynamic_cast<StringProperty*>(_filenamePrefix.get()); } auto filenamePrefix() const { return dynamic_cast<const StringProperty*>(_filenamePrefix.get()); } auto filenameSuffix() { return dynamic_cast<StringProperty*>(_filenameSuffix.get()); } diff --git a/Grinder/project/properties/ImageReferenceSelectionProperty.cpp b/Grinder/project/properties/ImageReferenceSelectionProperty.cpp index 63d28bb1a99865769c6654b1218517cfa172dc39..caa126835080e540d446ed083924429efa0a51f6 100644 --- a/Grinder/project/properties/ImageReferenceSelectionProperty.cpp +++ b/Grinder/project/properties/ImageReferenceSelectionProperty.cpp @@ -31,9 +31,9 @@ QString ImageReferenceSelectionProperty::toString() const if (!imageNames.isEmpty()) { if (imageNames.size() == 1) - return QString{"1 image (%1)"}.arg(imageNames.join(", ")); + return "1 image"; else - return QString{"%2 images (%1)"}.arg(imageNames.join(", ")).arg(imageNames.size()); + return QString{"%1 images"}.arg(imageNames.size()); } else return "No images"; diff --git a/Grinder/res/Grinder.qrc b/Grinder/res/Grinder.qrc index 827f12488f96068d010e136bd12997c9d5626f97..2be16db5fa5bb7259338ec5df96b6280ce1f8fae 100644 --- a/Grinder/res/Grinder.qrc +++ b/Grinder/res/Grinder.qrc @@ -75,6 +75,7 @@ <file>icons/overlay.png</file> <file>icons/overlay-tagged.png</file> <file>icons/batch.png</file> + <file>icons/folder-out-interface-symbol.png</file> </qresource> <qresource prefix="/"> <file>css/global.css</file> diff --git a/Grinder/res/Resources.h b/Grinder/res/Resources.h index 78f61cb66265f547d248653fcd1102448f07f30f..c1f1539e9b9f63007cc0588dbba6cfad6943ac19 100644 --- a/Grinder/res/Resources.h +++ b/Grinder/res/Resources.h @@ -47,6 +47,9 @@ #define FILE_ICON_WARNING ":/icons/icons/triangular-warning-sign.png" #define FILE_ICON_START ":/icons/icons/start.png" #define FILE_ICON_PAUSE ":/icons/icons/pause.png" +#define FILE_ICON_FOLDER ":/icons/icons/folder-with-information.png" +#define FILE_ICON_OPEN ":/icons/icons/folder-out-interface-symbol.png" +#define FILE_ICON_SAVE ":/icons/icons/floppy-disk-digital-data-storage-or-save-interface-symbol.png" #define FILE_ICON_MOVEUP ":/icons/icons/arrow-up.png" #define FILE_ICON_MOVEDOWN ":/icons/icons/arrow-down.png" diff --git a/Grinder/ui/dlg/BrowseDialog.cpp b/Grinder/ui/dlg/BrowseDialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f898b551554d98082ab5d8ae1c79ad4989249df --- /dev/null +++ b/Grinder/ui/dlg/BrowseDialog.cpp @@ -0,0 +1,71 @@ +/****************************************************************************** + * File: BrowseDialog.cpp + * Date: 07.8.2019 + *****************************************************************************/ + +#include "Grinder.h" +#include "BrowseDialog.h" +#include "ui_BrowseDialog.h" + +BrowseDialog::BrowseDialog(QWidget *parent) : QDialog(parent, Qt::Dialog|Qt::WindowTitleHint|Qt::WindowCloseButtonHint), + ui{new Ui::BrowseDialog} +{ + setupUi(); +} + +BrowseDialog::~BrowseDialog() +{ + delete ui; +} + +QString BrowseDialog::browse(BrowseType browseType, QString caption, QString value, QIcon icon, bool* accepted, QString fileFilter) +{ + _browseType = browseType; + _fileFilter = fileFilter; + + setWindowTitle(caption); + ui->lblCaption->setText(caption + ":"); + ui->txtInput->setText(value); + ui->btnBrowse->setIcon(icon); + + if (accepted) + *accepted = false; + + if (QDialog::exec() == QDialog::Accepted) + { + if (accepted) + *accepted = true; + + return ui->txtInput->text(); + } + + return ""; +} + +void BrowseDialog::setupUi() +{ + ui->setupUi(this); +} + +void BrowseDialog::on_btnBrowse_clicked() +{ + QString value; + + switch (_browseType) + { + case BrowseType::Directory: + value = QFileDialog::getExistingDirectory(this, "Select directory"); + break; + + case BrowseType::OpenFile: + value = QFileDialog::getOpenFileName(this, "Select file", {}, _fileFilter); + break; + + case BrowseType::SaveFile: + value = QFileDialog::getSaveFileName(this, "Select file", {}, _fileFilter); + break; + } + + if (!value.isEmpty()) + ui->txtInput->setText(value); +} diff --git a/Grinder/ui/dlg/BrowseDialog.h b/Grinder/ui/dlg/BrowseDialog.h new file mode 100644 index 0000000000000000000000000000000000000000..3e19e51edfcc6436247b3e3d560eb9ef358e97e5 --- /dev/null +++ b/Grinder/ui/dlg/BrowseDialog.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * File: BrowseDialog.h + * Date: 07.8.2019 + *****************************************************************************/ + +#ifndef BROWSEDIALOG_H +#define BROWSEDIALOG_H + +#include <QDialog> + +namespace Ui +{ + class BrowseDialog; +} + +namespace grndr +{ + class BrowseDialog : public QDialog + { + Q_OBJECT + + public: + enum class BrowseType + { + Directory, + OpenFile, + SaveFile, + }; + + public: + BrowseDialog(QWidget *parent = nullptr); + virtual ~BrowseDialog(); + + public: + QString browse(BrowseType browseType, QString caption, QString value, QIcon icon, bool* accepted = nullptr, QString fileFilter = ""); + + private: + void setupUi(); + Ui::BrowseDialog *ui; + + private slots: + void on_btnBrowse_clicked(); + + private: + BrowseType _browseType{BrowseType::Directory}; + QString _fileFilter{""}; + }; +} + +#endif diff --git a/Grinder/ui/dlg/BrowseDialog.ui b/Grinder/ui/dlg/BrowseDialog.ui new file mode 100644 index 0000000000000000000000000000000000000000..b7fb4bec6111530c9ce4999d526770fd9d584922 --- /dev/null +++ b/Grinder/ui/dlg/BrowseDialog.ui @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>BrowseDialog</class> + <widget class="QDialog" name="BrowseDialog"> + <property name="windowModality"> + <enum>Qt::ApplicationModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>353</width> + <height>112</height> + </rect> + </property> + <property name="windowTitle"> + <string>Browse...</string> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetFixedSize</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="lblCaption"> + <property name="text"> + <string>Caption:</string> + </property> + <property name="buddy"> + <cstring>txtInput</cstring> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLineEdit" name="txtInput"> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QToolButton" name="btnBrowse"> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset resource="../../res/Grinder.qrc"> + <normaloff>:/icons/icons/basic-text-format.png</normaloff>:/icons/icons/basic-text-format.png</iconset> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>200</width> + <height>17</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources> + <include location="../../res/Grinder.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>BrowseDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>92</y> + </hint> + <hint type="destinationlabel"> + <x>6</x> + <y>9</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>BrowseDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>75</x> + <y>82</y> + </hint> + <hint type="destinationlabel"> + <x>15</x> + <y>56</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/Grinder/ui/properties/editors/FilePropertyEditor.cpp b/Grinder/ui/properties/editors/FilePropertyEditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b3fc1ffa59a32b847d0f23130d0a26c8827996aa --- /dev/null +++ b/Grinder/ui/properties/editors/FilePropertyEditor.cpp @@ -0,0 +1,30 @@ +/****************************************************************************** + * File: FilePropertyEditor.cpp + * Date: 07.8.2019 + *****************************************************************************/ + +#include "Grinder.h" +#include "FilePropertyEditor.h" +#include "ui/dlg/BrowseDialog.h" +#include "res/Resources.h" + +FilePropertyEditor::FilePropertyEditor(FileProperty* property, bool saveMode, QString fileFilter, QWidget* parent) : DialogPropertyEditor(property, parent), + _saveMode{saveMode}, _fileFilter{fileFilter} +{ + +} + +void FilePropertyEditor::invokeDialog() +{ + BrowseDialog dlg{this}; + bool accepted = false; + QString value; + + if (_saveMode) + value = dlg.browse(BrowseDialog::BrowseType::SaveFile, "Select file", getPropertyValue(), QIcon{FILE_ICON_SAVE}, &accepted, _fileFilter); + else + value = dlg.browse(BrowseDialog::BrowseType::OpenFile, "Select file", getPropertyValue(), QIcon{FILE_ICON_OPEN}, &accepted, _fileFilter); + + if (accepted) + setPropertyValue(value); +} diff --git a/Grinder/ui/properties/editors/FilePropertyEditor.h b/Grinder/ui/properties/editors/FilePropertyEditor.h new file mode 100644 index 0000000000000000000000000000000000000000..8f4f255a423fd8620ab050e70dde1055536bd2bc --- /dev/null +++ b/Grinder/ui/properties/editors/FilePropertyEditor.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * File: FilePropertyEditor.h + * Date: 07.8.2019 + *****************************************************************************/ + +#ifndef FILEPROPERTYEDITOR_H +#define FILEPROPERTYEDITOR_H + +#include "DialogPropertyEditor.h" +#include "common/properties/types/FileProperty.h" + +namespace grndr +{ + class FilePropertyEditor : public DialogPropertyEditor<FileProperty> + { + Q_OBJECT + + public: + FilePropertyEditor(FileProperty* property, bool saveMode, QString fileFilter = "All files (*.*)", QWidget *parent = nullptr); + + protected: + virtual void invokeDialog() override; + + private: + bool _saveMode{false}; + QString _fileFilter; + }; +} + +#endif diff --git a/Grinder/ui/properties/editors/PathPropertyEditor.cpp b/Grinder/ui/properties/editors/PathPropertyEditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..289df66534af1039231484adb5e6de5d5269a92f --- /dev/null +++ b/Grinder/ui/properties/editors/PathPropertyEditor.cpp @@ -0,0 +1,24 @@ +/****************************************************************************** + * File: PathPropertyEditor.cpp + * Date: 07.8.2019 + *****************************************************************************/ + +#include "Grinder.h" +#include "PathPropertyEditor.h" +#include "ui/dlg/BrowseDialog.h" +#include "res/Resources.h" + +PathPropertyEditor::PathPropertyEditor(PathProperty* property, QWidget* parent) : DialogPropertyEditor(property, parent) +{ + +} + +void PathPropertyEditor::invokeDialog() +{ + BrowseDialog dlg{this}; + bool accepted = false; + QString value = dlg.browse(BrowseDialog::BrowseType::Directory, "Select directory", getPropertyValue(), QIcon{FILE_ICON_FOLDER}, &accepted); + + if (accepted) + setPropertyValue(value); +} diff --git a/Grinder/ui/properties/editors/PathPropertyEditor.h b/Grinder/ui/properties/editors/PathPropertyEditor.h new file mode 100644 index 0000000000000000000000000000000000000000..7a523cc965153f6ee997ab69d555efd1faa056c3 --- /dev/null +++ b/Grinder/ui/properties/editors/PathPropertyEditor.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * File: PathPropertyEditor.h + * Date: 07.8.2019 + *****************************************************************************/ + +#ifndef PATHPROPERTYEDITOR_H +#define PATHPROPERTYEDITOR_H + +#include "DialogPropertyEditor.h" +#include "common/properties/types/PathProperty.h" + +namespace grndr +{ + class PathPropertyEditor : public DialogPropertyEditor<PathProperty> + { + Q_OBJECT + + public: + PathPropertyEditor(PathProperty* property, QWidget *parent = nullptr); + + protected: + virtual void invokeDialog() override; + }; +} + +#endif