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/EntityMimeTypeFilterModel>
18#include <Akonadi/EntityTreeModel>
19
20#include <KLocalizedString>
21#include <KMessageBox>
22#include <QInputDialog>
23#include <QMenu>
24
25#include <KConfigGroup>
26#include <QDialogButtonBox>
27#include <QPushButton>
28#include <QShowEvent>
29#include <QVBoxLayout>
30
31using namespace MailCommon;
32class Q_DECL_HIDDEN MailCommon::FolderSelectionDialog::FolderSelectionDialogPrivate
33{
34public:
35 FolderTreeWidget *folderTreeWidget = nullptr;
36 QPushButton *mUser1Button = nullptr;
37 QPushButton *mOkButton = nullptr;
38 bool mNotAllowToCreateNewFolder = false;
39 bool mUseGlobalSettings = true;
40};
41
42FolderSelectionDialog::FolderSelectionDialog(QWidget *parent, SelectionFolderOptions options)
43 : QDialog(parent)
44 , d(new FolderSelectionDialogPrivate())
45{
46 setObjectName(QLatin1StringView("folder dialog"));
47
48 d->mNotAllowToCreateNewFolder = (options & FolderSelectionDialog::NotAllowToCreateNewFolder);
50 auto mainLayout = new QVBoxLayout(this);
51 d->mOkButton = buttonBox->button(QDialogButtonBox::Ok);
52 d->mOkButton->setDefault(true);
53 d->mOkButton->setAutoDefault(true);
54 d->mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
55 connect(buttonBox, &QDialogButtonBox::accepted, this, &FolderSelectionDialog::accept);
56 connect(buttonBox, &QDialogButtonBox::rejected, this, &FolderSelectionDialog::reject);
57
58 if (!d->mNotAllowToCreateNewFolder) {
59 d->mUser1Button = new QPushButton;
60 d->mUser1Button->setDefault(false);
61 d->mUser1Button->setAutoDefault(false);
62 buttonBox->addButton(d->mUser1Button, QDialogButtonBox::ActionRole);
63 KGuiItem::assign(d->mUser1Button,
64 KGuiItem(i18n("&New Subfolder..."), QStringLiteral("folder-new"), i18n("Create a new subfolder under the currently selected folder")));
65 }
66 FolderTreeWidget::TreeViewOptions opt = FolderTreeWidget::None;
67 if (options & FolderSelectionDialog::ShowUnreadCount) {
68 opt |= FolderTreeWidget::ShowUnreadCount;
69 }
70 opt |= FolderTreeWidget::UseDistinctSelectionModel;
71
72 FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModelOptions optReadableProxy = FolderTreeWidgetProxyModel::None;
73
74 if (options & FolderSelectionDialog::HideVirtualFolder) {
75 optReadableProxy |= FolderTreeWidgetProxyModel::HideVirtualFolder;
76 }
77
78 optReadableProxy |= FolderTreeWidgetProxyModel::HideSpecificFolder;
79
80 if (options & FolderSelectionDialog::HideOutboxFolder) {
81 optReadableProxy |= FolderTreeWidgetProxyModel::HideOutboxFolder;
82 }
83
84 d->folderTreeWidget = new FolderTreeWidget(this, nullptr, opt, optReadableProxy);
85 d->folderTreeWidget->readConfig();
86 d->folderTreeWidget->disableContextMenuAndExtraColumn();
87 d->folderTreeWidget->folderTreeWidgetProxyModel()->setEnabledCheck((options & EnableCheck));
88 // Necessary otherwise we overwrite tooltip config for all application
89 d->folderTreeWidget->folderTreeView()->disableSaveConfig();
90 d->folderTreeWidget->folderTreeView()->setTooltipsPolicy(FolderTreeWidget::DisplayNever);
91 d->folderTreeWidget->folderTreeView()->setEnableDragDrop(false);
92 mainLayout->addWidget(d->folderTreeWidget);
93 mainLayout->addWidget(buttonBox);
94
95 d->mOkButton->setEnabled(false);
96 if (!d->mNotAllowToCreateNewFolder) {
97 d->mUser1Button->setEnabled(false);
98 connect(d->mUser1Button, &QPushButton::clicked, this, &FolderSelectionDialog::slotAddChildFolder);
99 d->folderTreeWidget->folderTreeView()->setContextMenuPolicy(Qt::CustomContextMenu);
100 connect(d->folderTreeWidget->folderTreeView(),
102 this,
103 &FolderSelectionDialog::slotFolderTreeWidgetContextMenuRequested);
104 }
105
106 connect(d->folderTreeWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &FolderSelectionDialog::slotSelectionChanged);
107 connect(d->folderTreeWidget->folderTreeWidgetProxyModel(), &QAbstractItemModel::rowsInserted, this, &FolderSelectionDialog::rowsInserted);
108
109 connect(d->folderTreeWidget->folderTreeView(), &QAbstractItemView::doubleClicked, this, &FolderSelectionDialog::slotDoubleClick);
110
111 d->mUseGlobalSettings = !(options & NotUseGlobalSettings);
112 readConfig();
113}
114
115FolderSelectionDialog::~FolderSelectionDialog()
116{
117 writeConfig();
118}
119
120void FolderSelectionDialog::slotFolderTreeWidgetContextMenuRequested(const QPoint &pos)
121{
122 if (d->mUser1Button && d->mUser1Button->isEnabled() && d->folderTreeWidget->folderTreeView()->indexAt(pos).isValid()) {
123 QMenu menu(this);
124 menu.addAction(i18n("&New Subfolder..."), this, &FolderSelectionDialog::slotAddChildFolder);
125 menu.exec(QCursor::pos());
126 }
127}
128
129void FolderSelectionDialog::slotDoubleClick(const QModelIndex &index)
130{
131 Q_UNUSED(index)
132 const bool hasSelectedCollection = (!d->folderTreeWidget->selectionModel()->selectedIndexes().isEmpty());
133 if (hasSelectedCollection) {
134 accept();
135 }
136}
137
138void FolderSelectionDialog::focusTreeView()
139{
140 d->folderTreeWidget->folderTreeView()->expandAll();
141 d->folderTreeWidget->folderTreeView()->setFocus();
142}
143
144void FolderSelectionDialog::showEvent(QShowEvent *event)
145{
146 if (!event->spontaneous()) {
147 focusTreeView();
148 FolderTreeView *view = d->folderTreeWidget->folderTreeView();
149 view->scrollTo(view->currentIndex());
150 }
152}
153
154void FolderSelectionDialog::rowsInserted(const QModelIndex &, int, int)
155{
156 d->folderTreeWidget->folderTreeView()->expandAll();
157}
158
159bool FolderSelectionDialog::canCreateCollection(Akonadi::Collection &parentCol)
160{
161 parentCol = selectedCollection();
162 if (!parentCol.isValid()) {
163 return false;
164 }
165
167 return true;
168 }
169 return false;
170}
171
172void FolderSelectionDialog::slotAddChildFolder()
173{
174 Akonadi::Collection parentCol;
175 if (canCreateCollection(parentCol)) {
176 bool ok = false;
177 const QString name = QInputDialog::getText(this, i18nc("@title:window", "New Folder"), i18nc("@label:textbox, name of a thing", "Name"), {}, {}, &ok);
178
179 if (name.isEmpty() || !ok) {
180 return;
181 }
182
184 col.setName(name);
185 col.parentCollection().setId(parentCol.id());
186 auto job = new Akonadi::CollectionCreateJob(col);
187 connect(job, &Akonadi::CollectionCreateJob::result, this, &FolderSelectionDialog::collectionCreationResult);
188 }
189}
190
191void FolderSelectionDialog::collectionCreationResult(KJob *job)
192{
193 if (job->error()) {
194 KMessageBox::error(this, i18n("Could not create folder: %1", job->errorString()), i18n("Folder creation failed"));
195 }
196}
197
198void FolderSelectionDialog::slotSelectionChanged()
199{
200 const bool enablebuttons = (!d->folderTreeWidget->selectionModel()->selectedIndexes().isEmpty());
201 d->mOkButton->setEnabled(enablebuttons);
202
203 if (!d->mNotAllowToCreateNewFolder) {
205 d->mUser1Button->setEnabled(canCreateCollection(parent));
206 if (parent.isValid()) {
207 const QSharedPointer<FolderSettings> fd(FolderSettings::forCollection(parent, false));
208 d->mOkButton->setEnabled(fd->canCreateMessages());
209 }
210 }
211}
212
213void FolderSelectionDialog::setSelectionMode(QAbstractItemView::SelectionMode mode)
214{
215 d->folderTreeWidget->setSelectionMode(mode);
216}
217
218QAbstractItemView::SelectionMode FolderSelectionDialog::selectionMode() const
219{
220 return d->folderTreeWidget->selectionMode();
221}
222
223Akonadi::Collection FolderSelectionDialog::selectedCollection() const
224{
225 qDebug() << " d->folderTreeWidget->selectedCollection()" << d->folderTreeWidget->selectedCollection();
226 return d->folderTreeWidget->selectedCollection();
227}
228
229void FolderSelectionDialog::setSelectedCollection(const Akonadi::Collection &collection)
230{
231 d->folderTreeWidget->selectCollectionFolder(collection);
232}
233
234Akonadi::Collection::List FolderSelectionDialog::selectedCollections() const
235{
236 qDebug() << " selectedCollections " << d->folderTreeWidget->selectedCollections();
237 return d->folderTreeWidget->selectedCollections();
238}
239
240static const char myFilterConvertToSieveResultDialogGroupName[] = "FolderSelectionDialog";
241
242void FolderSelectionDialog::readConfig()
243{
244 KConfigGroup group(KernelIf->config(), QLatin1StringView(myFilterConvertToSieveResultDialogGroupName));
245
246 const QSize size = group.readEntry("Size", QSize(500, 300));
247 if (size.isValid()) {
248 resize(size);
249 }
250 if (d->mUseGlobalSettings) {
251 const Akonadi::Collection::Id id = SettingsIf->lastSelectedFolder();
252 if (id > -1) {
253 const Akonadi::Collection col = Kernel::self()->collectionFromId(id);
254 d->folderTreeWidget->selectCollectionFolder(col);
255 }
256 }
257}
258
259void FolderSelectionDialog::writeConfig()
260{
261 KConfigGroup group(KernelIf->config(), QLatin1StringView(myFilterConvertToSieveResultDialogGroupName));
262 group.writeEntry("Size", size());
263
264 if (d->mUseGlobalSettings) {
265 Akonadi::Collection col = selectedCollection();
266 if (col.isValid()) {
267 SettingsIf->setLastSelectedFolder(col.id());
268 }
269 }
270}
271
272void FolderSelectionDialog::hideEvent(QHideEvent *)
273{
274 d->folderTreeWidget->clearFilter();
275}
276
277#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...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QString name(StandardShortcut id)
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)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
void setDefault(bool)
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 Tue Mar 26 2024 11:14:01 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.