File indexing completed on 2024-09-22 04:49:58

0001 /*
0002 
0003   SPDX-FileCopyrightText: 2011-2024 Laurent Montel <montel@kde.org>
0004 
0005   SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "filteractionmissingfolderdialog.h"
0009 #include "folder/folderrequester.h"
0010 #include "kernel/mailkernel.h"
0011 #include "util/mailutil.h"
0012 
0013 #include <Akonadi/EntityMimeTypeFilterModel>
0014 
0015 #include <KLocalizedString>
0016 
0017 #include <KConfigGroup>
0018 #include <KWindowConfig>
0019 #include <QDialogButtonBox>
0020 #include <QLabel>
0021 #include <QListWidget>
0022 #include <QPushButton>
0023 #include <QVBoxLayout>
0024 #include <QWindow>
0025 namespace
0026 {
0027 static const char myFilterActionMissingCollectionDialogConfigGroupName[] = "FilterActionMissingCollectionDialog";
0028 }
0029 
0030 FilterActionMissingFolderDialog::FilterActionMissingFolderDialog(const Akonadi::Collection::List &list,
0031                                                                  const QString &filtername,
0032                                                                  const QString &argStr,
0033                                                                  QWidget *parent)
0034     : QDialog(parent)
0035     , mFolderRequester(new MailCommon::FolderRequester(this))
0036 {
0037     setModal(true);
0038     setWindowTitle(i18nc("@title:window", "Select Folder"));
0039     auto mainLayout = new QVBoxLayout(this);
0040 
0041     auto lab = new QLabel(i18n("Folder path was \"%1\".", argStr));
0042     lab->setObjectName(QLatin1StringView("argumentlabel"));
0043     lab->setWordWrap(true);
0044     mainLayout->addWidget(lab);
0045     if (!list.isEmpty()) {
0046         lab = new QLabel(i18n("The following folders can be used for this filter:"));
0047         lab->setObjectName(QLatin1StringView("label"));
0048         lab->setWordWrap(true);
0049         mainLayout->addWidget(lab);
0050         mListwidget = new QListWidget(this);
0051         mainLayout->addWidget(mListwidget);
0052         const int numberOfItems(list.count());
0053         for (int i = 0; i < numberOfItems; ++i) {
0054             const Akonadi::Collection col = list.at(i);
0055             auto item = new QListWidgetItem(MailCommon::Util::fullCollectionPath(col));
0056             item->setData(FilterActionMissingFolderDialog::IdentifyCollection, col.id());
0057             mListwidget->addItem(item);
0058         }
0059         connect(mListwidget, &QListWidget::currentItemChanged, this, &FilterActionMissingFolderDialog::slotCurrentItemChanged);
0060         connect(mListwidget, &QListWidget::itemDoubleClicked, this, &FilterActionMissingFolderDialog::slotDoubleItemClicked);
0061     }
0062 
0063     auto label = new QLabel(this);
0064     label->setObjectName(QLatin1StringView("folderlabel"));
0065     label->setWordWrap(true);
0066     if (filtername.isEmpty()) {
0067         label->setText(i18n("Please select a folder:"));
0068     } else {
0069         label->setText(
0070             i18n("Filter folder is missing. "
0071                  "Please select a folder to use with filter \"%1\":",
0072                  filtername));
0073     }
0074     mainLayout->addWidget(label);
0075     mFolderRequester->setObjectName(QLatin1StringView("folderrequester"));
0076     connect(mFolderRequester, &MailCommon::FolderRequester::folderChanged, this, &FilterActionMissingFolderDialog::slotFolderChanged);
0077     mainLayout->addWidget(mFolderRequester);
0078     mainLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Expanding));
0079 
0080     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0081     buttonBox->setObjectName(QLatin1StringView("buttonbox"));
0082     mOkButton = buttonBox->button(QDialogButtonBox::Ok);
0083     mOkButton->setDefault(true);
0084     mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0085     mOkButton->setEnabled(false);
0086     connect(buttonBox, &QDialogButtonBox::accepted, this, &FilterActionMissingFolderDialog::accept);
0087     connect(buttonBox, &QDialogButtonBox::rejected, this, &FilterActionMissingFolderDialog::reject);
0088     mainLayout->addWidget(buttonBox);
0089     readConfig();
0090 }
0091 
0092 FilterActionMissingFolderDialog::~FilterActionMissingFolderDialog()
0093 {
0094     writeConfig();
0095 }
0096 
0097 void FilterActionMissingFolderDialog::readConfig()
0098 {
0099     create(); // ensure a window is created
0100     windowHandle()->resize(QSize(500, 300));
0101     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myFilterActionMissingCollectionDialogConfigGroupName));
0102     KWindowConfig::restoreWindowSize(windowHandle(), group);
0103     resize(windowHandle()->size()); // workaround for QTBUG-40584
0104 }
0105 
0106 void FilterActionMissingFolderDialog::writeConfig()
0107 {
0108     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myFilterActionMissingCollectionDialogConfigGroupName));
0109     KWindowConfig::saveWindowSize(windowHandle(), group);
0110     group.sync();
0111 }
0112 
0113 void FilterActionMissingFolderDialog::slotFolderChanged(const Akonadi::Collection &col)
0114 {
0115     mOkButton->setEnabled(col.isValid());
0116 }
0117 
0118 void FilterActionMissingFolderDialog::slotDoubleItemClicked(QListWidgetItem *item)
0119 {
0120     if (!item) {
0121         return;
0122     }
0123 
0124     const Akonadi::Collection::Id id = item->data(FilterActionMissingFolderDialog::IdentifyCollection).toLongLong();
0125 
0126     mFolderRequester->setCollection(Akonadi::Collection(id));
0127     accept();
0128 }
0129 
0130 void FilterActionMissingFolderDialog::slotCurrentItemChanged()
0131 {
0132     QListWidgetItem *currentItem = mListwidget->currentItem();
0133     if (currentItem) {
0134         const Akonadi::Collection::Id id = currentItem->data(FilterActionMissingFolderDialog::IdentifyCollection).toLongLong();
0135         mFolderRequester->setCollection(Akonadi::Collection(id));
0136     }
0137 }
0138 
0139 Akonadi::Collection FilterActionMissingFolderDialog::selectedCollection() const
0140 {
0141     return mFolderRequester->collection();
0142 }
0143 
0144 void FilterActionMissingFolderDialog::getPotentialFolders(const QAbstractItemModel *model,
0145                                                           const QModelIndex &parentIndex,
0146                                                           const QString &lastElement,
0147                                                           Akonadi::Collection::List &list)
0148 {
0149     const int rowCount = model->rowCount(parentIndex);
0150     for (int row = 0; row < rowCount; ++row) {
0151         const QModelIndex index = model->index(row, 0, parentIndex);
0152         if (model->rowCount(index) > 0) {
0153             getPotentialFolders(model, index, lastElement, list);
0154         }
0155         if (model->data(index).toString() == lastElement) {
0156             list << model->data(index, Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
0157         }
0158     }
0159 }
0160 
0161 Akonadi::Collection::List FilterActionMissingFolderDialog::potentialCorrectFolders(const QString &path, bool &exactPath)
0162 {
0163     Akonadi::Collection::List lst;
0164     const QString realPath = MailCommon::Util::realFolderPath(path);
0165     if (realPath.isEmpty()) {
0166         return lst;
0167     }
0168 
0169     if (KernelIf->collectionModel()) {
0170         const int lastSlash = realPath.lastIndexOf(QLatin1Char('/'));
0171         QString lastElement;
0172         if (lastSlash == -1) {
0173             lastElement = realPath;
0174         } else {
0175             lastElement = realPath.right(realPath.length() - lastSlash - 1);
0176         }
0177 
0178         FilterActionMissingFolderDialog::getPotentialFolders(KernelIf->collectionModel(), QModelIndex(), lastElement, lst);
0179 
0180         const int numberOfItems(lst.count());
0181         for (int i = 0; i < numberOfItems; ++i) {
0182             if (MailCommon::Util::fullCollectionPath(lst.at(i)) == realPath) {
0183                 exactPath = true;
0184                 return Akonadi::Collection::List() << lst.at(i);
0185             }
0186         }
0187     }
0188     return lst;
0189 }
0190 
0191 #include "moc_filteractionmissingfolderdialog.cpp"