summaryrefslogtreecommitdiffstats
path: root/kcontrol/keys/treeview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kcontrol/keys/treeview.cpp')
-rw-r--r--kcontrol/keys/treeview.cpp282
1 files changed, 282 insertions, 0 deletions
diff --git a/kcontrol/keys/treeview.cpp b/kcontrol/keys/treeview.cpp
new file mode 100644
index 000000000..0c2056766
--- /dev/null
+++ b/kcontrol/keys/treeview.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2000 Matthias Elter <elter@kde.org>
+ * Copyright (C) 2001-2002 Raffaele Sandrini <sandrini@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 <qdir.h>
+#include <qimage.h>
+#include <qstringlist.h>
+#include <qcursor.h>
+
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kservicegroup.h>
+
+#include "treeview.h"
+#include "treeview.moc"
+#include "khotkeys.h"
+
+AppTreeItem::AppTreeItem(QListViewItem *parent, const QString& storageId)
+ : KListViewItem(parent), m_init(false), m_storageId(storageId) {}
+
+AppTreeItem::AppTreeItem(QListViewItem *parent, QListViewItem *after, const QString& storageId)
+ : KListViewItem(parent, after), m_init(false), m_storageId(storageId) {}
+
+AppTreeItem::AppTreeItem(QListView *parent, const QString& storageId)
+ : KListViewItem(parent), m_init(false), m_storageId(storageId) {}
+
+AppTreeItem::AppTreeItem(QListView *parent, QListViewItem *after, const QString& storageId)
+ : KListViewItem(parent, after), m_init(false), m_storageId(storageId) {}
+
+void AppTreeItem::setName(const QString &name)
+{
+ m_name = name;
+ setText(0, m_name);
+}
+
+void AppTreeItem::setAccel(const QString &accel)
+{
+ m_accel = accel;
+ int temp = accel.find(';');
+ if (temp != -1)
+ {
+ setText(1, accel.left(temp));
+ setText(2, accel.right(accel.length() - temp - 1));
+ }
+ else
+ {
+ setText(1, m_accel);
+ setText(2, QString::null);
+ }
+}
+
+void AppTreeItem::setOpen(bool o)
+{
+ if (o && !m_directoryPath.isEmpty() && !m_init)
+ {
+ m_init = true;
+ AppTreeView *tv = static_cast<AppTreeView *>(listView());
+ tv->fillBranch(m_directoryPath, this);
+ }
+ QListViewItem::setOpen(o);
+}
+
+static QPixmap appIcon(const QString &iconName)
+{
+ QPixmap normal = SmallIcon( iconName );
+ // 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;
+}
+
+
+AppTreeView::AppTreeView( QWidget *parent, const char *name )
+ : KListView(parent, name)
+{
+ setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
+ setAllColumnsShowFocus(true);
+ setRootIsDecorated(true);
+ setSorting(-1);
+ setAcceptDrops(false);
+ setDragEnabled(false);
+ setMinimumWidth(240);
+ setResizeMode(AllColumns);
+
+ addColumn(i18n("Command"));
+ addColumn(i18n("Shortcut"));
+ addColumn(i18n("Alternate"));
+
+ connect(this, SIGNAL(clicked( QListViewItem* )),
+ SLOT(itemSelected( QListViewItem* )));
+
+ connect(this,SIGNAL(selectionChanged ( QListViewItem * )),
+ SLOT(itemSelected( QListViewItem* )));
+}
+
+AppTreeView::~AppTreeView()
+{
+}
+
+void AppTreeView::fill()
+{
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ clear();
+ fillBranch(QString::null, 0);
+ QApplication::restoreOverrideCursor();
+}
+
+void AppTreeView::fillBranch(const QString& rPath, AppTreeItem *parent)
+{
+ // get rid of leading slash in the relative path
+ QString relPath = rPath;
+ if(relPath[0] == '/')
+ relPath = relPath.mid(1, relPath.length());
+
+ // We ask KSycoca to give us all services (sorted).
+ KServiceGroup::Ptr root = KServiceGroup::group(relPath);
+
+ if (!root || !root->isValid())
+ return;
+
+ KServiceGroup::List list = root->entries(true);
+
+ QListViewItem *after = 0;
+
+ 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));
+ QString groupCaption = g->caption();
+
+ // Item names may contain ampersands. To avoid them being converted
+ // to accelerators, replace them with two ampersands.
+ groupCaption.replace("&", "&&");
+
+ AppTreeItem *item;
+ if (parent == 0)
+ item = new AppTreeItem(this, after, QString::null);
+ else
+ item = new AppTreeItem(parent, after, QString::null);
+
+ item->setName(groupCaption);
+ item->setPixmap(0, appIcon(g->icon()));
+ item->setDirectoryPath(g->relPath());
+ item->setExpandable(true);
+ after = item;
+ }
+ else if (e->isType(KST_KService))
+ {
+ KService::Ptr s(static_cast<KService *>(e));
+ QString serviceCaption = s->name();
+
+ // Item names may contain ampersands. To avoid them being converted
+ // to accelerators, replace them with two ampersands.
+ serviceCaption.replace("&", "&&");
+
+ AppTreeItem* item;
+ if (parent == 0)
+ item = new AppTreeItem(this, after, s->storageId());
+ else
+ item = new AppTreeItem(parent, after, s->storageId());
+
+ item->setName(serviceCaption);
+ item->setAccel(KHotKeys::getMenuEntryShortcut(s->storageId()));
+ item->setPixmap(0, appIcon(s->icon()));
+
+ after = item;
+ }
+ }
+}
+
+void AppTreeView::itemSelected(QListViewItem *item)
+{
+ AppTreeItem *_item = static_cast<AppTreeItem*>(item);
+
+ if(!item) return;
+
+ emit entrySelected(_item->storageId(), _item->accel(), _item->isDirectory());
+}
+
+QStringList AppTreeView::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 AppTreeView::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;
+}