Advertisement
Guest User

AddTableRolesProxy

a guest
Sep 8th, 2016
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // addtablerolesproxy.h
  2. #ifndef AddTableRolesProxy_h__
  3. #define AddTableRolesProxy_h__
  4. #include <QIdentityProxyModel>
  5. #include <QSet>
  6. /*!
  7. \brief Adds support for additional roles in flat models
  8. \details This proxy adds support for other roles to models like QStringListModel that do not have it  
  9. use setBaseRoles() to determine which roles should be handled by the base model instead than this proxy. By default Qt::EditRole and Qt::DisplayRole are handled by the base directly
  10. \warning This proxy only support indexes without parents, child items are passed directly to the base model regardless of the role.
  11. */
  12. class AddTableRolesProxyPrivate;
  13. class AddTableRolesProxy : public QIdentityProxyModel
  14. {
  15.     Q_OBJECT
  16.     Q_DECLARE_PRIVATE(AddTableRolesProxy)
  17. public:
  18.     explicit AddTableRolesProxy(QObject* parent = nullptr);
  19.     virtual ~AddTableRolesProxy();
  20.     virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
  21.     virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
  22.     //! Roles handled by the source model
  23.     const QSet<int>& baseRoles() const;
  24.     //! Set the roles handled by the source model
  25.     void setBaseRoles(const QSet<int>& val);
  26. private:
  27.     AddTableRolesProxyPrivate* d_ptr;
  28.    
  29. };
  30. #endif // AddTableRolesProxy_h__
  31.  
  32. //////////////////////////////////////////////////////////////////////////
  33.  
  34. // addtablerolesproxy.cpp
  35.  
  36. #include "AddTableRolesProxy.h"
  37. #include <memory>
  38. #include <QHash>
  39. class AddTableRolesProxyPrivate
  40. {
  41.     Q_DECLARE_PUBLIC(AddTableRolesProxy)
  42.     AddTableRolesProxyPrivate(AddTableRolesProxy* q);
  43.     AddTableRolesProxyPrivate() = delete;
  44.     AddTableRolesProxyPrivate(const AddTableRolesProxyPrivate&) = delete;
  45.     AddTableRolesProxy* q_ptr;
  46.     QHash<qint64, std::shared_ptr< QHash<int, QVariant> > > m_otherRoles;
  47.     QSet<int> m_baseRoles;
  48. };
  49.  
  50. AddTableRolesProxyPrivate::AddTableRolesProxyPrivate(AddTableRolesProxy* q)
  51.     :q_ptr(q)
  52.     , m_baseRoles({ Qt::EditRole, Qt::DisplayRole })
  53. {
  54.     Q_ASSERT(q);
  55. }
  56.  
  57. AddTableRolesProxy::AddTableRolesProxy(QObject* parent)
  58.     :QIdentityProxyModel(parent)
  59.     , d_ptr(new AddTableRolesProxyPrivate(this))
  60. {}
  61.  
  62. AddTableRolesProxy::~AddTableRolesProxy()
  63. {
  64.     delete d_ptr;
  65. }
  66.  
  67. bool AddTableRolesProxy::setData(const QModelIndex &index, const QVariant &value, int role )
  68. {
  69.     Q_D(AddTableRolesProxy);
  70.     if (d->m_baseRoles.contains(role))
  71.         return QIdentityProxyModel::setData(index, value, role);
  72.     if (index.parent().isValid())
  73.         return QIdentityProxyModel::setData(index, value, role); // Trees are not supported
  74.     if (!index.isValid())
  75.         return false;
  76.     Q_ASSERT(index.model() == this);
  77.     if (index.row() < 0 || index.row() > rowCount() || index.column() < 0 || index.column() > columnCount())
  78.         return false;
  79.     const qint64 rowColIdx = (static_cast<qint64>(index.row()) << 32) | static_cast<qint64>(index.column());
  80.     auto roleIter = d->m_otherRoles.find(rowColIdx);
  81.     if (roleIter == d->m_otherRoles.end())
  82.         roleIter = d->m_otherRoles.insert(rowColIdx, std::make_shared<QHash<int, QVariant> >());
  83.     const auto valueIter = roleIter.value()->find(role);
  84.     if (valueIter == roleIter.value()->end()) {
  85.         roleIter.value()->insert(role, value);
  86.     }
  87.     else {
  88.         if (valueIter.value() == value)
  89.             return true;
  90.         valueIter.value() = value;
  91.     }
  92.     emit dataChanged(index, index, QVector<int>() << role);
  93.     return true;
  94. }
  95.  
  96. QVariant AddTableRolesProxy::data(const QModelIndex &index, int role) const
  97. {
  98.     Q_D(const AddTableRolesProxy);
  99.     if (d->m_baseRoles.contains(role))
  100.         return QIdentityProxyModel::data(index, role);
  101.     if (index.parent().isValid())
  102.         return QIdentityProxyModel::data(index, role); // Trees are not supported
  103.     if (!index.isValid())
  104.         return QVariant();
  105.     Q_ASSERT(index.model() == this);
  106.     if (index.row() < 0 || index.row() > rowCount() || index.column() < 0 || index.column() > columnCount())
  107.         return QVariant();
  108.     const qint64 rowColIdx = (static_cast<qint64>(index.row()) << 32) | static_cast<qint64>(index.column());
  109.     const auto roleIter = d->m_otherRoles.constFind(rowColIdx);
  110.     if (roleIter == d->m_otherRoles.constEnd())
  111.         return QVariant();
  112.     return roleIter.value()->value(role, QVariant());
  113. }
  114.  
  115. const QSet<int>& AddTableRolesProxy::baseRoles() const
  116. {
  117.     Q_D(const AddTableRolesProxy);
  118.     return d->m_baseRoles;
  119. }
  120.  
  121. void AddTableRolesProxy::setBaseRoles(const QSet<int>& val)
  122. {
  123.     Q_D(AddTableRolesProxy);
  124.     d->m_baseRoles = val;
  125. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement