Mailcommon

folderselectiondialog.cpp
1 /*
2 
3  SPDX-FileCopyrightText: 2009-2022 Laurent Montel <[email protected]>
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 
31 using namespace MailCommon;
32 class Q_DECL_HIDDEN MailCommon::FolderSelectionDialog::FolderSelectionDialogPrivate
33 {
34 public:
35  FolderTreeWidget *folderTreeWidget = nullptr;
36  QPushButton *mUser1Button = nullptr;
37  QPushButton *mOkButton = nullptr;
38  bool mNotAllowToCreateNewFolder = false;
39  bool mUseGlobalSettings = true;
40 };
41 
42 FolderSelectionDialog::FolderSelectionDialog(QWidget *parent, SelectionFolderOptions options)
43  : QDialog(parent)
44  , d(new FolderSelectionDialogPrivate())
45 {
46  setObjectName(QStringLiteral("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);
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 
115 FolderSelectionDialog::~FolderSelectionDialog()
116 {
117  writeConfig();
118 }
119 
120 void 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 
129 void 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 
138 void FolderSelectionDialog::focusTreeView()
139 {
140  d->folderTreeWidget->folderTreeView()->expandAll();
141  d->folderTreeWidget->folderTreeView()->setFocus();
142 }
143 
144 void 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 
154 void FolderSelectionDialog::rowsInserted(const QModelIndex &, int, int)
155 {
156  d->folderTreeWidget->folderTreeView()->expandAll();
157 }
158 
159 bool 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 
172 void 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 
191 void 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 
198 void 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 
213 void FolderSelectionDialog::setSelectionMode(QAbstractItemView::SelectionMode mode)
214 {
215  d->folderTreeWidget->setSelectionMode(mode);
216 }
217 
218 QAbstractItemView::SelectionMode FolderSelectionDialog::selectionMode() const
219 {
220  return d->folderTreeWidget->selectionMode();
221 }
222 
223 Akonadi::Collection FolderSelectionDialog::selectedCollection() const
224 {
225  qDebug() << " d->folderTreeWidget->selectedCollection()" << d->folderTreeWidget->selectedCollection();
226  return d->folderTreeWidget->selectedCollection();
227 }
228 
229 void FolderSelectionDialog::setSelectedCollection(const Akonadi::Collection &collection)
230 {
231  d->folderTreeWidget->selectCollectionFolder(collection);
232 }
233 
234 Akonadi::Collection::List FolderSelectionDialog::selectedCollections() const
235 {
236  qDebug() << " selectedCollections " << d->folderTreeWidget->selectedCollections();
237  return d->folderTreeWidget->selectedCollections();
238 }
239 
240 static const char myFilterConvertToSieveResultDialogGroupName[] = "FolderSelectionDialog";
241 
242 void FolderSelectionDialog::readConfig()
243 {
244  KConfigGroup group(KernelIf->config(), 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 
259 void FolderSelectionDialog::writeConfig()
260 {
261  KConfigGroup group(KernelIf->config(), 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 
272 void FolderSelectionDialog::hideEvent(QHideEvent *)
273 {
274  d->folderTreeWidget->clearFilter();
275 }
void doubleClicked(const QModelIndex &index)
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void setId(Id identifier)
virtual void reject()
void result(KJob *job)
void customContextMenuRequested(const QPoint &pos)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
void clicked(bool checked)
virtual bool event(QEvent *event) override
void readConfig()
@ DisplayNever
Nevery display tooltips.
CustomContextMenu
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static void assign(QPushButton *button, const KGuiItem &item)
QString i18n(const char *text, const TYPE &arg...)
This is the widget that shows the main folder tree.
bool isEmpty() const const
Collection & parentCollection()
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)
virtual void accept()
Rights rights() const
This is an enhanced EntityTreeView specially suited for the folders in KMail's main folder widget.
virtual void scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint) override
static QString mimeType()
QStringList contentMimeTypes() const
Key_Return
QPoint pos()
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
void resize(int w, int h)
void rowsInserted(const QModelIndex &parent, int first, int last)
void setObjectName(const QString &name)
QString name(StandardShortcut id)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void setDefault(bool)
bool isValid() const
QModelIndex currentIndex() const const
virtual QString errorString() const
int error() const
void setName(const QString &name)
QObject * parent() const const
The filter dialog.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Oct 1 2022 04:00:53 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.