/* * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. * * See the LICENSE file for terms of use. */ #include "Wt/WStandardItem" #include "Wt/WStandardItemModel" #ifndef DOXYGEN_ONLY namespace Wt { WStandardItemModel::WStandardItemModel(WObject *parent) : WAbstractItemModel(parent), sortRole_(DisplayRole), itemChanged_(this) { init(); } WStandardItemModel::WStandardItemModel(int rows, int columns, WObject *parent) : WAbstractItemModel(parent), sortRole_(DisplayRole), itemChanged_(this) { init(); invisibleRootItem_->setColumnCount(columns); invisibleRootItem_->setRowCount(rows); } void WStandardItemModel::init() { invisibleRootItem_ = new WStandardItem(); invisibleRootItem_->model_ = this; itemPrototype_ = new WStandardItem(); } WStandardItemModel::~WStandardItemModel() { delete invisibleRootItem_; delete itemPrototype_; } void WStandardItemModel::clear() { invisibleRootItem_->setRowCount(0); invisibleRootItem_->setColumnCount(0); columnHeaderData_.clear(); rowHeaderData_.clear(); columnHeaderFlags_.clear(); rowHeaderFlags_.clear(); reset(); } WModelIndex WStandardItemModel::indexFromItem(const WStandardItem *item) const { if (item == invisibleRootItem_) return WModelIndex(); else return createIndex(item->row(), item->column(), static_cast(item->parent())); } WStandardItem *WStandardItemModel::itemFromIndex(const WModelIndex& index) const { return itemFromIndex(index, true); } WStandardItem *WStandardItemModel::itemFromIndex(const WModelIndex& index, bool lazyCreate) const { if (!index.isValid()) return invisibleRootItem_; else if (index.model() != this) return 0; else { WStandardItem *parent = static_cast(index.internalPointer()); WStandardItem *c = parent->child(index.row(), index.column()); if (lazyCreate && !c) { c = itemPrototype()->clone(); parent->setChild(index.row(), index.column(), c); } return c; } } void WStandardItemModel::appendColumn(const std::vector& items) { insertColumn(columnCount(), items); } void WStandardItemModel::insertColumn(int column, const std::vector& items) { invisibleRootItem_->insertColumn(column, items); } void WStandardItemModel::appendRow(const std::vector& items) { insertRow(rowCount(), items); } void WStandardItemModel::insertRow(int row, const std::vector& items) { invisibleRootItem_->insertRow(row, items); } void WStandardItemModel::appendRow(WStandardItem *item) { insertRow(rowCount(), item); } void WStandardItemModel::insertRow(int row, WStandardItem *item) { invisibleRootItem_->insertRow(row, item); } WStandardItem *WStandardItemModel::item(int row, int column) const { return invisibleRootItem_->child(row, column); } void WStandardItemModel::setItem(int row, int column, WStandardItem *item) { invisibleRootItem_->setChild(row, column, item); } WStandardItem *WStandardItemModel::itemPrototype() const { return itemPrototype_; } void WStandardItemModel::setItemPrototype(WStandardItem *item) { delete itemPrototype_; itemPrototype_ = item; } std::vector WStandardItemModel::takeColumn(int column) { return invisibleRootItem_->takeColumn(column); } std::vector WStandardItemModel::takeRow(int row) { return invisibleRootItem_->takeRow(row); } WStandardItem *WStandardItemModel::takeItem(int row, int column) { return invisibleRootItem_->takeChild(row, column); } WFlags WStandardItemModel::flags(const WModelIndex& index) const { WStandardItem *item = itemFromIndex(index, false); return item ? item->flags() : WFlags(0); } WModelIndex WStandardItemModel::parent(const WModelIndex& index) const { if (!index.isValid()) return index; WStandardItem *parent = static_cast(index.internalPointer()); return indexFromItem(parent); } boost::any WStandardItemModel::data(const WModelIndex& index, int role) const { WStandardItem *item = itemFromIndex(index, false); return item ? item->data(role) : boost::any(); } boost::any WStandardItemModel::headerData(int section, Orientation orientation, int role) const { if (role == LevelRole) return 0; std::vector header = (orientation == Horizontal) ? columnHeaderData_ : rowHeaderData_; if(header.size() <= section) return boost::any(); const HeaderData& d = header[section]; HeaderData::const_iterator i = d.find(role); if (i != d.end()) { /* * Work around CLang bug, 'return i->second' would try to create * a boost::any ... ? */ boost::any result = i->second; return result; } else return boost::any(); } WModelIndex WStandardItemModel::index(int row, int column, const WModelIndex& parent) const { WStandardItem *parentItem = itemFromIndex(parent, false); if (parentItem && row >= 0 && column >= 0 && row < parentItem->rowCount() && column < parentItem->columnCount()) return createIndex(row, column, static_cast(parentItem)); return WModelIndex(); } int WStandardItemModel::columnCount(const WModelIndex& parent) const { WStandardItem *parentItem = itemFromIndex(parent, false); return parentItem ? parentItem->columnCount() : 0; } int WStandardItemModel::rowCount(const WModelIndex& parent) const { WStandardItem *parentItem = itemFromIndex(parent, false); return parentItem ? parentItem->rowCount() : 0; } bool WStandardItemModel::insertColumns(int column, int count, const WModelIndex& parent) { WStandardItem *parentItem = itemFromIndex(parent); // lazy create ok if (parentItem) parentItem->insertColumns(column, count); return parentItem; } bool WStandardItemModel::insertRows(int row, int count, const WModelIndex& parent) { WStandardItem *parentItem = itemFromIndex(parent); // lazy create ok if (parentItem) parentItem->insertRows(row, count); return parentItem; } bool WStandardItemModel::removeColumns(int column, int count, const WModelIndex& parent) { WStandardItem *parentItem = itemFromIndex(parent, false); if (parentItem) parentItem->removeColumns(column, count); return parentItem; } bool WStandardItemModel::removeRows(int row, int count, const WModelIndex& parent) { WStandardItem *parentItem = itemFromIndex(parent, false); if (parentItem) parentItem->removeRows(row, count); return parentItem; } void WStandardItemModel::beginInsertColumns(const WModelIndex& parent, int first, int last) { WAbstractItemModel::beginInsertColumns(parent, first, last); insertHeaderData(columnHeaderData_, columnHeaderFlags_, itemFromIndex(parent), first, last - first + 1); } void WStandardItemModel::beginInsertRows(const WModelIndex& parent, int first, int last) { WAbstractItemModel::beginInsertRows(parent, first, last); insertHeaderData(rowHeaderData_, rowHeaderFlags_, itemFromIndex(parent), first, last - first + 1); } void WStandardItemModel::beginRemoveColumns(const WModelIndex& parent, int first, int last) { WAbstractItemModel::beginRemoveColumns(parent, first, last); removeHeaderData(columnHeaderData_, columnHeaderFlags_, itemFromIndex(parent), first, last - first + 1); } void WStandardItemModel::beginRemoveRows(const WModelIndex& parent, int first, int last) { WAbstractItemModel::beginRemoveRows(parent, first, last); removeHeaderData(rowHeaderData_, rowHeaderFlags_, itemFromIndex(parent), first, last - first + 1); } void WStandardItemModel::insertHeaderData(std::vector& headerData, std::vector >& fl, WStandardItem *item, int index, int count) { if (item == invisibleRootItem_) { headerData.insert(headerData.begin() + index, count, HeaderData()); fl.insert(fl.begin() + index, count, WFlags()); } } void WStandardItemModel::removeHeaderData(std::vector& headerData, std::vector >& fl, WStandardItem *item, int index, int count) { if (item == invisibleRootItem_) { headerData.erase(headerData.begin() + index, headerData.begin() + index + count); fl.erase(fl.begin() + index, fl.begin() + index + count); } } bool WStandardItemModel::setData(const WModelIndex& index, const boost::any& value, int role) { WStandardItem *item = itemFromIndex(index); if (item) item->setData(value, role); return item; } bool WStandardItemModel::setHeaderData(int section, Orientation orientation, const boost::any& value, int role) { std::vector& header = (orientation == Horizontal) ? columnHeaderData_ : rowHeaderData_; HeaderData& d = header[section]; if (role == EditRole) role = DisplayRole; d[role] = value; headerDataChanged().emit(orientation, section, section); return true; } void WStandardItemModel::setHeaderFlags(int section, Orientation orientation, WFlags flags) { std::vector >& fl = (orientation == Horizontal) ? columnHeaderFlags_ : rowHeaderFlags_; fl[section] = flags; } WFlags WStandardItemModel::headerFlags(int section, Orientation orientation) const { const std::vector >& fl = (orientation == Horizontal) ? columnHeaderFlags_ : rowHeaderFlags_; if(fl.size() > section) return fl[section]; else return WFlags(); } void *WStandardItemModel::toRawIndex(const WModelIndex& index) const { return static_cast(itemFromIndex(index)); } WModelIndex WStandardItemModel::fromRawIndex(void *rawIndex) const { return indexFromItem(static_cast(rawIndex)); } void WStandardItemModel::setSortRole(int role) { sortRole_ = role; } void WStandardItemModel::sort(int column, SortOrder order) { invisibleRootItem_->sortChildren(column, order); } } #endif // DOXYGEN_ONLY