You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
513 lines
15 KiB
513 lines
15 KiB
/***************************************************************************
|
|
treewidget.cpp - Tree/detailed list widget
|
|
-------------------
|
|
copyright : (C) 2002-2003 Marc Britton <consume@optusnet.com.au>
|
|
(C) 2004 Michal Rudolf <mrudolf@kdewebdev.org>
|
|
(C) 2008 Andras Mantia <amantia@kdewebdev.org>
|
|
(C) 2008 Eric Laffoon <eric@kdewebdev.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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
/* KDE INCLUDES */
|
|
#include <klocale.h>
|
|
#include <kglobal.h>
|
|
#include <kiconloader.h>
|
|
#include <klistview.h>
|
|
|
|
/* QT INCLUDES */
|
|
#include <qstring.h>
|
|
#include <qwidget.h>
|
|
#include <qstringlist.h>
|
|
#include <qevent.h>
|
|
#include <qlistview.h>
|
|
|
|
/* OTHER INCLUDES */
|
|
#include <specials.h>
|
|
#include "treewidget.h"
|
|
#include "kommanderplugin.h"
|
|
#include "specials.h"
|
|
|
|
#define TW_FUNCTION 275
|
|
#define addColumnTree TW_FUNCTION+1
|
|
#define setAltBackground TW_FUNCTION+2
|
|
#define setColAlignment TW_FUNCTION+3
|
|
//#define colCount TW_FUNCTION+3
|
|
#define colCaption TW_FUNCTION+4
|
|
#define setColWidth TW_FUNCTION+5
|
|
#define setSortCol TW_FUNCTION+6
|
|
#define TW_LAST_FUNCTION setSortCol
|
|
|
|
enum Functions {
|
|
FirstFunction = 189,
|
|
SelectedIndexes,
|
|
TW_childCount,
|
|
TW_setOpen,
|
|
TW_isOpen,
|
|
LastFunction
|
|
};
|
|
|
|
TreeWidget::TreeWidget(QWidget *a_parent, const char *a_name)
|
|
: KListView(a_parent, a_name), KommanderWidget(this)
|
|
{
|
|
QStringList states;
|
|
states << "default";
|
|
setStates(states);
|
|
setDisplayStates(states);
|
|
setPathSeparator("/");
|
|
KommanderPlugin::setDefaultGroup(Group::DCOP);
|
|
KommanderPlugin::registerFunction(SelectedIndexes, "selectedIndexes(QString widget)", "", 1);
|
|
KommanderPlugin::registerFunction(addColumnTree, "addColumn(QString widget, const QString & label, int width = -1 )", i18n("Add column at end with column header"), 2, 3);
|
|
KommanderPlugin::registerFunction(setSortCol, "setSortColumn(QString widget, int column, bool ascending=true)", i18n("Set sorting for a column"), 2, 3);
|
|
//KommanderPlugin::registerFunction(setAltBackground, "setAltBackground(QString widget, const QColor & c)", i18n("Alternate colors in list view"), 2);
|
|
// KommanderPlugin::registerFunction(colCount, "colCount(QString widget)", i18n("Get the column count"), 1);
|
|
KommanderPlugin::registerFunction(colCaption, "columnCaption(QString widget, int column)", i18n("Get the column caption for column index"), 2);
|
|
KommanderPlugin::registerFunction(setColWidth, "setColWidth(QString widget, int column, int width)", i18n("Set the pixel width for column index - use 0 to hide"), 3);
|
|
KommanderPlugin::registerFunction(setColAlignment, "setColumnAlignment(QString widget, int column, QString Alignment)", i18n("Set to <i>left</i>, <i>right</i> or <i>center</i>, case insensitive "), 3);
|
|
KommanderPlugin::registerFunction(TW_childCount, "childCount(QString widget)", i18n("Get the count of top level items."), 1);
|
|
KommanderPlugin::registerFunction(TW_setOpen, "setOpen(QString widget, int Index, bool Open)", i18n("Expand or collapse a node."), 3);
|
|
KommanderPlugin::registerFunction(TW_isOpen, "isOpen(QString widget, int Index)", i18n("See if node is open or closed."), 2);
|
|
}
|
|
|
|
TreeWidget::~TreeWidget()
|
|
{
|
|
}
|
|
|
|
QString TreeWidget::pathSeparator() const
|
|
{
|
|
return m_pathSeparator;
|
|
}
|
|
|
|
void TreeWidget::setPathSeparator(const QString& a_pathSep)
|
|
{
|
|
m_pathSeparator = a_pathSep;
|
|
}
|
|
|
|
void TreeWidget::addItemFromString(const QString& s)
|
|
{
|
|
QStringList elements = QStringList::split(m_pathSeparator, s, true);
|
|
if (elements.count() > 1)
|
|
setRootIsDecorated(true);
|
|
QListViewItem* parent = 0;
|
|
if (m_lastPath.size() < elements.count())
|
|
m_lastPath.resize(elements.count());
|
|
uint i = 0;
|
|
for (QStringList::ConstIterator it = elements.begin(); it != elements.end(); ++it)
|
|
{
|
|
if (m_lastPath[i] && m_lastPath[i]->text(0) == elements[i])
|
|
{
|
|
parent = m_lastPath[i];
|
|
i++;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
QListViewItem* item = (i>0) ? parent->firstChild() : firstChild();
|
|
while (item)
|
|
{
|
|
if (item->text(0) == *it)
|
|
break;
|
|
item = item->nextSibling();
|
|
}
|
|
if (item)
|
|
parent = item;
|
|
else
|
|
parent = itemFromString(parent, *it);
|
|
m_lastPath.insert(i, parent);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
QListViewItem* TreeWidget::itemFromString(QListViewItem* parent, const QString& s)
|
|
{
|
|
QStringList elements;
|
|
if (s.contains("\t"))
|
|
elements = QStringList::split("\t", s, true);
|
|
else
|
|
elements = QStringList::split("\\t", s, true);
|
|
int cols = elements.count();
|
|
if (cols >= columns())
|
|
cols = columns();
|
|
QListViewItem* item;
|
|
if (parent)
|
|
item = new QListViewItem(parent);
|
|
else
|
|
item = new QListViewItem(this);
|
|
int i = 0;
|
|
for (QStringList::ConstIterator it = elements.constBegin(); it != elements.constEnd(); ++it)
|
|
item->setText(i++, *it);
|
|
return item;
|
|
}
|
|
|
|
int TreeWidget::itemToIndex(QListViewItem* item)
|
|
{
|
|
// if (!item->isSelected())
|
|
// return -1;
|
|
QListViewItemIterator it(this);
|
|
int index = 0;
|
|
while (it.current()) {
|
|
if (it.current() == item)
|
|
return index;
|
|
++it;
|
|
++index;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int TreeWidget::itemToIndexSafe(QListViewItem* item)
|
|
{
|
|
QListViewItemIterator it(this);
|
|
int index = 0;
|
|
while (it.current()) {
|
|
if (it.current() == item)
|
|
return index;
|
|
++it;
|
|
++index;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
QListViewItem* TreeWidget::indexToItem(int item)
|
|
{
|
|
QListViewItemIterator it(this);
|
|
int index = 0;
|
|
while (it.current()) {
|
|
if (index == item)
|
|
return it.current();
|
|
++it;
|
|
++index;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
QString TreeWidget::itemText(QListViewItem* item) const
|
|
{
|
|
if (!item)
|
|
return QString();
|
|
QStringList items;
|
|
for (int i=0; i<columns(); i++)
|
|
items.append(item->text(i));
|
|
return items.join("\t");
|
|
}
|
|
|
|
QString TreeWidget::itemsText()
|
|
{
|
|
QStringList items;
|
|
QListViewItemIterator it(this);
|
|
while (it.current())
|
|
{
|
|
QString path = itemPath(it.current());
|
|
if (path.isEmpty())
|
|
items.append(itemText(it.current()));
|
|
else
|
|
items.append(QString("%1%2%3").arg(path).arg(m_pathSeparator)
|
|
.arg(itemText(it.current())));
|
|
++it;
|
|
}
|
|
return items.join("\n");
|
|
}
|
|
|
|
QString TreeWidget::itemPath(QListViewItem* item) const
|
|
{
|
|
if (!item)
|
|
return QString();
|
|
item = item->parent();
|
|
if (!item)
|
|
return QString();
|
|
QStringList path;
|
|
while (item)
|
|
{
|
|
path.prepend(item->text(0));
|
|
item = item->parent();
|
|
}
|
|
return path.join(m_pathSeparator);
|
|
}
|
|
|
|
QString TreeWidget::currentState() const
|
|
{
|
|
return QString("default");
|
|
}
|
|
|
|
bool TreeWidget::isKommanderWidget() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void TreeWidget::setCurrentItem(QListViewItem* item)
|
|
{
|
|
KListView::setCurrentItem(item);
|
|
setSelected(item, true);
|
|
ensureItemVisible(item);
|
|
}
|
|
|
|
QStringList TreeWidget::associatedText() const
|
|
{
|
|
return KommanderWidget::associatedText();
|
|
}
|
|
|
|
void TreeWidget::setAssociatedText(const QStringList& a_at)
|
|
{
|
|
KommanderWidget::setAssociatedText(a_at);
|
|
}
|
|
|
|
void TreeWidget::setPopulationText(const QString& a_text)
|
|
{
|
|
KommanderWidget::setPopulationText( a_text );
|
|
}
|
|
|
|
QString TreeWidget::populationText() const
|
|
{
|
|
return KommanderWidget::populationText();
|
|
}
|
|
|
|
void TreeWidget::populate()
|
|
{
|
|
setWidgetText(KommanderWidget::evalAssociatedText( populationText()));
|
|
}
|
|
|
|
void TreeWidget::setWidgetText(const QString &a_text)
|
|
{
|
|
handleDCOP(DCOP::setText, a_text);
|
|
emit widgetTextChanged(a_text);
|
|
}
|
|
|
|
void TreeWidget::showEvent(QShowEvent* e)
|
|
{
|
|
QListView::showEvent( e );
|
|
emit widgetOpened();
|
|
}
|
|
|
|
void TreeWidget::contextMenuEvent( QContextMenuEvent * e )
|
|
{
|
|
e->accept();
|
|
QPoint p = e->globalPos();
|
|
emit contextMenuRequested(p.x(), p.y());
|
|
}
|
|
|
|
void TreeWidget::setColAlign(int column, const QString& align)
|
|
{
|
|
if (align.lower() == "left")
|
|
setColumnAlignment (column, Qt::AlignLeft);
|
|
else if (align.lower() == "right")
|
|
setColumnAlignment (column, Qt::AlignRight);
|
|
else if (align.lower() == "center")
|
|
setColumnAlignment (column, Qt::AlignCenter);
|
|
}
|
|
|
|
bool TreeWidget::isFunctionSupported(int f)
|
|
{
|
|
return f == DCOP::insertItem || f == DCOP::text || f == DCOP::setText || f == DCOP::insertItems ||
|
|
f == DCOP::selection || f == DCOP::setSelection || f == DCOP::clear || f == DCOP::removeItem ||
|
|
f == DCOP::currentItem || f == DCOP::setCurrentItem || f == DCOP::findItem || f == DCOP::item ||
|
|
f == DCOP::itemPath || f == DCOP::itemDepth || f == DCOP::setPixmap || f == DCOP::setColumnCaption || f == DCOP::removeColumn || f == DCOP::columnCount || f == DCOP::geometry || f == DCOP::hasFocus || f == DCOP::getBackgroundColor || f == DCOP::setBackgroundColor || (f > FirstFunction && f < LastFunction) || (f >= TW_FUNCTION && f <= TW_LAST_FUNCTION);
|
|
}
|
|
|
|
QString TreeWidget::handleDCOP(int function, const QStringList& args)
|
|
{
|
|
switch (function) {
|
|
case DCOP::insertItem:
|
|
addItemFromString(args[0]);
|
|
break;
|
|
case DCOP::text:
|
|
return itemsText();
|
|
case DCOP::setText:
|
|
clear(); /* break omitted: setText is equivalent to clear and insertItems */
|
|
m_lastPath.clear();
|
|
case DCOP::insertItems:
|
|
{
|
|
QStringList items(QStringList::split("\n", args[0], true));
|
|
for (QStringList::ConstIterator it = items.constBegin(); it != items.constEnd(); ++it)
|
|
addItemFromString(*it);
|
|
break;
|
|
}
|
|
case TW_setOpen:
|
|
setOpen(indexToItem(args[0].toInt()), args[1].toInt());
|
|
break;
|
|
case TW_isOpen:
|
|
return QString::number(isOpen(indexToItem(args[0].toInt())));
|
|
break;
|
|
case SelectedIndexes:
|
|
{
|
|
QString selection = "";
|
|
QListViewItemIterator it(this);
|
|
while (it.current())
|
|
{
|
|
if (it.current()->isSelected())
|
|
{
|
|
selection.append(QString("%1\n").arg(itemToIndexSafe(it.current())));
|
|
}
|
|
++it;
|
|
}
|
|
if (!selection.isEmpty())
|
|
selection = selection.left(selection.length() - 1);
|
|
return selection;
|
|
break;
|
|
}
|
|
case DCOP::selection:
|
|
{
|
|
QString selection = "";
|
|
QListViewItemIterator it(this);
|
|
while (it.current())
|
|
{
|
|
if (it.current()->isSelected())
|
|
selection.append(itemText(it.current()) + "\n");
|
|
++it;
|
|
}
|
|
if (!selection.isEmpty())
|
|
selection = selection.left(selection.length() - 1);
|
|
return selection;
|
|
break;
|
|
}
|
|
case DCOP::setSelection:
|
|
if (selectionModeExt() == Single || selectionModeExt() == NoSelection)
|
|
setCurrentItem(findItem(args[0], 0));
|
|
else
|
|
{
|
|
clearSelection();
|
|
QStringList items(QStringList::split("\n", args[0]));
|
|
for (QStringList::ConstIterator it = items.begin(); it != items.end(); ++it)
|
|
{
|
|
QListViewItem* item = findItem(*it, 0);
|
|
if (item)
|
|
{
|
|
item->setSelected(true);
|
|
ensureItemVisible(item);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case DCOP::clear:
|
|
clear();
|
|
m_lastPath.clear();
|
|
break;
|
|
case DCOP::removeItem:
|
|
{
|
|
if (args[0].toInt() >= 0 )
|
|
{
|
|
delete indexToItem(args[0].toInt());
|
|
m_lastPath.clear();
|
|
}
|
|
break;
|
|
}
|
|
case DCOP::currentItem:
|
|
return QString::number(itemToIndexSafe(currentItem()));
|
|
break;
|
|
case DCOP::setCurrentItem:
|
|
setCurrentItem(indexToItem(args[0].toInt()));
|
|
break;
|
|
case DCOP::findItem:
|
|
if (!args[1])
|
|
return QString::number(itemToIndexSafe(findItem(args[0], 0)));
|
|
else
|
|
{
|
|
if (args[2].toUInt() && args[3].toUInt())
|
|
return QString::number(itemToIndexSafe(findItem(args[0], args[1].toInt())));
|
|
else if (args[2].toUInt())
|
|
return QString::number(itemToIndexSafe(findItem(args[0], args[1].toInt(), Qt::CaseSensitive | Qt::Contains)));
|
|
else if (args[3].toUInt())
|
|
return QString::number(itemToIndexSafe(findItem(args[0], args[1].toInt(), Qt::ExactMatch)));
|
|
else
|
|
return QString::number(itemToIndexSafe(findItem(args[0], args[1].toInt(), Qt::Contains)));
|
|
}
|
|
break;
|
|
case DCOP::item:
|
|
return itemText(indexToItem(args[0].toInt()));
|
|
break;
|
|
case DCOP::itemPath:
|
|
return itemPath(indexToItem(args[0].toInt()));
|
|
break;
|
|
case DCOP::itemDepth:
|
|
{
|
|
QListViewItem* item = indexToItem(args[0].toInt());
|
|
return (item) ? QString::number(item->depth()) : QString::number(-1);
|
|
}
|
|
case DCOP::setPixmap:
|
|
{
|
|
QPixmap pixmap = KGlobal::iconLoader()->loadIcon(args[0], KIcon::Small);
|
|
if (args[1].toInt() == -1)
|
|
for (QListViewItemIterator it(this); it.current(); ++it)
|
|
it.current()->setPixmap(0, pixmap);
|
|
else
|
|
{
|
|
QListViewItem* item = indexToItem(args[1].toInt());
|
|
if (item)
|
|
item->setPixmap(0, pixmap);
|
|
}
|
|
break;
|
|
}
|
|
case DCOP::setColumnCaption:
|
|
if (columns() >= args[0].toInt())
|
|
setColumnText(args[0].toInt(), args[1]);
|
|
break;
|
|
case DCOP::getBackgroundColor:
|
|
return this->paletteBackgroundColor().name();
|
|
break;
|
|
case DCOP::setBackgroundColor:
|
|
{
|
|
QColor color;
|
|
color.setNamedColor(args[0]);
|
|
this->setPaletteBackgroundColor(color);
|
|
break;
|
|
}
|
|
case addColumnTree:
|
|
return QString::number(KListView::addColumn(args[0], args[1].toInt()));
|
|
break;
|
|
case setSortCol:
|
|
KListView::setSorting(args[0].toInt(), args[1].toInt());
|
|
break;
|
|
case DCOP::columnCount:
|
|
return QString::number(QListView::columns() );
|
|
break;
|
|
case colCaption:
|
|
return QListView::columnText(args[0].toInt()) ;
|
|
break;
|
|
case setColWidth:
|
|
QListView::setColumnWidth(args[0].toInt(), args[1].toInt());
|
|
break;
|
|
case setColAlignment:
|
|
setColAlign(args[0].toInt(), args[1]);
|
|
break;
|
|
case setAltBackground:
|
|
KListView::setAlternateBackground(QColor(args[0]));
|
|
break;
|
|
case DCOP::removeColumn:
|
|
{
|
|
if (!args[1].toInt())
|
|
removeColumn(args[0].toInt());
|
|
else
|
|
{
|
|
int column = args[0].toInt();
|
|
int lines = args[1].toInt();
|
|
for (int i = 0; i < lines; i++)
|
|
removeColumn(column);
|
|
}
|
|
break;
|
|
}
|
|
case TW_childCount:
|
|
return QString::number(childCount());
|
|
break;
|
|
case DCOP::geometry:
|
|
{
|
|
QString geo = QString::number(this->x())+" "+QString::number(this->y())+" "+QString::number(this->width())+" "+QString::number(this->height());
|
|
return geo;
|
|
break;
|
|
}
|
|
case DCOP::hasFocus:
|
|
return QString::number(this->hasFocus());
|
|
break;
|
|
default:
|
|
return KommanderWidget::handleDCOP(function, args);
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
#include "treewidget.moc"
|