File indexing completed on 2025-01-12 06:47:28
0001 // 0002 // C++ Implementation: clist 0003 // 0004 // Description: Viewer of the object model. 0005 // 0006 /* 0007 Copyright 2008-2011 Tomas Mecir <kmuddy@kmuddy.com> 0008 0009 This program is free software; you can redistribute it and/or 0010 modify it under the terms of the GNU General Public License as 0011 published by the Free Software Foundation; either version 2 of 0012 the License, or (at your option) any later version. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #include "clistviewer.h" 0024 0025 #include "clist.h" 0026 #include "clistmanager.h" 0027 #include "clistgroup.h" 0028 #include <KActionCollection> 0029 #include <KLocalizedString> 0030 #include <kmessagebox.h> 0031 0032 #include <QAction> 0033 #include <QContextMenuEvent> 0034 #include <QHeaderView> 0035 #include <QIcon> 0036 #include <QInputDialog> 0037 #include <QMenu> 0038 #include <QStandardItemModel> 0039 #include <QRegExpValidator> 0040 0041 struct cListViewer::Private { 0042 cList *list; 0043 cListObject *currentItem; 0044 QStandardItemModel *emptyModel; 0045 QMenu *objectMenu, *groupMenu, *outsideMenu; 0046 QRegExpValidator *validator; 0047 KActionCollection *col; 0048 }; 0049 0050 cListViewer::cListViewer (QWidget *parent) 0051 : QTreeView (parent) 0052 { 0053 d = new Private; 0054 d->currentItem = nullptr; 0055 d->emptyModel = new QStandardItemModel; 0056 setList (nullptr); 0057 header()->hide(); // no header 0058 d->validator = new QRegExpValidator (QRegExp("^[0-9A-Za-z_ ]+$"), this); 0059 d->col = new KActionCollection (this); 0060 0061 // create the actions and popup menus 0062 QAction *actDeleteObj = new QAction (this); 0063 actDeleteObj->setText (i18n ("Delete object")); 0064 actDeleteObj->setIcon (QIcon::fromTheme ("list-remove")); 0065 connect (actDeleteObj, &QAction::triggered, this, &cListViewer::deleteObject); 0066 d->col->addAction ("DeleteObject", actDeleteObj); 0067 QAction *actDeleteGroup = new QAction (this); 0068 actDeleteGroup->setText (i18n ("Delete group")); 0069 connect (actDeleteGroup, &QAction::triggered, this, &cListViewer::deleteObject); 0070 d->col->addAction ("DeleteGroup", actDeleteGroup); 0071 QAction *actAddSubGroup = new QAction (this); 0072 actAddSubGroup->setText (i18n ("Add subgroup")); 0073 actAddSubGroup->setIcon (QIcon::fromTheme ("folder-new")); 0074 connect (actAddSubGroup, &QAction::triggered, this, &cListViewer::addGroup); 0075 d->col->addAction ("AddSubGroup", actAddSubGroup); 0076 QAction *actAddGroup = new QAction (this); 0077 actAddGroup->setText (i18n ("Add group")); 0078 actAddGroup->setIcon (QIcon::fromTheme ("folder-new")); 0079 connect (actAddGroup, &QAction::triggered, this, &cListViewer::addGroup); 0080 d->col->addAction ("AddGroup", actAddGroup); 0081 QAction *actAddObject = new QAction (this); 0082 actAddObject->setText (i18n ("Add object")); 0083 actAddObject->setIcon (QIcon::fromTheme ("list-add")); 0084 connect (actAddObject, &QAction::triggered, this, &cListViewer::addObject); 0085 d->col->addAction ("AddObject", actAddObject); 0086 0087 d->outsideMenu = new QMenu (this); 0088 d->outsideMenu->addAction (actAddGroup); 0089 d->outsideMenu->addAction (actAddObject); 0090 d->objectMenu = new QMenu (this); 0091 d->objectMenu->addAction (actDeleteObj); 0092 d->groupMenu = new QMenu (this); 0093 d->groupMenu->addAction (actAddObject); 0094 d->groupMenu->addAction (actAddSubGroup); 0095 d->groupMenu->addAction (actDeleteGroup); 0096 0097 setSelectionMode (SingleSelection); 0098 0099 setDragDropMode (InternalMove); 0100 setDragEnabled (true); 0101 setAcceptDrops (true); 0102 setDropIndicatorShown (true); 0103 } 0104 0105 cListViewer::~cListViewer () 0106 { 0107 delete d->col; 0108 delete d->validator; 0109 delete d->emptyModel; 0110 delete d; 0111 } 0112 0113 void cListViewer::setList (cList *l) 0114 { 0115 d->list = l; 0116 d->currentItem = nullptr; 0117 setModel (l ? l->model() : d->emptyModel); 0118 } 0119 0120 void cListViewer::selectObject (cListObject *obj) 0121 { 0122 QModelIndex index = obj->list()->indexOf (obj); 0123 scrollTo (index); 0124 setCurrentIndex (index); 0125 } 0126 0127 KActionCollection *cListViewer::actionCollection () 0128 { 0129 return d->col; 0130 } 0131 0132 void cListViewer::currentChanged (const QModelIndex ¤t, const QModelIndex &) 0133 { 0134 if (!d->list) return; 0135 d->currentItem = d->list->objectAt (current); 0136 emit itemActivated (d->currentItem); 0137 } 0138 0139 void cListViewer::contextMenuEvent (QContextMenuEvent *event) 0140 { 0141 if (!d->list) return; 0142 // we need to figure out which object we clicked on, and display the 0143 // appropriate context menu 0144 QMenu *menu = d->outsideMenu; 0145 QModelIndex index = indexAt (event->pos()); 0146 if (index.isValid()) { 0147 d->currentItem = d->list->objectAt (index); 0148 menu = d->currentItem->isGroup() ? d->groupMenu : d->objectMenu; 0149 } 0150 menu->exec (event->globalPos()); 0151 } 0152 0153 void cListViewer::deleteObject () { 0154 if (!d->list) return; 0155 // verify that the object still exists 0156 if (!cListManager::self()->objectId (d->currentItem)) return; 0157 0158 // ask for confirmation 0159 QString message1; 0160 QString message2; 0161 if (d->currentItem->isGroup()) { 0162 message1 = i18n ("Do you really want to delete this group?"); 0163 message2 = i18n ("Delete group"); 0164 } else { 0165 message1 = i18n ("Do you really want to delete this %1?", d->list->objName()); 0166 message2 = i18n ("Delete %1", d->list->objName()); 0167 } 0168 if (KMessageBox::questionTwoActions (this, message1, message2, KGuiItem(i18n("Delete")), KStandardGuiItem::cancel()) != KMessageBox::PrimaryAction) return; 0169 0170 // verify that the object still exists 0171 if (!cListManager::self()->objectId (d->currentItem)) return; 0172 0173 // delete the object 0174 if (d->currentItem->isGroup()) 0175 d->list->removeGroup ((cListGroup *) d->currentItem); 0176 else 0177 d->list->deleteObject (d->currentItem); 0178 } 0179 0180 void cListViewer::addGroup () { 0181 if (!d->list) return; 0182 cListObject *obj = d->currentItem; 0183 // nothing selected ? use root 0184 if (!obj) obj = d->list->rootGroup(); 0185 // verify that the group still exists 0186 if (!cListManager::self()->objectId (obj)) return; 0187 // selected object not a group ? use its parent 0188 if ((!obj->isGroup())) obj = obj->parentGroup(); 0189 0190 // ask for group name 0191 bool ok = false; 0192 QString name = QInputDialog::getText (this, i18n ("Create Group"), i18n ("Please enter the group name:"), QLineEdit::Normal, QString(), &ok); 0193 if (!ok) return; 0194 int pos = 0; 0195 if (d->validator->validate(name, pos) != QValidator::Acceptable) { 0196 KMessageBox::error (this, i18n ("Cannot create the group, as the provided name is not valid.")); 0197 return; 0198 } 0199 0200 // check if such group exists yet 0201 cListGroup *g = d->list->group (name); 0202 if (g) { 0203 KMessageBox::error (this, i18n ("Cannot create the group, as a group with this name already exists.")); 0204 return; 0205 } 0206 0207 // verify that the group still exists 0208 if (!cListManager::self()->objectId (obj)) return; 0209 0210 // add a subgroup to the given group 0211 d->list->addGroup ((cListGroup *) obj, name); 0212 // and select it 0213 selectObject (d->list->group (name)); 0214 } 0215 0216 void cListViewer::addObject () { 0217 if (!d->list) return; 0218 cListObject *obj = d->currentItem; 0219 if (!obj) obj = d->list->rootGroup(); // nothing selected ? use root 0220 // verify that the group still exists 0221 if (!cListManager::self()->objectId (obj)) return; 0222 // selected object not a group ? use its parent 0223 if ((!obj->isGroup())) obj = obj->parentGroup(); 0224 0225 // create the object 0226 cListObject *o = d->list->newObject(); 0227 d->list->addToGroup ((cListGroup *) obj, o); 0228 // and select it 0229 selectObject (o); 0230 } 0231 0232 void cListViewer::moveDown () 0233 { 0234 cListObject *obj = d->currentItem; 0235 if (!obj) return; 0236 obj->parentGroup()->moveObjectDown (obj->positionInGroup()); 0237 selectObject (obj); 0238 } 0239 0240 void cListViewer::moveUp () 0241 { 0242 cListObject *obj = d->currentItem; 0243 if (!obj) return; 0244 obj->parentGroup()->moveObjectUp (obj->positionInGroup()); 0245 selectObject (obj); 0246 } 0247 0248 void cListViewer::moveLeft () 0249 { 0250 cListObject *obj = d->currentItem; 0251 if (!obj) return; 0252 // find parent group - it must not be the root group 0253 cListGroup *parent = obj->parentGroup(); 0254 if (parent == d->list->rootGroup()) return; 0255 0256 // move the object to the parent's parent, under the current parent 0257 int pos = parent->positionInGroup (); 0258 cList *list = obj->list(); 0259 list->addToGroup (parent->parentGroup(), obj); 0260 parent->parentGroup()->moveObjectToPosition (obj, pos + 1); 0261 selectObject (obj); 0262 } 0263 0264 void cListViewer::moveRight () 0265 { 0266 cListObject *obj = d->currentItem; 0267 if (!obj) return; 0268 // the object above us must be a group 0269 // we become the last child of that group 0270 int pos = obj->positionInGroup (); 0271 if (pos == 0) return; 0272 cListObject *g = obj->parentGroup()->objectAt (pos - 1); 0273 if (!g->isGroup()) return; 0274 obj->list()->addToGroup ((cListGroup *) g, obj); 0275 0276 selectObject (obj); 0277 } 0278 0279 #include "moc_clistviewer.cpp"