aboutsummaryrefslogtreecommitdiffstats
path: root/desktop-widgets
diff options
context:
space:
mode:
Diffstat (limited to 'desktop-widgets')
-rw-r--r--desktop-widgets/CMakeLists.txt2
-rw-r--r--desktop-widgets/filterconstraintwidget.cpp472
-rw-r--r--desktop-widgets/filterconstraintwidget.h70
3 files changed, 544 insertions, 0 deletions
diff --git a/desktop-widgets/CMakeLists.txt b/desktop-widgets/CMakeLists.txt
index 1de8914ee..a9a6a59a7 100644
--- a/desktop-widgets/CMakeLists.txt
+++ b/desktop-widgets/CMakeLists.txt
@@ -77,6 +77,8 @@ set(SUBSURFACE_INTERFACE
divesiteimportdialog.h
downloadfromdivecomputer.cpp
downloadfromdivecomputer.h
+ filterconstraintwidget.cpp
+ filterconstraintwidget.h
filterwidget2.cpp
filterwidget2.h
findmovedimagesdialog.cpp
diff --git a/desktop-widgets/filterconstraintwidget.cpp b/desktop-widgets/filterconstraintwidget.cpp
new file mode 100644
index 000000000..8cc8f130a
--- /dev/null
+++ b/desktop-widgets/filterconstraintwidget.cpp
@@ -0,0 +1,472 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "filterconstraintwidget.h"
+#include "starwidget.h"
+#include "core/pref.h"
+#include "desktop-widgets/preferences/preferencesdialog.h"
+#include "qt-models/cleanertablemodel.h" // for trashIcon()
+#include "qt-models/filterconstraintmodel.h"
+
+#include <QComboBox>
+#include <QDateEdit>
+#include <QDoubleSpinBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QListWidget>
+#include <QPushButton>
+#include <QTimeEdit>
+
+// Helper function to get enums through Qt's variants
+template<typename T>
+static T getEnum(const QModelIndex &idx, int role)
+{
+ return static_cast<T>(idx.data(role).value<int>());
+}
+
+// Helper function, which creates a combo box for a given model role
+// or returns null if the model doesn't return a proper list.
+static QComboBox *makeCombo(const QModelIndex &index, int role)
+{
+ QStringList list = index.data(role).value<QStringList>();
+ if (list.isEmpty())
+ return nullptr;
+ QComboBox *res = new QComboBox;
+ res->addItems(list);
+ res->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ return res;
+}
+
+// Helper function, which creates a multiple choice list for a given model role
+// or returns null if the model doesn't return a proper list.
+static QListWidget *makeMultipleChoice(const QModelIndex &index, int role)
+{
+ QStringList list = index.data(role).value<QStringList>();
+ if (list.isEmpty())
+ return nullptr;
+ QListWidget *res = new QListWidget;
+ res->addItems(list);
+ res->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ return res;
+}
+
+// Helper function to create a floating point spin box.
+// Currently, this allows a large range of values.
+// The limits should be adapted to the constraint in question.
+static QDoubleSpinBox *makeSpinBox(int numDecimals)
+{
+ QDoubleSpinBox *res = new QDoubleSpinBox;
+ res->setRange(-10000.0, 10000.0);
+ res->setDecimals(numDecimals);
+ res->setSingleStep(pow(10.0, -numDecimals));
+ return res;
+}
+
+// Helper function to create a date edit widget
+static QDateEdit *makeDateEdit()
+{
+ QDateEdit *res = new QDateEdit;
+ res->setCalendarPopup(true);
+ res->setTimeSpec(Qt::UTC);
+ return res;
+}
+
+// Helper function to create a date edit widget
+static QTimeEdit *makeTimeEdit()
+{
+ QTimeEdit *res = new QTimeEdit;
+ res->setTimeSpec(Qt::UTC);
+ return res;
+}
+
+// Helper function, which creates a label with a given string
+// or returns null if the string is empty.
+static QLabel *makeLabel(const QString &s)
+{
+ if (s.isEmpty())
+ return nullptr;
+ return new QLabel(s);
+}
+
+// Helper function, which sets the index of a combo box for a given
+// model role, if the combo box is not null.
+static void setIndex(QComboBox *w, const QModelIndex &index, int role)
+{
+ if (!w)
+ return;
+ w->setCurrentIndex(index.data(role).value<int>());
+}
+
+// Helper function to add a widget to a layout if it is non-null
+static void addWidgetToLayout(QWidget *w, QHBoxLayout *l)
+{
+ if (w) {
+ l->addWidget(w);
+ l->setAlignment(w, Qt::AlignLeft);
+ }
+}
+
+// Helper functions that show / hide non-null widgets
+static void showWidget(QWidget *w)
+{
+ if (w)
+ w->show();
+}
+
+// Helper functions that show / hide non-null widgets
+static void hideWidget(QWidget *w)
+{
+ if (w)
+ w->hide();
+}
+
+// Helper function to create datatimes from either a single date widget,
+// or a combination of a date and a time widget.
+static QDateTime makeDateTime(const QDateEdit *d, const QTimeEdit *t)
+{
+ if (!d)
+ return QDateTime();
+ if (!t)
+ return d->dateTime();
+ QDateTime res = d->dateTime();
+ res.setTime(t->time());
+ return res;
+}
+
+FilterConstraintWidget::FilterConstraintWidget(FilterConstraintModel *modelIn, const QModelIndex &index, QGridLayout *layoutIn) : QObject(layoutIn),
+ layout(layoutIn),
+ model(modelIn),
+ row(index.row()),
+ type(getEnum<filter_constraint_type>(index, FilterConstraintModel::TYPE_ROLE))
+{
+ rangeLayout.reset(new QHBoxLayout);
+ rangeLayout->setAlignment(Qt::AlignLeft);
+
+ trashButton.reset(new QPushButton(QIcon(trashIcon()), QString()));
+ trashButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ trashButton->setToolTip(tr("Click to remove this constraint"));
+ connect(trashButton.get(), &QPushButton::clicked, this, &FilterConstraintWidget::trash);
+
+ typeLabel.reset(new QLabel(index.data(FilterConstraintModel::TYPE_DISPLAY_ROLE).value<QString>()));
+ typeLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+ QString unitString = index.data(FilterConstraintModel::UNIT_ROLE).value<QString>();
+ negate.reset(makeCombo(index, FilterConstraintModel::NEGATE_COMBO_ROLE));
+ connect(negate.get(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FilterConstraintWidget::negateEdited);
+ stringMode.reset(makeCombo(index, FilterConstraintModel::STRING_MODE_COMBO_ROLE));
+ rangeMode.reset(makeCombo(index, FilterConstraintModel::RANGE_MODE_COMBO_ROLE));
+ multipleChoice.reset(makeMultipleChoice(index, FilterConstraintModel::MULTIPLE_CHOICE_LIST_ROLE));
+ bool isStarWidget = index.data(FilterConstraintModel::IS_STAR_WIDGET_ROLE).value<bool>();
+ bool hasDateWidget = index.data(FilterConstraintModel::HAS_DATE_WIDGET_ROLE).value<bool>();
+ bool hasTimeWidget = index.data(FilterConstraintModel::HAS_TIME_WIDGET_ROLE).value<bool>();
+ bool hasSpinBox = rangeMode && !stringMode && !hasDateWidget && !hasTimeWidget && !isStarWidget && !multipleChoice;
+ unitFrom.reset(makeLabel(unitString));
+ unitTo.reset(makeLabel(unitString));
+ if (stringMode) {
+ string.reset(new QLineEdit);
+ string->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+ }
+ int numDecimals = hasSpinBox ? index.data(FilterConstraintModel::NUM_DECIMALS_ROLE).value<int>() : 0;
+ if (string)
+ connect(string.get(), &QLineEdit::textEdited, this, &FilterConstraintWidget::stringEdited);
+
+ if (multipleChoice)
+ connect(multipleChoice.get(), &QListWidget::itemSelectionChanged, this, &FilterConstraintWidget::multipleChoiceEdited);
+
+ if (stringMode)
+ connect(stringMode.get(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FilterConstraintWidget::stringModeEdited);
+
+ if (rangeMode) {
+ toLabel.reset(new QLabel(tr("and")));
+ connect(rangeMode.get(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, &FilterConstraintWidget::rangeModeEdited);
+ }
+
+ if (hasSpinBox) {
+ spinBoxFrom.reset(makeSpinBox(numDecimals));
+ spinBoxTo.reset(makeSpinBox(numDecimals));
+ connect(spinBoxFrom.get(), QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &FilterConstraintWidget::fromEditedFloat);
+ connect(spinBoxTo.get(), QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &FilterConstraintWidget::toEditedFloat);
+ }
+
+ if (isStarWidget) {
+ starFrom.reset(new StarWidget);
+ starTo.reset(new StarWidget);
+ connect(starFrom.get(), &StarWidget::valueChanged, this, &FilterConstraintWidget::fromEditedInt);
+ connect(starTo.get(), &StarWidget::valueChanged, this, &FilterConstraintWidget::toEditedInt);
+ }
+
+ if (hasDateWidget) {
+ dateFrom.reset(makeDateEdit());
+ dateTo.reset(makeDateEdit());
+ connect(dateFrom.get(), &QDateEdit::dateTimeChanged, this, &FilterConstraintWidget::fromEditedTimestamp);
+ connect(dateTo.get(), &QDateEdit::dateTimeChanged, this, &FilterConstraintWidget::toEditedTimestamp);
+ }
+
+ if (hasTimeWidget) {
+ timeFrom.reset(makeTimeEdit());
+ timeTo.reset(makeTimeEdit());
+ connect(timeFrom.get(), &QTimeEdit::dateTimeChanged, this, &FilterConstraintWidget::fromEditedTimestamp);
+ connect(timeTo.get(), &QTimeEdit::dateTimeChanged, this, &FilterConstraintWidget::toEditedTimestamp);
+ }
+
+ addWidgetToLayout(string.get(), rangeLayout.get());
+ addWidgetToLayout(starFrom.get(), rangeLayout.get());
+ addWidgetToLayout(spinBoxFrom.get(), rangeLayout.get());
+ addWidgetToLayout(dateFrom.get(), rangeLayout.get());
+ addWidgetToLayout(timeFrom.get(), rangeLayout.get());
+ addWidgetToLayout(unitFrom.get(), rangeLayout.get());
+ addWidgetToLayout(toLabel.get(), rangeLayout.get());
+ addWidgetToLayout(starTo.get(), rangeLayout.get());
+ addWidgetToLayout(spinBoxTo.get(), rangeLayout.get());
+ addWidgetToLayout(dateTo.get(), rangeLayout.get());
+ addWidgetToLayout(timeTo.get(), rangeLayout.get());
+ addWidgetToLayout(unitTo.get(), rangeLayout.get());
+ rangeLayout->addStretch();
+
+ // Update the widget if the settings changed to reflect new units.
+ connect(PreferencesDialog::instance(), &PreferencesDialog::settingsChanged, this, &FilterConstraintWidget::update);
+
+ addToLayout();
+ update();
+}
+
+FilterConstraintWidget::~FilterConstraintWidget()
+{
+}
+
+void FilterConstraintWidget::addToLayout()
+{
+ // Careful: this must mirror the code in removeFromLayout() or weird things will happen.
+
+ // Note: we add 2 to row, because the first and second row of the filter layout
+ // are reserved for the title line and the fulltext widget!
+ int layoutRow = row + 2;
+ layout->addWidget(trashButton.get(), layoutRow, 0);
+ if (!stringMode && !rangeMode && !multipleChoice) {
+ // If there are no string or range modes, we rearrange to "negate / type" to get
+ // a layout of the type "is not planned" or "is not logged", where the subject is
+ // implicitly "dive". This presumes SVO grammar, but so does the rest of the layout.
+ layout->addWidget(negate.get(), layoutRow, 1, Qt::AlignLeft);
+ layout->addWidget(typeLabel.get(), layoutRow, 2, Qt::AlignLeft);
+ } else {
+ layout->addWidget(negate.get(), layoutRow, 2, Qt::AlignLeft);
+ layout->addWidget(typeLabel.get(), layoutRow, 1, Qt::AlignLeft);
+ }
+ if (stringMode)
+ layout->addWidget(stringMode.get(), layoutRow, 3, Qt::AlignLeft);
+ else if (rangeMode)
+ layout->addWidget(rangeMode.get(), layoutRow, 3, Qt::AlignLeft);
+ else if (multipleChoice)
+ layout->addWidget(multipleChoice.get(), layoutRow, 3, 1, 2, Qt::AlignLeft); // column span 2
+ if (!multipleChoice)
+ layout->addLayout(rangeLayout.get(), layoutRow, 4, Qt::AlignLeft);
+}
+
+void FilterConstraintWidget::removeFromLayout()
+{
+ // Careful: this must mirror the code in addToLayout() or weird things will happen.
+ layout->removeWidget(trashButton.get());
+ layout->removeWidget(negate.get());
+ layout->removeWidget(typeLabel.get());
+ if (stringMode)
+ layout->removeWidget(stringMode.get());
+ else if (rangeMode)
+ layout->removeWidget(rangeMode.get());
+ else if (multipleChoice)
+ layout->removeWidget(multipleChoice.get());
+ if (!multipleChoice)
+ layout->removeItem(rangeLayout.get());
+}
+
+void FilterConstraintWidget::update()
+{
+ // The user might have changed the date and/or time format. Let's update the widgets.
+ if (dateFrom)
+ dateFrom->setDisplayFormat(prefs.date_format);
+ if (dateTo)
+ dateTo->setDisplayFormat(prefs.date_format);
+ if (timeFrom)
+ timeFrom->setDisplayFormat(prefs.time_format);
+ if (timeTo)
+ timeTo->setDisplayFormat(prefs.time_format);
+
+ QModelIndex idx = model->index(row, 0);
+ setIndex(negate.get(), idx, FilterConstraintModel::NEGATE_INDEX_ROLE);
+ setIndex(stringMode.get(), idx, FilterConstraintModel::STRING_MODE_INDEX_ROLE);
+ setIndex(rangeMode.get(), idx, FilterConstraintModel::RANGE_MODE_INDEX_ROLE);
+ if (string)
+ string->setText(idx.data(FilterConstraintModel::STRING_ROLE).value<QString>());
+ if (starFrom)
+ starFrom->setCurrentStars(idx.data(FilterConstraintModel::INTEGER_FROM_ROLE).value<int>());
+ if (starTo)
+ starTo->setCurrentStars(idx.data(FilterConstraintModel::INTEGER_TO_ROLE).value<int>());
+ if (spinBoxFrom)
+ spinBoxFrom->setValue(idx.data(FilterConstraintModel::FLOAT_FROM_ROLE).value<double>());
+ if (spinBoxTo)
+ spinBoxTo->setValue(idx.data(FilterConstraintModel::FLOAT_TO_ROLE).value<double>());
+ if (dateFrom) {
+ QDateTime dateTime = idx.data(FilterConstraintModel::TIMESTAMP_FROM_ROLE).value<QDateTime>();
+ dateFrom->setDateTime(dateTime);
+ if (timeFrom)
+ timeFrom->setDateTime(dateTime);
+ } else if (timeFrom) {
+ timeFrom->setTime(idx.data(FilterConstraintModel::TIME_FROM_ROLE).value<QTime>());
+ }
+ if (dateTo) {
+ QDateTime dateTime = idx.data(FilterConstraintModel::TIMESTAMP_TO_ROLE).value<QDateTime>();
+ dateTo->setDateTime(dateTime);
+ if (timeTo)
+ timeTo->setDateTime(dateTime);
+ } else if (timeTo) {
+ timeTo->setTime(idx.data(FilterConstraintModel::INTEGER_TO_ROLE).value<QTime>());
+ }
+ if (multipleChoice) {
+ uint64_t bits = idx.data(FilterConstraintModel::MULTIPLE_CHOICE_ROLE).value<uint64_t>();
+ for (int i = 0; i < multipleChoice->count(); ++i)
+ multipleChoice->item(i)->setSelected(bits & (1 << i));
+ }
+
+ // Update the unit strings in case the locale was changed
+ if (unitFrom || unitTo) {
+ QString unitString = idx.data(FilterConstraintModel::UNIT_ROLE).value<QString>();
+ unitFrom->setText(unitString);
+ unitTo->setText(unitString);
+ }
+
+ if (rangeMode) {
+ switch(getEnum<filter_constraint_range_mode>(idx, FilterConstraintModel::RANGE_MODE_ROLE)) {
+ case FILTER_CONSTRAINT_LESS:
+ hideWidget(toLabel.get());
+ hideWidget(starFrom.get());
+ hideWidget(spinBoxFrom.get());
+ hideWidget(dateFrom.get());
+ hideWidget(timeFrom.get());
+ hideWidget(unitFrom.get());
+ showWidget(starTo.get());
+ showWidget(spinBoxTo.get());
+ showWidget(dateTo.get());
+ showWidget(timeTo.get());
+ showWidget(unitTo.get());
+ break;
+ case FILTER_CONSTRAINT_EQUAL:
+ case FILTER_CONSTRAINT_GREATER:
+ hideWidget(toLabel.get());
+ showWidget(starFrom.get());
+ showWidget(spinBoxFrom.get());
+ showWidget(dateFrom.get());
+ showWidget(timeFrom.get());
+ showWidget(unitFrom.get());
+ hideWidget(starTo.get());
+ hideWidget(spinBoxTo.get());
+ hideWidget(dateTo.get());
+ hideWidget(timeTo.get());
+ hideWidget(unitTo.get());
+ break;
+ case FILTER_CONSTRAINT_RANGE:
+ showWidget(toLabel.get());
+ showWidget(starFrom.get());
+ showWidget(spinBoxFrom.get());
+ showWidget(dateFrom.get());
+ showWidget(timeFrom.get());
+ showWidget(unitFrom.get());
+ showWidget(starTo.get());
+ showWidget(spinBoxTo.get());
+ showWidget(dateTo.get());
+ showWidget(timeTo.get());
+ showWidget(unitTo.get());
+ break;
+ }
+ }
+}
+
+void FilterConstraintWidget::stringEdited(const QString &s)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, s, FilterConstraintModel::STRING_ROLE);
+}
+
+void FilterConstraintWidget::multipleChoiceEdited()
+{
+ // Turn selected items into bit-field
+ uint64_t bits = 0;
+ for (const QModelIndex &idx: multipleChoice->selectionModel()->selectedIndexes()) {
+ int row = idx.row();
+ if (row >= 64)
+ qWarning("FilterConstraint: multiple-choice with more than 64 entries not supported");
+ bits |= 1 << row;
+ }
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, qulonglong(bits), FilterConstraintModel::MULTIPLE_CHOICE_ROLE);
+}
+
+void FilterConstraintWidget::fromEditedInt(int i)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, i, FilterConstraintModel::INTEGER_FROM_ROLE);
+}
+
+void FilterConstraintWidget::toEditedInt(int i)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, i, FilterConstraintModel::INTEGER_TO_ROLE);
+}
+
+void FilterConstraintWidget::fromEditedFloat(double f)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, f, FilterConstraintModel::FLOAT_FROM_ROLE);
+}
+
+void FilterConstraintWidget::toEditedFloat(double f)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, f, FilterConstraintModel::FLOAT_TO_ROLE);
+}
+
+void FilterConstraintWidget::fromEditedTimestamp(const QDateTime &datetime)
+{
+ QModelIndex idx = model->index(row, 0);
+ if (!dateFrom && timeFrom)
+ model->setData(idx, timeFrom->time(), FilterConstraintModel::TIME_FROM_ROLE);
+ else
+ model->setData(idx, makeDateTime(dateFrom.get(), timeFrom.get()), FilterConstraintModel::TIMESTAMP_FROM_ROLE);
+}
+
+void FilterConstraintWidget::toEditedTimestamp(const QDateTime &datetime)
+{
+ QModelIndex idx = model->index(row, 0);
+ if (!dateTo && timeTo)
+ model->setData(idx, timeTo->time(), FilterConstraintModel::TIME_TO_ROLE);
+ else
+ model->setData(idx, makeDateTime(dateTo.get(), timeTo.get()), FilterConstraintModel::TIMESTAMP_TO_ROLE);
+}
+
+void FilterConstraintWidget::negateEdited(int i)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, i, FilterConstraintModel::NEGATE_INDEX_ROLE);
+}
+
+void FilterConstraintWidget::rangeModeEdited(int i)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, i, FilterConstraintModel::RANGE_MODE_INDEX_ROLE);
+ update(); // Range mode may change the shown widgets
+}
+
+void FilterConstraintWidget::stringModeEdited(int i)
+{
+ QModelIndex idx = model->index(row, 0);
+ model->setData(idx, i, FilterConstraintModel::STRING_MODE_INDEX_ROLE);
+}
+
+void FilterConstraintWidget::moveToRow(int rowIn)
+{
+ removeFromLayout();
+ row = rowIn;
+ addToLayout();
+}
+
+void FilterConstraintWidget::trash()
+{
+ model->deleteConstraint(row);
+}
diff --git a/desktop-widgets/filterconstraintwidget.h b/desktop-widgets/filterconstraintwidget.h
new file mode 100644
index 000000000..60e613780
--- /dev/null
+++ b/desktop-widgets/filterconstraintwidget.h
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef FILTERCONSTRAINTWIDGET_H
+#define FILTERCONSTRAINTWIDGET_H
+
+#include "core/filterconstraint.h"
+#include <QWidget>
+#include <memory>
+
+class FilterConstraintModel;
+class QComboBox;
+class QDateEdit;
+class QDoubleSpinBox;
+class QGridLayout;
+class QHBoxLayout;
+class QLabel;
+class QLineEdit;
+class QListWidget;
+class QPushButton;
+class QTimeEdit;
+class StarWidget;
+
+// Technically, this is not a single widget, but numerous widgets,
+// which are added to the row of a QGridLayout
+class FilterConstraintWidget : public QObject {
+ Q_OBJECT
+public:
+ FilterConstraintWidget(FilterConstraintModel *model, const QModelIndex &index, QGridLayout *layout);
+ ~FilterConstraintWidget();
+ void moveToRow(int row); // call if the row of the widget has changed.
+ // this will update the index used to access the model as well as the position in the layout
+ void update();
+private
+slots:
+ void trash();
+ void stringEdited(const QString &s);
+ void multipleChoiceEdited();
+ void negateEdited(int index);
+ void rangeModeEdited(int index);
+ void stringModeEdited(int index);
+ void fromEditedInt(int i);
+ void toEditedInt(int i);
+ void fromEditedFloat(double f);
+ void toEditedFloat(double f);
+ void fromEditedTimestamp(const QDateTime &datetime);
+ void toEditedTimestamp(const QDateTime &datetime);
+private:
+ QGridLayout *layout;
+ FilterConstraintModel *model;
+ int row;
+ const filter_constraint_type type; // we don't support changing the type
+ void addToLayout();
+ void removeFromLayout();
+
+ std::unique_ptr<QHBoxLayout> rangeLayout;
+ std::unique_ptr<QPushButton> trashButton;
+ std::unique_ptr<QLabel> typeLabel;
+ std::unique_ptr<QComboBox> negate;
+ std::unique_ptr<QComboBox> stringMode;
+ std::unique_ptr<QComboBox> rangeMode;
+ std::unique_ptr<QListWidget> multipleChoice;
+ std::unique_ptr<QLineEdit> string;
+ std::unique_ptr<StarWidget> starFrom, starTo;
+ std::unique_ptr<QDoubleSpinBox> spinBoxFrom, spinBoxTo;
+ std::unique_ptr<QDateEdit> dateFrom, dateTo;
+ std::unique_ptr<QTimeEdit> timeFrom, timeTo;
+ std::unique_ptr<QLabel> unitFrom, unitTo;
+ std::unique_ptr<QLabel> toLabel;
+};
+
+#endif