File indexing completed on 2024-04-28 05:27:04

0001 /* This file is part of the KDE project
0002    SPDX-FileCopyrightText: 2022 Marco Rebhan <me@dblsaiko.net>
0003 
0004    SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
0005 */
0006 
0007 #include "multiapplydialog.h"
0008 
0009 #include "typeslistitem.h"
0010 #include "typeslistproxyitem.h"
0011 #include "typeslisttreewidget.h"
0012 #include <KLocalizedString>
0013 #include <QDialogButtonBox>
0014 #include <QVBoxLayout>
0015 
0016 MultiApplyDialog::MultiApplyDialog(const TypesListItem *source, const QList<TypesListItem *> &sourceItemList, QWidget *parent)
0017     : QDialog(parent)
0018 {
0019     setWindowTitle(i18n("Apply To..."));
0020     resize(400, 500);
0021 
0022     QVBoxLayout *l = new QVBoxLayout(this);
0023     QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0024     m_mimeTree = new TypesListTreeWidget(this);
0025     m_mimeTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
0026 
0027     m_mimeTree->setHeaderLabel(i18n("Known Types"));
0028 
0029     l->addWidget(m_mimeTree);
0030     l->addWidget(buttons);
0031 
0032     connect(m_mimeTree, &QTreeWidget::itemChanged, this, &MultiApplyDialog::onItemChanged);
0033     connect(buttons, &QDialogButtonBox::accepted, this, &MultiApplyDialog::accept);
0034     connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
0035 
0036     load(source, sourceItemList);
0037 }
0038 
0039 MultiApplyDialog::~MultiApplyDialog()
0040 {
0041 }
0042 
0043 const QList<TypesListItem *> MultiApplyDialog::selected() const
0044 {
0045     return m_selected;
0046 }
0047 
0048 void MultiApplyDialog::onItemChanged(QTreeWidgetItem *qitem, int column)
0049 {
0050     auto *item = static_cast<TypesListProxyItem *>(qitem);
0051 
0052     if (column != 0) {
0053         return;
0054     }
0055 
0056     QTreeWidgetItem *parent = item->parent();
0057 
0058     Qt::CheckState checkState = item->checkState(0);
0059 
0060     switch (checkState) {
0061     case Qt::Unchecked:
0062     case Qt::Checked:
0063         if (parent) {
0064             if (checkState == Qt::Unchecked) {
0065                 m_selected.removeAll(item->inner());
0066             } else {
0067                 if (!m_selected.contains(item->inner())) {
0068                     m_selected.append(item->inner());
0069                 }
0070             }
0071 
0072             if (parent->childCount() > 1) {
0073                 bool hasOtherState = false;
0074 
0075                 for (int i = 0; i < parent->childCount(); i += 1) {
0076                     auto *child = parent->child(i);
0077 
0078                     if (child != m_source && child->checkState(0) != checkState) {
0079                         hasOtherState = true;
0080                         break;
0081                     }
0082                 }
0083 
0084                 if (hasOtherState) {
0085                     parent->setCheckState(0, Qt::PartiallyChecked);
0086                 } else {
0087                     parent->setCheckState(0, checkState);
0088                 }
0089             } else {
0090                 parent->setCheckState(0, checkState);
0091             }
0092         }
0093 
0094         for (int i = 0; i < item->childCount(); i += 1) {
0095             auto *child = item->child(i);
0096 
0097             if (child != m_source) {
0098                 child->setCheckState(0, checkState);
0099             }
0100         }
0101 
0102         break;
0103     case Qt::PartiallyChecked:
0104         break;
0105     }
0106 }
0107 
0108 void MultiApplyDialog::load(const TypesListItem *source, const QList<TypesListItem *> &sourceItemList)
0109 {
0110     QMap<QString, TypesListProxyItem *> majorMap;
0111     m_mimeTree->clear();
0112     m_itemList.clear();
0113     m_selected.clear();
0114     m_source = nullptr;
0115 
0116     for (TypesListItem *type : sourceItemList) {
0117         const QString mimetype = type->name();
0118         const int index = mimetype.indexOf(QLatin1Char('/'));
0119         const QString maj = mimetype.left(index);
0120 
0121         TypesListProxyItem *groupItem = majorMap.value(maj);
0122 
0123         if (!groupItem) {
0124             groupItem = new TypesListProxyItem(static_cast<TypesListItem *>(type->parent()), m_mimeTree);
0125             groupItem->setCheckState(0, Qt::Unchecked);
0126             majorMap.insert(maj, groupItem);
0127         }
0128 
0129         TypesListProxyItem *item = new TypesListProxyItem(type, groupItem);
0130         item->setCheckState(0, Qt::Unchecked);
0131 
0132         if (type == source) {
0133             item->setFlags(Qt::ItemFlags());
0134             item->setCheckState(0, Qt::Checked);
0135             m_source = item;
0136         }
0137 
0138         m_itemList.append(item);
0139     }
0140 }
0141 
0142 #include "moc_multiapplydialog.cpp"