File indexing completed on 2024-04-28 04:41:51

0001 /***************************************************************************
0002  *   Copyright (C) 2018 by Emmanuel Lepage Vallee                          *
0003  *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@kde.org>             *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 3 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0017  **************************************************************************/
0018 #include "role.h"
0019 
0020 #include <QtCore/QModelIndex>
0021 #include <QtCore/QRectF>
0022 #include <QtCore/QHash>
0023 
0024 // KQuickItemViews
0025 #include <viewport.h>
0026 #include <adapters/modeladapter.h>
0027 
0028 class RoleStrategiesPrivate
0029 {
0030 public:
0031     bool    m_Reload           {       true       };
0032     int     m_SizeRole         { Qt::SizeHintRole };
0033     int     m_PositionRole     {        -1        };
0034     QString m_SizeRoleName     {    "sizeHint"    };
0035     QString m_PositionRoleName {                  };
0036 
0037     void updateName();
0038 
0039     GeometryStrategies::Role *q_ptr;
0040 };
0041 
0042 GeometryStrategies::Role::Role(Viewport *parent) : GeometryAdapter(parent),
0043     d_ptr(new RoleStrategiesPrivate())
0044 {
0045     d_ptr->q_ptr = this;
0046     setCapabilities(Capabilities::HAS_AHEAD_OF_TIME);
0047 }
0048 
0049 GeometryStrategies::Role::~Role()
0050 {
0051     delete d_ptr;
0052 }
0053 
0054 QSizeF GeometryStrategies::Role::sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const
0055 {
0056     Q_UNUSED(adapter)
0057 
0058     if (d_ptr->m_Reload)
0059         d_ptr->updateName();
0060 
0061     const auto val = index.data(d_ptr->m_SizeRole);
0062     Q_ASSERT(val.isValid());
0063 
0064     if (val.type() == QMetaType::QRectF) {
0065         const QRectF rect = val.toRectF();
0066 
0067         return rect.size();
0068     }
0069 
0070     Q_ASSERT(val.toSizeF().isValid());
0071 
0072     return val.toSizeF();
0073 }
0074 
0075 QPointF GeometryStrategies::Role::positionHint(const QModelIndex &index, AbstractItemAdapter *adapter) const
0076 {
0077     Q_UNUSED(adapter)
0078     if (d_ptr->m_Reload)
0079         d_ptr->updateName();
0080 
0081     const auto val = index.data(d_ptr->m_SizeRole);
0082     Q_ASSERT(val.isValid());
0083 
0084     if (val.type() == QMetaType::QRectF) {
0085         const QRectF rect = val.toRectF();
0086 
0087         return rect.topLeft();
0088     }
0089 
0090     return val.toPointF();
0091 }
0092 
0093 int GeometryStrategies::Role::sizeRole() const
0094 {
0095     return d_ptr->m_SizeRole;
0096 }
0097 
0098 void GeometryStrategies::Role::setSizeRole(int role)
0099 {
0100     d_ptr->m_SizeRole = role;
0101     d_ptr->updateName();
0102     emit roleChanged();
0103 }
0104 
0105 QString GeometryStrategies::Role::sizeRoleName() const
0106 {
0107     return d_ptr->m_SizeRoleName;
0108 }
0109 
0110 void GeometryStrategies::Role::setSizeRoleName(const QString& roleName)
0111 {
0112     if (d_ptr->m_SizeRoleName == roleName)
0113         return;
0114 
0115     d_ptr->m_SizeRoleName = roleName;
0116     d_ptr->updateName();
0117     emit roleChanged();
0118 }
0119 
0120 int GeometryStrategies::Role::positionRole() const
0121 {
0122     return d_ptr->m_PositionRole;
0123 }
0124 
0125 void GeometryStrategies::Role::setPositionRole(int role)
0126 {
0127     setCapabilities(
0128         Capabilities::HAS_AHEAD_OF_TIME | Capabilities::HAS_POSITION_HINTS
0129     );
0130 
0131     d_ptr->m_PositionRole = role;
0132     d_ptr->updateName();
0133     emit roleChanged();
0134 }
0135 
0136 QString GeometryStrategies::Role::positionRoleName() const
0137 {
0138     return d_ptr->m_PositionRoleName;
0139 }
0140 
0141 void GeometryStrategies::Role::setPositionRoleName(const QString& roleName)
0142 {
0143     if (d_ptr->m_PositionRoleName == roleName)
0144         return;
0145 
0146     d_ptr->m_PositionRoleName = roleName;
0147     d_ptr->updateName();
0148     emit roleChanged();
0149 }
0150 
0151 void RoleStrategiesPrivate::updateName()
0152 {
0153     //TODO set the role name from the role index
0154     const auto ma = q_ptr->viewport()->modelAdapter();
0155 
0156     if (!ma->rawModel()) {
0157         m_Reload = true;
0158         return;
0159     }
0160 
0161     const auto rn  = ma->rawModel()->roleNames();
0162     const auto rnv = rn.values();
0163 
0164     const QByteArray srn = m_SizeRoleName.toLatin1();
0165     const QByteArray prn = m_PositionRoleName.toLatin1();
0166 
0167     if ((!srn.isEmpty()) && ma->rawModel() && rnv.contains(srn)) {
0168         q_ptr->setSizeRole(rn.key(srn));
0169     }
0170 
0171     if ((!prn.isEmpty()) && ma->rawModel() && rnv.contains(prn)) {
0172         q_ptr->setPositionRole(rn.key(prn));
0173     }
0174 
0175     m_Reload = false;
0176 }