#include "qtavahimodel.h" namespace Avahi { namespace model { Row::~Row() { } int Row::columnCount() { return 0; } /* columns of child rows */ Row* Row::index(int /* row */) { return 0; } int Row::rowCount() { return 0; } Row* RowList::index(int row) { return list.value(row); } int RowList::rowCount() { return list.length(); } QVariant Root::data(int , int ) { return QVariant(); } QVariant Root::emptyData(int col, int role) { if (col == 0 && role == Qt::DisplayRole) { return ""; } return QVariant(); } bool Root::emptyShowData() { return true; } } BrowseModel::BrowseModel(Avahi::model::Root *root, QObject *parent) : QAbstractItemModel(parent), m_root(root) { } BrowseModel::Row *BrowseModel::getRow(const QModelIndex &index) const { if (index.isValid()) { return static_cast< Row* >(index.internalPointer()); } else { return m_root; } } int BrowseModel::columnCount(const QModelIndex & parent) const { if (parent.column() > 0) return 0; if (m_services.isEmpty()) { if (parent.isValid()) return 0; return m_root->columnCount(); } Row *row = getRow(parent); return row ? row->columnCount() : 0; } QVariant BrowseModel::data(const QModelIndex & index, int role) const { if (m_services.isEmpty()) { return m_root->emptyData(index.column(), role); } Row *row = getRow(index); return row ? row->data(index.column(), role) : QVariant(); } QModelIndex BrowseModel::index(int row, int column, const QModelIndex & parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); if (m_services.isEmpty()) { return createIndex(row, column, 0); } Row *r = getRow(parent); if (!r) return QModelIndex(); /* invalid */ Row *child = r->index(row); if (!child) return QModelIndex(); /* invalid */ return createIndex(row, column, child); } QModelIndex BrowseModel::parent(const QModelIndex & index) const { if (m_services.isEmpty()) { return QModelIndex(); } if (!index.isValid()) return QModelIndex(); Row *row = getRow(index); if (!row) return QModelIndex(); /* invalid */ Row *p = row->parent(); if (!p || p == m_root) return QModelIndex(); /* find row of p in parent of p */ Row *p2 = p->parent(); if (!p2) p2 = m_root; RowList *p2l = dynamic_cast< RowList* >(p2); if (!p2l) return QModelIndex(); int rown = p2l->list.indexOf(p); return createIndex(rown, 0, p); } int BrowseModel::rowCount(const QModelIndex & parent) const { if (parent.column() > 0) return 0; /* only first column has childs */ if (m_services.isEmpty()) { if (parent.isValid()) return 0; return m_root->emptyShowData() ? 1 : 0; } Row *row = getRow(parent); return row ? row->rowCount() : 0; } Avahi::ServiceKey BrowseModel::key(const Avahi::Service &s) { Avahi::ServiceKey k(s); k.interface = k.protocol = -1; return k; } void BrowseModel::insert(const Avahi::Service &s, void *priv) { Avahi::ServiceKey k = key(s); if (m_services.isEmpty()) { beginResetModel(); EntryList *el = m_root->newList(k); m_services.insert(k, el); m_root->list.push_front(el); el->list.push_front(el->newEntry(s, priv)); endResetModel(); } else if (m_services.contains(k)) { EntryList *el = m_services.value(k); int row = m_services.keys().indexOf(k); beginInsertRows(createIndex(row, 0, (Row*) el), 0, 0); el->list.push_front(el->newEntry(s, priv)); endInsertRows(); } else { EntryList *el = m_root->newList(k); QMap tmp(m_services); tmp.insert(k, el); int row = tmp.keys().indexOf(k); beginInsertRows(QModelIndex(), row, row); m_services = tmp; m_root->list.insert(row, el); el->list.push_front(el->newEntry(s, priv)); endInsertRows(); } } void BrowseModel::remove(const Avahi::Service &s) { Avahi::ServiceKey k = key(s); int row = m_services.keys().indexOf(k); if (row < 0) return; EntryList *el = m_services.value(k); for (int i = 0; i < el->list.size(); ++i) { Entry *e = dynamic_cast< Entry* >(el->list.value(i)); if (e->service() == s) { /* found service */ if (1 == el->list.size()) { /* last service for that key */ if (1 == m_services.size()) { /* last service in the tree */ beginResetModel(); el->list.removeAt(i); m_services.remove(k); m_root->list.removeAt(row); endResetModel(); } else { beginRemoveRows(QModelIndex(), row, row); el->list.removeAt(i); m_services.remove(k); m_root->list.removeAt(row); endRemoveRows(); } delete el; } else { beginRemoveRows(createIndex(row, 0, (Row*) el), i, i); el->list.removeAt(i); endRemoveRows(); } delete e; break; } } } }