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 }