the "tree" in it's name... can't see/write it anymore :p).
- The basic structure of the model has been improved.
- NetworkInfos and IrcChannel objects are now connected to the model
which allows pretty nice stuff. (we got a working topic yeahi!)
to be continued...
#include "bufferinfo.h"
#include "client.h"
#include "signalproxy.h"
+#include "networkinfo.h"
+#include "ircchannel.h"
+#include "ircuser.h"
/*****************************************
* Fancy Buffer Items
*****************************************/
-BufferTreeItem::BufferTreeItem(Buffer *buffer, TreeItem *parent)
- : TreeItem(parent),
+BufferTreeItem::BufferTreeItem(Buffer *buffer, AbstractTreeItem *parent)
+ : PropertyMapItem(QStringList() << "bufferName" << "topic" << "nickCount", parent),
buf(buffer),
activity(Buffer::NoActivity)
{
activity = level;
}
-QString BufferTreeItem::text(int column) const {
- switch(column) {
- case 0:
- return buf->name();
- case 1:
- return buf->networkName();
- default:
- return QString();
- }
-}
-
QColor BufferTreeItem::foreground(int column) const {
Q_UNUSED(column)
// for the time beeing we ignore the column :)
}
}
-
QVariant BufferTreeItem::data(int column, int role) const {
switch(role) {
- case Qt::DisplayRole:
- return text(column);
- case Qt::ForegroundRole:
- return foreground(column);
- case BufferTreeModel::BufferTypeRole:
- return int(buf->bufferType());
- case BufferTreeModel::BufferActiveRole:
- return buf->isActive();
case BufferTreeModel::BufferUidRole:
return buf->bufferInfo().uid();
case BufferTreeModel::NetworkIdRole:
return buf->bufferInfo().networkId();
-
+ case BufferTreeModel::BufferTypeRole:
+ return int(buf->bufferType());
+ case BufferTreeModel::BufferActiveRole:
+ return buf->isActive();
+ case Qt::ForegroundRole:
+ return foreground(column);
default:
- return TreeItem::data(column, role);
+ return PropertyMapItem::data(column, role);
}
}
+void BufferTreeItem::attachIrcChannel(IrcChannel *ircChannel) {
+ if(!ircChannel)
+ return;
+
+ _ircChannel = ircChannel;
+
+ connect(ircChannel, SIGNAL(topicSet(QString)),
+ this, SLOT(setTopic(QString)));
+ connect(ircChannel, SIGNAL(ircUserJoined(IrcUser *)),
+ this, SLOT(join(IrcUser *)));
+ connect(ircChannel, SIGNAL(ircUserParted(IrcUser *)),
+ this, SLOT(part(IrcUser *)));
+}
+
+QString BufferTreeItem::bufferName() const {
+ return buf->name();
+}
+
+QString BufferTreeItem::topic() const {
+ if(_ircChannel)
+ return _ircChannel->topic();
+ else
+ return QString();
+}
+
+int BufferTreeItem::nickCount() const {
+ if(_ircChannel)
+ return _ircChannel->ircUsers().count();
+ else
+ return 0;
+}
+
+void BufferTreeItem::setTopic(const QString &topic) {
+ Q_UNUSED(topic);
+ emit dataChanged(1);
+}
+
+void BufferTreeItem::join(IrcUser *ircUser) {
+ Q_UNUSED(ircUser);
+ emit dataChanged(2);
+}
+
+void BufferTreeItem::part(IrcUser *ircUser) {
+ Q_UNUSED(ircUser);
+ emit dataChanged(2);
+}
+
/*****************************************
* Network Items
*****************************************/
-NetworkTreeItem::NetworkTreeItem(const uint &netid, const QString &network, TreeItem *parent)
- : TreeItem(parent),
+NetworkTreeItem::NetworkTreeItem(const uint &netid, const QString &network, AbstractTreeItem *parent)
+ : PropertyMapItem(QList<QString>() << "networkName" << "currentServer" << "nickCount", parent),
_networkId(netid),
- net(network)
+ _networkName(network)
{
- net = network;
- itemData << net << "";
setFlags(Qt::ItemIsEnabled);
}
switch(role) {
case BufferTreeModel::NetworkIdRole:
return _networkId;
+ case BufferTreeModel::ItemTypeRole:
+ return BufferTreeModel::NetworkItem;
default:
- return TreeItem::data(column, role);
+ return PropertyMapItem::data(column, role);
}
}
return _networkId;
}
+QString NetworkTreeItem::networkName() const {
+ if(_networkInfo)
+ return _networkInfo->networkName();
+ else
+ return _networkName;
+}
+
+QString NetworkTreeItem::currentServer() const {
+ if(_networkInfo)
+ return _networkInfo->currentServer();
+ else
+ return QString();
+}
+
+int NetworkTreeItem::nickCount() const {
+ BufferTreeItem *bufferItem;
+ int count = 0;
+ for(int i = 0; i < childCount(); i++) {
+ bufferItem = qobject_cast<BufferTreeItem *>(child(i));
+ if(!bufferItem)
+ continue;
+ count += bufferItem->nickCount();
+ }
+ return count;
+}
+
+void NetworkTreeItem::attachNetworkInfo(NetworkInfo *networkInfo) {
+ if(!networkInfo)
+ return;
+
+ _networkInfo = networkInfo;
+
+ connect(networkInfo, SIGNAL(networkNameSet(QString)),
+ this, SLOT(setNetworkName(QString)));
+ connect(networkInfo, SIGNAL(currentServerSet(QString)),
+ this, SLOT(setCurrentServer(QString)));
+ connect(networkInfo, SIGNAL(ircChannelAdded(QString)),
+ this, SLOT(attachIrcChannel(QString)));
+ // FIXME: connect this and that...
+}
+
+void NetworkTreeItem::attachIrcChannel(const QString &channelName) {
+ IrcChannel *ircChannel = _networkInfo->ircChannel(channelName);
+ if(!ircChannel) {
+ qWarning() << "NetworkTreeItem::attachIrcChannel(): unkown Channel" << channelName;
+ return;
+ }
+
+ BufferTreeItem *bufferItem;
+ for(int i = 0; i < childCount(); i++) {
+ bufferItem = qobject_cast<BufferTreeItem *>(child(i));
+ if(bufferItem->bufferName() == ircChannel->name()) {
+ bufferItem->attachIrcChannel(ircChannel);
+ break;
+ }
+ }
+}
+
+void NetworkTreeItem::setNetworkName(const QString &networkName) {
+ Q_UNUSED(networkName);
+ emit dataChanged(0);
+}
+
+void NetworkTreeItem::setCurrentServer(const QString &serverName) {
+ Q_UNUSED(serverName);
+ emit dataChanged(1);
+}
+
/*****************************************
* BufferTreeModel
*****************************************/
QList<QVariant >BufferTreeModel::defaultHeader() {
QList<QVariant> data;
- data << tr("Buffer") << tr("Network");
+ data << tr("Buffer") << tr("Topic") << tr("Nick Count");
return data;
}
Buffer *BufferTreeModel::getBufferByIndex(const QModelIndex &index) const {
BufferTreeItem *item = static_cast<BufferTreeItem *>(index.internalPointer());
+ // FIXME get rid of this
+ Q_ASSERT(item->buffer() == Client::instance()->buffer(item->id()));
return item->buffer();
}
-QModelIndex BufferTreeModel::getOrCreateNetworkItemIndex(Buffer *buffer) {
- QString net = buffer->networkName();
- uint netId = buffer->networkId();
- TreeItem *networkItem;
- if(!(networkItem = rootItem->childById(netId))) {
- int nextRow = rootItem->childCount();
- networkItem = new NetworkTreeItem(netId, net, rootItem);
-
- beginInsertRows(QModelIndex(), nextRow, nextRow);
- rootItem->appendChild(networkItem);
- endInsertRows();
+// experimental stuff :)
+QModelIndex BufferTreeModel::networkIndex(uint networkId) {
+ return indexById(networkId);
+}
+
+NetworkTreeItem *BufferTreeModel::network(uint networkId) {
+ return qobject_cast<NetworkTreeItem *>(rootItem->childById(networkId));
+}
+
+NetworkTreeItem *BufferTreeModel::newNetwork(uint networkId, const QString &networkName) {
+ NetworkTreeItem *networkItem = network(networkId);
+
+ if(networkItem == 0) {
+ networkItem = new NetworkTreeItem(networkId, networkName, rootItem);
+ appendChild(rootItem, networkItem);
}
Q_ASSERT(networkItem);
- return index(networkItem->row(), 0);
+ return networkItem;
}
-QModelIndex BufferTreeModel::getOrCreateBufferItemIndex(Buffer *buffer) {
- QModelIndex networkItemIndex = getOrCreateNetworkItemIndex(buffer);
- NetworkTreeItem *networkItem = static_cast<NetworkTreeItem*>(networkItemIndex.internalPointer());
- TreeItem *bufferItem;
-
- if(!(bufferItem = networkItem->childById(buffer->bufferInfo().uid()))) {
- int nextRow = networkItem->childCount();
+QModelIndex BufferTreeModel::bufferIndex(BufferInfo bufferInfo) {
+ QModelIndex networkIdx = networkIndex(bufferInfo.networkId());
+ if(!networkIdx.isValid())
+ return QModelIndex();
+ else
+ return indexById(bufferInfo.uid(), networkIdx);
+}
+
+BufferTreeItem *BufferTreeModel::buffer(BufferInfo bufferInfo) {
+ QModelIndex bufferIdx = bufferIndex(bufferInfo);
+ if(bufferIdx.isValid())
+ return static_cast<BufferTreeItem *>(bufferIdx.internalPointer());
+ else
+ return 0;
+}
+
+BufferTreeItem *BufferTreeModel::newBuffer(BufferInfo bufferInfo) {
+ BufferTreeItem *bufferItem = buffer(bufferInfo);
+ if(bufferItem == 0) {
+ NetworkTreeItem *networkItem = newNetwork(bufferInfo.networkId(), bufferInfo.network());
+
+ // FIXME: get rid of the buffer pointer
+ Buffer *buffer = Client::instance()->buffer(bufferInfo.uid());
bufferItem = new BufferTreeItem(buffer, networkItem);
-
- beginInsertRows(networkItemIndex, nextRow, nextRow);
- networkItem->appendChild(bufferItem);
- endInsertRows();
+ appendChild(networkItem, bufferItem);
}
Q_ASSERT(bufferItem);
- return index(bufferItem->row(), 0, networkItemIndex);
+ return bufferItem;
}
QStringList BufferTreeModel::mimeTypes() const {
return true;
}
+void BufferTreeModel::attachNetworkInfo(NetworkInfo *networkInfo) {
+ NetworkTreeItem *networkItem = network(networkInfo->networkId());
+ if(!networkItem) {
+ qWarning() << "BufferTreeModel::attachNetworkInfo(): network is unknown!";
+ return;
+ }
+ networkItem->attachNetworkInfo(networkInfo);
+}
+
void BufferTreeModel::bufferUpdated(Buffer *buffer) {
- QModelIndex itemindex = getOrCreateBufferItemIndex(buffer);
+ BufferTreeItem *bufferItem = newBuffer(buffer->bufferInfo());
+ QModelIndex itemindex = indexByItem(bufferItem);
emit dataChanged(itemindex, itemindex);
}
}
}
-void BufferTreeModel::bufferActivity(Buffer::ActivityLevel level, Buffer *buffer) {
- BufferTreeItem *bufferItem = static_cast<BufferTreeItem*>(getOrCreateBufferItemIndex(buffer).internalPointer());
- if(buffer != currentBuffer)
+void BufferTreeModel::bufferActivity(Buffer::ActivityLevel level, Buffer *buf) {
+ BufferTreeItem *bufferItem = buffer(buf->bufferInfo());
+ if(!bufferItem) {
+ qWarning() << "BufferTreeModel::bufferActivity(): received Activity Info for uknown Buffer";
+ return;
+ }
+
+ if(buf != currentBuffer)
bufferItem->setActivity(level);
else
bufferItem->setActivity(Buffer::NoActivity);
- bufferUpdated(buffer);
+ bufferUpdated(buf);
}
void BufferTreeModel::selectBuffer(Buffer *buffer) {
- QModelIndex index = getOrCreateBufferItemIndex(buffer);
+ QModelIndex index = bufferIndex(buffer->bufferInfo());
+ if(!index.isValid()) {
+ qWarning() << "BufferTreeModel::selectBuffer(): unknown Buffer has been selected.";
+ return;
+ }
// SUPER UGLY!
setCurrentIndex(index, 0);
}
#include "modelpropertymapper.h"
class MappedSelectionModel;
class QAbstractItemView;
+class NetworkInfo;
+class IrcChannel;
+class IrcUser;
/*****************************************
* Fancy Buffer Items
*****************************************/
-class BufferTreeItem : public TreeItem {
+class BufferTreeItem : public PropertyMapItem {
Q_OBJECT
+ Q_PROPERTY(QString bufferName READ bufferName)
+ Q_PROPERTY(QString topic READ topic)
+ Q_PROPERTY(int nickCount READ nickCount)
public:
- BufferTreeItem(Buffer *, TreeItem *parent = 0);
+ BufferTreeItem(Buffer *, AbstractTreeItem *parent = 0);
virtual quint64 id() const;
- QVariant data(int column, int role) const;
+ virtual QVariant data(int column, int role) const;
+ void attachIrcChannel(IrcChannel *ircChannel);
+
+ QString bufferName() const;
+ QString topic() const;
+ int nickCount() const;
+
+
Buffer *buffer() const { return buf; }
void setActivity(const Buffer::ActivityLevel &);
+public slots:
+ void setTopic(const QString &topic);
+ void join(IrcUser *ircUser);
+ void part(IrcUser *ircUser);
+
private:
- QString text(int column) const;
QColor foreground(int column) const;
Buffer *buf;
Buffer::ActivityLevel activity;
+
+ QPointer<IrcChannel> _ircChannel;
};
/*****************************************
* Network Items
*****************************************/
-class NetworkTreeItem : public TreeItem {
+class NetworkTreeItem : public PropertyMapItem {
Q_OBJECT
-
+ Q_PROPERTY(QString networkName READ networkName)
+ Q_PROPERTY(QString currentServer READ currentServer)
+ Q_PROPERTY(int nickCount READ nickCount)
+
public:
- NetworkTreeItem(const uint &netid, const QString &, TreeItem *parent = 0);
+ NetworkTreeItem(const uint &netid, const QString &, AbstractTreeItem *parent = 0);
virtual QVariant data(int column, int row) const;
virtual quint64 id() const;
+ QString networkName() const;
+ QString currentServer() const;
+ int nickCount() const;
+
+public slots:
+ void setNetworkName(const QString &networkName);
+ void setCurrentServer(const QString &serverName);
+
+ void attachNetworkInfo(NetworkInfo *networkInfo);
+ void attachIrcChannel(const QString &channelName);
+
private:
uint _networkId;
- QString net;
+ QString _networkName;
+
+ QPointer<NetworkInfo> _networkInfo;
};
/*****************************************
BufferTypeRole = Qt::UserRole,
BufferActiveRole,
BufferUidRole,
- NetworkIdRole
+ NetworkIdRole,
+ ItemTypeRole
};
+ enum itemTypes {
+ AbstractItem,
+ SimpleItem,
+ NetworkItem,
+ BufferItem,
+ NickItem
+ };
+
BufferTreeModel(QObject *parent = 0);
static QList<QVariant> defaultHeader();
virtual QMimeData *mimeData(const QModelIndexList &) const;
virtual bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &);
-
+ void attachNetworkInfo(NetworkInfo *networkInfo);
+
public slots:
void bufferUpdated(Buffer *);
void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
private:
bool isBufferIndex(const QModelIndex &) const;
Buffer *getBufferByIndex(const QModelIndex &) const;
- QModelIndex getOrCreateNetworkItemIndex(Buffer *buffer);
- QModelIndex getOrCreateBufferItemIndex(Buffer *buffer);
+
+ QModelIndex networkIndex(uint networkId);
+ NetworkTreeItem *network(uint networkId);
+ NetworkTreeItem *newNetwork(uint networkId, const QString &networkName);
+
+ QModelIndex bufferIndex(BufferInfo bufferInfo);
+ BufferTreeItem *buffer(BufferInfo bufferInfo);
+ BufferTreeItem *newBuffer(BufferInfo bufferInfo);
QPointer<SelectionModelSynchronizer> _selectionModelSynchronizer;
QPointer<ModelPropertyMapper> _propertyMapper;
NetworkInfo *netinfo = new NetworkInfo(netid, this);
netinfo->setProxy(signalProxy());
+ bufferModel()->attachNetworkInfo(netinfo);
if(!isConnected()) {
connect(netinfo, SIGNAL(initDone()), this, SLOT(updateCoreConnectionProgress()));
#include "treemodel.h"
+#include <QDebug>
+
/*****************************************
- * Buffer Items stored in the Tree Model
+ * Abstract Items of a TreeModel
*****************************************/
-TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
+AbstractTreeItem::AbstractTreeItem(AbstractTreeItem *parent)
: QObject(parent),
- itemData(data),
_parentItem(parent),
_flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled)
{
}
-TreeItem::TreeItem(TreeItem *parent)
- : QObject(parent),
- itemData(QList<QVariant>()),
- _parentItem(parent),
- _flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled)
-{
+AbstractTreeItem::~AbstractTreeItem() {
+ foreach(int key, _childItems.keys()) {
+ qDeleteAll(_childItems[key]);
+ }
}
-TreeItem::~TreeItem() {
- qDeleteAll(_childItems);
+quint64 AbstractTreeItem::id() const {
+ return (quint64)this;
}
-quint64 TreeItem::id() const {
- return (quint64)this;
+int AbstractTreeItem::defaultColumn() const {
+ // invalid QModelIndexes aka rootNodes get their Childs stuffed into column -1
+ // all others to 0
+ if(_parentItem == 0)
+ return -1;
+ else
+ return 0;
}
-void TreeItem::appendChild(TreeItem *item) {
- _childItems.append(item);
- _childHash[item->id()] = item;
- connect(item, SIGNAL(destroyed()),
- this, SLOT(childDestroyed()));
+void AbstractTreeItem::appendChild(int column, AbstractTreeItem *item) {
+ if(!_childItems.contains(column)) {
+ _childItems[column] = QList<AbstractTreeItem *>();
+ _childHash[column] = QHash<quint64, AbstractTreeItem *>();
+ }
+
+ _childItems[column].append(item);
+ _childHash[column][item->id()] = item;
+
+ connect(item, SIGNAL(destroyed()), this, SLOT(childDestroyed()));
+}
+
+void AbstractTreeItem::appendChild(AbstractTreeItem *child) {
+ appendChild(defaultColumn(), child);
}
-void TreeItem::removeChild(int row) {
- if(row >= _childItems.size())
+void AbstractTreeItem::removeChild(int column, int row) {
+ if(!_childItems.contains(column)
+ || _childItems[column].size() <= row)
return;
- TreeItem *treeitem = _childItems.value(row);
- _childItems.removeAt(row);
- _childHash.remove(_childHash.key(treeitem));
+
+ AbstractTreeItem *treeitem = _childItems[column].value(row);
+ _childItems[column].removeAt(row);
+ _childHash[column].remove(_childHash[column].key(treeitem));
+ treeitem->deleteLater();
}
-TreeItem *TreeItem::child(int row) const {
- if(row < _childItems.size())
- return _childItems.value(row);
- else
+void AbstractTreeItem::removeChild(int row) {
+ removeChild(defaultColumn(), row);
+}
+
+AbstractTreeItem *AbstractTreeItem::child(int column, int row) const {
+ if(!_childItems.contains(column)
+ || _childItems[column].size() <= row)
return 0;
+ else
+ return _childItems[column].value(row);
}
-TreeItem *TreeItem::childById(const uint &id) const {
- if(_childHash.contains(id))
- return _childHash.value(id);
+AbstractTreeItem *AbstractTreeItem::child(int row) const {
+ return child(defaultColumn(), row);
+}
+
+AbstractTreeItem *AbstractTreeItem::childById(int column, const uint &id) const {
+ if(!_childHash.contains(column)
+ || !_childHash[column].contains(id))
+ return 0;
else
+ return _childHash[column].value(id);
+}
+
+AbstractTreeItem *AbstractTreeItem::childById(const uint &id) const {
+ return childById(defaultColumn(), id);
+}
+
+int AbstractTreeItem::childCount(int column) const {
+ if(!_childItems.contains(column))
return 0;
+ else
+ return _childItems[column].count();
}
-int TreeItem::childCount() const {
- return _childItems.count();
+int AbstractTreeItem::childCount() const {
+ return childCount(defaultColumn());
}
-int TreeItem::row() const {
- if(_parentItem)
- return _parentItem->_childItems.indexOf(const_cast<TreeItem*>(this));
+int AbstractTreeItem::column() const {
+ if(!_parentItem)
+ return -1;
+
+ QHash<int, QList<AbstractTreeItem*> >::const_iterator iter = _parentItem->_childItems.constBegin();
+ int pos;
+ while(iter != _parentItem->_childItems.constEnd()) {
+ pos = iter.value().indexOf(const_cast<AbstractTreeItem *>(this));
+ if(pos != -1)
+ return iter.key();
+ iter++;
+ }
+
+ // unable to find us o_O
+ return _parentItem->defaultColumn();
+}
+
+int AbstractTreeItem::row() const {
+ if(!_parentItem)
+ return -1;
else
- return 0;
+ return _parentItem->_childItems[column()].indexOf(const_cast<AbstractTreeItem*>(this));
}
-TreeItem *TreeItem::parent() {
+AbstractTreeItem *AbstractTreeItem::parent() {
return _parentItem;
}
-int TreeItem::columnCount() const {
- return itemData.count();
+Qt::ItemFlags AbstractTreeItem::flags() const {
+ return _flags;
+}
+
+void AbstractTreeItem::setFlags(Qt::ItemFlags flags) {
+ _flags = flags;
}
-QVariant TreeItem::data(int column, int role) const {
- if(role == Qt::DisplayRole && column < itemData.count())
- return itemData[column];
+void AbstractTreeItem::childDestroyed() {
+ AbstractTreeItem *item = static_cast<AbstractTreeItem*>(sender());
+ removeChild(item->column(), item->row());
+}
+
+/*****************************************
+ * SimpleTreeItem
+ *****************************************/
+SimpleTreeItem::SimpleTreeItem(const QList<QVariant> &data, AbstractTreeItem *parent)
+ : AbstractTreeItem(parent),
+ _itemData(data)
+{
+}
+
+SimpleTreeItem::~SimpleTreeItem() {
+}
+
+QVariant SimpleTreeItem::data(int column, int role) const {
+ if(role == Qt::DisplayRole && column < _itemData.count())
+ return _itemData[column];
else
return QVariant();
}
-Qt::ItemFlags TreeItem::flags() const {
- return _flags;
+int SimpleTreeItem::columnCount() const {
+ return _itemData.count();
}
-void TreeItem::setFlags(Qt::ItemFlags flags) {
- _flags = flags;
+/*****************************************
+ * PropertyMapItem
+ *****************************************/
+PropertyMapItem::PropertyMapItem(const QStringList &propertyOrder, AbstractTreeItem *parent)
+ : AbstractTreeItem(parent),
+ _propertyOrder(propertyOrder)
+{
+}
+
+PropertyMapItem::PropertyMapItem(AbstractTreeItem *parent)
+ : AbstractTreeItem(parent),
+ _propertyOrder(QStringList())
+{
+}
+
+
+PropertyMapItem::~PropertyMapItem() {
}
+
+QVariant PropertyMapItem::data(int column, int role) const {
+ if(column >= columnCount())
+ return QVariant();
-void TreeItem::childDestroyed() {
- TreeItem *item = static_cast<TreeItem*>(sender());
- removeChild(item->row());
+ if(role != Qt::DisplayRole)
+ return QVariant();
+
+ return property(_propertyOrder[column].toAscii());
+}
+
+int PropertyMapItem::columnCount() const {
+ return _propertyOrder.count();
}
+void PropertyMapItem::appendProperty(const QString &property) {
+ _propertyOrder << property;
+}
+
/*****************************************
TreeModel::TreeModel(const QList<QVariant> &data, QObject *parent)
: QAbstractItemModel(parent)
{
- rootItem = new TreeItem(data, 0);
+ rootItem = new SimpleTreeItem(data, 0);
}
TreeModel::~TreeModel() {
if(!hasIndex(row, column, parent))
return QModelIndex();
- TreeItem *parentItem;
+ AbstractTreeItem *parentItem;
if(!parent.isValid())
parentItem = rootItem;
else
- parentItem = static_cast<TreeItem*>(parent.internalPointer());
+ parentItem = static_cast<AbstractTreeItem*>(parent.internalPointer());
- TreeItem *childItem = parentItem->child(row);
+ AbstractTreeItem *childItem = parentItem->child(parent.column(), row);
+
if(childItem)
return createIndex(row, column, childItem);
else
}
QModelIndex TreeModel::indexById(uint id, const QModelIndex &parent) const {
- TreeItem *parentItem;
+ AbstractTreeItem *parentItem;
if(!parent.isValid())
parentItem = rootItem;
else
- parentItem = static_cast<TreeItem *>(parent.internalPointer());
+ parentItem = static_cast<AbstractTreeItem *>(parent.internalPointer());
+
+ AbstractTreeItem *childItem = parentItem->childById(parent.column(), id);
- TreeItem *childItem = parentItem->childById(id);
if(childItem)
return createIndex(childItem->row(), 0, childItem);
else
return QModelIndex();
}
+QModelIndex TreeModel::indexByItem(AbstractTreeItem *item) const {
+ if(item == 0) {
+ qWarning() << "TreeModel::indexByItem(AbstractTreeItem *item) received NULL-Pointer";
+ return QModelIndex();
+ }
+
+ if(item == rootItem)
+ return QModelIndex();
+ else
+ return createIndex(item->row(), 0, item);
+
+}
+
QModelIndex TreeModel::parent(const QModelIndex &index) const {
if(!index.isValid())
return QModelIndex();
- TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
- TreeItem *parentItem = static_cast<TreeItem*>(childItem->parent());
+ AbstractTreeItem *childItem = static_cast<AbstractTreeItem *>(index.internalPointer());
+ AbstractTreeItem *parentItem = static_cast<AbstractTreeItem *>(childItem->parent());
if(parentItem == rootItem)
return QModelIndex();
}
int TreeModel::rowCount(const QModelIndex &parent) const {
- TreeItem *parentItem;
+ AbstractTreeItem *parentItem;
if(!parent.isValid())
parentItem = rootItem;
else
- parentItem = static_cast<TreeItem*>(parent.internalPointer());
-
- return parentItem->childCount();
+ parentItem = static_cast<AbstractTreeItem*>(parent.internalPointer());
+
+ return parentItem->childCount(parent.column());
}
int TreeModel::columnCount(const QModelIndex &parent) const {
if(parent.isValid())
- return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
+ return static_cast<AbstractTreeItem*>(parent.internalPointer())->columnCount();
else
return rootItem->columnCount();
}
if(!index.isValid())
return QVariant();
- TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
+ AbstractTreeItem *item = static_cast<AbstractTreeItem*>(index.internalPointer());
return item->data(index.column(), role);
}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const {
- TreeItem *item;
+ AbstractTreeItem *item;
if(!index.isValid())
item = rootItem;
else
- item = static_cast<TreeItem *>(index.internalPointer());
+ item = static_cast<AbstractTreeItem *>(index.internalPointer());
return item->flags();
}
return QVariant();
}
+void TreeModel::itemDataChanged(int column) {
+ AbstractTreeItem *item = qobject_cast<AbstractTreeItem *>(sender());
+ QModelIndex itemIndex;
+
+ if(item == rootItem)
+ itemIndex = QModelIndex();
+ else
+ itemIndex = createIndex(item->row(), column, item);
+
+ emit dataChanged(itemIndex, itemIndex);
+}
+
+void TreeModel::appendChild(AbstractTreeItem *parent, AbstractTreeItem *child) {
+ if(parent == 0 or child == 0) {
+ qWarning() << "TreeModel::apendChild(parent, child) parent and child have to be valid pointers!" << parent << child;
+ return;
+ }
+
+ int nextRow = parent->childCount();
+ beginInsertRows(indexByItem(parent), nextRow, nextRow);
+ parent->appendChild(child);
+ endInsertRows();
+
+ connect(child, SIGNAL(dataChanged(int)),
+ this, SLOT(itemDataChanged(int)));
+}
+
+
bool TreeModel::removeRow(int row, const QModelIndex &parent) {
if(row > rowCount(parent))
return false;
- TreeItem *item;
+ AbstractTreeItem *item;
if(!parent.isValid())
item = rootItem;
else
- item = static_cast<TreeItem*>(parent.internalPointer());
+ item = static_cast<AbstractTreeItem*>(parent.internalPointer());
beginRemoveRows(parent, row, row);
- item->removeChild(row);
+ item->removeChild(parent.column(), row);
endRemoveRows();
return true;
}
if(row + count - 1 > rowCount(parent) || row < 0 || count < 0)
return false;
- TreeItem *item;
+ AbstractTreeItem *item;
if(!parent.isValid())
item = rootItem;
else
- item = static_cast<TreeItem*>(parent.internalPointer());
+ item = static_cast<AbstractTreeItem *>(parent.internalPointer());
beginRemoveRows(parent, row, row + count - 1);
for(int i = row + count - 1; i >= 0; i--) {
- item->removeChild(i);
+ item->removeChild(parent.column(), i);
}
endRemoveRows();
return true;
#define _TREEMODEL_H_
#include <QList>
+#include <QStringList>
#include <QVariant>
#include <QHash>
#include <QAbstractItemModel>
/*****************************************
* general item used in the Tree Model
*****************************************/
-class TreeItem : public QObject {
+class AbstractTreeItem : public QObject {
Q_OBJECT
Q_PROPERTY(uint id READ id)
public:
- TreeItem(const QList<QVariant> &data, TreeItem *parent = 0);
- TreeItem(TreeItem *parent = 0);
- virtual ~TreeItem();
+ AbstractTreeItem(AbstractTreeItem *parent = 0);
+ virtual ~AbstractTreeItem();
- void appendChild(TreeItem *child);
+ void appendChild(int column, AbstractTreeItem *child);
+ void appendChild(AbstractTreeItem *child);
+
+ void removeChild(int column, int row);
void removeChild(int row);
virtual quint64 id() const;
- TreeItem *child(int row) const;
- TreeItem *childById(const uint &) const;
+ AbstractTreeItem *child(int column, int row) const;
+ AbstractTreeItem *child(int row) const;
+
+ AbstractTreeItem *childById(int column, const uint &id) const;
+ AbstractTreeItem *childById(const uint &id) const;
+ int childCount(int column) const;
int childCount() const;
- int columnCount() const;
- virtual QVariant data(int column, int role) const;
+ virtual int columnCount() const = 0;
- Qt::ItemFlags flags() const;
- void setFlags(Qt::ItemFlags);
+ virtual QVariant data(int column, int role) const = 0;
- int row() const;
- TreeItem *parent();
+ virtual Qt::ItemFlags flags() const;
+ virtual void setFlags(Qt::ItemFlags);
+ int column() const;
+ int row() const;
+ AbstractTreeItem *parent();
+signals:
+ void dataChanged(int column);
+
private slots:
void childDestroyed();
+private:
+ QHash<int, QList<AbstractTreeItem *> > _childItems;
+ QHash<int, QHash<quint64, AbstractTreeItem *> > _childHash; // uint to be compatible to qHash functions
+ AbstractTreeItem *_parentItem;
+ Qt::ItemFlags _flags;
+
+ int defaultColumn() const;
+};
-protected:
- QList<QVariant> itemData;
+
+/*****************************************
+ * SimpleTreeItem
+ *****************************************/
+class SimpleTreeItem : public AbstractTreeItem {
+ Q_OBJECT
+
+public:
+ SimpleTreeItem(const QList<QVariant> &data, AbstractTreeItem *parent = 0);
+ virtual ~SimpleTreeItem();
+ virtual QVariant data(int column, int role) const;
+ virtual int columnCount() const;
private:
- QList<TreeItem *> _childItems;
- QHash<quint64, TreeItem *> _childHash; // uint to be compatible to qHash functions
- TreeItem *_parentItem;
- Qt::ItemFlags _flags;
+ QList<QVariant> _itemData;
+};
+
+/*****************************************
+ * PropertyMapItem
+ *****************************************/
+class PropertyMapItem : public AbstractTreeItem {
+ Q_OBJECT
+
+public:
+ PropertyMapItem(const QStringList &propertyOrder, AbstractTreeItem *parent = 0);
+ PropertyMapItem(AbstractTreeItem *parent = 0);
+
+ virtual ~PropertyMapItem();
+
+ virtual QVariant data(int column, int role) const;
+ virtual int columnCount() const;
+
+ void appendProperty(const QString &property);
+
+private:
+ QStringList _propertyOrder;
};
QVariant data(const QModelIndex &index, int role) const;
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex indexById(uint id, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex indexByItem(AbstractTreeItem *item) const;
+
QModelIndex parent(const QModelIndex &index) const;
+
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual void clear();
+private slots:
+ void itemDataChanged(int column);
+
protected:
+ void appendChild(AbstractTreeItem *parent, AbstractTreeItem *child);
+
bool removeRow(int row, const QModelIndex &parent = QModelIndex());
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
- TreeItem *rootItem;
+ AbstractTreeItem *rootItem;
};
#endif
void SignalProxy::setSyncMap(QObject *obj) {
const QMetaObject *meta = obj->metaObject();
-
QHash<int, int> syncMap;
QList<int> slotIndexes;
QObject *receiver = _syncSlave[className][objectName];
if(!syncMap(receiver).contains(signalId)) {
- qWarning() << "received Sync Call with invalid SignalId" << className << objectName << signalId;
- }
+ const QMetaObject *meta = receiver->metaObject();
+ QString signalName;
+ if(signalId < meta->methodCount())
+ signalName = QString(meta->method(signalId).signature());
+ else
+ signalName = QString::number(signalId);
+
+ qWarning() << "received Sync Call for Object" << receiver
+ << "- no matching Slot for Signal:" << signalName;
+ return;
+ }
int slotId = syncMap(receiver)[signalId];
if(!invokeSlot(receiver, slotId, params))
qWarning("SignalProxy::handleSync(): invokeMethod for \"%s\" failed ", methodName(receiver, slotId).constData());
qDebug() << "number of Classes cached:" << _classInfo.count();
}
+void SignalProxy::dumpSyncMap(QObject *object) {
+ const QMetaObject *meta = object->metaObject();
+ qDebug() << "SignalProxy: SyncMap for Class" << meta->className();
+ QHash<int, int> syncMap_ = syncMap(object);
+ QHash<int, int>::const_iterator iter = syncMap_.constBegin();
+ while(iter != syncMap_.constEnd()) {
+ qDebug() << iter.key() << meta->method(iter.key()).signature() << "-->" << iter.value() << meta->method(iter.value()).signature();
+ iter++;
+ }
+}
void _detachSignals(QObject *sender);
void _detachSlots(QObject *receiver);
+ void dumpSyncMap(QObject *object);
+
// containg a list of argtypes for fast access
QHash<const QMetaObject *, ClassInfo*> _classInfo;
QHash<QIODevice*, quint32> _peerByteCount;
ProxyMode _proxyMode;
-
+
friend class SignalRelay;
};
TopicWidget *topicwidget = new TopicWidget(dock);
dock->setWidget(topicwidget);
- Client::bufferModel()->mapProperty(0, Qt::DisplayRole, topicwidget, "topic");
+ Client::bufferModel()->mapProperty(1, Qt::DisplayRole, topicwidget, "topic");
addDockWidget(Qt::TopDockWidgetArea, dock);
void BufferView::init() {
setIndentation(10);
- header()->hide();
- header()->hideSection(1);
+ // header()->hide();
+ // header()->hideSection(1);
expandAll();
setAnimated(true);