File indexing completed on 2024-12-22 05:00:56

0001 /*
0002    SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "settingsdialog.h"
0008 #include "mailkernel.h"
0009 #include "unifiedmailbox.h"
0010 #include "unifiedmailboxeditor.h"
0011 
0012 #include <QDialogButtonBox>
0013 #include <QItemSelectionModel>
0014 #include <QListView>
0015 #include <QPushButton>
0016 #include <QStandardItem>
0017 #include <QStandardItemModel>
0018 #include <QVBoxLayout>
0019 
0020 #include <KConfigGroup>
0021 #include <KLocalizedString>
0022 #include <KMessageBox>
0023 #include <KWindowConfig>
0024 #include <QMenu>
0025 #include <QWindow>
0026 
0027 #include <memory>
0028 
0029 namespace
0030 {
0031 static constexpr const char *DialogGroup = "UnifiedMailboxSettingsDialog";
0032 }
0033 
0034 SettingsDialog::SettingsDialog(const KSharedConfigPtr &config, UnifiedMailboxManager &boxManager, WId, QWidget *parent)
0035     : QDialog(parent)
0036     , mBoxModel(new QStandardItemModel(this))
0037     , mBoxManager(boxManager)
0038     , mKernel(new MailKernel(config, this))
0039     , mConfig(config)
0040 {
0041     setWindowIcon(QIcon::fromTheme(QStringLiteral("kmail")));
0042     auto l = new QVBoxLayout(this);
0043 
0044     auto h = new QHBoxLayout;
0045     l->addLayout(h);
0046     auto view = new QListView(this);
0047     view->setEditTriggers(QListView::NoEditTriggers);
0048     view->setModel(mBoxModel);
0049     h->addWidget(view);
0050 
0051     auto v = new QVBoxLayout;
0052     h->addLayout(v);
0053     auto addButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-add-symbolic")), i18n("Add"));
0054     v->addWidget(addButton);
0055     const auto addMailBox = [this]() {
0056         auto mailbox = std::make_unique<UnifiedMailbox>();
0057         auto editor = new UnifiedMailboxEditor(mailbox.get(), mConfig, this);
0058         if (editor->exec()) {
0059             mailbox->setId(mailbox->name()); // assign ID
0060             addBox(mailbox.get());
0061             mBoxManager.insertBox(std::move(mailbox));
0062             mBoxManager.saveBoxes();
0063         }
0064         delete editor;
0065     };
0066     connect(addButton, &QPushButton::clicked, this, addMailBox);
0067 
0068     auto editButton = new QPushButton(QIcon::fromTheme(QStringLiteral("entry-edit")), i18n("Modify"));
0069     editButton->setEnabled(false);
0070     v->addWidget(editButton);
0071 
0072     const auto modifyMailBox = [this, view]() {
0073         const auto indexes = view->selectionModel()->selectedIndexes();
0074         if (!indexes.isEmpty()) {
0075             auto item = mBoxModel->itemFromIndex(indexes[0]);
0076             auto mailbox = item->data().value<UnifiedMailbox *>();
0077             auto editor = new UnifiedMailboxEditor(mailbox, mConfig, this);
0078             if (editor->exec()) {
0079                 item->setText(mailbox->name());
0080                 item->setIcon(QIcon::fromTheme(mailbox->icon()));
0081             }
0082             delete editor;
0083             mBoxManager.saveBoxes();
0084         }
0085     };
0086 
0087     connect(view, &QListView::doubleClicked, this, modifyMailBox);
0088     connect(editButton, &QPushButton::clicked, this, modifyMailBox);
0089 
0090     auto removeButton = new QPushButton(QIcon::fromTheme(QStringLiteral("list-remove-symbolic")), i18n("Remove"));
0091     removeButton->setEnabled(false);
0092     v->addWidget(removeButton);
0093 
0094     const auto removeMailBox = [this, view]() {
0095         const auto indexes = view->selectionModel()->selectedIndexes();
0096         if (!indexes.isEmpty()) {
0097             auto item = mBoxModel->itemFromIndex(indexes[0]);
0098             const auto mailbox = item->data().value<UnifiedMailbox *>();
0099             if (KMessageBox::warningTwoActions(this,
0100                                                i18n("Do you really want to remove unified mailbox <b>%1</b>?", mailbox->name()),
0101                                                i18nc("@title:window", "Really Remove?"),
0102                                                KStandardGuiItem::remove(),
0103                                                KStandardGuiItem::cancel())
0104                 == KMessageBox::ButtonCode::PrimaryAction) {
0105                 mBoxModel->removeRow(item->row());
0106                 mBoxManager.removeBox(mailbox->id());
0107                 mBoxManager.saveBoxes();
0108             }
0109         }
0110     };
0111     connect(removeButton, &QPushButton::clicked, this, removeMailBox);
0112     v->addStretch(1);
0113 
0114     connect(view->selectionModel(), &QItemSelectionModel::selectionChanged, this, [view, editButton, removeButton]() {
0115         const bool hasSelection = view->selectionModel()->hasSelection();
0116         editButton->setEnabled(hasSelection);
0117         removeButton->setEnabled(hasSelection);
0118     });
0119 
0120     auto box = new QDialogButtonBox(QDialogButtonBox::Close, this);
0121     connect(box, &QDialogButtonBox::rejected, this, &SettingsDialog::reject);
0122     l->addWidget(box);
0123     view->setContextMenuPolicy(Qt::CustomContextMenu);
0124     connect(view, &QListView::customContextMenuRequested, this, [this, view, addMailBox, removeMailBox, modifyMailBox](const QPoint &pos) {
0125         Q_UNUSED(pos);
0126         const auto mboxSelected = view->selectionModel()->selectedIndexes();
0127         QMenu menu(this);
0128         QAction *addAction = menu.addAction(QIcon::fromTheme(QStringLiteral("list-add-symbolic")), i18n("Add"));
0129         QAction *removeAction = nullptr;
0130         QAction *editAction = nullptr;
0131         if (!mboxSelected.isEmpty()) {
0132             editAction = menu.addAction(QIcon::fromTheme(QStringLiteral("entry-edit")), i18n("Modify"));
0133             menu.addSeparator();
0134             removeAction = menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove-symbolic")), i18n("Remove"));
0135         }
0136         QAction *result = menu.exec(QCursor::pos());
0137         if (result) {
0138             if (result == addAction) {
0139                 addMailBox();
0140             } else if (result == removeAction) {
0141                 removeMailBox();
0142             } else if (result == editAction) {
0143                 modifyMailBox();
0144             }
0145         }
0146     });
0147 
0148     loadBoxes();
0149     readConfig();
0150 }
0151 
0152 SettingsDialog::~SettingsDialog()
0153 {
0154     writeConfig();
0155 }
0156 
0157 void SettingsDialog::readConfig()
0158 {
0159     create(); // ensure a window is created
0160     windowHandle()->resize(QSize(500, 500));
0161     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(DialogGroup));
0162     KWindowConfig::restoreWindowSize(windowHandle(), group);
0163     resize(windowHandle()->size()); // workaround for QTBUG-40584
0164 }
0165 
0166 void SettingsDialog::writeConfig()
0167 {
0168     auto dlgGroup = mConfig->group(QLatin1StringView(DialogGroup));
0169     KWindowConfig::saveWindowSize(windowHandle(), dlgGroup);
0170     dlgGroup.sync();
0171 }
0172 
0173 void SettingsDialog::loadBoxes()
0174 {
0175     mBoxModel->clear();
0176     for (const auto &mailboxIt : mBoxManager) {
0177         addBox(mailboxIt.second.get());
0178     }
0179 }
0180 
0181 void SettingsDialog::addBox(UnifiedMailbox *box)
0182 {
0183     auto item = new QStandardItem(QIcon::fromTheme(box->icon()), box->name());
0184     item->setData(QVariant::fromValue(box));
0185     mBoxModel->appendRow(item);
0186 }
0187 
0188 #include "moc_settingsdialog.cpp"