8#include "tagselectioncombobox.h"
13#include <KCheckableProxyModel>
14#include <QAbstractItemView>
16#include <QItemSelectionModel>
21#include <KLocalizedString>
30template<
typename List>
34 for (
int i = 0; i < selection.
size(); ++i) {
35 const auto indexes = selection.
at(i).indexes();
36 std::transform(indexes.cbegin(), indexes.cend(), std::back_inserter(tags), [role](
const auto &idx) {
37 return idx.model()->data(idx, role).template value<typename List::value_type>();
45 const auto tags = tagsFromSelection<Tag::List>(selection, TagModel::TagRole);
48 std::transform(tags.cbegin(), tags.cend(), std::back_inserter(names), std::bind(&Tag::name, std::placeholders::_1));
54class Akonadi::TagSelectionComboBoxPrivate
67 template<
typename Selection,
typename Comp>
68 void setSelection(
const Selection &entries, Comp &&cmp)
71 mPendingSelection = entries;
75 const auto forEachIndex = [
this, entries, cmp](
auto &&func) {
76 for (
int i = 0, cnt = tagModel->rowCount(); i < cnt; ++i) {
77 const auto index = tagModel->index(i, 0);
78 const auto tag = tagModel->data(index, TagModel::TagRole).value<
Tag>();
79 if (std::any_of(entries.cbegin(), entries.cend(), std::bind(cmp, tag, std::placeholders::_1))) {
80 if (func(index) == Break) {
89 forEachIndex([&selection](
const QModelIndex &index) {
102 void toggleItem(
const QModelIndex &tagModelIndex)
const
112 void setCheckable(
bool checkable)
115 selectionModel = std::make_unique<QItemSelectionModel>(tagModel.get(), q);
116 checkableProxy = std::make_unique<KCheckableProxyModel>(q);
117 checkableProxy->setSourceModel(tagModel.get());
118 checkableProxy->setSelectionModel(selectionModel.get());
120 tagModel->setParent(
nullptr);
122 tagModel->setParent(q);
134 const auto selection = selectionModel->selection();
135 q->setEditText(getEditText(selection));
136 Q_EMIT q->selectionChanged(tagsFromSelection<Tag::List>(selection, TagModel::TagRole));
139 if (q->view()->isVisible()) {
140 const auto index = tagModel->index(i, 0);
147 tagModel->setParent(
nullptr);
149 tagModel->setParent(q);
161 selectionModel.reset();
162 checkableProxy.reset();
166 std::unique_ptr<QItemSelectionModel> selectionModel;
167 std::unique_ptr<TagModel> tagModel;
168 std::unique_ptr<KCheckableProxyModel> checkableProxy;
170 bool mCheckable =
false;
171 bool mAllowHide =
true;
172 bool mModelReady =
false;
174 std::variant<std::monostate, Tag::List, QStringList> mPendingSelection;
180TagSelectionComboBox::TagSelectionComboBox(
QWidget *parent)
182 , d(new TagSelectionComboBoxPrivate(this))
184 auto monitor =
new Monitor(
this);
186 monitor->setTypeMonitored(Monitor::Tags);
188 d->tagModel = std::make_unique<TagModel>(monitor,
this);
189 connect(d->tagModel.get(), &TagModel::populated,
this, [
this]() {
190 d->mModelReady = true;
191 if (auto list = std::get_if<Tag::List>(&d->mPendingSelection)) {
193 }
else if (
auto slist = std::get_if<QStringList>(&d->mPendingSelection)) {
194 setSelection(*slist);
196 d->mPendingSelection = std::monostate{};
199 d->setCheckable(d->mCheckable);
202TagSelectionComboBox::~TagSelectionComboBox() =
default;
204void TagSelectionComboBox::setCheckable(
bool checkable)
206 if (d->mCheckable != checkable) {
207 d->mCheckable = checkable;
208 d->setCheckable(d->mCheckable);
212bool TagSelectionComboBox::checkable()
const
214 return d->mCheckable;
217void TagSelectionComboBox::setSelection(
const Tag::List &tags)
219 d->setSelection(tags, [](
const Tag &a,
const Tag &b) {
220 return a.name() == b.name();
224void TagSelectionComboBox::setSelection(
const QStringList &tagNames)
226 d->setSelection(tagNames, [](
const Tag &a,
const QString &b) {
227 return a.name() == b;
231Tag::List TagSelectionComboBox::selection()
const
233 if (!d->selectionModel) {
236 return tagsFromSelection<Tag::List>(d->selectionModel->selection(), TagModel::TagRole);
239QStringList TagSelectionComboBox::selectionNames()
const
241 if (!d->selectionModel) {
244 return tagsFromSelection<QStringList>(d->selectionModel->selection(), TagModel::NameRole);
247void TagSelectionComboBox::hidePopup()
252 d->mAllowHide =
true;
255void TagSelectionComboBox::keyPressEvent(
QKeyEvent *event)
257 switch (
event->key()) {
274bool TagSelectionComboBox::eventFilter(
QObject *receiver,
QEvent *event)
276 switch (
event->type()) {
291 d->mAllowHide =
false;
303#include "moc_tagselectioncombobox.cpp"
Monitors an item or collection for changes.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
void activated(int index)
void setCurrentIndex(int index)
void setEditable(bool editable)
virtual bool event(QEvent *event) override
QLineEdit * lineEdit() const const
virtual void setModel(QAbstractItemModel *model)
QAbstractItemView * view() const const
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void setAlignment(Qt::Alignment flag)
void setPlaceholderText(const QString &)
const_reference at(qsizetype i) const const
void push_back(parameter_type value)
void reserve(qsizetype size)
qsizetype size() const const
QString createSeparatedList(const QStringList &list) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool eventFilter(QObject *watched, QEvent *event)
void installEventFilter(QObject *filterObj)
void removeEventFilter(QObject *obj)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)