not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kmenuedit / treeview.cpp
bloba5c74b7baabf081a8659ac1821d7ad82d2832a63
1 /*
2 * Copyright (C) 2000 Matthias Elter <elter@kde.org>
3 * Copyright (C) 2001-2002 Raffaele Sandrini <sandrini@kde.org>
4 * Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
5 * Copyright (C) 2008 Laurent Montel <montel@kde.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <unistd.h>
25 #include <QCursor>
26 #include <QDataStream>
27 #include <QDir>
28 #include <QEvent>
29 #include <QFileInfo>
30 #include <Qt3Support/Q3Header>
31 #include <QPainter>
32 #include <QRegExp>
33 //Added by qt3to4:
34 #include <QPixmap>
35 #include <Q3PtrList>
36 #include <QFrame>
37 #include <QDropEvent>
38 #include <QMenu>
39 #include <QtDBus/QtDBus>
41 #include <kaction.h>
42 #include <kactioncollection.h>
43 #include <kapplication.h>
44 #include <kbuildsycocaprogressdialog.h>
45 #include <kdebug.h>
46 #include <kdesktopfile.h>
47 #include <kglobal.h>
48 #include <kiconloader.h>
49 #include <kinputdialog.h>
50 #include <klocale.h>
51 #include <kmessagebox.h>
52 #include <kservice.h>
53 #include <kservicegroup.h>
54 #include <kconfig.h>
55 #include <kconfiggroup.h>
56 #include <kstandarddirs.h>
57 #include <k3multipledrag.h>
58 #include <k3urldrag.h>
59 #include <kio/netaccess.h>
61 #include "treeview.h"
62 #include "treeview.moc"
63 #include "menufile.h"
64 #include "menuinfo.h"
66 #define MOVE_FOLDER 'M'
67 #define COPY_FOLDER 'C'
68 #define MOVE_FILE 'm'
69 #define COPY_FILE 'c'
70 #define COPY_SEPARATOR 'S'
72 TreeItem::TreeItem(Q3ListViewItem *parent, Q3ListViewItem *after, const QString& menuId, bool __init)
73 :Q3ListViewItem(parent, after), _hidden(false), _init(__init), _layoutDirty(false), _menuId(menuId),
74 m_folderInfo(0), m_entryInfo(0) {}
76 TreeItem::TreeItem(Q3ListView *parent, Q3ListViewItem *after, const QString& menuId, bool __init)
77 : Q3ListViewItem(parent, after), _hidden(false), _init(__init), _layoutDirty(false), _menuId(menuId),
78 m_folderInfo(0), m_entryInfo(0) {}
80 void TreeItem::setName(const QString &name)
82 _name = name;
83 update();
86 void TreeItem::setHidden(bool b)
88 if (_hidden == b) return;
89 _hidden = b;
90 update();
93 void TreeItem::update()
95 QString s = _name;
96 if (_hidden)
97 s += i18n(" [Hidden]");
98 setText(0, s);
101 void TreeItem::setOpen(bool o)
103 if (o)
104 load();
106 Q3ListViewItem::setOpen(o);
109 void TreeItem::load()
111 if (m_folderInfo && !_init)
113 _init = true;
114 TreeView *tv = static_cast<TreeView *>(listView());
115 tv->fillBranch(m_folderInfo, this);
119 void TreeItem::paintCell ( QPainter * p, const QColorGroup & cg, int column, int width, int align )
121 Q3ListViewItem::paintCell(p, cg, column, width, align);
123 if (!m_folderInfo && !m_entryInfo)
125 // Draw Separator
126 int h = (height() / 2) -1;
127 if (isSelected())
128 p->setPen( cg.color( QPalette::HighlightedText ) );
129 else
130 p->setPen( cg.color( QPalette::Text ) );
131 p->drawLine(0, h,
132 width, h);
136 void TreeItem::setup()
138 Q3ListViewItem::setup();
139 if (!m_folderInfo && !m_entryInfo)
140 setHeight(8);
143 static QPixmap appIcon(const QString &iconName)
145 QPixmap normal = KIconLoader::global()->loadIcon(iconName, KIconLoader::Small, 0, KIconLoader::DefaultState, QStringList(), 0L, true);
146 // make sure they are not larger than 20x20
147 if (normal.width() > 20 || normal.height() > 20)
149 QImage tmp = normal.toImage();
150 tmp = tmp.scaled(20, 20, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
151 normal = QPixmap::fromImage(tmp);
153 return normal;
157 TreeView::TreeView( KActionCollection *ac, QWidget *parent, const char *name )
158 : K3ListView(parent), m_ac(ac), m_rmb(0), m_clipboard(0),
159 m_clipboardFolderInfo(0), m_clipboardEntryInfo(0),
160 m_layoutDirty(false)
162 setObjectName(name);
163 setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
164 setAllColumnsShowFocus(true);
165 setRootIsDecorated(true);
166 setSorting(-1);
167 setAcceptDrops(true);
168 setDropVisualizer(true);
169 setDragEnabled(true);
170 setMinimumWidth(240);
172 addColumn("");
173 header()->hide();
175 connect(this, SIGNAL(dropped(QDropEvent*, Q3ListViewItem*, Q3ListViewItem*)),
176 SLOT(slotDropped(QDropEvent*, Q3ListViewItem*, Q3ListViewItem*)));
178 connect(this, SIGNAL(clicked( Q3ListViewItem* )),
179 SLOT(itemSelected( Q3ListViewItem* )));
181 connect(this,SIGNAL(selectionChanged ( Q3ListViewItem * )),
182 SLOT(itemSelected( Q3ListViewItem* )));
184 connect(this, SIGNAL(rightButtonPressed(Q3ListViewItem*, const QPoint&, int)),
185 SLOT(slotRMBPressed(Q3ListViewItem*, const QPoint&)));
187 // connect actions
188 connect(m_ac->action("newitem"), SIGNAL(activated()), SLOT(newitem()));
189 connect(m_ac->action("newsubmenu"), SIGNAL(activated()), SLOT(newsubmenu()));
190 connect(m_ac->action("newsep"), SIGNAL(activated()), SLOT(newsep()));
192 m_menuFile = new MenuFile( KStandardDirs::locateLocal("xdgconf-menu", "applications-kmenuedit.menu"));
193 m_rootFolder = new MenuFolderInfo;
194 m_separator = new MenuSeparatorInfo;
195 m_drag = 0;
196 #if 0
197 // Read menu format configuration information
198 KSharedConfig::Ptr pConfig = KSharedConfig::openConfig("kickerrc");
199 KConfigGroup cg(pConfig, "menus");
200 m_detailedMenuEntries = cg.readEntry("DetailedMenuEntries", true);
201 if (m_detailedMenuEntries)
203 m_detailedEntriesNamesFirst = cg.readEntry("DetailedEntriesNamesFirst", false);
205 #endif
208 TreeView::~TreeView() {
209 cleanupClipboard();
210 delete m_rootFolder;
211 delete m_separator;
214 void TreeView::setViewMode(bool showHidden)
216 delete m_rmb;
218 // setup rmb menu
219 m_rmb = new QMenu(this);
220 QAction *action;
222 action = m_ac->action("edit_cut");
223 m_rmb->addAction( action );
224 action->setEnabled(false);
225 connect(action, SIGNAL(activated()), SLOT(cut()));
227 action = m_ac->action("edit_copy");
228 m_rmb->addAction( action );
229 action->setEnabled(false);
230 connect(action, SIGNAL(activated()), SLOT(copy()));
232 action = m_ac->action("edit_paste");
233 m_rmb->addAction( action );
234 action->setEnabled(false);
235 connect(action, SIGNAL(activated()), SLOT(paste()));
237 m_rmb->addSeparator();
239 action = m_ac->action("delete");
240 m_rmb->addAction( action );
241 action->setEnabled(false);
242 connect(action, SIGNAL(activated()), SLOT(del()));
244 m_rmb->addSeparator();
246 m_rmb->addAction( m_ac->action("newitem") );
247 m_rmb->addAction( m_ac->action("newsubmenu") );
248 m_rmb->addAction( m_ac->action("newsep") );
250 m_showHidden = showHidden;
251 readMenuFolderInfo();
252 fill();
255 void TreeView::readMenuFolderInfo(MenuFolderInfo *folderInfo, KServiceGroup::Ptr folder, const QString &prefix)
257 if (!folderInfo)
259 folderInfo = m_rootFolder;
260 folder = KServiceGroup::root();
263 if (!folder || !folder->isValid())
264 return;
266 folderInfo->caption = folder->caption();
267 folderInfo->comment = folder->comment();
269 // Item names may contain ampersands. To avoid them being converted
270 // to accelerators, replace them with two ampersands.
271 folderInfo->hidden = folder->noDisplay();
272 folderInfo->directoryFile = folder->directoryEntryPath();
273 folderInfo->icon = folder->icon();
274 QString id = folder->relPath();
275 int i = id.lastIndexOf('/', -2);
276 id = id.mid(i+1);
277 folderInfo->id = id;
278 folderInfo->fullId = prefix + id;
280 foreach(const KSycocaEntry::Ptr &e, folder->entries(true, !m_showHidden, true, m_detailedMenuEntries && !m_detailedEntriesNamesFirst))
282 if (e->isType(KST_KServiceGroup))
284 KServiceGroup::Ptr g(KServiceGroup::Ptr::staticCast(e));
285 MenuFolderInfo *subFolderInfo = new MenuFolderInfo();
286 readMenuFolderInfo(subFolderInfo, g, folderInfo->fullId);
287 folderInfo->add(subFolderInfo, true);
289 else if (e->isType(KST_KService))
291 folderInfo->add(new MenuEntryInfo(KService::Ptr::staticCast(e)), true);
293 else if (e->isType(KST_KServiceSeparator))
295 folderInfo->add(m_separator, true);
300 void TreeView::fill()
302 QApplication::setOverrideCursor(Qt::WaitCursor);
303 clear();
304 fillBranch(m_rootFolder, 0);
305 QApplication::restoreOverrideCursor();
308 QString TreeView::findName(KDesktopFile *df, bool deleted)
310 QString name = df->readName();
311 if (deleted)
313 if (name == "empty")
314 name.clear();
315 if (name.isEmpty())
317 QString file = df->fileName();
318 QString res = df->resource();
320 bool isLocal = true;
321 const QStringList files = KGlobal::dirs()->findAllResources(res.toLatin1(), file);
322 for(QStringList::ConstIterator it = files.constBegin();
323 it != files.constEnd();
324 ++it)
326 if (isLocal)
328 isLocal = false;
329 continue;
332 KDesktopFile df2(*it);
333 name = df2.readName();
335 if (!name.isEmpty() && (name != "empty"))
336 return name;
340 return name;
343 TreeItem *TreeView::createTreeItem(TreeItem *parent, Q3ListViewItem *after, MenuFolderInfo *folderInfo, bool _init)
345 TreeItem *item;
346 if (parent == 0)
347 item = new TreeItem(this, after, QString(), _init);
348 else
349 item = new TreeItem(parent, after, QString(), _init);
351 item->setMenuFolderInfo(folderInfo);
352 item->setName(folderInfo->caption);
353 item->setPixmap(0, appIcon(folderInfo->icon));
354 item->setDirectoryPath(folderInfo->fullId);
355 item->setHidden(folderInfo->hidden);
356 item->setExpandable(true);
357 return item;
360 TreeItem *TreeView::createTreeItem(TreeItem *parent, Q3ListViewItem *after, MenuEntryInfo *entryInfo, bool _init)
362 bool hidden = entryInfo->hidden;
364 TreeItem* item;
365 if (parent == 0)
366 item = new TreeItem(this, after, entryInfo->menuId(), _init);
367 else
368 item = new TreeItem(parent, after, entryInfo->menuId(),_init);
370 QString name;
372 if (m_detailedMenuEntries && entryInfo->description.length() != 0)
374 if (m_detailedEntriesNamesFirst)
376 name = entryInfo->caption + " (" + entryInfo->description + ')';
378 else
380 name = entryInfo->description + " (" + entryInfo->caption + ')';
383 else
385 name = entryInfo->caption;
387 item->setMenuEntryInfo(entryInfo);
388 item->setName(name);
389 item->setPixmap(0, appIcon(entryInfo->icon));
391 item->setHidden(hidden);
392 return item;
395 TreeItem *TreeView::createTreeItem(TreeItem *parent, Q3ListViewItem *after, MenuSeparatorInfo *, bool _init)
397 TreeItem* item;
398 if (parent == 0)
399 item = new TreeItem(this, after, QString(), _init);
400 else
401 item = new TreeItem(parent, after, QString(),_init);
403 return item;
406 void TreeView::fillBranch(MenuFolderInfo *folderInfo, TreeItem *parent)
408 QString relPath = parent ? parent->directory() : QString();
409 Q3PtrListIterator<MenuInfo> it( folderInfo->initialLayout );
410 TreeItem *after = 0;
411 for (MenuInfo *info; (info = it.current()); ++it)
413 MenuEntryInfo *entry = dynamic_cast<MenuEntryInfo*>(info);
414 if (entry)
416 after = createTreeItem(parent, after, entry);
417 continue;
420 MenuFolderInfo *subFolder = dynamic_cast<MenuFolderInfo*>(info);
421 if (subFolder)
423 after = createTreeItem(parent, after, subFolder);
424 continue;
426 MenuSeparatorInfo *separator = dynamic_cast<MenuSeparatorInfo*>(info);
427 if (separator)
429 after = createTreeItem(parent, after, separator);
430 continue;
435 void TreeView::closeAllItems(Q3ListViewItem *item)
437 if (!item) return;
438 while(item)
440 item->setOpen(false);
441 closeAllItems(item->firstChild());
442 item = item->nextSibling();
446 void TreeView::selectMenu(const QString &menu)
448 closeAllItems(firstChild());
450 if (menu.length() <= 1)
452 setCurrentItem(firstChild());
453 clearSelection();
454 return; // Root menu
457 QString restMenu = menu;
458 if ( menu.startsWith( '/' ) )
459 restMenu = menu.mid(1);
460 if (!restMenu.endsWith('/'))
461 restMenu += '/';
463 TreeItem *item = 0;
466 int i = restMenu.indexOf("/");
467 QString subMenu = restMenu.left(i+1);
468 restMenu = restMenu.mid(i+1);
470 item = (TreeItem*)(item ? item->firstChild() : firstChild());
471 while(item)
473 MenuFolderInfo *folderInfo = item->folderInfo();
474 if (folderInfo && (folderInfo->id == subMenu))
476 item->setOpen(true);
477 break;
479 item = (TreeItem*) item->nextSibling();
482 while( item && !restMenu.isEmpty());
484 if (item)
486 setCurrentItem(item);
487 ensureItemVisible(item);
491 void TreeView::selectMenuEntry(const QString &menuEntry)
493 TreeItem *item = (TreeItem *) selectedItem();
494 if (!item)
496 item = (TreeItem *) currentItem();
497 while (item && item->isDirectory())
498 item = (TreeItem*) item->nextSibling();
500 else
501 item = (TreeItem *) item->firstChild();
503 while(item)
505 MenuEntryInfo *entry = item->entryInfo();
506 if (entry )
508 kDebug()<<" entry->menuId() :"<<entry->menuId();
509 if ( entry->menuId() == menuEntry )
511 setCurrentItem(item);
512 ensureItemVisible(item);
513 return;
516 item = (TreeItem*) item->nextSibling();
520 void TreeView::itemSelected(Q3ListViewItem *item)
522 TreeItem *_item = (TreeItem*)item;
523 bool selected = false;
524 bool dselected = false;
525 if (_item) {
526 selected = true;
527 dselected = _item->isHidden();
530 m_ac->action("edit_cut")->setEnabled(selected);
531 m_ac->action("edit_copy")->setEnabled(selected);
533 if (m_ac->action("delete"))
534 m_ac->action("delete")->setEnabled(selected && !dselected);
536 if(!item)
538 emit disableAction();
539 return;
542 if (_item->isDirectory())
543 emit entrySelected(_item->folderInfo());
544 else
545 emit entrySelected(_item->entryInfo());
548 void TreeView::currentChanged(MenuFolderInfo *folderInfo)
550 TreeItem *item = (TreeItem*)selectedItem();
551 if (item == 0) return;
552 if (folderInfo == 0) return;
554 item->setName(folderInfo->caption);
555 item->setPixmap(0, appIcon(folderInfo->icon));
558 void TreeView::currentChanged(MenuEntryInfo *entryInfo)
560 TreeItem *item = (TreeItem*)selectedItem();
561 if (item == 0) return;
562 if (entryInfo == 0) return;
564 QString name;
566 if (m_detailedMenuEntries && entryInfo->description.length() != 0)
568 if (m_detailedEntriesNamesFirst)
570 name = entryInfo->caption + " (" + entryInfo->description + ')';
572 else
574 name = entryInfo->description + " (" + entryInfo->caption + ')';
577 else
579 name = entryInfo->caption;
581 item->setName(name);
582 item->setPixmap(0, appIcon(entryInfo->icon));
585 QStringList TreeView::fileList(const QString& rPath)
587 QString relativePath = rPath;
589 // truncate "/.directory"
590 int pos = relativePath.lastIndexOf("/.directory");
591 if (pos > 0) relativePath.truncate(pos);
593 QStringList filelist;
595 // loop through all resource dirs and build a file list
596 const QStringList resdirlist = KGlobal::dirs()->resourceDirs("apps");
597 for (QStringList::ConstIterator it = resdirlist.constBegin(); it != resdirlist.constEnd(); ++it)
599 QDir dir((*it) + '/' + relativePath);
600 if(!dir.exists()) continue;
602 dir.setFilter(QDir::Files);
603 dir.setNameFilters(QStringList() << "*.desktop;*.kdelnk");
605 // build a list of files
606 const QStringList files = dir.entryList();
607 for (QStringList::ConstIterator it = files.constBegin(); it != files.constEnd(); ++it) {
608 // does not work?!
609 //if (filelist.contains(*it)) continue;
611 if (relativePath.isEmpty()) {
612 filelist.removeAll(*it); // hack
613 filelist.append(*it);
615 else {
616 filelist.removeAll(relativePath + '/' + *it); //hack
617 filelist.append(relativePath + '/' + *it);
621 return filelist;
624 QStringList TreeView::dirList(const QString& rPath)
626 QString relativePath = rPath;
628 // truncate "/.directory"
629 int pos = relativePath.lastIndexOf("/.directory");
630 if (pos > 0) relativePath.truncate(pos);
632 QStringList dirlist;
634 // loop through all resource dirs and build a subdir list
635 const QStringList resdirlist = KGlobal::dirs()->resourceDirs("apps");
636 for (QStringList::ConstIterator it = resdirlist.constBegin(); it != resdirlist.constEnd(); ++it)
638 QDir dir((*it) + '/' + relativePath);
639 if(!dir.exists()) continue;
640 dir.setFilter(QDir::Dirs);
642 // build a list of subdirs
643 const QStringList subdirs = dir.entryList();
644 for (QStringList::ConstIterator it = subdirs.constBegin(); it != subdirs.constEnd(); ++it) {
645 if ((*it) == "." || (*it) == "..") continue;
646 // does not work?!
647 // if (dirlist.contains(*it)) continue;
649 if (relativePath.isEmpty()) {
650 dirlist.removeAll(*it); //hack
651 dirlist.append(*it);
653 else {
654 dirlist.removeAll(relativePath + '/' + *it); //hack
655 dirlist.append(relativePath + '/' + *it);
659 return dirlist;
662 bool TreeView::acceptDrag(QDropEvent* e) const
664 if (e->provides("application/x-kmenuedit-internal") &&
665 (e->source() == const_cast<TreeView *>(this)))
666 return true;
667 KUrl::List urls;
668 if (K3URLDrag::decode(e, urls) && (urls.count() == 1) &&
669 urls[0].isLocalFile() && urls[0].path().endsWith(".desktop"))
670 return true;
671 return false;
675 static QString createDesktopFile(const QString &file, QString *menuId, QStringList *excludeList)
677 QString base = file.mid(file.lastIndexOf('/')+1);
678 base = base.left(base.lastIndexOf('.'));
680 QRegExp r("(.*)(?=-\\d+)");
681 base = (r.indexIn(base) > -1) ? r.cap(1) : base;
683 QString result = KService::newServicePath(true, base, menuId, excludeList);
684 excludeList->append(*menuId);
685 // Todo for Undo-support: Undo menuId allocation:
687 return result;
690 static KDesktopFile *copyDesktopFile(MenuEntryInfo *entryInfo, QString *menuId, QStringList *excludeList)
692 QString result = createDesktopFile(entryInfo->file(), menuId, excludeList);
693 KDesktopFile *df = entryInfo->desktopFile()->copyTo(result);
694 df->desktopGroup().deleteEntry("Categories"); // Don't set any categories!
696 return df;
699 static QString createDirectoryFile(const QString &file, QStringList *excludeList)
701 QString base = file.mid(file.lastIndexOf('/')+1);
702 base = base.left(base.lastIndexOf('.'));
704 QString result;
705 int i = 1;
706 while(true)
708 if (i == 1)
709 result = base + ".directory";
710 else
711 result = base + QString("-%1.directory").arg(i);
713 if (!excludeList->contains(result))
715 if (KStandardDirs::locate("xdgdata-dirs", result).isEmpty())
716 break;
718 i++;
720 excludeList->append(result);
721 result = KStandardDirs::locateLocal("xdgdata-dirs", result);
722 return result;
726 void TreeView::slotDropped (QDropEvent * e, Q3ListViewItem *parent, Q3ListViewItem*after)
728 if(!e) return;
730 // get destination folder
731 TreeItem *parentItem = static_cast<TreeItem*>(parent);
732 QString folder = parentItem ? parentItem->directory() : QString();
733 MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
735 if (e->source() != this)
737 // External drop
738 KUrl::List urls;
739 if (!K3URLDrag::decode(e, urls) || (urls.count() != 1) || !urls[0].isLocalFile())
740 return;
741 QString path = urls[0].path();
742 if (!path.endsWith(".desktop"))
743 return;
745 QString menuId;
746 QString result = createDesktopFile(path, &menuId, &m_newMenuIds);
747 KDesktopFile orig_df(path);
748 KDesktopFile *df = orig_df.copyTo(result);
749 df->desktopGroup().deleteEntry("Categories"); // Don't set any categories!
751 KService::Ptr s(new KService(df));
752 s->setMenuId(menuId);
754 MenuEntryInfo *entryInfo = new MenuEntryInfo(s, df);
756 QString oldCaption = entryInfo->caption;
757 QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
758 entryInfo->setCaption(newCaption);
760 // Add file to menu
761 // m_menuFile->addEntry(folder, menuId);
762 m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
764 // create the TreeItem
765 if(parentItem)
766 parentItem->setOpen(true);
768 // update fileInfo data
769 parentFolderInfo->add(entryInfo);
771 TreeItem *newItem = createTreeItem(parentItem, after, entryInfo, true);
773 setSelected ( newItem, true);
774 itemSelected( newItem);
776 m_drag = 0;
777 setLayoutDirty(parentItem);
778 return;
781 // is there content in the clipboard?
782 if (!m_drag) return;
784 if (m_dragItem == after) return; // Nothing to do
786 int command = m_drag;
787 if (command == MOVE_FOLDER)
789 MenuFolderInfo *folderInfo = m_dragInfo;
790 if (e->action() == QDropEvent::Copy)
792 // Ugh.. this is hard :)
793 // * Create new .directory file
794 // Add
796 else
798 TreeItem *tmpItem = static_cast<TreeItem*>(parentItem);
799 while ( tmpItem )
801 if ( tmpItem == m_dragItem )
803 m_drag = 0;
804 return;
806 tmpItem = static_cast<TreeItem*>(tmpItem->parent() );
809 // Remove MenuFolderInfo
810 TreeItem *oldParentItem = static_cast<TreeItem*>(m_dragItem->parent());
811 MenuFolderInfo *oldParentFolderInfo = oldParentItem ? oldParentItem->folderInfo() : m_rootFolder;
812 oldParentFolderInfo->take(folderInfo);
814 // Move menu
815 QString oldFolder = folderInfo->fullId;
816 QString folderName = folderInfo->id;
817 QString newFolder = m_menuFile->uniqueMenuName(folder, folderName, parentFolderInfo->existingMenuIds());
818 folderInfo->id = newFolder;
820 // Add file to menu
821 //m_menuFile->moveMenu(oldFolder, folder + newFolder);
822 m_menuFile->pushAction(MenuFile::MOVE_MENU, oldFolder, folder + newFolder);
824 // Make sure caption is unique
825 QString newCaption = parentFolderInfo->uniqueMenuCaption(folderInfo->caption);
826 if (newCaption != folderInfo->caption)
828 folderInfo->setCaption(newCaption);
831 // create the TreeItem
832 if(parentItem)
833 parentItem->setOpen(true);
835 // update fileInfo data
836 folderInfo->updateFullId(parentFolderInfo->fullId);
837 folderInfo->setInUse(true);
838 parentFolderInfo->add(folderInfo);
840 if ((parentItem != oldParentItem) || !after)
842 if (oldParentItem)
843 oldParentItem->takeItem(m_dragItem);
844 else
845 takeItem(m_dragItem);
846 if (parentItem)
847 parentItem->insertItem(m_dragItem);
848 else
849 insertItem(m_dragItem);
851 m_dragItem->moveItem(after);
852 m_dragItem->setName(folderInfo->caption);
853 m_dragItem->setDirectoryPath(folderInfo->fullId);
854 setSelected(m_dragItem, true);
855 itemSelected(m_dragItem);
858 else if (command == MOVE_FILE)
860 MenuEntryInfo *entryInfo = m_dragItem->entryInfo();
861 QString menuId = entryInfo->menuId();
863 if (e->action() == QDropEvent::Copy)
866 // Need to copy file and then add it
867 KDesktopFile *df = copyDesktopFile(entryInfo, &menuId, &m_newMenuIds); // Duplicate
868 //UNDO-ACTION: NEW_MENU_ID (menuId)
870 KService::Ptr s(new KService(df));
871 s->setMenuId(menuId);
873 entryInfo = new MenuEntryInfo(s, df);
875 QString oldCaption = entryInfo->caption;
876 QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
877 entryInfo->setCaption(newCaption);
879 else
881 del(m_dragItem, false);
882 QString oldCaption = entryInfo->caption;
883 QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption);
884 entryInfo->setCaption(newCaption);
885 entryInfo->setInUse(true);
887 // Add file to menu
888 // m_menuFile->addEntry(folder, menuId);
889 m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
891 // create the TreeItem
892 if(parentItem)
893 parentItem->setOpen(true);
895 // update fileInfo data
896 parentFolderInfo->add(entryInfo);
898 TreeItem *newItem = createTreeItem(parentItem, after, entryInfo, true);
900 setSelected ( newItem, true);
901 itemSelected( newItem);
903 else if (command == COPY_SEPARATOR)
905 if (e->action() != QDropEvent::Copy)
906 del(m_dragItem, false);
908 TreeItem *newItem = createTreeItem(parentItem, after, m_separator, true);
910 setSelected ( newItem, true);
911 itemSelected( newItem);
913 else
915 // Error
917 m_drag = 0;
918 setLayoutDirty(parentItem);
922 void TreeView::startDrag()
924 Q3DragObject *drag = dragObject();
926 if (!drag)
927 return;
929 drag->dragMove();
932 Q3DragObject *TreeView::dragObject()
934 m_dragPath.clear();
935 TreeItem *item = (TreeItem*)selectedItem();
936 if(item == 0) return 0;
938 K3MultipleDrag *drag = new K3MultipleDrag( this );
940 if (item->isDirectory())
942 m_drag = MOVE_FOLDER;
943 m_dragInfo = item->folderInfo();
944 m_dragItem = item;
946 else if (item->isEntry())
948 m_drag = MOVE_FILE;
949 m_dragInfo = 0;
950 m_dragItem = item;
951 QString menuId = item->menuId();
952 m_dragPath = item->entryInfo()->service->entryPath();
953 if (!m_dragPath.isEmpty())
954 m_dragPath = KStandardDirs::locate("apps", m_dragPath);
955 if (!m_dragPath.isEmpty())
957 KUrl url;
958 url.setPath(m_dragPath);
959 drag->addDragObject( new K3URLDrag(url, 0));
962 else
964 m_drag = COPY_SEPARATOR;
965 m_dragInfo = 0;
966 m_dragItem = item;
969 drag->addDragObject( new Q3StoredDrag("application/x-kmenuedit-internal", 0));
970 if ( item->pixmap(0) )
971 drag->setPixmap(*item->pixmap(0));
972 return drag;
975 void TreeView::slotRMBPressed(Q3ListViewItem*, const QPoint& p)
977 TreeItem *item = (TreeItem*)selectedItem();
978 if(item == 0) return;
980 if(m_rmb) m_rmb->exec(p);
983 void TreeView::newsubmenu()
985 TreeItem *parentItem = 0;
986 TreeItem *item = (TreeItem*)selectedItem();
988 bool ok;
989 QString caption = KInputDialog::getText( i18n( "New Submenu" ),
990 i18n( "Submenu name:" ), QString(), &ok, this );
992 if (!ok) return;
994 QString file = caption;
995 file.replace('/', '-');
997 file = createDirectoryFile(file, &m_newDirectoryList); // Create
999 // get destination folder
1000 QString folder;
1002 if(!item)
1004 parentItem = 0;
1005 folder.clear();
1007 else if(item->isDirectory())
1009 parentItem = item;
1010 item = 0;
1011 folder = parentItem->directory();
1013 else
1015 parentItem = static_cast<TreeItem*>(item->parent());
1016 folder = parentItem ? parentItem->directory() : QString();
1019 MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
1020 MenuFolderInfo *folderInfo = new MenuFolderInfo();
1021 folderInfo->caption = parentFolderInfo->uniqueMenuCaption(caption);
1022 folderInfo->id = m_menuFile->uniqueMenuName(folder, caption, parentFolderInfo->existingMenuIds());
1023 folderInfo->directoryFile = file;
1024 folderInfo->icon = "package";
1025 folderInfo->hidden = false;
1026 folderInfo->setDirty();
1028 KDesktopFile *df = new KDesktopFile(file);
1029 KConfigGroup desktopGroup = df->desktopGroup();
1030 desktopGroup.writeEntry("Name", folderInfo->caption);
1031 desktopGroup.writeEntry("Icon", folderInfo->icon);
1032 df->sync();
1033 delete df;
1034 // Add file to menu
1035 // m_menuFile->addMenu(folder + folderInfo->id, file);
1036 m_menuFile->pushAction(MenuFile::ADD_MENU, folder + folderInfo->id, file);
1038 folderInfo->fullId = parentFolderInfo->fullId + folderInfo->id;
1040 // create the TreeItem
1041 if(parentItem)
1042 parentItem->setOpen(true);
1044 // update fileInfo data
1045 parentFolderInfo->add(folderInfo);
1047 TreeItem *newItem = createTreeItem(parentItem, item, folderInfo, true);
1049 setSelected ( newItem, true);
1050 itemSelected( newItem);
1052 setLayoutDirty(parentItem);
1055 void TreeView::newitem()
1057 TreeItem *parentItem = 0;
1058 TreeItem *item = (TreeItem*)selectedItem();
1060 bool ok;
1061 QString caption = KInputDialog::getText( i18n( "New Item" ),
1062 i18n( "Item name:" ), QString(), &ok, this );
1064 if (!ok) return;
1066 QString menuId;
1067 QString file = caption;
1068 file.replace('/', '-');
1070 file = createDesktopFile(file, &menuId, &m_newMenuIds); // Create
1072 KDesktopFile *df = new KDesktopFile(file);
1073 KConfigGroup desktopGroup = df->desktopGroup();
1074 desktopGroup.writeEntry("Name", caption);
1075 desktopGroup.writeEntry("Type", "Application");
1077 // get destination folder
1078 QString folder;
1080 if(!item)
1082 parentItem = 0;
1083 folder.clear();
1085 else if(item->isDirectory())
1087 parentItem = item;
1088 item = 0;
1089 folder = parentItem->directory();
1091 else
1093 parentItem = static_cast<TreeItem*>(item->parent());
1094 folder = parentItem ? parentItem->directory() : QString();
1097 MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
1099 // Add file to menu
1100 // m_menuFile->addEntry(folder, menuId);
1101 m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
1103 KService::Ptr s(new KService(df));
1104 s->setMenuId(menuId);
1106 MenuEntryInfo *entryInfo = new MenuEntryInfo(s, df);
1108 // create the TreeItem
1109 if(parentItem)
1110 parentItem->setOpen(true);
1112 // update fileInfo data
1113 parentFolderInfo->add(entryInfo);
1115 TreeItem *newItem = createTreeItem(parentItem, item, entryInfo, true);
1117 setSelected ( newItem, true);
1118 itemSelected( newItem);
1120 setLayoutDirty(parentItem);
1123 void TreeView::newsep()
1125 TreeItem *parentItem = 0;
1126 TreeItem *item = (TreeItem*)selectedItem();
1128 if(!item)
1130 parentItem = 0;
1132 else if(item->isDirectory())
1134 parentItem = item;
1135 item = 0;
1137 else
1139 parentItem = static_cast<TreeItem*>(item->parent());
1142 // create the TreeItem
1143 if(parentItem)
1144 parentItem->setOpen(true);
1146 TreeItem *newItem = createTreeItem(parentItem, item, m_separator, true);
1148 setSelected ( newItem, true);
1149 itemSelected( newItem);
1151 setLayoutDirty(parentItem);
1154 void TreeView::cut()
1156 copy( true );
1158 m_ac->action("edit_cut")->setEnabled(false);
1159 m_ac->action("edit_copy")->setEnabled(false);
1160 m_ac->action("delete")->setEnabled(false);
1162 // Select new current item
1163 setSelected( currentItem(), true );
1164 // Switch the UI to show that item
1165 itemSelected( selectedItem() );
1168 void TreeView::copy()
1170 copy( false );
1173 void TreeView::copy( bool cutting )
1175 TreeItem *item = (TreeItem*)selectedItem();
1177 // nil selected? -> nil to copy
1178 if (item == 0) return;
1180 if (cutting)
1181 setLayoutDirty((TreeItem*)item->parent());
1183 // clean up old stuff
1184 cleanupClipboard();
1186 // is item a folder or a file?
1187 if(item->isDirectory())
1189 QString folder = item->directory();
1190 if (cutting)
1192 // Place in clipboard
1193 m_clipboard = MOVE_FOLDER;
1194 m_clipboardFolderInfo = item->folderInfo();
1196 del(item, false);
1198 else
1200 // Place in clipboard
1201 m_clipboard = COPY_FOLDER;
1202 m_clipboardFolderInfo = item->folderInfo();
1205 else if (item->isEntry())
1207 if (cutting)
1209 // Place in clipboard
1210 m_clipboard = MOVE_FILE;
1211 m_clipboardEntryInfo = item->entryInfo();
1213 del(item, false);
1215 else
1217 // Place in clipboard
1218 m_clipboard = COPY_FILE;
1219 m_clipboardEntryInfo = item->entryInfo();
1222 else
1224 // Place in clipboard
1225 m_clipboard = COPY_SEPARATOR;
1226 if (cutting)
1227 del(item, false);
1230 m_ac->action("edit_paste")->setEnabled(true);
1234 void TreeView::paste()
1236 TreeItem *parentItem = 0;
1237 TreeItem *item = (TreeItem*)selectedItem();
1239 // nil selected? -> nil to paste to
1240 if (item == 0) return;
1242 // is there content in the clipboard?
1243 if (!m_clipboard) return;
1245 // get destination folder
1246 QString folder;
1248 if(item->isDirectory())
1250 parentItem = item;
1251 item = 0;
1252 folder = parentItem->directory();
1254 else
1256 parentItem = static_cast<TreeItem*>(item->parent());
1257 folder = parentItem ? parentItem->directory() : QString();
1260 MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
1261 int command = m_clipboard;
1262 if ((command == COPY_FOLDER) || (command == MOVE_FOLDER))
1264 MenuFolderInfo *folderInfo = m_clipboardFolderInfo;
1265 if (command == COPY_FOLDER)
1267 // Ugh.. this is hard :)
1268 // * Create new .directory file
1269 // Add
1271 else if (command == MOVE_FOLDER)
1273 // Move menu
1274 QString oldFolder = folderInfo->fullId;
1275 QString folderName = folderInfo->id;
1276 QString newFolder = m_menuFile->uniqueMenuName(folder, folderName, parentFolderInfo->existingMenuIds());
1277 folderInfo->id = newFolder;
1279 // Add file to menu
1280 // m_menuFile->moveMenu(oldFolder, folder + newFolder);
1281 m_menuFile->pushAction(MenuFile::MOVE_MENU, oldFolder, folder + newFolder);
1283 // Make sure caption is unique
1284 QString newCaption = parentFolderInfo->uniqueMenuCaption(folderInfo->caption);
1285 if (newCaption != folderInfo->caption)
1287 folderInfo->setCaption(newCaption);
1289 // create the TreeItem
1290 if(parentItem)
1291 parentItem->setOpen(true);
1293 // update fileInfo data
1294 folderInfo->fullId = parentFolderInfo->fullId + folderInfo->id;
1295 folderInfo->setInUse(true);
1296 parentFolderInfo->add(folderInfo);
1298 TreeItem *newItem = createTreeItem(parentItem, item, folderInfo);
1300 setSelected ( newItem, true);
1301 itemSelected( newItem);
1304 m_clipboard = COPY_FOLDER; // Next one copies.
1306 else if ((command == COPY_FILE) || (command == MOVE_FILE))
1308 MenuEntryInfo *entryInfo = m_clipboardEntryInfo;
1309 QString menuId;
1311 if (command == COPY_FILE)
1313 // Need to copy file and then add it
1314 KDesktopFile *df = copyDesktopFile(entryInfo, &menuId, &m_newMenuIds); // Duplicate
1316 KService::Ptr s(new KService(df));
1317 s->setMenuId(menuId);
1318 entryInfo = new MenuEntryInfo(s, df);
1320 QString oldCaption = entryInfo->caption;
1321 QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
1322 entryInfo->setCaption(newCaption);
1324 else if (command == MOVE_FILE)
1326 menuId = entryInfo->menuId();
1327 m_clipboard = COPY_FILE; // Next one copies.
1329 QString oldCaption = entryInfo->caption;
1330 QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption);
1331 entryInfo->setCaption(newCaption);
1332 entryInfo->setInUse(true);
1334 // Add file to menu
1335 // m_menuFile->addEntry(folder, menuId);
1336 m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
1338 // create the TreeItem
1339 if(parentItem)
1340 parentItem->setOpen(true);
1342 // update fileInfo data
1343 parentFolderInfo->add(entryInfo);
1345 TreeItem *newItem = createTreeItem(parentItem, item, entryInfo, true);
1347 setSelected ( newItem, true);
1348 itemSelected( newItem);
1350 else
1352 // create separator
1353 if(parentItem)
1354 parentItem->setOpen(true);
1356 TreeItem *newItem = createTreeItem(parentItem, item, m_separator, true);
1358 setSelected ( newItem, true);
1359 itemSelected( newItem);
1361 setLayoutDirty(parentItem);
1364 void TreeView::del()
1366 TreeItem *item = (TreeItem*)selectedItem();
1368 // nil selected? -> nil to delete
1369 if (item == 0) return;
1371 del(item, true);
1373 m_ac->action("edit_cut")->setEnabled(false);
1374 m_ac->action("edit_copy")->setEnabled(false);
1375 m_ac->action("delete")->setEnabled(false);
1376 // Select new current item
1377 setSelected( currentItem(), true );
1378 // Switch the UI to show that item
1379 itemSelected( selectedItem() );
1382 void TreeView::del(TreeItem *item, bool deleteInfo)
1384 TreeItem *parentItem = static_cast<TreeItem*>(item->parent());
1385 // is file a .directory or a .desktop file
1386 if(item->isDirectory())
1388 if ( KMessageBox::warningYesNo(this, i18n("All submenus of '%1' will be removed. Do you want to continue?", item->name() ) ) == KMessageBox::No )
1389 return;
1391 MenuFolderInfo *folderInfo = item->folderInfo();
1393 // Remove MenuFolderInfo
1394 MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
1395 parentFolderInfo->take(folderInfo);
1396 folderInfo->setInUse(false);
1398 if (m_clipboard == COPY_FOLDER && (m_clipboardFolderInfo == folderInfo))
1400 // Copy + Del == Cut
1401 m_clipboard = MOVE_FOLDER; // Clipboard now owns folderInfo
1404 else
1406 if (folderInfo->takeRecursive(m_clipboardFolderInfo))
1407 m_clipboard = MOVE_FOLDER; // Clipboard now owns m_clipboardFolderInfo
1409 if (deleteInfo)
1410 delete folderInfo; // Delete folderInfo
1413 // Remove from menu
1414 // m_menuFile->removeMenu(item->directory());
1415 m_menuFile->pushAction(MenuFile::REMOVE_MENU, item->directory(), QString());
1417 // Remove tree item
1418 delete item;
1420 else if (item->isEntry())
1422 MenuEntryInfo *entryInfo = item->entryInfo();
1423 QString menuId = entryInfo->menuId();
1425 // Remove MenuFolderInfo
1426 MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
1427 parentFolderInfo->take(entryInfo);
1428 entryInfo->setInUse(false);
1430 if (m_clipboard == COPY_FILE && (m_clipboardEntryInfo == entryInfo))
1432 // Copy + Del == Cut
1433 m_clipboard = MOVE_FILE; // Clipboard now owns entryInfo
1435 else
1437 if (deleteInfo)
1438 delete entryInfo; // Delete entryInfo
1441 // Remove from menu
1442 QString folder = parentItem ? parentItem->directory() : QString();
1443 // m_menuFile->removeEntry(folder, menuId);
1444 m_menuFile->pushAction(MenuFile::REMOVE_ENTRY, folder, menuId);
1446 // Remove tree item
1447 delete item;
1449 else
1451 // Remove separator
1452 delete item;
1454 setLayoutDirty(parentItem);
1457 void TreeView::cleanupClipboard() {
1458 if (m_clipboard == MOVE_FOLDER)
1459 delete m_clipboardFolderInfo;
1460 m_clipboardFolderInfo = 0;
1462 if (m_clipboard == MOVE_FILE)
1463 delete m_clipboardEntryInfo;
1464 m_clipboardEntryInfo = 0;
1466 m_clipboard = 0;
1469 static QStringList extractLayout(TreeItem *item)
1471 bool firstFolder = true;
1472 bool firstEntry = true;
1473 QStringList layout;
1474 for(;item; item = static_cast<TreeItem*>(item->nextSibling()))
1476 if (item->isDirectory())
1478 if (firstFolder)
1480 firstFolder = false;
1481 layout << ":M"; // Add new folders here...
1483 layout << (item->folderInfo()->id);
1485 else if (item->isEntry())
1487 if (firstEntry)
1489 firstEntry = false;
1490 layout << ":F"; // Add new entries here...
1492 layout << (item->entryInfo()->menuId());
1494 else
1496 layout << ":S";
1499 return layout;
1502 QStringList TreeItem::layout()
1504 QStringList layout = extractLayout(static_cast<TreeItem*>(firstChild()));
1505 _layoutDirty = false;
1506 return layout;
1509 void TreeView::saveLayout()
1511 if (m_layoutDirty)
1513 QStringList layout = extractLayout(static_cast<TreeItem*>(firstChild()));
1514 m_menuFile->setLayout(m_rootFolder->fullId, layout);
1515 m_layoutDirty = false;
1518 Q3PtrList<Q3ListViewItem> lst;
1519 Q3ListViewItemIterator it( this );
1520 while ( it.current() ) {
1521 TreeItem *item = static_cast<TreeItem*>(it.current());
1522 if ( item->isLayoutDirty() )
1524 m_menuFile->setLayout(item->folderInfo()->fullId, item->layout());
1526 ++it;
1530 bool TreeView::save()
1532 saveLayout();
1533 m_rootFolder->save(m_menuFile);
1535 bool success = m_menuFile->performAllActions();
1537 m_newMenuIds.clear();
1538 m_newDirectoryList.clear();
1540 if (success)
1542 KBuildSycocaProgressDialog::rebuildKSycoca(this);
1544 else
1546 KMessageBox::sorry(this, "<qt>"+i18n("Menu changes could not be saved because of the following problem:")+"<br><br>"+
1547 m_menuFile->error()+"</qt>");
1550 sendReloadMenu();
1552 return success;
1555 void TreeView::setLayoutDirty(TreeItem *parentItem)
1557 if (parentItem)
1558 parentItem->setLayoutDirty();
1559 else
1560 m_layoutDirty = true;
1563 bool TreeView::isLayoutDirty()
1565 Q3PtrList<Q3ListViewItem> lst;
1566 Q3ListViewItemIterator it( this );
1567 while ( it.current() ) {
1568 if ( static_cast<TreeItem*>(it.current())->isLayoutDirty() )
1569 return true;
1570 ++it;
1572 return false;
1575 bool TreeView::dirty()
1577 return m_layoutDirty || m_rootFolder->hasDirt() || m_menuFile->dirty() || isLayoutDirty();
1580 void TreeView::findServiceShortcut(const KShortcut&cut, KService::Ptr &service)
1582 service = m_rootFolder->findServiceShortcut(cut);
1585 void TreeView::restoreMenuSystem()
1587 if ( KMessageBox::warningYesNo( this, i18n( "Do you want to restore the system menu? Warning: This will remove all custom menus." ) )==KMessageBox::No )
1588 return;
1589 QString kmenueditfile = KStandardDirs::locateLocal("xdgconf-menu", "applications-kmenuedit.menu");
1590 if ( QFile::exists( kmenueditfile ) )
1592 if ( !QFile::remove( kmenueditfile ) )
1593 qWarning()<<"Could not delete "<<kmenueditfile;
1596 QString xdgdir = KGlobal::dirs()->KStandardDirs::localxdgdatadir();
1597 if ( !KIO::NetAccess::del( xdgdir + "/applications" , this) )
1598 qWarning()<<"Could not delete dir :"<<( xdgdir+"/applications" );
1599 if ( !KIO::NetAccess::del( xdgdir +"/desktop-directories" , this) )
1600 qWarning()<<"Could not delete dir :"<<( xdgdir + "/desktop-directories");
1602 KBuildSycocaProgressDialog::rebuildKSycoca(this);
1603 clear();
1604 cleanupClipboard();
1605 delete m_rootFolder;
1606 delete m_separator;
1608 m_layoutDirty = false;
1609 m_newMenuIds.clear();
1610 m_newDirectoryList.clear();
1611 m_menuFile->restoreMenuSystem(kmenueditfile);
1613 m_rootFolder = new MenuFolderInfo;
1614 m_separator = new MenuSeparatorInfo;
1616 readMenuFolderInfo();
1617 fill();
1618 sendReloadMenu();
1619 emit disableAction();
1620 emit entrySelected(( MenuEntryInfo* ) 0 );
1623 void TreeView::updateTreeView(bool showHidden)
1625 m_showHidden = showHidden;
1626 clear();
1627 cleanupClipboard();
1628 delete m_rootFolder;
1629 delete m_separator;
1631 m_layoutDirty = false;
1632 m_newMenuIds.clear();
1633 m_newDirectoryList.clear();
1635 m_rootFolder = new MenuFolderInfo;
1636 m_separator = new MenuSeparatorInfo;
1638 readMenuFolderInfo();
1639 fill();
1640 sendReloadMenu();
1641 emit disableAction();
1642 emit entrySelected(( MenuEntryInfo* ) 0 );
1645 void TreeView::sendReloadMenu()
1647 QDBusMessage message =
1648 QDBusMessage::createSignal("/kickoff", "org.kde.plasma", "reloadMenu");
1649 QDBusConnection::sessionBus().send(message);