diff --git a/app/Widgets/FilterChoice.cpp b/app/Widgets/FilterChoice.cpp index 90446487091d3e1313ecf8d9c4a8c79261a540ca..7027a270992654423e6ff9cc5d15763bf5e2ca2c 100644 --- a/app/Widgets/FilterChoice.cpp +++ b/app/Widgets/FilterChoice.cpp @@ -40,6 +40,7 @@ #include <QSpinBox> #include <QTableView> #include <QLineEdit> +#include <QCheckBox> #include <QFile> #include <QDomDocument> @@ -158,9 +159,22 @@ void FilterChoice::initUI() radioBox->layout()->addWidget(_stdResButton); radioBox->layout()->addWidget(_dblResButton); + QGroupBox* checkbox = new QGroupBox(tr("Options")); + QHBoxLayout* optLayout = new QHBoxLayout(); + _offsetButton = new QCheckBox(tr("Offset")); + _scalingButton = new QCheckBox(tr("Scaling")); + _offsetButton->setChecked(true); + _scalingButton->setChecked(true); + _offsetButton->setAutoExclusive(false); + _scalingButton->setAutoExclusive(false); + optLayout->addWidget(_offsetButton); + optLayout->addWidget(_scalingButton); + checkbox->setLayout(optLayout); + leftLayout->addWidget(stdOrCustomBox); leftLayout->addWidget(confBox); leftLayout->addWidget(radioBox); + leftLayout->addWidget(checkbox); mainLayout->addWidget(leftWidget); @@ -169,6 +183,7 @@ void FilterChoice::initUI() QObject::connect(_number, SIGNAL(valueChanged(const QString&)), this, SLOT(dataChanged(const QString&))); QObject::connect(_stdDevBox, SIGNAL(valueChanged(const QString&)), this, SLOT(dataChanged(const QString&))); QObject::connect(_filterPathSelect, SIGNAL(clicked()), this, SLOT(openFile())); + QObject::connect(_stdResButton, SIGNAL(toggled(bool)), this, SLOT(updateOptions(bool))); QWidget* rightWidget = new QWidget(); @@ -420,8 +435,13 @@ void FilterChoice::deleteFilter() if(msgBox.exec() == QMessageBox::Yes) { QString name = _blurChoices->itemText(_blurChoices->currentIndex()); - _blurChoices->setCurrentIndex(_blurChoices->currentIndex() - 1); - _blurChoices->removeItem(_blurChoices->currentIndex() + 1); + if(_blurChoices->currentIndex()==0){ + _blurChoices->setCurrentIndex(_blurChoices->currentIndex()); + _blurChoices->removeItem(_blurChoices->currentIndex()); + }else{ + _blurChoices->setCurrentIndex(_blurChoices->currentIndex()-1); + _blurChoices->removeItem(_blurChoices->currentIndex()+1); + } QFile file("filters.xml"); if(file.exists()) { @@ -588,3 +608,17 @@ void FilterChoice::updatePath(){ _path = _filterPath->text(); updateBlur(true); } + +void FilterChoice::updateOptions(bool a){ + if(a){ + _offsetButton->setChecked(true); + _scalingButton->setChecked(true); + _offsetButton->setEnabled(true); + _scalingButton->setEnabled(true); + }else{ + _offsetButton->setChecked(true); + _scalingButton->setChecked(true); + _offsetButton->setEnabled(false); + _scalingButton->setEnabled(false); + } +} diff --git a/app/Widgets/FilterChoice.h b/app/Widgets/FilterChoice.h index 42118ce0353f418928419c177993da8c3f6fa9d8..84c775a44cb7cb7eabe994c23dc945b592372520 100644 --- a/app/Widgets/FilterChoice.h +++ b/app/Widgets/FilterChoice.h @@ -37,6 +37,7 @@ #include <Algorithm/Filtering.h> #include <QRadioButton> #include <QTextEdit> +#include <QCheckBox> namespace filtrme { @@ -53,6 +54,8 @@ namespace filtrme FilterChoice(QWidget *parent); inline imagein::algorithm::Filtering* getFiltering() { return _filtering; } inline bool doubleResult() { return _dblResButton->isChecked(); } + inline bool scalingResult() { return _scalingButton->isChecked(); } + inline bool offsetResult() { return _offsetButton->isChecked(); } inline void setDoubleResult(bool c) { _dblResButton->setChecked(c); _stdResButton->setChecked(!c);} signals: @@ -68,6 +71,7 @@ namespace filtrme void updateBlur(bool); void openFile(); void updatePath(); + void updateOptions(bool); private: bool _a = true; @@ -88,6 +92,8 @@ namespace filtrme QRadioButton* _customButton; QHBoxLayout* _pathLayout; QString _path; + QCheckBox* _offsetButton; + QCheckBox* _scalingButton; QLabel* _labelNumber; QSpinBox* _number; diff --git a/app/Widgets/FilterEditor.cpp b/app/Widgets/FilterEditor.cpp index c0773199d563d8960a47f79383619d68165845b4..f4a8822bb0247ca78213f456e1c59f4c005a589a 100644 --- a/app/Widgets/FilterEditor.cpp +++ b/app/Widgets/FilterEditor.cpp @@ -31,6 +31,7 @@ #include <QSpinBox> #include <QMdiArea> #include <QPushButton> +#include <QFont> #include <QTimer> #include <QFile> @@ -38,18 +39,27 @@ #include <QtXml/QDomImplementation> #include <QtXml/QDomElement> #include <QTextStream> +#include <QFileDialog> +#include <regex> using namespace filtrme; using namespace imagein::algorithm; using namespace std; +/** + * @brief FilterEditor::FilterEditor + * + * Constructor + */ FilterEditor::FilterEditor() { _nbFilters = 1; initUI(); } - +/** + * @brief FilterEditor::initUI + */ void FilterEditor::initUI() { _filterLayout = new QVBoxLayout(); @@ -59,6 +69,20 @@ void FilterEditor::initUI() QVBoxLayout* layout = new QVBoxLayout(); QScrollArea* scroll = new QScrollArea(); + QWidget* widgetPath = new QWidget(); + QHBoxLayout* hLayoutPath = new QHBoxLayout(widgetPath); + _buttonPath = new QPushButton("..."); + _buttonPath->setFixedWidth(50); + QLabel* labelPath = new QLabel(tr("Filter file:")); + QLabel* labelPath2 = new QLabel(tr("Select a filter file:")); + _linePath = new QLineEdit(tr("No XML file selected!")); + _linePath->setReadOnly(true); + hLayoutPath->addWidget(labelPath); + hLayoutPath->addWidget(_linePath); + hLayoutPath->addWidget(labelPath2); + hLayoutPath->addWidget(_buttonPath); + _filterLayout->addWidget(widgetPath); + QHBoxLayout* hLayout = new QHBoxLayout(); QWidget* widget = new QWidget(); widget->setLayout(hLayout); @@ -66,7 +90,7 @@ void FilterEditor::initUI() QLabel *label_3; QLabel *label_4; label_3 = new QLabel(); - label_3->setText(tr("Name:")); + label_3->setText(tr("Name of your filter:")); _name = new QLineEdit(); label_4 = new QLabel(); label_4->setText(tr("Number of filters:")); @@ -86,40 +110,74 @@ void FilterEditor::initUI() buttonBox = new QDialogButtonBox(); buttonBox->setOrientation(Qt::Horizontal); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Save); -// QPushButton* applyButton = buttonBox->addButton(QString::fromStdString("Apply"), QDialogButtonBox::ApplyRole); - _filterLayout->addWidget(buttonBox); + QLabel* labelInfo = new QLabel(tr("You need to select a file and a name for your filter to save it")); + QFont* fontInfo = new QFont(labelInfo->font()); + fontInfo->setItalic(true); + labelInfo->setFont(*fontInfo); - QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(save())); - QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(cancel())); -// QObject::connect(applyButton, SIGNAL(clicked()), this, SLOT(apply())); - QObject::connect(spinBoxNbFilters, SIGNAL(valueChanged(int)), this, SLOT(nbFiltersChanged(int))); _saveButton = buttonBox->button(QDialogButtonBox::Save); _saveButton->setEnabled(false); - QObject::connect(_name, SIGNAL(textEdited(QString)), this, SLOT(nameChanged(QString))); + + QHBoxLayout* hLayoutInfo = new QHBoxLayout(); + hLayoutInfo->addWidget(labelInfo); + hLayoutInfo->addWidget(buttonBox); scroll->setWidget(widgetPrinc); scroll->setWidgetResizable(true); layout->addWidget(scroll); + layout->addLayout(hLayoutInfo); this->setLayout(layout); this->setMinimumSize(670, 470); this->setWindowTitle(tr("FilterEditor")); + + QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(save())); + QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(cancel())); + QObject::connect(spinBoxNbFilters, SIGNAL(valueChanged(int)), this, SLOT(nbFiltersChanged(int))); + QObject::connect(_name, SIGNAL(textEdited(QString)), this, SLOT(nameChanged(QString))); + QObject::connect(_buttonPath, SIGNAL(clicked()), this, SLOT(saveFile())); } +/** + * @brief FilterEditor::saveFile + */ +void FilterEditor::saveFile() { + QString file = QFileDialog::getSaveFileName(this, tr("Chose a file filter"), QString(), tr("XML Files (*.xml)")); + if(file.size()==0) return; + _linePath->setText(file.toUtf8()); +} + +/** + * @brief FilterEditor::nameChanged + * @param name + */ void FilterEditor::nameChanged(QString name) { _saveButton->setEnabled(!name.isEmpty()); } +/** + * @brief FilterEditor::save + */ void FilterEditor::save() { vector<Filter*> filters; if(_name->text() == "") { - QMessageBox msgBox(QMessageBox::Critical, tr("Error!"), tr("Your filter has to have a name to be saved.")); + QMessageBox msgBox(QMessageBox::Critical, tr("Error!"), tr("Your filter needs a name to be saved.")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.exec(); + return; + } + //condition regex sur le format du fichier .xml + if(!regex_match(_linePath->text().toStdString(),regex("(.*).xml$"))){ + QMessageBox msgBox(QMessageBox::Critical, tr("Error!"), tr("Your file needs .xml format.")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); return; } + + bool ok; filters = validFilters(&ok); if(ok) { @@ -128,9 +186,13 @@ void FilterEditor::save() } } +/** + * @brief FilterEditor::saveXML + * @param filtersToSave + */ void FilterEditor::saveXML(vector<Filter*> filtersToSave) { - QFile file("filters.xml"); + QFile file(_linePath->text()); // document QDomImplementation impl = QDomDocument().implementation(); // document with document type @@ -163,8 +225,8 @@ void FilterEditor::saveXML(vector<Filter*> filtersToSave) // We know how to treat appearance and geometry if (e.attribute("name") == _name->text()) { - QMessageBox msgBox(QMessageBox::Warning, tr("Warning!"), tr("This filter name is already use.")); - msgBox.setInformativeText(tr("Do you want to replace it?")); + QMessageBox msgBox(QMessageBox::Warning, tr("Warning!"), tr("This filter name is already used.")); + msgBox.setInformativeText(tr("Do you want to overwrite it?")); msgBox.setStandardButtons(QMessageBox::No|QMessageBox::Yes); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); @@ -222,13 +284,18 @@ void FilterEditor::saveXML(vector<Filter*> filtersToSave) } } +/** + * @brief FilterEditor::validFilters + * @param ok + * @return + */ vector<Filter*> FilterEditor::validFilters(bool* ok) { vector<Filter*> filters; *ok = true; - for(int i = 1; i <= _nbFilters; i++) + for(int i = 2; i <= 1+_nbFilters; i++) { FilterEditorItem* item = (FilterEditorItem*)_filterLayout->itemAt(i)->widget(); Filter* f = item->validFilter(); @@ -237,8 +304,8 @@ vector<Filter*> FilterEditor::validFilters(bool* ok) else { *ok = false; - QMessageBox msgBox(QMessageBox::Critical, tr("Error!"), tr("Every square have to be completed by int value.")); - msgBox.setInformativeText(tr("Filter %1 isn't ok.").arg(i)); + QMessageBox msgBox(QMessageBox::Critical, tr("Error!"), tr("Every square has to be filled with an integer.")); + msgBox.setInformativeText(tr("Filter %1 is not a valid filter.").arg(i-1)); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); @@ -249,6 +316,11 @@ vector<Filter*> FilterEditor::validFilters(bool* ok) return filters; } +/** + * @brief FilterEditor::cancel + * + * Manages popup window that comes when you press cancel. + */ void FilterEditor::cancel() { QMessageBox msgBox(QMessageBox::Warning, tr("Warning!"), tr("Unsaved changes will be lost.")); @@ -257,20 +329,30 @@ void FilterEditor::cancel() msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); if(ret == QMessageBox::Yes) -// QTimer::singleShot(200, this, SLOT(quit())); this->reject(); } + +/** + * @brief FilterEditor::nbFiltersChanged + * @param nb + */ void FilterEditor::nbFiltersChanged(const int nb) { if(_nbFilters < nb) { - FilterEditorItem* item = new FilterEditorItem(); - _filterLayout->insertWidget(_nbFilters + 1, item); + while(_nbFilters!= nb){ + _nbFilters++; + FilterEditorItem* item = new FilterEditorItem(); + _filterLayout->insertWidget(_nbFilters, item); + } } else if(_nbFilters > nb) { - _filterLayout->removeItem(_filterLayout->itemAt(_nbFilters)); + while(_nbFilters != nb){ + _filterLayout->removeItem(_filterLayout->itemAt(_nbFilters)); + _nbFilters--; + } } _nbFilters = nb; } diff --git a/app/Widgets/FilterEditor.h b/app/Widgets/FilterEditor.h index 3be4281b0f77477f077a69820cd0026caa67b3cd..32e6014367d10fbb1055cd2496e81c704436b365 100644 --- a/app/Widgets/FilterEditor.h +++ b/app/Widgets/FilterEditor.h @@ -53,12 +53,15 @@ namespace filtrme void cancel(); void nbFiltersChanged(const int); void nameChanged(QString); + void saveFile(); private: void initUI(); void saveXML(std::vector<imagein::algorithm::Filter*> filter); std::vector<imagein::algorithm::Filter*> validFilters(bool* ok); + QPushButton* _buttonPath; + QLineEdit* _linePath; QVBoxLayout* _filterLayout; QLineEdit* _name; int _nbFilters; diff --git a/app/Widgets/FilterEditorItem.cpp b/app/Widgets/FilterEditorItem.cpp index 1e8f18f5ba762e8d6d873ad6801a3715b8a88450..c57c569389def3018e779775db21c928f7864d9f 100644 --- a/app/Widgets/FilterEditorItem.cpp +++ b/app/Widgets/FilterEditorItem.cpp @@ -40,6 +40,9 @@ using namespace std; using namespace filtrme; using namespace imagein::algorithm; +/** + * @brief FilterEditorItem::FilterEditorItem + */ FilterEditorItem::FilterEditorItem() { _width = 3; @@ -47,7 +50,9 @@ FilterEditorItem::FilterEditorItem() initUI(); } - +/** + * @brief FilterEditorItem::initUI + */ void FilterEditorItem::initUI() { QSpinBox *spinBoxWidth; @@ -94,28 +99,49 @@ void FilterEditorItem::initUI() } +/** + * @brief FilterEditorItem::widthChanged + * @param width + */ void FilterEditorItem::widthChanged(const int width) { - if(_width < width) - emit(insertColumn(width-_width)); - else - emit(removeColumn(_width-width)); - - _width = width; + cout << "diff de width: " << width << " | " << _width << "\n"; + if(_width < width){ + while(_width!=width){ + emit(insertColumn(width-_width)); + _width++; + } + } + else{ + while(_width!=width){ + emit(removeColumn(_width-width)); + _width--; + } + } _filter->resizeColumnsToContents(); } void FilterEditorItem::heightChanged(const int height) { - if(_height < height) - emit(insertRow(height-_height)); - else - emit(removeRow(_height-height)); - - _height = height; + if(_height < height){ + while(_height!=height){ + emit(insertRow(height-_height)); + _height++; + } + } + else{ + while(_height!=height){ + emit(removeRow(_height-height)); + _height--; + } + } _filter->resizeRowsToContents(); } +/** + * @brief FilterEditorItem::validFilter + * @return + */ imagein::algorithm::Filter* FilterEditorItem::validFilter() { Filter* filter = new Filter(_width, _height);