#include "MListModel.h" /*! * \brief Constructor * \param[in] parent - Parent of this object. */ View::MListModel::MListModel(QObject *parent) : QAbstractListModel(parent) { connect(this, &MListModel::rowsInserted, this, &MListModel::countChanged); connect(this, &MListModel::rowsRemoved, this, &MListModel::countChanged); } /*! * \brief Inserts data into the model at a given position. * \param[in] pos - The position where the data will be inserted. * If row is less than 0, then data will be prepended to the model. * If row is greater than or equal to rowCount(), then data will be appeneded to the model. * \param[in] data - The data to insert into the model. */ void View::MListModel::insertRow(const int pos, const QHash &vData) { const int index = std::clamp(pos, 0, rowCount()); beginInsertRows(QModelIndex(), index, index); _data.insert(index, vData); endInsertRows(); } /*! * \brief Retrieve the role names set for this list model. * \return Role names used for this model. */ QHash View::MListModel::roleNames() const { return _roleNames; } /*! * \brief Set the role names for the data in this list model. * \param[in] roleNames New role names for this list model. * \note This will clear the list model of any data. */ void View::MListModel::setRoleNames(const QHash& vRoleNames) { if ( _roleNames != vRoleNames ) { clear(); _roleNames = vRoleNames; } } /*! * \brief Get the number of rows in this list model. * \return Number of rows in this list model. */ int View::MListModel::rowCount(const QModelIndex &) const { return _data.size(); } /*! * \brief Retrieve the data stored at the given index for the specified role. * \param[in] index Index of the data in the list model. * \param[in] role Role of the data to fetch. * \return Data at index for role or Invalid if index or role are not valid. */ QVariant View::MListModel::data(const QModelIndex &vIndex, int vRole) const { QVariant mData; // check for invalid or out of bounds index if ( ! vIndex.isValid() || vIndex.row() >= rowCount() ) { goto lOut; } // ensure the data is not empty if ( _data.isEmpty() ) { goto lOut; } // ensure the role is in the data if ( _data[vIndex.row()].find(vRole) == _data[vIndex.row()].end() ) { goto lOut; } mData = _data[vIndex.row()][vRole]; // check if data is valid if ( ! mData.isValid() ) { goto lOut; } lOut: return mData; } /*! * \brief Retrieve the data stored at the given index for the specified role and expose to QML * \param[in] vRow Index of the data in the list model. */ QVariantMap View::MListModel::get(int vRow) const { QVariantMap map; QHash roles = roleNames(); // Row bounds check if ( vRow < 0 || vRow >= rowCount() ) { goto lOut; } // Check if roles are defined if ( roles.isEmpty() ) { goto lOut; } for ( auto it = roles.cbegin(); it != roles.cend(); ++it ) { const int role = it.key(); const QByteArray roleName = it.value(); if ( roleName.isEmpty() ) { goto lOut; } QVariant value = data(index(vRow, 0), role); if ( ! value.isValid() ) { goto lOut; } map.insert( QString::fromUtf8(roleName), value ); } lOut: return map; } /*! * \brief Clear any data contained in this list model. */ void View::MListModel::clear() { beginRemoveRows(QModelIndex(), 0, rowCount()); _data.clear(); endRemoveRows(); } /*! * \brief Sets the value of the data in this list model at the given index and for the given role. * \param[in] index Location of data to update. * \param[in] value Value to set. * \param[in] role The role of the data at the given index to set. * \return Return true if data was set properly, otherwise false. */ bool View::MListModel::setData(const QModelIndex &vIndex, const QVariant& vValue, int vRole) { if ( ! vIndex.isValid() || vIndex.row() >= _data.count() ) { return false; } if ( _data[vIndex.row()][vRole] != vValue ) { _data[vIndex.row()][vRole] = vValue; // explicitly emit a dataChanged signal to notify anybody bound to this property (vRole) emit dataChanged(vIndex, vIndex, QVector(1, vRole)); } return true; } /*! * \brief Assignment operator * \return A reference to this object. */ View::MListModel& View::MListModel::operator = (const QList> &src) { clear(); if ( _data != src ) { beginInsertRows(QModelIndex(), 0, src.count() - 1); _data = src; endInsertRows(); } return *this; }