/* Copyright (C) 2013 * swift Project Community / Contributors * * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level * directory of this distribution and at http://www.swift-project.org/license.html. No part of Swift Project, * including this file, may be copied, modified, propagated, or distributed except according to the terms * contained in the LICENSE file. */ #include "listmodelbase.h" #include "blackmisc/namevariantpairlist.h" #include "blackmisc/statusmessagelist.h" #include "blackmisc/avatcstationlist.h" #include "blackmisc/avaircraftlist.h" #include "blackmisc/avairportlist.h" #include "blackmisc/nwserverlist.h" #include "blackmisc/nwuserlist.h" #include "blackmisc/nwclientlist.h" #include "blackmisc/hwkeyboardkeylist.h" #include "blackmisc/blackmiscfreefunctions.h" namespace BlackGui { namespace Models { /* * Column count */ template int CListModelBase::columnCount(const QModelIndex & /** modelIndex **/) const { int c = this->m_columns.size(); return c; } /* * Row count */ template int CListModelBase::rowCount(const QModelIndex & /** parent */) const { return this->m_container.size(); } /* * Column to property index */ template int CListModelBase::columnToPropertyIndex(int column) const { return this->m_columns.columnToPropertyIndex(column); } /* * Header data */ template QVariant CListModelBase::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { if (section < 0 || section >= this->m_columns.size()) return QVariant(); QString header = this->m_columns.at(section).getColumnName(false); return QVariant(header); } return QVariant(); } /* * Data */ template QVariant CListModelBase::data(const QModelIndex &index, int role) const { // checks if (index.row() < 0 || index.row() >= this->m_container.size() || index.column() < 0 || index.column() >= this->columnCount(index)) { return QVariant(); } if (role == Qt::DisplayRole) { if (this->m_columns.isIcon(index)) return QVariant(); ObjectType obj = this->m_container[index.row()]; int propertyIndex = this->columnToPropertyIndex(index.column()); QString propertyString = obj.propertyByIndexAsString(propertyIndex, true); return QVariant::fromValue(propertyString); } else if (role == Qt::DecorationRole) { if (!this->m_columns.isIcon(index)) return QVariant(); ObjectType obj = this->m_container[index.row()]; int propertyIndex = this->columnToPropertyIndex(index.column()); return obj.propertyByIndex(propertyIndex); } else if (role == Qt::TextAlignmentRole) { return this->m_columns.aligmentAsQVariant(index); } return QVariant(); } /* * Update */ template int CListModelBase::update(const ContainerType &container) { ContainerType copyList = (container.size() > 1 && this->hasValidSortColumn() ? this->sortListByColumn(container, this->m_sortedColumn, this->m_sortOrder) : container); this->beginResetModel(); this->m_container.clear(); foreach(ObjectType object, copyList) { this->m_container.push_back(object); } this->endResetModel(); return this->m_container.size(); } /* * Update */ template void CListModelBase::update(const QModelIndex &index, const ObjectType &object) { if (index.row() >= this->m_container.size()) return; this->m_container[index.row()] = object; QModelIndex i1 = index.sibling(index.row(), 0); QModelIndex i2 = index.sibling(index.row(), this->columnCount(index) - 1); emit this->dataChanged(i1, i2); // which range has been changed } /* * Push back */ template void CListModelBase::push_back(const ObjectType &object) { beginInsertRows(QModelIndex(), this->m_container.size(), this->m_container.size()); this->m_container.push_back(object); endInsertRows(); } /* * Push back */ template void CListModelBase::insert(const ObjectType &object) { beginInsertRows(QModelIndex(), 0, 0); this->m_container.insert(this->m_container.begin(), object); endInsertRows(); } /* * Remove object */ template void CListModelBase::remove(const ObjectType &object) { beginRemoveRows(QModelIndex(), 0, 0); this->m_container.remove(object); endRemoveRows(); } /* * Clear */ template void CListModelBase::clear() { beginResetModel(); this->m_container.clear(); endResetModel(); } /* * Sort */ template void CListModelBase::sort(int column, Qt::SortOrder order) { this->m_sortedColumn = column; this->m_sortOrder = order; if (this->m_container.size() < 2) return; // nothing to do // sort the values this->update( this->sortListByColumn(this->m_container, column, order) ); } /* * Sort list */ template ContainerType CListModelBase::sortListByColumn(const ContainerType &list, int column, Qt::SortOrder order) { if (list.size() < 2) return list; // nothing to do int propertyIndex = this->m_columns.columnToPropertyIndex(column); Q_ASSERT(propertyIndex >= 0); if (propertyIndex < 0) return list; // at release build do nothing // sort the values return list.sorted ([ = ](const ObjectType & a, const ObjectType & b) -> bool { QVariant aQv = a.propertyByIndex(propertyIndex); QVariant bQv = b.propertyByIndex(propertyIndex); int compare = (order == Qt::AscendingOrder) ? BlackMisc::compareQVariants(aQv, bQv) : BlackMisc::compareQVariants(bQv, aQv); return compare < 0; } ); // sorted } /* * Make editable */ template Qt::ItemFlags CListModelBase::flags(const QModelIndex &index) const { Qt::ItemFlags f = QAbstractListModel::flags(index); if (this->m_columns.isEditable(index)) return f | Qt::ItemIsEditable; else return f; } // see here for the reason of thess forward instantiations // http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html template class CListModelBase; template class CListModelBase; template class CListModelBase; template class CListModelBase; template class CListModelBase; template class CListModelBase; template class CListModelBase; template class CListModelBase; template class CListModelBase; } } // namespace