16#include <QApplication>
17#include <QDesktopWidget>
18#include <QStringListModel>
21#include "ui_categoryselector.h"
29 QSet<int> SelectedRows_;
34 : QStringListModel { &selector }
35 , Selector_ { selector }
39 QVariant
headerData (
int section, Qt::Orientation orientation,
int role)
const override
41 if (role != Qt::DisplayRole || orientation != Qt::Horizontal || section)
47 Qt::ItemFlags
flags (
const QModelIndex& index)
const override
49 return (QStringListModel::flags (index) & ~Qt::ItemIsEditable) | Qt::ItemIsUserCheckable;
52 QVariant
data (
const QModelIndex& index,
int role)
const override
54 if (role == Qt::CheckStateRole)
55 return SelectedRows_.contains (index.row ()) ? Qt::Checked : Qt::Unchecked;
57 return QStringListModel::data (index, role);
60 bool setData (
const QModelIndex& index,
const QVariant& value,
int role)
override
62 if (role != Qt::CheckStateRole)
65 if (value.value<Qt::CheckState> () == Qt::Checked)
66 SelectedRows_ << index.row ();
68 SelectedRows_.remove (index.row ());
69 emit dataChanged (index, index, { Qt::CheckStateRole });
70 Selector_.NotifyTagsSelection ();
76 const int size = stringList ().size ();
80 SelectedRows_.reserve (size);
81 for (
int i = 0; i < size; ++i)
84 emit dataChanged (index (0), index (size - 1), { Qt::CheckStateRole });
86 Selector_.NotifyTagsSelection ();
91 const int size = stringList ().size ();
95 SelectedRows_.clear ();
96 emit dataChanged (index (0), index (size - 1), { Qt::CheckStateRole });
98 Selector_.NotifyTagsSelection ();
103 if (header == Header_)
106 Header_ = std::move (header);
107 emit headerDataChanged (Qt::Horizontal, 0, 0);
117 setWindowTitle (tr (
"Tags selector"));
118 setWindowFlags (Qt::Dialog | Qt::WindowStaysOnTopHint);
121 Ui_->Tree_->setModel (&Model_);
123 const auto& avail = QApplication::desktop ()->availableGeometry (
this);
124 setMinimumHeight (avail.height () / 3 * 2);
126 const auto all =
new QAction (tr (
"Select all"),
this);
127 all->setProperty (
"ActionIcon",
"edit-select-all");
133 const auto none =
new QAction (tr (
"Select none"),
this);
134 none->setProperty (
"ActionIcon",
"edit-select-none");
140 Ui_->Tree_->addAction (all);
141 Ui_->Tree_->addAction (none);
143 Ui_->Tree_->setContextMenuPolicy (Qt::ActionsContextMenu);
150 Model_.SetHeader (caption);
155 auto guard = DisableNotifications ();
159 Model_.setStringList (tags);
160 Model_.SelectNone ();
165 return Model_.stringList ();
170 const auto& allTags = Model_.stringList ();
172 QStringList selected;
173 selected.reserve (selectedIdxes.size ());
174 for (
const auto idx : selectedIdxes)
175 selected << allTags [idx];
183 const auto& rowCount = Model_.stringList ().size ();
184 for (
int i = 0; i < rowCount; ++i)
186 const auto state = Model_.index (i).data (Qt::CheckStateRole).value<Qt::CheckState> ();
187 if (state == Qt::Checked)
196 auto guard = DisableNotifications (
false);
198 const auto& allTags = Model_.stringList ();
199 const auto rowCount = allTags.size ();
200 for (
int i = 0; i < rowCount; ++i)
202 const auto state = tags.contains (allTags [i]) ?
205 Model_.setData (Model_.index (i), state, Qt::CheckStateRole);
224 Ui_->ButtonsBox_->setVisible (
false);
227 Ui_->ButtonsBox_->setStandardButtons (QDialogButtonBox::Close);
228 Ui_->ButtonsBox_->setVisible (
true);
231 Ui_->ButtonsBox_->setStandardButtons (QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
232 Ui_->ButtonsBox_->setVisible (
true);
239 QWidget::moveEvent (e);
240 QPoint pos = e->pos ();
241 QRect avail = QApplication::desktop ()->availableGeometry (
this);
243 if (pos.x () + width () > avail.width ())
244 dx = width () + pos.x () - avail.width ();
245 if (pos.y () + height () > avail.height () &&
246 height () < avail.height ())
247 dy = height () + pos.y () - avail.height ();
250 move (pos - QPoint (dx, dy));
260 Model_.SelectNone ();
265 auto guard = DisableNotifications (
false);
269 void CategorySelector::NotifyTagsSelection ()
271 if (NotificationsEnabled_)
277 auto prevValue = NotificationsEnabled_;
278 NotificationsEnabled_ =
false;
281 NotificationsEnabled_ = prevValue;
283 NotifyTagsSelection ();
void SetSelections(const QStringList &subset)
Selects some of the items.
void SetButtonsMode(ButtonsMode)
Sets the buttons mode.
QList< int > GetSelectedIndexes() const
Gets the indexes of the selected items.
QStringList GetSelections() const
Gets selected items.
CategorySelector(QWidget *parent=nullptr)
Constructor.
QStringList GetPossibleSelections() const
QString GetSeparator() const
Returns the separator for the tags.
void moveEvent(QMoveEvent *) override
Checks whether after the move event the selector won't be beoynd the screen. if it would,...
void SelectNone()
Deselects all variants.
void SetCaption(const QString &caption)
Sets the caption of this selector.
void SetSeparator(const QString &)
Sets the separator for the tags.
virtual void SetPossibleSelections(QStringList selections, bool sort=true)
Sets possible selections.
void SetSelectionsFromString(const QString &newText)
Notifies CategorySelector about logical selection changes.
void SelectAll()
Selects all variants.
void tagsSelectionChanged(const QStringList &newSelections)
Indicates that selections have changed.
detail::ScopeGuard< F > MakeScopeGuard(const F &f)
Returns an object performing passed function on scope exit.
QString GetDefaultTagsSeparator()
detail::ScopeGuard< detail::DefaultScopeGuardDeleter > DefaultScopeGuard