Mailcommon

folderselectiondialog.cpp
1/*
2
3 SPDX-FileCopyrightText: 2009-2024 Laurent Montel <montel@kde.org>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "folderselectiondialog.h"
9
10#include "foldersettings.h"
11#include "foldertreeview.h"
12#include "foldertreewidget.h"
13#include "foldertreewidgetproxymodel.h"
14#include "kernel/mailkernel.h"
15
16#include <Akonadi/CollectionCreateJob>
17#include <Akonadi/ETMViewStateSaver>
18#include <Akonadi/EntityMimeTypeFilterModel>
19#include <Akonadi/EntityTreeModel>
20
21#include <KLocalizedString>
22#include <KMessageBox>
23#include <QInputDialog>
24#include <QMenu>
25
26#include <KConfigGroup>
27#include <QDialogButtonBox>
28#include <QPushButton>
29#include <QShowEvent>
30#include <QVBoxLayout>
31
32using namespace MailCommon;
33class Q_DECL_HIDDEN MailCommon::FolderSelectionDialog::FolderSelectionDialogPrivate
34{
35public:
36 FolderTreeWidget *folderTreeWidget = nullptr;
37 QPushButton *mUser1Button = nullptr;
38 QPushButton *mOkButton = nullptr;
39 bool mNotAllowToCreateNewFolder = false;
40 bool mUseGlobalSettings = true;
41};
42
43FolderSelectionDialog::FolderSelectionDialog(QWidget *parent, SelectionFolderOptions options)
44 : QDialog(parent)
45 , d(new FolderSelectionDialogPrivate())
46{
47 setObjectName(QLatin1StringView("folder dialog"));
48
49 d->mNotAllowToCreateNewFolder = (options & FolderSelectionDialog::NotAllowToCreateNewFolder);
51 auto mainLayout = new QVBoxLayout(this);
52 d->mOkButton = buttonBox->button(QDialogButtonBox::Ok);
53 d->mOkButton->setDefault(true);
54 d->mOkButton->setAutoDefault(true);
55 d->mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
56 connect(buttonBox, &QDialogButtonBox::accepted, this, &FolderSelectionDialog::accept);
57 connect(buttonBox, &QDialogButtonBox::rejected, this, &FolderSelectionDialog::reject);
58
59 if (!d->mNotAllowToCreateNewFolder) {
60 d->mUser1Button = new QPushButton(this);
61 d->mUser1Button->setDefault(false);
62 d->mUser1Button->setAutoDefault(false);
63 buttonBox->addButton(d->mUser1Button, QDialogButtonBox::ActionRole);
64 KGuiItem::assign(d->mUser1Button,
65 KGuiItem(i18nc("@action:button", "&New Subfolder…"),
66 QStringLiteral("folder-new"),
67 i18nc("@info:tooltip", "Create a new subfolder under the currently selected folder")));
68 }
69 FolderTreeWidget::TreeViewOptions opt = FolderTreeWidget::None;
70 if (options & FolderSelectionDialog::ShowUnreadCount) {
71 opt |= FolderTreeWidget::ShowUnreadCount;
72 }
73 opt |= FolderTreeWidget::UseDistinctSelectionModel;
74
75 FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModelOptions optReadableProxy = FolderTreeWidgetProxyModel::None;
76
77 if (options & FolderSelectionDialog::HideVirtualFolder) {
78 optReadableProxy |= FolderTreeWidgetProxyModel::HideVirtualFolder;
79 }
80
81 optReadableProxy |= FolderTreeWidgetProxyModel::HideSpecificFolder;
82
83 if (options & FolderSelectionDialog::HideOutboxFolder) {
84 optReadableProxy |= FolderTreeWidgetProxyModel::HideOutboxFolder;
85 }
86
87 d->folderTreeWidget = new FolderTreeWidget(this, nullptr, opt, optReadableProxy);
88 d->folderTreeWidget->readConfig();
89 d->folderTreeWidget->disableContextMenuAndExtraColumn();
90 d->folderTreeWidget->folderTreeWidgetProxyModel()->setEnabledCheck((options & EnableCheck));
91 // Necessary otherwise we overwrite tooltip config for all application
92 d->folderTreeWidget->folderTreeView()->disableSaveConfig();
93 d->folderTreeWidget->folderTreeView()->setTooltipsPolicy(FolderTreeWidget::DisplayNever);
94 d->folderTreeWidget->folderTreeView()->setEnableDragDrop(false);
95 mainLayout->addWidget(d->folderTreeWidget);
96 mainLayout->addWidget(buttonBox);
97
98 d->mOkButton->setEnabled(false);
99 if (!d->mNotAllowToCreateNewFolder) {
100 d->mUser1Button->setEnabled(false);
101 connect(d->mUser1Button, &QPushButton::clicked, this, &FolderSelectionDialog::slotAddChildFolder);
102 d->folderTreeWidget->folderTreeView()->setContextMenuPolicy(Qt::CustomContextMenu);
103 connect(d->folderTreeWidget->folderTreeView(),
105 this,
106 &FolderSelectionDialog::slotFolderTreeWidgetContextMenuRequested);
107 }
108
109 connect(d->folderTreeWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &FolderSelectionDialog::slotSelectionChanged);
110 connect(d->folderTreeWidget->folderTreeWidgetProxyModel(), &QAbstractItemModel::rowsInserted, this, &FolderSelectionDialog::rowsInserted);
111
112 connect(d->folderTreeWidget->folderTreeView(), &QAbstractItemView::doubleClicked, this, &FolderSelectionDialog::slotDoubleClick);
113
114 d->mUseGlobalSettings = !(options & NotUseGlobalSettings);
115 readConfig();
116}
117
118FolderSelectionDialog::~FolderSelectionDialog()
119{
120}
121
122void FolderSelectionDialog::slotFolderTreeWidgetContextMenuRequested(const QPoint &pos)
123{
124 if (d->mUser1Button && d->mUser1Button->isEnabled() && d->folderTreeWidget->folderTreeView()->indexAt(pos).isValid()) {
125 QMenu menu(this);
126 menu.addAction(i18n("&New Subfolder…"), this, &FolderSelectionDialog::slotAddChildFolder);
127 menu.exec(QCursor::pos());
128 }
129}
130
131void FolderSelectionDialog::slotDoubleClick(const QModelIndex &index)
132{
133 Q_UNUSED(index)
134 const bool hasSelectedCollection = (!d->folderTreeWidget->selectionModel()->selectedIndexes().isEmpty());
135 if (hasSelectedCollection) {
136 accept();
137 }
138}
139
140void FolderSelectionDialog::focusTreeView()
141{
142 d->folderTreeWidget->folderTreeView()->setFocus();
143}
144
145void FolderSelectionDialog::showEvent(QShowEvent *event)
146{
147 if (!event->spontaneous()) {
148 focusTreeView();
149 FolderTreeView *view = d->folderTreeWidget->folderTreeView();
150 view->scrollTo(view->currentIndex());
151 }
153}
154
155void FolderSelectionDialog::rowsInserted(const QModelIndex &, int, int)
156{
157 d->folderTreeWidget->folderTreeView()->expandAll();
158}
159
160bool FolderSelectionDialog::canCreateCollection(Akonadi::Collection &parentCol)
161{
162 parentCol = selectedCollection();
163 if (!parentCol.isValid()) {
164 return false;
165 }
166
168 return true;
169 }
170 return false;
171}
172
173void FolderSelectionDialog::slotAddChildFolder()
174{
175 Akonadi::Collection parentCol;
176 if (canCreateCollection(parentCol)) {
177 bool ok = false;
178 const QString name = QInputDialog::getText(this, i18nc("@title:window", "New Folder"), i18nc("@label:textbox, name of a thing", "Name"), {}, {}, &ok);
179
180 if (name.isEmpty() || !ok) {
181 return;
182 }
183
185 col.setName(name);
186 col.parentCollection().setId(parentCol.id());
187 auto job = new Akonadi::CollectionCreateJob(col);
188 connect(job, &Akonadi::CollectionCreateJob::result, this, &FolderSelectionDialog::collectionCreationResult);
189 }
190}
191
192void FolderSelectionDialog::collectionCreationResult(KJob *job)
193{
194 if (job->error()) {
195 KMessageBox::error(this, i18n("Could not create folder: %1", job->errorString()), i18nc("@title:window", "Folder creation failed"));
196 }
197}
198
199void FolderSelectionDialog::slotSelectionChanged()
200{
201 const bool enablebuttons = (!d->folderTreeWidget->selectionModel()->selectedIndexes().isEmpty());
202 d->mOkButton->setEnabled(enablebuttons);
203
204 if (!d->mNotAllowToCreateNewFolder) {
206 d->mUser1Button->setEnabled(canCreateCollection(parent));
207 if (parent.isValid()) {
208 const QSharedPointer<FolderSettings> fd(FolderSettings::forCollection(parent, false));
209 d->mOkButton->setEnabled(fd->canCreateMessages());
210 }
211 }
212}
213
214void FolderSelectionDialog::setSelectionMode(QAbstractItemView::SelectionMode mode)
215{
216 d->folderTreeWidget->setSelectionMode(mode);
217}
218
219QAbstractItemView::SelectionMode FolderSelectionDialog::selectionMode() const
220{
221 return d->folderTreeWidget->selectionMode();
222}
223
224Akonadi::Collection FolderSelectionDialog::selectedCollection() const
225{
226 // qDebug() << " d->folderTreeWidget->selectedCollection()" << d->folderTreeWidget->selectedCollection();
227 return d->folderTreeWidget->selectedCollection();
228}
229
230void FolderSelectionDialog::setSelectedCollection(const Akonadi::Collection &collection)
231{
232 d->folderTreeWidget->selectCollectionFolder(collection);
233}
234
235Akonadi::Collection::List FolderSelectionDialog::selectedCollections() const
236{
237 // qDebug() << " selectedCollections " << d->folderTreeWidget->selectedCollections();
238 return d->folderTreeWidget->selectedCollections();
239}
240
241void FolderSelectionDialog::setAccountActivities(Akonadi::AccountActivitiesAbstract *accountActivities)
242{
243 d->folderTreeWidget->setAccountActivities(accountActivities);
244}
245
246static const char myFilterConvertToSieveResultDialogGroupName[] = "FolderSelectionDialog";
247
248void FolderSelectionDialog::readConfig()
249{
250 KConfigGroup group(KernelIf->config(), QLatin1StringView(myFilterConvertToSieveResultDialogGroupName));
251
252 const QSize size = group.readEntry("Size", QSize(500, 300));
253 if (size.isValid()) {
254 resize(size);
255 }
256
257 const QStringList expansionState = group.readEntry("Expansion", QStringList());
258 if (!expansionState.isEmpty()) {
259 Akonadi::ETMViewStateSaver *saver = new Akonadi::ETMViewStateSaver;
260 saver->setView(d->folderTreeWidget->folderTreeView());
261 saver->restoreExpanded(expansionState);
262 } else {
263 d->folderTreeWidget->folderTreeView()->expandAll();
264 }
265
266 if (d->mUseGlobalSettings) {
267 const Akonadi::Collection::Id id = SettingsIf->lastSelectedFolder();
268 if (id > -1) {
269 const Akonadi::Collection col = Kernel::self()->collectionFromId(id);
270 d->folderTreeWidget->selectCollectionFolder(col);
271 }
272 }
273}
274
275void FolderSelectionDialog::writeConfig()
276{
277 KConfigGroup group(KernelIf->config(), QLatin1StringView(myFilterConvertToSieveResultDialogGroupName));
278 group.writeEntry("Size", size());
279
280 Akonadi::ETMViewStateSaver saver;
281 saver.setView(d->folderTreeWidget->folderTreeView());
282 group.writeEntry("Expansion", saver.expansionKeys());
283
284 if (d->mUseGlobalSettings) {
285 Akonadi::Collection col = selectedCollection();
286 if (col.isValid()) {
287 SettingsIf->setLastSelectedFolder(col.id());
288 }
289 }
290}
291
292void FolderSelectionDialog::hideEvent(QHideEvent *)
293{
294 writeConfig();
295 d->folderTreeWidget->clearFilter();
296}
297
298#include "moc_folderselectiondialog.cpp"
QStringList contentMimeTypes() const
static QString mimeType()
bool isValid() const
void setName(const QString &name)
Rights rights() const
Collection & parentCollection()
void setId(Id identifier)
static void assign(QPushButton *button, const KGuiItem &item)
virtual QString errorString() const
int error() const
void result(KJob *job)
This is an enhanced EntityTreeView specially suited for the folders in KMail's main folder widget.
This is the widget that shows the main folder tree.
@ DisplayNever
Nevery display tooltips.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString name(GameStandardAction id)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
The filter dialog.
void clicked(bool checked)
void rowsInserted(const QModelIndex &parent, int first, int last)
QModelIndex currentIndex() const const
void doubleClicked(const QModelIndex &index)
QPoint pos()
virtual void accept()
virtual void showEvent(QShowEvent *event) override
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
bool isEmpty() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
CustomContextMenu
Key_Return
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
virtual void scrollTo(const QModelIndex &index, ScrollHint hint) override
void customContextMenuRequested(const QPoint &pos)
virtual bool event(QEvent *event) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 29 2024 11:58:43 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.