File indexing completed on 2024-05-05 17:56:44

0001 /*
0002     SPDX-FileCopyrightText: 2006 Jonas Bähr <jonas.baehr@web.de>
0003     SPDX-FileCopyrightText: 2006-2022 Krusader Krew <https://krusader.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "useractionlistview.h"
0009 
0010 // QtCore
0011 #include <QDebug>
0012 // QtXml
0013 #include <QDomEntity>
0014 
0015 #include <KI18n/KLocalizedString>
0016 
0017 #include "../UserAction/kraction.h"
0018 #include "../UserAction/useraction.h"
0019 #include "../icon.h"
0020 #include "../krglobal.h"
0021 
0022 #define COL_TITLE 0
0023 
0024 // UserActionListView
0025 
0026 UserActionListView::UserActionListView(QWidget *parent)
0027     : KrTreeWidget(parent)
0028 {
0029     setHeaderLabel(i18n("Title"));
0030 
0031     setRootIsDecorated(true);
0032     setSelectionMode(QAbstractItemView::ExtendedSelection); // normally select single items but one may use Ctrl or Shift to select multiple
0033 
0034     setSortingEnabled(true);
0035     sortItems(COL_TITLE, Qt::AscendingOrder);
0036 
0037     connect(this, &UserActionListView::currentItemChanged, this, &UserActionListView::slotCurrentItemChanged);
0038 
0039     update();
0040 }
0041 
0042 UserActionListView::~UserActionListView() = default;
0043 
0044 QSize UserActionListView::sizeHint() const
0045 {
0046     return QSize(200, 400);
0047 }
0048 
0049 void UserActionListView::update()
0050 {
0051     clear();
0052     UserAction::KrActionList list = krUserAction->actionList();
0053 
0054     QListIterator<KrAction *> it(list);
0055     while (it.hasNext())
0056         insertAction(it.next());
0057 }
0058 
0059 void UserActionListView::update(KrAction *action)
0060 {
0061     UserActionListViewItem *item = findActionItem(action);
0062     if (item) {
0063         // deleting & re-inserting is _much_easier then tracking all possible cases of category changes!
0064         bool current = (item == currentItem());
0065         bool selected = item->isSelected();
0066         delete item;
0067         item = insertAction(action);
0068         if (current)
0069             setCurrentItem(item);
0070         if (selected)
0071             item->setSelected(true);
0072     }
0073 }
0074 
0075 UserActionListViewItem *UserActionListView::insertAction(KrAction *action)
0076 {
0077     if (!action)
0078         return nullptr;
0079 
0080     UserActionListViewItem *item;
0081 
0082     if (action->category().isEmpty())
0083         item = new UserActionListViewItem(this, action);
0084     else {
0085         QTreeWidgetItem *categoryItem = findCategoryItem(action->category());
0086         if (!categoryItem) {
0087             categoryItem = new QTreeWidgetItem(this); // create the new category item it not already present
0088             categoryItem->setText(0, action->category());
0089             categoryItem->setFlags(Qt::ItemIsEnabled);
0090         }
0091         item = new UserActionListViewItem(categoryItem, action);
0092     }
0093 
0094     item->setAction(action);
0095     return item;
0096 }
0097 
0098 QTreeWidgetItem *UserActionListView::findCategoryItem(const QString &category)
0099 {
0100     QTreeWidgetItemIterator it(this);
0101     while (*it) {
0102         if ((*it)->text(COL_TITLE) == category && !((*it)->flags() & Qt::ItemIsSelectable))
0103             return *it;
0104         it++;
0105     }
0106     return nullptr;
0107 }
0108 
0109 UserActionListViewItem *UserActionListView::findActionItem(const KrAction *action)
0110 {
0111     QTreeWidgetItemIterator it(this);
0112     while (*it) {
0113         if (auto *item = dynamic_cast<UserActionListViewItem *>(*it)) {
0114             if (item->action() == action)
0115                 return item;
0116         }
0117         it++;
0118     }
0119     return nullptr;
0120 }
0121 
0122 KrAction *UserActionListView::currentAction() const
0123 {
0124     if (auto *item = dynamic_cast<UserActionListViewItem *>(currentItem()))
0125         return item->action();
0126     else
0127         return nullptr;
0128 }
0129 
0130 void UserActionListView::setCurrentAction(const KrAction *action)
0131 {
0132     UserActionListViewItem *item = findActionItem(action);
0133     if (item) {
0134         setCurrentItem(item);
0135     }
0136 }
0137 
0138 void UserActionListView::setFirstActionCurrent()
0139 {
0140     QTreeWidgetItemIterator it(this);
0141     while (*it) {
0142         if (auto *item = dynamic_cast<UserActionListViewItem *>(*it)) {
0143             setCurrentItem(item);
0144             break;
0145         }
0146         it++;
0147     }
0148 }
0149 
0150 void UserActionListView::slotCurrentItemChanged(QTreeWidgetItem *item)
0151 {
0152     if (!item)
0153         return;
0154     scrollTo(indexOf(item));
0155 }
0156 
0157 QDomDocument UserActionListView::dumpSelectedActions(QDomDocument *mergeDoc) const
0158 {
0159     const QList<QTreeWidgetItem *> list = selectedItems();
0160     QDomDocument doc;
0161     if (mergeDoc)
0162         doc = *mergeDoc;
0163     else
0164         doc = UserAction::createEmptyDoc();
0165     QDomElement root = doc.documentElement();
0166 
0167     for (auto item : list) {
0168         if (auto *actionItem = dynamic_cast<UserActionListViewItem *>(item))
0169             root.appendChild(actionItem->action()->xmlDump(doc));
0170     }
0171 
0172     return doc;
0173 }
0174 
0175 void UserActionListView::removeSelectedActions()
0176 {
0177     const QList<QTreeWidgetItem *> list = selectedItems();
0178 
0179     for (auto item : list) {
0180         if (auto *actionItem = dynamic_cast<UserActionListViewItem *>(item)) {
0181             delete actionItem->action(); // remove the action itself
0182             delete actionItem; // remove the action from the list
0183         } // if
0184     }
0185 }
0186 
0187 // UserActionListViewItem
0188 
0189 UserActionListViewItem::UserActionListViewItem(QTreeWidget *view, KrAction *action)
0190     : QTreeWidgetItem(view)
0191 {
0192     setAction(action);
0193 }
0194 
0195 UserActionListViewItem::UserActionListViewItem(QTreeWidgetItem *item, KrAction *action)
0196     : QTreeWidgetItem(item)
0197 {
0198     setAction(action);
0199 }
0200 
0201 UserActionListViewItem::~UserActionListViewItem() = default;
0202 
0203 void UserActionListViewItem::setAction(KrAction *action)
0204 {
0205     if (!action)
0206         return;
0207 
0208     _action = action;
0209     update();
0210 }
0211 
0212 KrAction *UserActionListViewItem::action() const
0213 {
0214     return _action;
0215 }
0216 
0217 void UserActionListViewItem::update()
0218 {
0219     if (!_action)
0220         return;
0221 
0222     if (!_action->icon().isNull())
0223         setIcon(COL_TITLE, Icon(_action->iconName()));
0224     setText(COL_TITLE, _action->text());
0225 }
0226 
0227 bool UserActionListViewItem::operator<(const QTreeWidgetItem &other) const
0228 {
0229     // FIXME some how this only produces bullshit :-/
0230     // if (i->text(COL_NAME).isEmpty()) { // categories only have titles
0231     //     // qDebug() << "this->title: " << text(COL_TITLE) << " |=|   i->title: " << i->text(COL_TITLE);
0232     //     return (ascending ? -1 : 1); // <0 means this is smaller then i
0233     // } else
0234     return QTreeWidgetItem::operator<(other);
0235 }