refs #139, changed list model to support editable columns

This commit is contained in:
Klaus Basan
2014-02-17 02:11:23 +01:00
parent 141706158f
commit c6c2d31cac
2 changed files with 92 additions and 54 deletions

View File

@@ -9,6 +9,7 @@
#include "blackmisc/avaircraftlist.h" #include "blackmisc/avaircraftlist.h"
#include "blackmisc/nwserverlist.h" #include "blackmisc/nwserverlist.h"
#include "blackmisc/nwuserlist.h" #include "blackmisc/nwuserlist.h"
#include "blackmisc/hwkeyboardkeylist.h"
#include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/blackmiscfreefunctions.h"
namespace BlackGui namespace BlackGui
@@ -17,8 +18,8 @@ namespace BlackGui
/* /*
* Column count * Column count
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
int CListModelBase<ObjectType, ListType>::columnCount(const QModelIndex & /** modelIndex **/) const int CListModelBase<ObjectType, ContainerType>::columnCount(const QModelIndex & /** modelIndex **/) const
{ {
int c = this->m_columns.size(); int c = this->m_columns.size();
return c; return c;
@@ -27,17 +28,17 @@ namespace BlackGui
/* /*
* Row count * Row count
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
int CListModelBase<ObjectType, ListType>::rowCount(const QModelIndex & /** parent */) const int CListModelBase<ObjectType, ContainerType>::rowCount(const QModelIndex & /** parent */) const
{ {
return this->m_list.size(); return this->m_container.size();
} }
/* /*
* Column to property index * Column to property index
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
int CListModelBase<ObjectType, ListType>::columnToPropertyIndex(int column) const int CListModelBase<ObjectType, ContainerType>::columnToPropertyIndex(int column) const
{ {
return this->m_columns.columnToPropertyIndex(column); return this->m_columns.columnToPropertyIndex(column);
} }
@@ -45,15 +46,14 @@ namespace BlackGui
/* /*
* Header data * Header data
*/ */
template <typename ObjectType, typename ListType> QVariant template <typename ObjectType, typename ContainerType> QVariant
CListModelBase<ObjectType, ListType>::headerData(int section, Qt::Orientation orientation, int role) const CListModelBase<ObjectType, ContainerType>::headerData(int section, Qt::Orientation orientation, int role) const
{ {
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{ {
if (section < 0 || section >= this->m_columns.size()) return QVariant(); if (section < 0 || section >= this->m_columns.size()) return QVariant();
QString col = this->m_columns.columnToName(section); QString header = this->m_columns.at(section).getColumnName(false);
col = QCoreApplication::translate(this->m_columns.getTranslationContext(), col.toUtf8().constData()); return QVariant(header);
return QVariant(col);
} }
return QVariant(); return QVariant();
} }
@@ -61,11 +61,11 @@ namespace BlackGui
/* /*
* Data * Data
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
QVariant CListModelBase<ObjectType, ListType>::data(const QModelIndex &index, int role) const QVariant CListModelBase<ObjectType, ContainerType>::data(const QModelIndex &index, int role) const
{ {
// checks // checks
if (index.row() < 0 || index.row() >= this->m_list.size() || if (index.row() < 0 || index.row() >= this->m_container.size() ||
index.column() < 0 || index.column() >= this->columnCount(index)) index.column() < 0 || index.column() >= this->columnCount(index))
{ {
return QVariant(); return QVariant();
@@ -73,7 +73,7 @@ namespace BlackGui
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
ObjectType obj = this->m_list[index.row()]; ObjectType obj = this->m_container[index.row()];
int propertyIndex = this->columnToPropertyIndex(index.column()); int propertyIndex = this->columnToPropertyIndex(index.column());
QString propertyString = obj.propertyByIndexAsString(propertyIndex, true); QString propertyString = obj.propertyByIndexAsString(propertyIndex, true);
return QVariant::fromValue(propertyString); return QVariant::fromValue(propertyString);
@@ -88,74 +88,89 @@ namespace BlackGui
/* /*
* Update * Update
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
int CListModelBase<ObjectType, ListType>::update(const ListType &list) int CListModelBase<ObjectType, ContainerType>::update(const ContainerType &list)
{ {
ListType copyList = (list.size() > 1 && this->hasValidSortColumn() ? ContainerType copyList = (list.size() > 1 && this->hasValidSortColumn() ?
this->sortListByColumn(list, this->m_sortedColumn, this->m_sortOrder) : this->sortListByColumn(list, this->m_sortedColumn, this->m_sortOrder) :
list); list);
this->beginResetModel(); this->beginResetModel();
this->m_list.clear(); this->m_container.clear();
foreach(ObjectType object, copyList) foreach(ObjectType object, copyList)
{ {
this->m_list.push_back(object); this->m_container.push_back(object);
} }
this->endResetModel(); this->endResetModel();
return this->m_list.size(); return this->m_container.size();
}
/*
* Update
*/
template <typename ObjectType, typename ContainerType>
void CListModelBase<ObjectType, ContainerType>::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);
} }
/* /*
* Push back * Push back
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
void CListModelBase<ObjectType, ListType>::push_back(const ObjectType &object) void CListModelBase<ObjectType, ContainerType>::push_back(const ObjectType &object)
{ {
beginInsertRows(QModelIndex(), this->m_list.size(), this->m_list.size()); beginInsertRows(QModelIndex(), this->m_container.size(), this->m_container.size());
this->m_list.push_back(object); this->m_container.push_back(object);
endInsertRows(); endInsertRows();
} }
/* /*
* Push back * Push back
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
void CListModelBase<ObjectType, ListType>::insert(const ObjectType &object) void CListModelBase<ObjectType, ContainerType>::insert(const ObjectType &object)
{ {
beginInsertRows(QModelIndex(), 0, 0); beginInsertRows(QModelIndex(), 0, 0);
this->m_list.insert(this->m_list.begin(), object); this->m_container.insert(this->m_container.begin(), object);
endInsertRows(); endInsertRows();
} }
/* /*
* Clear * Clear
*/ */
template <typename ObjectType, typename ListType> template <typename ObjectType, typename ContainerType>
void CListModelBase<ObjectType, ListType>::clear() void CListModelBase<ObjectType, ContainerType>::clear()
{ {
beginResetModel(); beginResetModel();
this->m_list.clear(); this->m_container.clear();
endResetModel(); endResetModel();
} }
/* /*
* Sort * Sort
*/ */
template <typename ObjectType, typename ListType> void CListModelBase<ObjectType, ListType>::sort(int column, Qt::SortOrder order) template <typename ObjectType, typename ContainerType> void CListModelBase<ObjectType, ContainerType>::sort(int column, Qt::SortOrder order)
{ {
this->m_sortedColumn = column; this->m_sortedColumn = column;
this->m_sortOrder = order; this->m_sortOrder = order;
if (this->m_list.size() < 2) return; // nothing to do if (this->m_container.size() < 2) return; // nothing to do
// sort the values // sort the values
this->update( this->update(
this->sortListByColumn(this->m_list, column, order) this->sortListByColumn(this->m_container, column, order)
); );
} }
/* /*
* Sort list * Sort list
*/ */
template <typename ObjectType, typename ListType> ListType CListModelBase<ObjectType, ListType>::sortListByColumn(const ListType &list, int column, Qt::SortOrder order) template <typename ObjectType, typename ContainerType> ContainerType CListModelBase<ObjectType, ContainerType>::sortListByColumn(const ContainerType &list, int column, Qt::SortOrder order)
{ {
if (list.size() < 2) return list; // nothing to do if (list.size() < 2) return list; // nothing to do
int propertyIndex = this->m_columns.columnToPropertyIndex(column); int propertyIndex = this->m_columns.columnToPropertyIndex(column);
@@ -173,8 +188,19 @@ namespace BlackGui
BlackMisc::compareQVariants(bQv, aQv); BlackMisc::compareQVariants(bQv, aQv);
return compare < 0; return compare < 0;
} }
); ); // sorted
}
/*
* Make editable
*/
template <typename ObjectType, typename ContainerType> Qt::ItemFlags CListModelBase<ObjectType, ContainerType>::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 // see here for the reason of thess forward instantiations
@@ -184,6 +210,6 @@ namespace BlackGui
template class CListModelBase<BlackMisc::Aviation::CAircraft, BlackMisc::Aviation::CAircraftList>; template class CListModelBase<BlackMisc::Aviation::CAircraft, BlackMisc::Aviation::CAircraftList>;
template class CListModelBase<BlackMisc::Network::CServer, BlackMisc::Network::CServerList>; template class CListModelBase<BlackMisc::Network::CServer, BlackMisc::Network::CServerList>;
template class CListModelBase<BlackMisc::Network::CUser, BlackMisc::Network::CUserList>; template class CListModelBase<BlackMisc::Network::CUser, BlackMisc::Network::CUserList>;
template class CListModelBase<BlackMisc::Hardware::CKeyboardKey, BlackMisc::Hardware::CKeyboardKeyList>;
} // namespace } // namespace

