Mailcommon

accountconfigorderdialog.cpp
1 /*
2  SPDX-FileCopyrightText: 2012-2022 Laurent Montel <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "accountconfigorderdialog.h"
8 #include "mailcommon_debug.h"
9 #include "mailcommonsettings_base.h"
10 #include "util/mailutil.h"
11 #include <KLocalizedString>
12 #include <PimCommon/PimUtil>
13 #include <QIcon>
14 #include <QPushButton>
15 #include <QVBoxLayout>
16 
17 #include <Akonadi/AgentInstance>
18 #include <Akonadi/AgentManager>
19 
20 #include <KConfigGroup>
21 #include <QCheckBox>
22 #include <QDialogButtonBox>
23 #include <QHBoxLayout>
24 #include <QListWidget>
25 
26 using namespace MailCommon;
27 
28 struct InstanceStruct {
29  QString name;
30  QIcon icon;
31  Q_REQUIRED_RESULT bool isValid() const
32  {
33  return !name.isEmpty();
34  }
35 };
36 
37 class MailCommon::AccountConfigOrderDialogPrivate
38 {
39 public:
40  QListWidget *mListAccount = nullptr;
41  QPushButton *mUpButton = nullptr;
42  QPushButton *mDownButton = nullptr;
43  QCheckBox *mEnableAccountOrder = nullptr;
44  MailCommon::MailCommonSettings *mSettings = nullptr;
45 };
46 
47 AccountConfigOrderDialog::AccountConfigOrderDialog(MailCommon::MailCommonSettings *settings, QWidget *parent)
48  : QDialog(parent)
49  , d(new MailCommon::AccountConfigOrderDialogPrivate)
50 {
51  d->mSettings = settings;
52  setWindowTitle(i18nc("@title:window", "Edit Accounts Order"));
54  auto mainLayout = new QVBoxLayout(this);
55 
56  QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
57  okButton->setDefault(true);
58  okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
59  connect(buttonBox, &QDialogButtonBox::rejected, this, &AccountConfigOrderDialog::reject);
60 
61  auto page = new QWidget(this);
62  mainLayout->addWidget(page);
63  mainLayout->addWidget(buttonBox);
64 
65  auto vbox = new QVBoxLayout;
66  vbox->setContentsMargins({});
67  page->setLayout(vbox);
68 
69  d->mEnableAccountOrder = new QCheckBox(i18n("Use custom order"), this);
70  connect(d->mEnableAccountOrder, &QCheckBox::clicked, this, &AccountConfigOrderDialog::slotEnableAccountOrder);
71  vbox->addWidget(d->mEnableAccountOrder);
72 
73  auto vlay = new QHBoxLayout;
74  vbox->addLayout(vlay);
75 
76  d->mListAccount = new QListWidget(this);
77  d->mListAccount->setDragDropMode(QAbstractItemView::InternalMove);
78  vlay->addWidget(d->mListAccount);
79 
80  auto upDownBox = new QWidget(page);
81  auto upDownBoxVBoxLayout = new QVBoxLayout(upDownBox);
82  upDownBoxVBoxLayout->setContentsMargins({});
83  d->mUpButton = new QPushButton(upDownBox);
84  upDownBoxVBoxLayout->addWidget(d->mUpButton);
85  d->mUpButton->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
86  d->mUpButton->setToolTip(i18nc("Move selected account up.", "Up"));
87  d->mUpButton->setEnabled(false); // b/c no item is selected yet
88  d->mUpButton->setFocusPolicy(Qt::StrongFocus);
89  d->mUpButton->setAutoRepeat(true);
90 
91  d->mDownButton = new QPushButton(upDownBox);
92  upDownBoxVBoxLayout->addWidget(d->mDownButton);
93  d->mDownButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
94  d->mDownButton->setToolTip(i18nc("Move selected account down.", "Down"));
95  d->mDownButton->setEnabled(false); // b/c no item is selected yet
96  d->mDownButton->setFocusPolicy(Qt::StrongFocus);
97  d->mDownButton->setAutoRepeat(true);
98 
99  auto spacer = new QWidget(upDownBox);
100  upDownBoxVBoxLayout->addWidget(spacer);
101  upDownBoxVBoxLayout->setStretchFactor(spacer, 100);
102  vlay->addWidget(upDownBox);
103 
104  connect(d->mUpButton, &QPushButton::clicked, this, &AccountConfigOrderDialog::slotMoveUp);
105  connect(d->mDownButton, &QPushButton::clicked, this, &AccountConfigOrderDialog::slotMoveDown);
106  connect(d->mListAccount, &QListWidget::itemSelectionChanged, this, &AccountConfigOrderDialog::slotEnableControls);
107  connect(d->mListAccount->model(), &QAbstractItemModel::rowsMoved, this, &AccountConfigOrderDialog::slotEnableControls);
108 
109  connect(okButton, &QPushButton::clicked, this, &AccountConfigOrderDialog::slotOk);
110  readConfig();
111  init();
112 }
113 
114 AccountConfigOrderDialog::~AccountConfigOrderDialog()
115 {
116  writeConfig();
117 }
118 
119 void AccountConfigOrderDialog::slotEnableAccountOrder(bool state)
120 {
121  d->mListAccount->setEnabled(state);
122  d->mUpButton->setEnabled(state);
123  d->mDownButton->setEnabled(state);
124  if (state) {
125  slotEnableControls();
126  }
127 }
128 
129 void AccountConfigOrderDialog::slotMoveUp()
130 {
131  if (!d->mListAccount->currentItem()) {
132  return;
133  }
134  const int pos = d->mListAccount->row(d->mListAccount->currentItem());
135  d->mListAccount->blockSignals(true);
136  QListWidgetItem *item = d->mListAccount->takeItem(pos);
137  // now selected item is at idx(idx-1), so
138  // insert the other item at idx, ie. above(below).
139  d->mListAccount->insertItem(pos - 1, item);
140  d->mListAccount->blockSignals(false);
141  d->mListAccount->setCurrentRow(pos - 1);
142 }
143 
144 void AccountConfigOrderDialog::slotMoveDown()
145 {
146  if (!d->mListAccount->currentItem()) {
147  return;
148  }
149  const int pos = d->mListAccount->row(d->mListAccount->currentItem());
150  d->mListAccount->blockSignals(true);
151  QListWidgetItem *item = d->mListAccount->takeItem(pos);
152  // now selected item is at idx(idx-1), so
153  // insert the other item at idx, ie. above(below).
154  d->mListAccount->insertItem(pos + 1, item);
155  d->mListAccount->blockSignals(false);
156  d->mListAccount->setCurrentRow(pos + 1);
157 }
158 
159 void AccountConfigOrderDialog::slotEnableControls()
160 {
161  QListWidgetItem *item = d->mListAccount->currentItem();
162 
163  d->mUpButton->setEnabled(item && d->mListAccount->currentRow() != 0);
164  d->mDownButton->setEnabled(item && d->mListAccount->currentRow() != d->mListAccount->count() - 1);
165 }
166 
167 void AccountConfigOrderDialog::init()
168 {
169  const QStringList listOrderAccount = d->mSettings->order();
170  QStringList instanceList;
171 
172  QMap<QString, InstanceStruct> mapInstance;
174  for (const Akonadi::AgentInstance &instance : lstInstances) {
175  const QString identifier = instance.identifier();
176  if (!MailCommon::Util::isMailAgent(instance) || identifier.contains(POP3_RESOURCE_IDENTIFIER)) {
177  continue;
178  }
179  instanceList << instance.identifier();
180  InstanceStruct instanceStruct;
181  instanceStruct.name = instance.name();
182  if (PimCommon::Util::isImapResource(identifier)) {
183  instanceStruct.name += QLatin1String(" (IMAP)");
184  } else if (identifier.startsWith(QLatin1String("akonadi_maildir_resource"))) {
185  instanceStruct.name += QLatin1String(" (Maildir)");
186  } else if (identifier.startsWith(QLatin1String("akonadi_mailbox_resource"))) {
187  instanceStruct.name += QLatin1String(" (Mailbox)");
188  } else if (identifier.startsWith(QLatin1String("akonadi_mixedmaildir_resource"))) {
189  instanceStruct.name += QLatin1String(" (Mixedmaildir)");
190  } else {
191  qCDebug(MAILCOMMON_LOG) << " Unknown resource type " << identifier;
192  }
193  instanceStruct.icon = instance.type().icon();
194  mapInstance.insert(instance.identifier(), instanceStruct);
195  }
196  instanceList.sort(Qt::CaseInsensitive);
197  const int numberOfList(listOrderAccount.count());
198  for (int i = 0; i < numberOfList; ++i) {
199  instanceList.removeOne(listOrderAccount.at(i));
200  }
201 
202  QStringList finalList(listOrderAccount);
203  finalList += instanceList;
204 
205  const int numberOfElement(finalList.count());
206  for (int i = 0; i < numberOfElement; ++i) {
207  const QString identifier(finalList.at(i));
208  const InstanceStruct tmp = mapInstance.value(identifier);
209  if (tmp.isValid()) {
210  auto item = new QListWidgetItem(tmp.icon, tmp.name, d->mListAccount);
211  item->setData(AccountConfigOrderDialog::IdentifierAccount, identifier);
212  d->mListAccount->addItem(item);
213  }
214  }
215  const bool enabled = d->mSettings->enableAccountOrder();
216  d->mEnableAccountOrder->setChecked(enabled);
217  slotEnableAccountOrder(enabled);
218 }
219 
220 void AccountConfigOrderDialog::slotOk()
221 {
222  QStringList order;
223  const int numberOfItems(d->mListAccount->count());
224  order.reserve(numberOfItems);
225  for (int i = 0; i < numberOfItems; ++i) {
226  order << d->mListAccount->item(i)->data(AccountConfigOrderDialog::IdentifierAccount).toString();
227  }
228 
229  d->mSettings->setOrder(order);
230  d->mSettings->setEnableAccountOrder(d->mEnableAccountOrder->isChecked());
231  d->mSettings->save();
232  QDialog::accept();
233 }
234 
235 void AccountConfigOrderDialog::readConfig()
236 {
237  KConfigGroup accountConfigDialog(d->mSettings->config(), "AccountConfigOrderDialog");
238  const QSize size = accountConfigDialog.readEntry("Size", QSize(600, 400));
239  if (size.isValid()) {
240  resize(size);
241  }
242 }
243 
244 void AccountConfigOrderDialog::writeConfig()
245 {
246  KConfigGroup accountConfigDialog(d->mSettings->config(), "AccountConfigOrderDialog");
247  accountConfigDialog.writeEntry("Size", size());
248  accountConfigDialog.sync();
249 }
CaseInsensitive
void setShortcut(const QKeySequence &key)
const T value(const Key &key, const T &defaultValue) const const
QCA_EXPORT void init()
int count(const T &value) const const
void clicked(bool checked)
void readConfig()
QIcon fromTheme(const QString &name)
void reserve(int alloc)
QMap::iterator insert(const Key &key, const T &value)
void rowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row)
QString i18n(const char *text, const TYPE &arg...)
virtual void setData(int role, const QVariant &value)
bool removeOne(const T &value)
bool isEmpty() const const
const T & at(int i) const const
virtual void accept()
Key_Return
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
void resize(int w, int h)
bool isValid(QStringView ifopt)
QString name(StandardShortcut id)
void setContentsMargins(int left, int top, int right, int bottom)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void setDefault(bool)
static AgentManager * self()
void itemSelectionChanged()
AgentInstance::List instances() const
void addLayout(QLayout *layout, int stretch)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
StrongFocus
The filter dialog.
void sort(Qt::CaseSensitivity cs)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Oct 1 2022 04:00:52 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.