File indexing completed on 2025-01-05 04:47:08
0001 /* 0002 SPDX-FileCopyrightText: 2008 Ingo Klöcker <kloecker@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "collectionrequester.h" 0008 #include "collectionfetchjob.h" 0009 #include "collectionfetchscope.h" 0010 #include "entitydisplayattribute.h" 0011 0012 #include <KLocalizedString> 0013 #include <KStandardShortcut> 0014 #include <QLineEdit> 0015 0016 #include <QAction> 0017 #include <QEvent> 0018 #include <QHBoxLayout> 0019 #include <QPushButton> 0020 0021 using namespace Akonadi; 0022 0023 class Akonadi::CollectionRequesterPrivate 0024 { 0025 public: 0026 explicit CollectionRequesterPrivate(CollectionRequester *parent) 0027 : q(parent) 0028 { 0029 } 0030 0031 ~CollectionRequesterPrivate() 0032 { 0033 } 0034 0035 void fetchCollection(const Collection &collection); 0036 0037 void init(); 0038 0039 // slots 0040 void _k_slotOpenDialog(); 0041 void _k_collectionReceived(KJob *job); 0042 void _k_collectionsNamesReceived(KJob *job); 0043 0044 CollectionRequester *const q; 0045 Collection collection; 0046 QLineEdit *edit = nullptr; 0047 QPushButton *button = nullptr; 0048 CollectionDialog *collectionDialog = nullptr; 0049 }; 0050 0051 void CollectionRequesterPrivate::fetchCollection(const Collection &collection) 0052 { 0053 auto job = new CollectionFetchJob(collection, Akonadi::CollectionFetchJob::Base, q); 0054 job->setProperty("OriginalCollectionId", collection.id()); 0055 job->fetchScope().setAncestorRetrieval(CollectionFetchScope::All); 0056 QObject::connect(job, &CollectionFetchJob::finished, q, [this](KJob *job) { 0057 _k_collectionReceived(job); 0058 }); 0059 } 0060 0061 void CollectionRequesterPrivate::_k_collectionReceived(KJob *job) 0062 { 0063 auto fetch = qobject_cast<CollectionFetchJob *>(job); 0064 if (!fetch) { 0065 return; 0066 } 0067 if (fetch->collections().size() == 1) { 0068 Collection::List chain; 0069 Collection currentCollection = fetch->collections().at(0); 0070 while (currentCollection.isValid()) { 0071 chain << currentCollection; 0072 currentCollection = Collection(currentCollection.parentCollection()); 0073 } 0074 0075 auto namesFetch = new CollectionFetchJob(chain, CollectionFetchJob::Base, q); 0076 namesFetch->setProperty("OriginalCollectionId", job->property("OriginalCollectionId")); 0077 namesFetch->fetchScope().setAncestorRetrieval(CollectionFetchScope::Parent); 0078 QObject::connect(namesFetch, &CollectionFetchJob::finished, q, [this](KJob *job) { 0079 _k_collectionsNamesReceived(job); 0080 }); 0081 } else { 0082 _k_collectionsNamesReceived(job); 0083 } 0084 } 0085 0086 void CollectionRequesterPrivate::_k_collectionsNamesReceived(KJob *job) 0087 { 0088 auto fetch = qobject_cast<CollectionFetchJob *>(job); 0089 const qint64 originalId = fetch->property("OriginalCollectionId").toLongLong(); 0090 0091 QMap<qint64, Collection> names; 0092 const Akonadi::Collection::List lstCols = fetch->collections(); 0093 for (const Collection &collection : lstCols) { 0094 names.insert(collection.id(), collection); 0095 } 0096 0097 QStringList namesList; 0098 Collection currentCollection = names.take(originalId); 0099 while (currentCollection.isValid()) { 0100 namesList.prepend(currentCollection.displayName()); 0101 currentCollection = names.take(currentCollection.parentCollection().id()); 0102 } 0103 edit->setText(namesList.join(QLatin1Char('/'))); 0104 } 0105 0106 void CollectionRequesterPrivate::init() 0107 { 0108 auto hbox = new QHBoxLayout(q); 0109 hbox->setContentsMargins({}); 0110 0111 edit = new QLineEdit(q); 0112 edit->setReadOnly(true); 0113 edit->setPlaceholderText(i18n("No Folder")); 0114 edit->setClearButtonEnabled(false); 0115 edit->setFocusPolicy(Qt::NoFocus); 0116 hbox->addWidget(edit); 0117 0118 button = new QPushButton(q); 0119 button->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); 0120 const int buttonSize = edit->sizeHint().height(); 0121 button->setFixedSize(buttonSize, buttonSize); 0122 button->setToolTip(i18n("Open collection dialog")); 0123 hbox->addWidget(button); 0124 0125 hbox->setSpacing(-1); 0126 0127 edit->installEventFilter(q); 0128 q->setFocusProxy(button); 0129 q->setFocusPolicy(Qt::StrongFocus); 0130 0131 q->connect(button, &QPushButton::clicked, q, [this]() { 0132 _k_slotOpenDialog(); 0133 }); 0134 0135 auto openAction = new QAction(q); 0136 openAction->setShortcut(KStandardShortcut::Open); 0137 q->connect(openAction, &QAction::triggered, q, [this]() { 0138 _k_slotOpenDialog(); 0139 }); 0140 0141 collectionDialog = new CollectionDialog(q); 0142 collectionDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("akonadi"))); 0143 collectionDialog->setWindowTitle(i18nc("@title:window", "Select a Collection")); 0144 collectionDialog->setSelectionMode(QAbstractItemView::SingleSelection); 0145 collectionDialog->changeCollectionDialogOptions(CollectionDialog::KeepTreeExpanded); 0146 } 0147 0148 void CollectionRequesterPrivate::_k_slotOpenDialog() 0149 { 0150 CollectionDialog *dlg = collectionDialog; 0151 0152 if (dlg->exec() != QDialog::Accepted) { 0153 return; 0154 } 0155 0156 const Akonadi::Collection collection = dlg->selectedCollection(); 0157 q->setCollection(collection); 0158 Q_EMIT q->collectionChanged(collection); 0159 } 0160 0161 CollectionRequester::CollectionRequester(QWidget *parent) 0162 : QWidget(parent) 0163 , d(new CollectionRequesterPrivate(this)) 0164 { 0165 d->init(); 0166 } 0167 0168 CollectionRequester::CollectionRequester(const Akonadi::Collection &collection, QWidget *parent) 0169 : QWidget(parent) 0170 , d(new CollectionRequesterPrivate(this)) 0171 { 0172 d->init(); 0173 setCollection(collection); 0174 } 0175 0176 CollectionRequester::~CollectionRequester() = default; 0177 0178 Collection CollectionRequester::collection() const 0179 { 0180 return d->collection; 0181 } 0182 0183 void CollectionRequester::setCollection(const Collection &collection) 0184 { 0185 d->collection = collection; 0186 QString name; 0187 if (collection.isValid()) { 0188 name = collection.displayName(); 0189 } 0190 0191 d->edit->setText(name); 0192 Q_EMIT collectionChanged(collection); 0193 d->fetchCollection(collection); 0194 } 0195 0196 void CollectionRequester::setMimeTypeFilter(const QStringList &mimeTypes) 0197 { 0198 if (d->collectionDialog) { 0199 d->collectionDialog->setMimeTypeFilter(mimeTypes); 0200 } 0201 } 0202 0203 QStringList CollectionRequester::mimeTypeFilter() const 0204 { 0205 if (d->collectionDialog) { 0206 return d->collectionDialog->mimeTypeFilter(); 0207 } else { 0208 return QStringList(); 0209 } 0210 } 0211 0212 void CollectionRequester::setAccessRightsFilter(Collection::Rights rights) 0213 { 0214 if (d->collectionDialog) { 0215 d->collectionDialog->setAccessRightsFilter(rights); 0216 } 0217 } 0218 0219 Collection::Rights CollectionRequester::accessRightsFilter() const 0220 { 0221 if (d->collectionDialog) { 0222 return d->collectionDialog->accessRightsFilter(); 0223 } else { 0224 return Akonadi::Collection::ReadOnly; 0225 } 0226 } 0227 0228 void CollectionRequester::changeCollectionDialogOptions(CollectionDialog::CollectionDialogOptions options) 0229 { 0230 if (d->collectionDialog) { 0231 d->collectionDialog->changeCollectionDialogOptions(options); 0232 } 0233 } 0234 0235 void CollectionRequester::setContentMimeTypes(const QStringList &mimetypes) 0236 { 0237 if (d->collectionDialog) { 0238 d->collectionDialog->setContentMimeTypes(mimetypes); 0239 } 0240 } 0241 0242 void CollectionRequester::changeEvent(QEvent *event) 0243 { 0244 if (event->type() == QEvent::WindowTitleChange) { 0245 if (d->collectionDialog) { 0246 d->collectionDialog->setWindowTitle(windowTitle()); 0247 } 0248 } else if (event->type() == QEvent::EnabledChange) { 0249 if (d->collectionDialog) { 0250 d->collectionDialog->setEnabled(true); 0251 } 0252 } 0253 QWidget::changeEvent(event); 0254 } 0255 0256 #include "moc_collectionrequester.cpp"