Mailcommon

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

KDE's Doxygen guidelines are available online.