View File

@@ -18,11 +18,11 @@ namespace BlackGui
/*! /*!
* \brief List model * \brief List model
*/ */
template <typename ObjectType, typename ListType> class CListModelBase : public QAbstractListModel template <typename ObjectType, typename ContainerType> class CListModelBase : public QAbstractListModel
{ {
protected: protected:
ListType m_list; //!< used container ContainerType m_container; //!< used container
CColumns m_columns; //!< columns metadata CColumns m_columns; //!< columns metadata
int m_sortedColumn; //!< current sort column int m_sortedColumn; //!< current sort column
Qt::SortOrder m_sortOrder; //!< sort order (asc/desc) Qt::SortOrder m_sortOrder; //!< sort order (asc/desc)
@@ -45,7 +45,7 @@ namespace BlackGui
* \param order sort order (asccending / descending) * \param order sort order (asccending / descending)
* \return * \return
*/ */
ListType sortListByColumn(const ListType &list, int column, Qt::SortOrder order); ContainerType sortListByColumn(const ContainerType &list, int column, Qt::SortOrder order);
public: public:
@@ -115,22 +115,34 @@ namespace BlackGui
return this->m_sortOrder; return this->m_sortOrder;
} }
/*! //! \brief Used container data
* \copydoc QAbstractListModel::data() virtual const ContainerType &getContainer() const
*/ {
return this->m_container;
}
//! \copydoc QAbstractListModel::data()
virtual QVariant data(const QModelIndex &index, int role) const; virtual QVariant data(const QModelIndex &index, int role) const;
/*! //! \copydoc QAbstractListModel::rowCount()
* \copydoc QAbstractListModel::rowCount()
*/
virtual int rowCount(const QModelIndex &index = QModelIndex()) const; virtual int rowCount(const QModelIndex &index = QModelIndex()) const;
//! \copydoc QAbstractTableModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override;
/*! /*!
* \brief Update by new list * \brief Update by new list
* \param list * \param list
* \return new list size * \return new list size
*/ */
virtual int update(const ListType &list); virtual int update(const ContainerType &list);
/*!
* \brief Update single element
* \param index
* \param object
*/
virtual void update(const QModelIndex &index, const ObjectType &object);
/*! /*!
* \brief Object at row position * \brief Object at row position
@@ -139,24 +151,24 @@ namespace BlackGui
*/ */
virtual const ObjectType &at(const QModelIndex &index) const virtual const ObjectType &at(const QModelIndex &index) const
{ {
if (index.row() < 0 || index.row() >= this->m_list.size()) if (index.row() < 0 || index.row() >= this->m_container.size())
{ {
const static ObjectType def; const static ObjectType def;
return def; return def;
} }
else else
{ {
return this->m_list[index.row()]; return this->m_container[index.row()];
} }
} }
//! \copydoc QAbstractListModel::sort() //! \copydoc QAbstractListModel::sort()
virtual void sort(int column, Qt::SortOrder order); virtual void sort(int column, Qt::SortOrder order);
//! \brief Similar to ListType::push_back //! \brief Similar to ContainerType::push_back
virtual void push_back(const ObjectType &object); virtual void push_back(const ObjectType &object);
//! \brief Similar to ListType::insert here inserts at first position //! \brief Similar to ContainerType::insert here inserts at first position
virtual void insert(const ObjectType &object); virtual void insert(const ObjectType &object);
//! \brief clear the list //! \brief clear the list