File indexing completed on 2025-01-05 04:49:51

0001 /*
0002    SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
0003    based on subscriptiondialog from kdepim-runtime
0004 
0005    SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "selectimapfolderwidget.h"
0009 #include "imapfoldercompletionplugin_debug.h"
0010 #include "selectimapfoldermodel.h"
0011 #include "selectimapfoldertreeview.h"
0012 #include "selectimaploadfoldersjob.h"
0013 #include <KMessageBox>
0014 #include <QHeaderView>
0015 #include <QInputDialog>
0016 #include <QLineEdit>
0017 #include <QSortFilterProxyModel>
0018 #include <QStandardItemModel>
0019 #include <QVBoxLayout>
0020 
0021 #include <KLocalizedString>
0022 #include <QToolButton>
0023 
0024 SelectImapFolderWidget::SelectImapFolderWidget(const KSieveCore::SieveImapAccountSettings &account, QWidget *parent)
0025     : QWidget(parent)
0026     , mAccount(account)
0027     , mSearchLineEdit(new QLineEdit(this))
0028     , mTreeView(new SelectImapFolderTreeView(this))
0029 {
0030     bool modelIsInitialized = false;
0031     mModel = SelectImapFolderModel::self()->folderModel(mAccount, modelIsInitialized);
0032     connect(SelectImapFolderModel::self(), &SelectImapFolderModel::modelLoaded, this, &SelectImapFolderWidget::slotModelLoaded);
0033     auto mainLayout = new QVBoxLayout(this);
0034     mainLayout->setObjectName(QLatin1StringView("mainlayout"));
0035     mainLayout->setContentsMargins({});
0036 
0037     auto topLayout = new QHBoxLayout;
0038     topLayout->setContentsMargins({});
0039     mainLayout->addLayout(topLayout);
0040     mSearchLineEdit->setObjectName(QLatin1StringView("searchline"));
0041     mSearchLineEdit->setClearButtonEnabled(true);
0042     mSearchLineEdit->setPlaceholderText(i18n("Search..."));
0043     topLayout->addWidget(mSearchLineEdit);
0044 
0045     auto refreshImap = new QToolButton(this);
0046     refreshImap->setObjectName(QLatin1StringView("refreshimap"));
0047     refreshImap->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh")));
0048     refreshImap->setToolTip(i18n("Refresh IMAP Folder List"));
0049     connect(refreshImap, &QToolButton::clicked, this, &SelectImapFolderWidget::slotRefreshImap);
0050     topLayout->addWidget(refreshImap);
0051 
0052     mTreeView->setObjectName(QLatin1StringView("treeview"));
0053     mTreeView->header()->hide();
0054     mFilter = new QSortFilterProxyModel(this);
0055     mFilter->setFilterCaseSensitivity(Qt::CaseInsensitive);
0056     mFilter->setRecursiveFilteringEnabled(true);
0057     mFilter->setSourceModel(mModel);
0058 
0059     mTreeView->setModel(mFilter);
0060     connect(mTreeView, &QTreeView::doubleClicked, this, &SelectImapFolderWidget::slotDoubleClicked);
0061     mainLayout->addWidget(mTreeView);
0062 
0063     connect(mSearchLineEdit, &QLineEdit::textChanged, this, &SelectImapFolderWidget::slotSearchPattern);
0064     connect(mTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &SelectImapFolderWidget::slotCurrentChanged);
0065     if (modelIsInitialized) {
0066         mTreeView->setStatus(SelectImapFolderTreeView::Success);
0067     }
0068 }
0069 
0070 SelectImapFolderWidget::~SelectImapFolderWidget() = default;
0071 
0072 void SelectImapFolderWidget::slotModelLoaded(QStandardItemModel *model, bool success)
0073 {
0074     if (mModel == model) {
0075         mTreeView->setStatus(success ? SelectImapFolderTreeView::Success : SelectImapFolderTreeView::Failed);
0076     }
0077 }
0078 
0079 void SelectImapFolderWidget::slotSearchPattern(const QString &pattern)
0080 {
0081     mTreeView->expandAll();
0082     mFilter->setFilterFixedString(pattern);
0083 }
0084 
0085 void SelectImapFolderWidget::slotDoubleClicked(const QModelIndex &index)
0086 {
0087     if (index.isValid()) {
0088         Q_EMIT folderSelected();
0089     }
0090 }
0091 
0092 QString SelectImapFolderWidget::selectedFolderName() const
0093 {
0094     QString currentPath;
0095     const QModelIndex index = mTreeView->currentIndex();
0096     if (index.isValid()) {
0097         currentPath = index.data(SelectImapLoadFoldersJob::PathRole).toString();
0098     }
0099     return currentPath;
0100 }
0101 
0102 void SelectImapFolderWidget::createFolder()
0103 {
0104     const QModelIndex index = mTreeView->currentIndex();
0105     if (index.isValid()) {
0106         bool ok = false;
0107         const QString name = QInputDialog::getText(this, i18n("Create Folder"), i18n("Folder Name:"), {}, {}, &ok);
0108         if (!ok) {
0109             return;
0110         }
0111         if (!name.trimmed().isEmpty()) {
0112             const QString currentPath = index.data(SelectImapLoadFoldersJob::PathRole).toString();
0113             if (name.contains(QLatin1Char('/'))) {
0114                 KMessageBox::error(this, i18n("Slashes are not allowed in folder names."), i18n("Create Folder"));
0115                 return;
0116             }
0117             // TODO more check for folder name ?
0118             SelectImapFolderModel::self()->createNewFolder(mAccount, currentPath + QLatin1Char('/') + name);
0119         } else {
0120             KMessageBox::error(this, i18n("Empty folder name is not supported."), i18nc("@title:window", "Create Folder"));
0121         }
0122     }
0123 }
0124 
0125 void SelectImapFolderWidget::slotCurrentChanged(const QModelIndex &current, const QModelIndex &previous)
0126 {
0127     Q_UNUSED(previous)
0128     Q_EMIT folderIsSelected(current.isValid());
0129 }
0130 
0131 void SelectImapFolderWidget::slotRefreshImap()
0132 {
0133     SelectImapFolderModel::self()->reloadFolderModel(mAccount);
0134 }
0135 
0136 #include "moc_selectimapfolderwidget.cpp"