summaryrefslogtreecommitdiffstats
path: root/kmenuedit/treeview.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit4aed2c8219774f5d797760606b8489a92ddc5163 (patch)
tree3f8c130f7d269626bf6a9447407ef6c35954426a /kmenuedit/treeview.cpp
downloadtdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz
tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kmenuedit/treeview.cpp')
-rw-r--r--kmenuedit/treeview.cpp1581
1 files changed, 1581 insertions, 0 deletions
diff --git a/kmenuedit/treeview.cpp b/kmenuedit/treeview.cpp
new file mode 100644
index 000000000..760c052fe
--- /dev/null
+++ b/kmenuedit/treeview.cpp
@@ -0,0 +1,1581 @@
+/*
+ * Copyright (C) 2000 Matthias Elter <elter@kde.org>
+ * Copyright (C) 2001-2002 Raffaele Sandrini <sandrini@kde.org)
+ * Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <unistd.h>
+
+#include <qcstring.h>
+#include <qcursor.h>
+#include <qdatastream.h>
+#include <qdir.h>
+#include <qdragobject.h>
+#include <qfileinfo.h>
+#include <qheader.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <ksimpleconfig.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kdesktopfile.h>
+#include <kaction.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <kservice.h>
+#include <kservicegroup.h>
+#include <kmultipledrag.h>
+#include <kurldrag.h>
+
+#include "treeview.h"
+#include "treeview.moc"
+#include "khotkeys.h"
+#include "menufile.h"
+#include "menuinfo.h"
+
+#define MOVE_FOLDER 'M'
+#define COPY_FOLDER 'C'
+#define MOVE_FILE 'm'
+#define COPY_FILE 'c'
+#define COPY_SEPARATOR 'S'
+
+TreeItem::TreeItem(QListViewItem *parent, QListViewItem *after, const QString& menuId, bool __init)
+ :QListViewItem(parent, after), _hidden(false), _init(__init), _layoutDirty(false), _menuId(menuId),
+ m_folderInfo(0), m_entryInfo(0) {}
+
+TreeItem::TreeItem(QListView *parent, QListViewItem *after, const QString& menuId, bool __init)
+ : QListViewItem(parent, after), _hidden(false), _init(__init), _layoutDirty(false), _menuId(menuId),
+ m_folderInfo(0), m_entryInfo(0) {}
+
+void TreeItem::setName(const QString &name)
+{
+ _name = name;
+ update();
+}
+
+void TreeItem::setHidden(bool b)
+{
+ if (_hidden == b) return;
+ _hidden = b;
+ update();
+}
+
+void TreeItem::update()
+{
+ QString s = _name;
+ if (_hidden)
+ s += i18n(" [Hidden]");
+ setText(0, s);
+}
+
+void TreeItem::setOpen(bool o)
+{
+ if (o)
+ load();
+
+ QListViewItem::setOpen(o);
+}
+
+void TreeItem::load()
+{
+ if (m_folderInfo && !_init)
+ {
+ _init = true;
+ TreeView *tv = static_cast<TreeView *>(listView());
+ tv->fillBranch(m_folderInfo, this);
+ }
+}
+
+void TreeItem::paintCell ( QPainter * p, const QColorGroup & cg, int column, int width, int align )
+{
+ QListViewItem::paintCell(p, cg, column, width, align);
+
+ if (!m_folderInfo && !m_entryInfo)
+ {
+ // Draw Separator
+ int h = (height() / 2) -1;
+ if (isSelected())
+ p->setPen( cg.highlightedText() );
+ else
+ p->setPen( cg.text() );
+ p->drawLine(0, h,
+ width, h);
+ }
+}
+
+void TreeItem::setup()
+{
+ QListViewItem::setup();
+ if (!m_folderInfo && !m_entryInfo)
+ setHeight(8);
+}
+
+static QPixmap appIcon(const QString &iconName)
+{
+ QPixmap normal = KGlobal::iconLoader()->loadIcon(iconName, KIcon::Small, 0, KIcon::DefaultState, 0L, true);
+ // make sure they are not larger than 20x20
+ if (normal.width() > 20 || normal.height() > 20)
+ {
+ QImage tmp = normal.convertToImage();
+ tmp = tmp.smoothScale(20, 20);
+ normal.convertFromImage(tmp);
+ }
+ return normal;
+}
+
+
+TreeView::TreeView( bool controlCenter, KActionCollection *ac, QWidget *parent, const char *name )
+ : KListView(parent, name), m_ac(ac), m_rmb(0), m_clipboard(0),
+ m_clipboardFolderInfo(0), m_clipboardEntryInfo(0),
+ m_controlCenter(controlCenter), m_layoutDirty(false)
+{
+ setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
+ setAllColumnsShowFocus(true);
+ setRootIsDecorated(true);
+ setSorting(-1);
+ setAcceptDrops(true);
+ setDropVisualizer(true);
+ setDragEnabled(true);
+ setMinimumWidth(240);
+
+ addColumn("");
+ header()->hide();
+
+ connect(this, SIGNAL(dropped(QDropEvent*, QListViewItem*, QListViewItem*)),
+ SLOT(slotDropped(QDropEvent*, QListViewItem*, QListViewItem*)));
+
+ connect(this, SIGNAL(clicked( QListViewItem* )),
+ SLOT(itemSelected( QListViewItem* )));
+
+ connect(this,SIGNAL(selectionChanged ( QListViewItem * )),
+ SLOT(itemSelected( QListViewItem* )));
+
+ connect(this, SIGNAL(rightButtonPressed(QListViewItem*, const QPoint&, int)),
+ SLOT(slotRMBPressed(QListViewItem*, const QPoint&)));
+
+ // connect actions
+ connect(m_ac->action("newitem"), SIGNAL(activated()), SLOT(newitem()));
+ connect(m_ac->action("newsubmenu"), SIGNAL(activated()), SLOT(newsubmenu()));
+ if (m_ac->action("newsep"))
+ connect(m_ac->action("newsep"), SIGNAL(activated()), SLOT(newsep()));
+
+ m_menuFile = new MenuFile( locateLocal("xdgconf-menu", "applications-kmenuedit.menu"));
+ m_rootFolder = new MenuFolderInfo;
+ m_separator = new MenuSeparatorInfo;
+ m_drag = 0;
+
+ // Read menu format configuration information
+ KSharedConfig::Ptr pConfig = KSharedConfig::openConfig("kickerrc");
+
+ pConfig->setGroup("menus");
+ m_detailedMenuEntries = pConfig->readBoolEntry("DetailedMenuEntries",true);
+ if (m_detailedMenuEntries)
+ {
+ m_detailedEntriesNamesFirst = pConfig->readBoolEntry("DetailedEntriesNamesFirst",false);
+ }
+}
+
+TreeView::~TreeView() {
+ cleanupClipboard();
+ delete m_rootFolder;
+ delete m_separator;
+}
+
+void TreeView::setViewMode(bool showHidden)
+{
+ delete m_rmb;
+
+ // setup rmb menu
+ m_rmb = new QPopupMenu(this);
+ KAction *action;
+
+ action = m_ac->action("edit_cut");
+ if(action) {
+ action->plug(m_rmb);
+ action->setEnabled(false);
+ connect(action, SIGNAL(activated()), SLOT(cut()));
+ }
+
+ action = m_ac->action("edit_copy");
+ if(action) {
+ action->plug(m_rmb);
+ action->setEnabled(false);
+ connect(action, SIGNAL(activated()), SLOT(copy()));
+ }
+
+ action = m_ac->action("edit_paste");
+ if(action) {
+ action->plug(m_rmb);
+ action->setEnabled(false);
+ connect(action, SIGNAL(activated()), SLOT(paste()));
+ }
+
+ m_rmb->insertSeparator();
+
+ action = m_ac->action("delete");
+ if(action) {
+ action->plug(m_rmb);
+ action->setEnabled(false);
+ connect(action, SIGNAL(activated()), SLOT(del()));
+ }
+
+ m_rmb->insertSeparator();
+
+ if(m_ac->action("newitem"))
+ m_ac->action("newitem")->plug(m_rmb);
+ if(m_ac->action("newsubmenu"))
+ m_ac->action("newsubmenu")->plug(m_rmb);
+ if(m_ac->action("newsep"))
+ m_ac->action("newsep")->plug(m_rmb);
+
+ m_showHidden = showHidden;
+ readMenuFolderInfo();
+ fill();
+}
+
+void TreeView::readMenuFolderInfo(MenuFolderInfo *folderInfo, KServiceGroup::Ptr folder, const QString &prefix)
+{
+ if (!folderInfo)
+ {
+ folderInfo = m_rootFolder;
+ if (m_controlCenter)
+ folder = KServiceGroup::baseGroup("settings");
+ else
+ folder = KServiceGroup::root();
+ }
+
+ if (!folder || !folder->isValid())
+ return;
+
+ folderInfo->caption = folder->caption();
+ folderInfo->comment = folder->comment();
+
+ // Item names may contain ampersands. To avoid them being converted
+ // to accelerators, replace them with two ampersands.
+ folderInfo->hidden = folder->noDisplay();
+ folderInfo->directoryFile = folder->directoryEntryPath();
+ folderInfo->icon = folder->icon();
+ QString id = folder->relPath();
+ int i = id.findRev('/', -2);
+ id = id.mid(i+1);
+ folderInfo->id = id;
+ folderInfo->fullId = prefix + id;
+
+ KServiceGroup::List list = folder->entries(true, !m_showHidden, true, m_detailedMenuEntries && !m_detailedEntriesNamesFirst);
+
+ for(KServiceGroup::List::ConstIterator it = list.begin();
+ it != list.end(); ++it)
+ {
+ KSycocaEntry * e = *it;
+
+ if (e->isType(KST_KServiceGroup))
+ {
+ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
+ MenuFolderInfo *subFolderInfo = new MenuFolderInfo();
+ readMenuFolderInfo(subFolderInfo, g, folderInfo->fullId);
+ folderInfo->add(subFolderInfo, true);
+ }
+ else if (e->isType(KST_KService))
+ {
+ folderInfo->add(new MenuEntryInfo(static_cast<KService *>(e)), true);
+ }
+ else if (e->isType(KST_KServiceSeparator))
+ {
+ folderInfo->add(m_separator, true);
+ }
+ }
+}
+
+void TreeView::fill()
+{
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ clear();
+ fillBranch(m_rootFolder, 0);
+ QApplication::restoreOverrideCursor();
+}
+
+QString TreeView::findName(KDesktopFile *df, bool deleted)
+{
+ QString name = df->readName();
+ if (deleted)
+ {
+ if (name == "empty")
+ name = QString::null;
+ if (name.isEmpty())
+ {
+ QString file = df->fileName();
+ QString res = df->resource();
+
+ bool isLocal = true;
+ QStringList files = KGlobal::dirs()->findAllResources(res.latin1(), file);
+ for(QStringList::ConstIterator it = files.begin();
+ it != files.end();
+ ++it)
+ {
+ if (isLocal)
+ {
+ isLocal = false;
+ continue;
+ }
+
+ KDesktopFile df2(*it);
+ name = df2.readName();
+
+ if (!name.isEmpty() && (name != "empty"))
+ return name;
+ }
+ }
+ }
+ return name;
+}
+
+TreeItem *TreeView::createTreeItem(TreeItem *parent, QListViewItem *after, MenuFolderInfo *folderInfo, bool _init)
+{
+ TreeItem *item;
+ if (parent == 0)
+ item = new TreeItem(this, after, QString::null, _init);
+ else
+ item = new TreeItem(parent, after, QString::null, _init);
+
+ item->setMenuFolderInfo(folderInfo);
+ item->setName(folderInfo->caption);
+ item->setPixmap(0, appIcon(folderInfo->icon));
+ item->setDirectoryPath(folderInfo->fullId);
+ item->setHidden(folderInfo->hidden);
+ item->setExpandable(true);
+ return item;
+}
+
+TreeItem *TreeView::createTreeItem(TreeItem *parent, QListViewItem *after, MenuEntryInfo *entryInfo, bool _init)
+{
+ bool hidden = entryInfo->hidden;
+
+ TreeItem* item;
+ if (parent == 0)
+ item = new TreeItem(this, after, entryInfo->menuId(), _init);
+ else
+ item = new TreeItem(parent, after, entryInfo->menuId(),_init);
+
+ QString name;
+
+ if (m_detailedMenuEntries && entryInfo->description.length() != 0)
+ {
+ if (m_detailedEntriesNamesFirst)
+ {
+ name = entryInfo->caption + " (" + entryInfo->description + ")";
+ }
+ else
+ {
+ name = entryInfo->description + " (" + entryInfo->caption + ")";
+ }
+ }
+ else
+ {
+ name = entryInfo->caption;
+ }
+ item->setMenuEntryInfo(entryInfo);
+ item->setName(name);
+ item->setPixmap(0, appIcon(entryInfo->icon));
+
+ item->setHidden(hidden);
+ return item;
+}
+
+TreeItem *TreeView::createTreeItem(TreeItem *parent, QListViewItem *after, MenuSeparatorInfo *, bool _init)
+{
+ TreeItem* item;
+ if (parent == 0)
+ item = new TreeItem(this, after, QString::null, _init);
+ else
+ item = new TreeItem(parent, after, QString::null,_init);
+
+ return item;
+}
+
+void TreeView::fillBranch(MenuFolderInfo *folderInfo, TreeItem *parent)
+{
+ QString relPath = parent ? parent->directory() : QString::null;
+ QPtrListIterator<MenuInfo> it( folderInfo->initialLayout );
+ TreeItem *after = 0;
+ for (MenuInfo *info; (info = it.current()); ++it)
+ {
+ MenuEntryInfo *entry = dynamic_cast<MenuEntryInfo*>(info);
+ if (entry)
+ {
+ after = createTreeItem(parent, after, entry);
+ continue;
+ }
+
+ MenuFolderInfo *subFolder = dynamic_cast<MenuFolderInfo*>(info);
+ if (subFolder)
+ {
+ after = createTreeItem(parent, after, subFolder);
+ continue;
+ }
+ MenuSeparatorInfo *separator = dynamic_cast<MenuSeparatorInfo*>(info);
+ if (separator)
+ {
+ after = createTreeItem(parent, after, separator);
+ continue;
+ }
+ }
+}
+
+void TreeView::closeAllItems(QListViewItem *item)
+{
+ if (!item) return;
+ while(item)
+ {
+ item->setOpen(false);
+ closeAllItems(item->firstChild());
+ item = item->nextSibling();
+ }
+}
+
+void TreeView::selectMenu(const QString &menu)
+{
+ closeAllItems(firstChild());
+
+ if (menu.length() <= 1)
+ {
+ setCurrentItem(firstChild());
+ clearSelection();
+ return; // Root menu
+ }
+
+ QString restMenu = menu.mid(1);
+ if (!restMenu.endsWith("/"))
+ restMenu += "/";
+
+ TreeItem *item = 0;
+ do
+ {
+ int i = restMenu.find("/");
+ QString subMenu = restMenu.left(i+1);
+ restMenu = restMenu.mid(i+1);
+
+ item = (TreeItem*)(item ? item->firstChild() : firstChild());
+ while(item)
+ {
+ MenuFolderInfo *folderInfo = item->folderInfo();
+ if (folderInfo && (folderInfo->id == subMenu))
+ {
+ item->setOpen(true);
+ break;
+ }
+ item = (TreeItem*) item->nextSibling();
+ }
+ }
+ while( item && !restMenu.isEmpty());
+
+ if (item)
+ {
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ }
+}
+
+void TreeView::selectMenuEntry(const QString &menuEntry)
+{
+ TreeItem *item = (TreeItem *) selectedItem();
+ if (!item)
+ {
+ item = (TreeItem *) currentItem();
+ while (item && item->isDirectory())
+ item = (TreeItem*) item->nextSibling();
+ }
+ else
+ item = (TreeItem *) item->firstChild();
+
+ while(item)
+ {
+ MenuEntryInfo *entry = item->entryInfo();
+ if (entry && (entry->menuId() == menuEntry))
+ {
+ setCurrentItem(item);
+ ensureItemVisible(item);
+ return;
+ }
+ item = (TreeItem*) item->nextSibling();
+ }
+}
+
+void TreeView::itemSelected(QListViewItem *item)
+{
+ TreeItem *_item = (TreeItem*)item;
+ bool selected = false;
+ bool dselected = false;
+ if (_item) {
+ selected = true;
+ dselected = _item->isHidden();
+ }
+
+ m_ac->action("edit_cut")->setEnabled(selected);
+ m_ac->action("edit_copy")->setEnabled(selected);
+
+ if (m_ac->action("delete"))
+ m_ac->action("delete")->setEnabled(selected && !dselected);
+
+ if(!item)
+ {
+ emit disableAction();
+ return;
+ }
+
+ if (_item->isDirectory())
+ emit entrySelected(_item->folderInfo());
+ else
+ emit entrySelected(_item->entryInfo());
+}
+
+void TreeView::currentChanged(MenuFolderInfo *folderInfo)
+{
+ TreeItem *item = (TreeItem*)selectedItem();
+ if (item == 0) return;
+ if (folderInfo == 0) return;
+
+ item->setName(folderInfo->caption);
+ item->setPixmap(0, appIcon(folderInfo->icon));
+}
+
+void TreeView::currentChanged(MenuEntryInfo *entryInfo)
+{
+ TreeItem *item = (TreeItem*)selectedItem();
+ if (item == 0) return;
+ if (entryInfo == 0) return;
+
+ QString name;
+
+ if (m_detailedMenuEntries && entryInfo->description.length() != 0)
+ {
+ if (m_detailedEntriesNamesFirst)
+ {
+ name = entryInfo->caption + " (" + entryInfo->description + ")";
+ }
+ else
+ {
+ name = entryInfo->description + " (" + entryInfo->caption + ")";
+ }
+ }
+ else
+ {
+ name = entryInfo->caption;
+ }
+ item->setName(name);
+ item->setPixmap(0, appIcon(entryInfo->icon));
+}
+
+QStringList TreeView::fileList(const QString& rPath)
+{
+ QString relativePath = rPath;
+
+ // truncate "/.directory"
+ int pos = relativePath.findRev("/.directory");
+ if (pos > 0) relativePath.truncate(pos);
+
+ QStringList filelist;
+
+ // loop through all resource dirs and build a file list
+ QStringList resdirlist = KGlobal::dirs()->resourceDirs("apps");
+ for (QStringList::ConstIterator it = resdirlist.begin(); it != resdirlist.end(); ++it)
+ {
+ QDir dir((*it) + "/" + relativePath);
+ if(!dir.exists()) continue;
+
+ dir.setFilter(QDir::Files);
+ dir.setNameFilter("*.desktop;*.kdelnk");
+
+ // build a list of files
+ QStringList files = dir.entryList();
+ for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
+ // does not work?!
+ //if (filelist.contains(*it)) continue;
+
+ if (relativePath.isEmpty()) {
+ filelist.remove(*it); // hack
+ filelist.append(*it);
+ }
+ else {
+ filelist.remove(relativePath + "/" + *it); //hack
+ filelist.append(relativePath + "/" + *it);
+ }
+ }
+ }
+ return filelist;
+}
+
+QStringList TreeView::dirList(const QString& rPath)
+{
+ QString relativePath = rPath;
+
+ // truncate "/.directory"
+ int pos = relativePath.findRev("/.directory");
+ if (pos > 0) relativePath.truncate(pos);
+
+ QStringList dirlist;
+
+ // loop through all resource dirs and build a subdir list
+ QStringList resdirlist = KGlobal::dirs()->resourceDirs("apps");
+ for (QStringList::ConstIterator it = resdirlist.begin(); it != resdirlist.end(); ++it)
+ {
+ QDir dir((*it) + "/" + relativePath);
+ if(!dir.exists()) continue;
+ dir.setFilter(QDir::Dirs);
+
+ // build a list of subdirs
+ QStringList subdirs = dir.entryList();
+ for (QStringList::ConstIterator it = subdirs.begin(); it != subdirs.end(); ++it) {
+ if ((*it) == "." || (*it) == "..") continue;
+ // does not work?!
+ // if (dirlist.contains(*it)) continue;
+
+ if (relativePath.isEmpty()) {
+ dirlist.remove(*it); //hack
+ dirlist.append(*it);
+ }
+ else {
+ dirlist.remove(relativePath + "/" + *it); //hack
+ dirlist.append(relativePath + "/" + *it);
+ }
+ }
+ }
+ return dirlist;
+}
+
+bool TreeView::acceptDrag(QDropEvent* e) const
+{
+ if (e->provides("application/x-kmenuedit-internal") &&
+ (e->source() == const_cast<TreeView *>(this)))
+ return true;
+ KURL::List urls;
+ if (KURLDrag::decode(e, urls) && (urls.count() == 1) &&
+ urls[0].isLocalFile() && urls[0].path().endsWith(".desktop"))
+ return true;
+ return false;
+}
+
+
+static QString createDesktopFile(const QString &file, QString *menuId, QStringList *excludeList)
+{
+ QString base = file.mid(file.findRev('/')+1);
+ base = base.left(base.findRev('.'));
+
+ QRegExp r("(.*)(?=-\\d+)");
+ base = (r.search(base) > -1) ? r.cap(1) : base;
+
+ QString result = KService::newServicePath(true, base, menuId, excludeList);
+ excludeList->append(*menuId);
+ // Todo for Undo-support: Undo menuId allocation:
+
+ return result;
+}
+
+static KDesktopFile *copyDesktopFile(MenuEntryInfo *entryInfo, QString *menuId, QStringList *excludeList)
+{
+ QString result = createDesktopFile(entryInfo->file(), menuId, excludeList);
+ KDesktopFile *df = entryInfo->desktopFile()->copyTo(result);
+ df->deleteEntry("Categories"); // Don't set any categories!
+
+ return df;
+}
+
+static QString createDirectoryFile(const QString &file, QStringList *excludeList)
+{
+ QString base = file.mid(file.findRev('/')+1);
+ base = base.left(base.findRev('.'));
+
+ QString result;
+ int i = 1;
+ while(true)
+ {
+ if (i == 1)
+ result = base + ".directory";
+ else
+ result = base + QString("-%1.directory").arg(i);
+
+ if (!excludeList->contains(result))
+ {
+ if (locate("xdgdata-dirs", result).isEmpty())
+ break;
+ }
+ i++;
+ }
+ excludeList->append(result);
+ result = locateLocal("xdgdata-dirs", result);
+ return result;
+}
+
+
+void TreeView::slotDropped (QDropEvent * e, QListViewItem *parent, QListViewItem*after)
+{
+ if(!e) return;
+
+ // get destination folder
+ TreeItem *parentItem = static_cast<TreeItem*>(parent);
+ QString folder = parentItem ? parentItem->directory() : QString::null;
+ MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
+
+ if (e->source() != this)
+ {
+ // External drop
+ KURL::List urls;
+ if (!KURLDrag::decode(e, urls) || (urls.count() != 1) || !urls[0].isLocalFile())
+ return;
+ QString path = urls[0].path();
+ if (!path.endsWith(".desktop"))
+ return;
+
+ QString menuId;
+ QString result = createDesktopFile(path, &menuId, &m_newMenuIds);
+ KDesktopFile orig_df(path);
+ KDesktopFile *df = orig_df.copyTo(result);
+ df->deleteEntry("Categories"); // Don't set any categories!
+
+ KService *s = new KService(df);
+ s->setMenuId(menuId);
+
+ MenuEntryInfo *entryInfo = new MenuEntryInfo(s, df);
+
+ QString oldCaption = entryInfo->caption;
+ QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
+ entryInfo->setCaption(newCaption);
+
+ // Add file to menu
+ // m_menuFile->addEntry(folder, menuId);
+ m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
+
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ // update fileInfo data
+ parentFolderInfo->add(entryInfo);
+
+ TreeItem *newItem = createTreeItem(parentItem, after, entryInfo, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+
+ m_drag = 0;
+ setLayoutDirty(parentItem);
+ return;
+ }
+
+ // is there content in the clipboard?
+ if (!m_drag) return;
+
+ if (m_dragItem == after) return; // Nothing to do
+
+ int command = m_drag;
+ if (command == MOVE_FOLDER)
+ {
+ MenuFolderInfo *folderInfo = m_dragInfo;
+ if (e->action() == QDropEvent::Copy)
+ {
+ // Ugh.. this is hard :)
+ // * Create new .directory file
+ // Add
+ }
+ else
+ {
+ TreeItem *tmpItem = static_cast<TreeItem*>(parentItem);
+ while ( tmpItem )
+ {
+ if ( tmpItem == m_dragItem )
+ {
+ m_drag = 0;
+ return;
+ }
+ tmpItem = static_cast<TreeItem*>(tmpItem->parent() );
+ }
+
+ // Remove MenuFolderInfo
+ TreeItem *oldParentItem = static_cast<TreeItem*>(m_dragItem->parent());
+ MenuFolderInfo *oldParentFolderInfo = oldParentItem ? oldParentItem->folderInfo() : m_rootFolder;
+ oldParentFolderInfo->take(folderInfo);
+
+ // Move menu
+ QString oldFolder = folderInfo->fullId;
+ QString folderName = folderInfo->id;
+ QString newFolder = m_menuFile->uniqueMenuName(folder, folderName, parentFolderInfo->existingMenuIds());
+ folderInfo->id = newFolder;
+
+ // Add file to menu
+ //m_menuFile->moveMenu(oldFolder, folder + newFolder);
+ m_menuFile->pushAction(MenuFile::MOVE_MENU, oldFolder, folder + newFolder);
+
+ // Make sure caption is unique
+ QString newCaption = parentFolderInfo->uniqueMenuCaption(folderInfo->caption);
+ if (newCaption != folderInfo->caption)
+ {
+ folderInfo->setCaption(newCaption);
+ }
+
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ // update fileInfo data
+ folderInfo->updateFullId(parentFolderInfo->fullId);
+ folderInfo->setInUse(true);
+ parentFolderInfo->add(folderInfo);
+
+ if ((parentItem != oldParentItem) || !after)
+ {
+ if (oldParentItem)
+ oldParentItem->takeItem(m_dragItem);
+ else
+ takeItem(m_dragItem);
+ if (parentItem)
+ parentItem->insertItem(m_dragItem);
+ else
+ insertItem(m_dragItem);
+ }
+ m_dragItem->moveItem(after);
+ m_dragItem->setName(folderInfo->caption);
+ m_dragItem->setDirectoryPath(folderInfo->fullId);
+ setSelected(m_dragItem, true);
+ itemSelected(m_dragItem);
+ }
+ }
+ else if (command == MOVE_FILE)
+ {
+ MenuEntryInfo *entryInfo = m_dragItem->entryInfo();
+ QString menuId = entryInfo->menuId();
+
+ if (e->action() == QDropEvent::Copy)
+ {
+
+ // Need to copy file and then add it
+ KDesktopFile *df = copyDesktopFile(entryInfo, &menuId, &m_newMenuIds); // Duplicate
+//UNDO-ACTION: NEW_MENU_ID (menuId)
+
+ KService *s = new KService(df);
+ s->setMenuId(menuId);
+
+ entryInfo = new MenuEntryInfo(s, df);
+
+ QString oldCaption = entryInfo->caption;
+ QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
+ entryInfo->setCaption(newCaption);
+ }
+ else
+ {
+ del(m_dragItem, false);
+ QString oldCaption = entryInfo->caption;
+ QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption);
+ entryInfo->setCaption(newCaption);
+ entryInfo->setInUse(true);
+ }
+ // Add file to menu
+ // m_menuFile->addEntry(folder, menuId);
+ m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
+
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ // update fileInfo data
+ parentFolderInfo->add(entryInfo);
+
+ TreeItem *newItem = createTreeItem(parentItem, after, entryInfo, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+ }
+ else if (command == COPY_SEPARATOR)
+ {
+ if (e->action() != QDropEvent::Copy)
+ del(m_dragItem, false);
+
+ TreeItem *newItem = createTreeItem(parentItem, after, m_separator, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+ }
+ else
+ {
+ // Error
+ }
+ m_drag = 0;
+ setLayoutDirty(parentItem);
+}
+
+
+void TreeView::startDrag()
+{
+ QDragObject *drag = dragObject();
+
+ if (!drag)
+ return;
+
+ drag->dragMove();
+}
+
+QDragObject *TreeView::dragObject()
+{
+ m_dragPath = QString::null;
+ TreeItem *item = (TreeItem*)selectedItem();
+ if(item == 0) return 0;
+
+ KMultipleDrag *drag = new KMultipleDrag( this );
+
+ if (item->isDirectory())
+ {
+ m_drag = MOVE_FOLDER;
+ m_dragInfo = item->folderInfo();
+ m_dragItem = item;
+ }
+ else if (item->isEntry())
+ {
+ m_drag = MOVE_FILE;
+ m_dragInfo = 0;
+ m_dragItem = item;
+ QString menuId = item->menuId();
+ m_dragPath = item->entryInfo()->service->desktopEntryPath();
+ if (!m_dragPath.isEmpty())
+ m_dragPath = locate("apps", m_dragPath);
+ if (!m_dragPath.isEmpty())
+ {
+ KURL url;
+ url.setPath(m_dragPath);
+ drag->addDragObject( new KURLDrag(url, 0));
+ }
+ }
+ else
+ {
+ m_drag = COPY_SEPARATOR;
+ m_dragInfo = 0;
+ m_dragItem = item;
+ }
+
+ drag->addDragObject( new QStoredDrag("application/x-kmenuedit-internal", 0));
+ if ( item->pixmap(0) )
+ drag->setPixmap(*item->pixmap(0));
+ return drag;
+}
+
+void TreeView::slotRMBPressed(QListViewItem*, const QPoint& p)
+{
+ TreeItem *item = (TreeItem*)selectedItem();
+ if(item == 0) return;
+
+ if(m_rmb) m_rmb->exec(p);
+}
+
+void TreeView::newsubmenu()
+{
+ TreeItem *parentItem = 0;
+ TreeItem *item = (TreeItem*)selectedItem();
+
+ bool ok;
+ QString caption = KInputDialog::getText( i18n( "New Submenu" ),
+ i18n( "Submenu name:" ), QString::null, &ok, this );
+
+ if (!ok) return;
+
+ QString file = caption;
+ file.replace('/', '-');
+
+ file = createDirectoryFile(file, &m_newDirectoryList); // Create
+
+ // get destination folder
+ QString folder;
+
+ if(!item)
+ {
+ parentItem = 0;
+ folder = QString::null;
+ }
+ else if(item->isDirectory())
+ {
+ parentItem = item;
+ item = 0;
+ folder = parentItem->directory();
+ }
+ else
+ {
+ parentItem = static_cast<TreeItem*>(item->parent());
+ folder = parentItem ? parentItem->directory() : QString::null;
+ }
+
+ MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
+ MenuFolderInfo *folderInfo = new MenuFolderInfo();
+ folderInfo->caption = parentFolderInfo->uniqueMenuCaption(caption);
+ folderInfo->id = m_menuFile->uniqueMenuName(folder, caption, parentFolderInfo->existingMenuIds());
+ folderInfo->directoryFile = file;
+ folderInfo->icon = "package";
+ folderInfo->hidden = false;
+ folderInfo->setDirty();
+
+ KDesktopFile *df = new KDesktopFile(file);
+ df->writeEntry("Name", folderInfo->caption);
+ df->writeEntry("Icon", folderInfo->icon);
+ df->sync();
+ delete df;
+ // Add file to menu
+ // m_menuFile->addMenu(folder + folderInfo->id, file);
+ m_menuFile->pushAction(MenuFile::ADD_MENU, folder + folderInfo->id, file);
+
+ folderInfo->fullId = parentFolderInfo->fullId + folderInfo->id;
+
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ // update fileInfo data
+ parentFolderInfo->add(folderInfo);
+
+ TreeItem *newItem = createTreeItem(parentItem, item, folderInfo, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+
+ setLayoutDirty(parentItem);
+}
+
+void TreeView::newitem()
+{
+ TreeItem *parentItem = 0;
+ TreeItem *item = (TreeItem*)selectedItem();
+
+ bool ok;
+ QString caption = KInputDialog::getText( i18n( "New Item" ),
+ i18n( "Item name:" ), QString::null, &ok, this );
+
+ if (!ok) return;
+
+ QString menuId;
+ QString file = caption;
+ file.replace('/', '-');
+
+ file = createDesktopFile(file, &menuId, &m_newMenuIds); // Create
+
+ KDesktopFile *df = new KDesktopFile(file);
+ df->writeEntry("Name", caption);
+ df->writeEntry("Type", "Application");
+
+ // get destination folder
+ QString folder;
+
+ if(!item)
+ {
+ parentItem = 0;
+ folder = QString::null;
+ }
+ else if(item->isDirectory())
+ {
+ parentItem = item;
+ item = 0;
+ folder = parentItem->directory();
+ }
+ else
+ {
+ parentItem = static_cast<TreeItem*>(item->parent());
+ folder = parentItem ? parentItem->directory() : QString::null;
+ }
+
+ MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
+
+ // Add file to menu
+ // m_menuFile->addEntry(folder, menuId);
+ m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
+
+ KService *s = new KService(df);
+ s->setMenuId(menuId);
+
+ MenuEntryInfo *entryInfo = new MenuEntryInfo(s, df);
+
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ // update fileInfo data
+ parentFolderInfo->add(entryInfo);
+
+ TreeItem *newItem = createTreeItem(parentItem, item, entryInfo, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+
+ setLayoutDirty(parentItem);
+}
+
+void TreeView::newsep()
+{
+ TreeItem *parentItem = 0;
+ TreeItem *item = (TreeItem*)selectedItem();
+
+ if(!item)
+ {
+ parentItem = 0;
+ }
+ else if(item->isDirectory())
+ {
+ parentItem = item;
+ item = 0;
+ }
+ else
+ {
+ parentItem = static_cast<TreeItem*>(item->parent());
+ }
+
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ TreeItem *newItem = createTreeItem(parentItem, item, m_separator, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+
+ setLayoutDirty(parentItem);
+}
+
+void TreeView::cut()
+{
+ copy( true );
+
+ m_ac->action("edit_cut")->setEnabled(false);
+ m_ac->action("edit_copy")->setEnabled(false);
+ m_ac->action("delete")->setEnabled(false);
+
+ // Select new current item
+ setSelected( currentItem(), true );
+ // Switch the UI to show that item
+ itemSelected( selectedItem() );
+}
+
+void TreeView::copy()
+{
+ copy( false );
+}
+
+void TreeView::copy( bool cutting )
+{
+ TreeItem *item = (TreeItem*)selectedItem();
+
+ // nil selected? -> nil to copy
+ if (item == 0) return;
+
+ if (cutting)
+ setLayoutDirty((TreeItem*)item->parent());
+
+ // clean up old stuff
+ cleanupClipboard();
+
+ // is item a folder or a file?
+ if(item->isDirectory())
+ {
+ QString folder = item->directory();
+ if (cutting)
+ {
+ // Place in clipboard
+ m_clipboard = MOVE_FOLDER;
+ m_clipboardFolderInfo = item->folderInfo();
+
+ del(item, false);
+ }
+ else
+ {
+ // Place in clipboard
+ m_clipboard = COPY_FOLDER;
+ m_clipboardFolderInfo = item->folderInfo();
+ }
+ }
+ else if (item->isEntry())
+ {
+ if (cutting)
+ {
+ // Place in clipboard
+ m_clipboard = MOVE_FILE;
+ m_clipboardEntryInfo = item->entryInfo();
+
+ del(item, false);
+ }
+ else
+ {
+ // Place in clipboard
+ m_clipboard = COPY_FILE;
+ m_clipboardEntryInfo = item->entryInfo();
+ }
+ }
+ else
+ {
+ // Place in clipboard
+ m_clipboard = COPY_SEPARATOR;
+ if (cutting)
+ del(item, false);
+ }
+
+ m_ac->action("edit_paste")->setEnabled(true);
+}
+
+
+void TreeView::paste()
+{
+ TreeItem *parentItem = 0;
+ TreeItem *item = (TreeItem*)selectedItem();
+
+ // nil selected? -> nil to paste to
+ if (item == 0) return;
+
+ // is there content in the clipboard?
+ if (!m_clipboard) return;
+
+ // get destination folder
+ QString folder;
+
+ if(item->isDirectory())
+ {
+ parentItem = item;
+ item = 0;
+ folder = parentItem->directory();
+ }
+ else
+ {
+ parentItem = static_cast<TreeItem*>(item->parent());
+ folder = parentItem ? parentItem->directory() : QString::null;
+ }
+
+ MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
+ int command = m_clipboard;
+ if ((command == COPY_FOLDER) || (command == MOVE_FOLDER))
+ {
+ MenuFolderInfo *folderInfo = m_clipboardFolderInfo;
+ if (command == COPY_FOLDER)
+ {
+ // Ugh.. this is hard :)
+ // * Create new .directory file
+ // Add
+ }
+ else if (command == MOVE_FOLDER)
+ {
+ // Move menu
+ QString oldFolder = folderInfo->fullId;
+ QString folderName = folderInfo->id;
+ QString newFolder = m_menuFile->uniqueMenuName(folder, folderName, parentFolderInfo->existingMenuIds());
+ folderInfo->id = newFolder;
+
+ // Add file to menu
+ // m_menuFile->moveMenu(oldFolder, folder + newFolder);
+ m_menuFile->pushAction(MenuFile::MOVE_MENU, oldFolder, folder + newFolder);
+
+ // Make sure caption is unique
+ QString newCaption = parentFolderInfo->uniqueMenuCaption(folderInfo->caption);
+ if (newCaption != folderInfo->caption)
+ {
+ folderInfo->setCaption(newCaption);
+ }
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ // update fileInfo data
+ folderInfo->fullId = parentFolderInfo->fullId + folderInfo->id;
+ folderInfo->setInUse(true);
+ parentFolderInfo->add(folderInfo);
+
+ TreeItem *newItem = createTreeItem(parentItem, item, folderInfo);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+ }
+
+ m_clipboard = COPY_FOLDER; // Next one copies.
+ }
+ else if ((command == COPY_FILE) || (command == MOVE_FILE))
+ {
+ MenuEntryInfo *entryInfo = m_clipboardEntryInfo;
+ QString menuId;
+
+ if (command == COPY_FILE)
+ {
+ // Need to copy file and then add it
+ KDesktopFile *df = copyDesktopFile(entryInfo, &menuId, &m_newMenuIds); // Duplicate
+
+ KService *s = new KService(df);
+ s->setMenuId(menuId);
+ entryInfo = new MenuEntryInfo(s, df);
+
+ QString oldCaption = entryInfo->caption;
+ QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption, oldCaption);
+ entryInfo->setCaption(newCaption);
+ }
+ else if (command == MOVE_FILE)
+ {
+ menuId = entryInfo->menuId();
+ m_clipboard = COPY_FILE; // Next one copies.
+
+ QString oldCaption = entryInfo->caption;
+ QString newCaption = parentFolderInfo->uniqueItemCaption(oldCaption);
+ entryInfo->setCaption(newCaption);
+ entryInfo->setInUse(true);
+ }
+ // Add file to menu
+ // m_menuFile->addEntry(folder, menuId);
+ m_menuFile->pushAction(MenuFile::ADD_ENTRY, folder, menuId);
+
+ // create the TreeItem
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ // update fileInfo data
+ parentFolderInfo->add(entryInfo);
+
+ TreeItem *newItem = createTreeItem(parentItem, item, entryInfo, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+ }
+ else
+ {
+ // create separator
+ if(parentItem)
+ parentItem->setOpen(true);
+
+ TreeItem *newItem = createTreeItem(parentItem, item, m_separator, true);
+
+ setSelected ( newItem, true);
+ itemSelected( newItem);
+ }
+ setLayoutDirty(parentItem);
+}
+
+void TreeView::del()
+{
+ TreeItem *item = (TreeItem*)selectedItem();
+
+ // nil selected? -> nil to delete
+ if (item == 0) return;
+
+ del(item, true);
+
+ m_ac->action("edit_cut")->setEnabled(false);
+ m_ac->action("edit_copy")->setEnabled(false);
+ m_ac->action("delete")->setEnabled(false);
+ // Select new current item
+ setSelected( currentItem(), true );
+ // Switch the UI to show that item
+ itemSelected( selectedItem() );
+}
+
+void TreeView::del(TreeItem *item, bool deleteInfo)
+{
+ TreeItem *parentItem = static_cast<TreeItem*>(item->parent());
+ // is file a .directory or a .desktop file
+ if(item->isDirectory())
+ {
+ MenuFolderInfo *folderInfo = item->folderInfo();
+
+ // Remove MenuFolderInfo
+ MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
+ parentFolderInfo->take(folderInfo);
+ folderInfo->setInUse(false);
+
+ if (m_clipboard == COPY_FOLDER && (m_clipboardFolderInfo == folderInfo))
+ {
+ // Copy + Del == Cut
+ m_clipboard = MOVE_FOLDER; // Clipboard now owns folderInfo
+
+ }
+ else
+ {
+ if (folderInfo->takeRecursive(m_clipboardFolderInfo))
+ m_clipboard = MOVE_FOLDER; // Clipboard now owns m_clipboardFolderInfo
+
+ if (deleteInfo)
+ delete folderInfo; // Delete folderInfo
+ }
+
+ // Remove from menu
+ // m_menuFile->removeMenu(item->directory());
+ m_menuFile->pushAction(MenuFile::REMOVE_MENU, item->directory(), QString::null);
+
+ // Remove tree item
+ delete item;
+ }
+ else if (item->isEntry())
+ {
+ MenuEntryInfo *entryInfo = item->entryInfo();
+ QString menuId = entryInfo->menuId();
+
+ // Remove MenuFolderInfo
+ MenuFolderInfo *parentFolderInfo = parentItem ? parentItem->folderInfo() : m_rootFolder;
+ parentFolderInfo->take(entryInfo);
+ entryInfo->setInUse(false);
+
+ if (m_clipboard == COPY_FILE && (m_clipboardEntryInfo == entryInfo))
+ {
+ // Copy + Del == Cut
+ m_clipboard = MOVE_FILE; // Clipboard now owns entryInfo
+ }
+ else
+ {
+ if (deleteInfo)
+ delete entryInfo; // Delete entryInfo
+ }
+
+ // Remove from menu
+ QString folder = parentItem ? parentItem->directory() : QString::null;
+ // m_menuFile->removeEntry(folder, menuId);
+ m_menuFile->pushAction(MenuFile::REMOVE_ENTRY, folder, menuId);
+
+ // Remove tree item
+ delete item;
+ }
+ else
+ {
+ // Remove separator
+ delete item;
+ }
+ setLayoutDirty(parentItem);
+}
+
+void TreeView::cleanupClipboard() {
+ if (m_clipboard == MOVE_FOLDER)
+ delete m_clipboardFolderInfo;
+ m_clipboardFolderInfo = 0;
+
+ if (m_clipboard == MOVE_FILE)
+ delete m_clipboardEntryInfo;
+ m_clipboardEntryInfo = 0;
+
+ m_clipboard = 0;
+}
+
+static QStringList extractLayout(TreeItem *item)
+{
+ bool firstFolder = true;
+ bool firstEntry = true;
+ QStringList layout;
+ for(;item; item = static_cast<TreeItem*>(item->nextSibling()))
+ {
+ if (item->isDirectory())
+ {
+ if (firstFolder)
+ {
+ firstFolder = false;
+ layout << ":M"; // Add new folders here...
+ }
+ layout << (item->folderInfo()->id);
+ }
+ else if (item->isEntry())
+ {
+ if (firstEntry)
+ {
+ firstEntry = false;
+ layout << ":F"; // Add new entries here...
+ }
+ layout << (item->entryInfo()->menuId());
+ }
+ else
+ {
+ layout << ":S";
+ }
+ }
+ return layout;
+}
+
+QStringList TreeItem::layout()
+{
+ QStringList layout = extractLayout(static_cast<TreeItem*>(firstChild()));
+ _layoutDirty = false;
+ return layout;
+}
+
+void TreeView::saveLayout()
+{
+ if (m_layoutDirty)
+ {
+ QStringList layout = extractLayout(static_cast<TreeItem*>(firstChild()));
+ m_menuFile->setLayout(m_rootFolder->fullId, layout);
+ m_layoutDirty = false;
+ }
+
+ QPtrList<QListViewItem> lst;
+ QListViewItemIterator it( this );
+ while ( it.current() ) {
+ TreeItem *item = static_cast<TreeItem*>(it.current());
+ if ( item->isLayoutDirty() )
+ {
+ m_menuFile->setLayout(item->folderInfo()->fullId, item->layout());
+ }
+ ++it;
+ }
+}
+
+bool TreeView::save()
+{
+ saveLayout();
+ m_rootFolder->save(m_menuFile);
+
+ bool success = m_menuFile->performAllActions();
+
+ m_newMenuIds.clear();
+ m_newDirectoryList.clear();
+
+ if (success)
+ {
+ KService::rebuildKSycoca(this);
+ }
+ else
+ {
+ KMessageBox::sorry(this, "<qt>"+i18n("Menu changes could not be saved because of the following problem:")+"<br><br>"+
+ m_menuFile->error()+"</qt>");
+ }
+ return success;
+}
+
+void TreeView::setLayoutDirty(TreeItem *parentItem)
+{
+ if (parentItem)
+ parentItem->setLayoutDirty();
+ else
+ m_layoutDirty = true;
+}
+
+bool TreeView::isLayoutDirty()
+{
+ QPtrList<QListViewItem> lst;
+ QListViewItemIterator it( this );
+ while ( it.current() ) {
+ if ( static_cast<TreeItem*>(it.current())->isLayoutDirty() )
+ return true;
+ ++it;
+ }
+ return false;
+}
+
+bool TreeView::dirty()
+{
+ return m_layoutDirty || m_rootFolder->hasDirt() || m_menuFile->dirty() || isLayoutDirty();
+}
+
+void TreeView::findServiceShortcut(const KShortcut&cut, KService::Ptr &service)
+{
+ service = m_rootFolder->findServiceShortcut(cut);
+}
+