Mailcommon

accountconfigorderdialog.cpp
1/*
2 SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org>
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
28using namespace MailCommon;
29namespace
30{
31static const char myAccountConfigOrderDialogName[] = "AccountConfigOrderDialog";
32}
33struct InstanceStruct {
34 QString name;
35 QIcon icon;
36 [[nodiscard]] bool isValid() const
37 {
38 return !name.isEmpty();
39 }
40};
41
42class MailCommon::AccountConfigOrderDialogPrivate
43{
44public:
45 QListWidget *mListAccount = nullptr;
46 QPushButton *mUpButton = nullptr;
47 QPushButton *mDownButton = nullptr;
48 QCheckBox *mEnableAccountOrder = nullptr;
49 MailCommon::MailCommonSettings *mSettings = nullptr;
50};
51
52AccountConfigOrderDialog::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);
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
119AccountConfigOrderDialog::~AccountConfigOrderDialog()
120{
121 writeConfig();
122}
123
124void 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
134void 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
149void 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
164void 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
172void AccountConfigOrderDialog::init()
173{
174 const QStringList listOrderAccount = d->mSettings->order();
175 QStringList instanceList;
176
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 += QLatin1StringView(" (IMAP)");
189 } else if (identifier.startsWith(QLatin1StringView("akonadi_maildir_resource"))) {
190 instanceStruct.name += QLatin1StringView(" (Maildir)");
191 } else if (identifier.startsWith(QLatin1StringView("akonadi_mailbox_resource"))) {
192 instanceStruct.name += QLatin1StringView(" (Mailbox)");
193 } else if (identifier.startsWith(QLatin1StringView("akonadi_mixedmaildir_resource"))) {
194 instanceStruct.name += QLatin1StringView(" (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
225void 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();
238}
239
240void AccountConfigOrderDialog::readConfig()
241{
242 create(); // ensure a window is created
243 windowHandle()->resize(QSize(500, 150));
244 KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myAccountConfigOrderDialogName));
246 resize(windowHandle()->size()); // workaround for QTBUG-40584
247}
248
249void AccountConfigOrderDialog::writeConfig()
250{
251 KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myAccountConfigOrderDialogName));
253 group.sync();
254}
255
256#include "moc_accountconfigorderdialog.cpp"
static AgentManager * self()
AgentInstance::List instances() const
static KSharedConfig::Ptr openStateConfig(const QString &fileName=QString())
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString name(StandardShortcut id)
KCONFIGGUI_EXPORT void saveWindowSize(const QWindow *window, KConfigGroup &config, KConfigGroup::WriteConfigFlags options=KConfigGroup::Normal)
KCONFIGGUI_EXPORT void restoreWindowSize(QWindow *window, const KConfigGroup &config)
The filter dialog.
QCA_EXPORT void init()
void clicked(bool checked)
void setShortcut(const QKeySequence &key)
void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
void addLayout(QLayout *layout, int stretch)
virtual void accept()
QIcon fromTheme(const QString &name)
void setContentsMargins(const QMargins &margins)
const_reference at(qsizetype i) const const
qsizetype count() const const
bool removeOne(const AT &t)
void reserve(qsizetype size)
void itemSelectionChanged()
virtual void setData(int role, const QVariant &value)
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue) const const
void setDefault(bool)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
void sort(Qt::CaseSensitivity cs)
CaseInsensitive
StrongFocus
Key_Return
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void create(WId window, bool initializeWindow, bool destroyOldWindow)
void resize(const QSize &)
QWindow * windowHandle() const const
void resize(const QSize &newSize)
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.