File indexing completed on 2024-04-28 12:30:04

0001 /***************************************************************************
0002  *   Copyright (C) 2017 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 "singlemodelviewbase.h"
0019 
0020 // Qt
0021 #include <QtCore/QTimer>
0022 
0023 // KQuickItemViews
0024 #include <KQuickItemViews/adapters/selectionadapter.h>
0025 #include <KQuickItemViews/adapters/contextadapter.h>
0026 #include <KQuickItemViews/adapters/modeladapter.h>
0027 #include "viewport.h"
0028 #include "private/viewport_p.h"
0029 #include "private/geostrategyselector_p.h"
0030 
0031 class SingleModelViewBasePrivate
0032 {
0033 public:
0034     bool          m_IsSortingEnabled {  false  };
0035     ModelAdapter *m_pModelAdapter    { nullptr };
0036 
0037     SingleModelViewBase* q_ptr;
0038 };
0039 
0040 SingleModelViewBase::SingleModelViewBase(ItemFactoryBase *factory, QQuickItem* parent) : ViewBase(parent),
0041     d_ptr(new SingleModelViewBasePrivate())
0042 {
0043     d_ptr->q_ptr = this;
0044 
0045     d_ptr->m_pModelAdapter = new ModelAdapter(this);
0046     addModelAdapter(d_ptr->m_pModelAdapter);
0047 
0048     auto vp = d_ptr->m_pModelAdapter->viewports().first();
0049     vp->setItemFactory(factory);
0050 
0051     auto sm = d_ptr->m_pModelAdapter->selectionAdapter();
0052 
0053     // Ok, connecting signals to signals is not a very good idea, I am lazy
0054     connect(sm, &SelectionAdapter::currentIndexChanged,
0055         this, &SingleModelViewBase::currentIndexChanged);
0056     connect(sm, &SelectionAdapter::selectionModelChanged,
0057         this, &SingleModelViewBase::selectionModelChanged);
0058     connect(d_ptr->m_pModelAdapter, &ModelAdapter::modelAboutToChange,
0059         this, &SingleModelViewBase::applyModelChanges);
0060     connect(vp, &Viewport::cornerChanged,
0061         this, &SingleModelViewBase::cornerChanged);
0062 }
0063 
0064 SingleModelViewBase::~SingleModelViewBase()
0065 {
0066     delete d_ptr;
0067 }
0068 
0069 QQmlComponent* SingleModelViewBase::highlight() const
0070 {
0071     return d_ptr->m_pModelAdapter->selectionAdapter()->highlight();
0072 }
0073 
0074 void SingleModelViewBase::setHighlight(QQmlComponent* h)
0075 {
0076     d_ptr->m_pModelAdapter->selectionAdapter()->setHighlight(h);
0077 }
0078 
0079 void SingleModelViewBase::setDelegate(QQmlComponent* delegate)
0080 {
0081     d_ptr->m_pModelAdapter->setDelegate(delegate);
0082     emit delegateChanged(delegate);
0083     refresh();
0084 }
0085 
0086 QQmlComponent* SingleModelViewBase::delegate() const
0087 {
0088     return d_ptr->m_pModelAdapter->delegate();
0089 }
0090 
0091 QSharedPointer<QItemSelectionModel> SingleModelViewBase::selectionModel() const
0092 {
0093     return d_ptr->m_pModelAdapter->selectionAdapter()->selectionModel();
0094 }
0095 
0096 QVariant SingleModelViewBase::model() const
0097 {
0098     return d_ptr->m_pModelAdapter->model();
0099 }
0100 
0101 void SingleModelViewBase::setModel(const QVariant& m)
0102 {
0103     d_ptr->m_pModelAdapter->setModel(m);
0104     emit modelChanged();
0105 }
0106 
0107 void SingleModelViewBase::setSelectionModel(QSharedPointer<QItemSelectionModel> m)
0108 {
0109     d_ptr->m_pModelAdapter->selectionAdapter()->setSelectionModel(m);
0110     emit selectionModelChanged();
0111 }
0112 
0113 QAbstractItemModel *SingleModelViewBase::rawModel() const
0114 {
0115     return d_ptr->m_pModelAdapter->rawModel();
0116 }
0117 
0118 void SingleModelViewBase::applyModelChanges(QAbstractItemModel* m)
0119 {
0120     if (d_ptr->m_IsSortingEnabled && m) {
0121         m->sort(0);
0122     }
0123 }
0124 
0125 bool SingleModelViewBase::isDelegateSizeForced() const
0126 {
0127     return d_ptr->m_pModelAdapter->viewports().constFirst()->s_ptr->
0128         m_pGeoAdapter->isSizeForced();
0129 }
0130 
0131 void SingleModelViewBase::setDelegateSizeForced(bool f)
0132 {
0133     d_ptr->m_pModelAdapter->viewports().constFirst()->s_ptr->
0134         m_pGeoAdapter->setSizeForced(f);
0135 }
0136 
0137 bool SingleModelViewBase::isSortingEnabled() const
0138 {
0139     return d_ptr->m_IsSortingEnabled;
0140 }
0141 
0142 void SingleModelViewBase::setSortingEnabled(bool val)
0143 {
0144     d_ptr->m_IsSortingEnabled = val;
0145 
0146     if (d_ptr->m_IsSortingEnabled && rawModel()) {
0147         rawModel()->sort(0);
0148     }
0149 }
0150 
0151 QModelIndex SingleModelViewBase::currentIndex() const
0152 {
0153     return selectionModel()->currentIndex();
0154 }
0155 
0156 void SingleModelViewBase::setCurrentIndex(const QModelIndex& index, QItemSelectionModel::SelectionFlags f)
0157 {
0158     selectionModel()->setCurrentIndex(index, f);
0159 }
0160 
0161 bool SingleModelViewBase::hasUniformRowHeight() const
0162 {
0163     return d_ptr->m_pModelAdapter->viewports().constFirst()->s_ptr->
0164         m_pGeoAdapter->capabilities() & GeometryAdapter::Capabilities::HAS_UNIFORM_HEIGHT;
0165 }
0166 
0167 void SingleModelViewBase::setUniformRowHeight(bool value)
0168 {
0169     Q_UNUSED(value)
0170     //d_ptr->m_pModelAdapter->setUniformRowHeight(value);
0171 }
0172 
0173 bool SingleModelViewBase::hasUniformColumnWidth() const
0174 {
0175     return d_ptr->m_pModelAdapter->viewports().constFirst()->s_ptr->
0176         m_pGeoAdapter->capabilities() & GeometryAdapter::Capabilities::HAS_UNIFORM_WIDTH;
0177 }
0178 
0179 void SingleModelViewBase::setUniformColumnColumnWidth(bool value)
0180 {
0181     Q_UNUSED(value)
0182     //d_ptr->m_pModelAdapter->setUniformColumnColumnWidth(value);
0183 }
0184 
0185 void SingleModelViewBase::moveTo(Qt::Edge e)
0186 {
0187     QTimer::singleShot(0, [this, e]() {
0188         //HACK This need the viewportAdapter to be optimized
0189         switch(e) {
0190             case Qt::TopEdge:
0191                 setContentY(0);
0192                 break;
0193             case Qt::BottomEdge: {
0194                 int y = contentY();
0195                 // Keep loading until it doesn't load anything else
0196                 do {
0197                     setContentY(999999);
0198                 } while (contentY() > y && (y = contentY()));
0199             }
0200             case Qt::LeftEdge:
0201             case Qt::RightEdge:
0202                 break; //TODO
0203         }
0204     });
0205 }
0206 
0207 QModelIndex SingleModelViewBase::indexAt(const QPoint & point) const
0208 {
0209     return d_ptr->m_pModelAdapter->viewports().first()->indexAt(point);
0210 }
0211 
0212 QModelIndex SingleModelViewBase::topLeft() const
0213 {
0214     return d_ptr->m_pModelAdapter->viewports().first()->indexAt(Qt::TopLeftCorner);
0215 }
0216 
0217 QModelIndex SingleModelViewBase::topRight() const
0218 {
0219     return d_ptr->m_pModelAdapter->viewports().first()->indexAt(Qt::TopRightCorner);
0220 }
0221 
0222 QModelIndex SingleModelViewBase::bottomLeft() const
0223 {
0224     return d_ptr->m_pModelAdapter->viewports().first()->indexAt(Qt::BottomLeftCorner);
0225 }
0226 
0227 QModelIndex SingleModelViewBase::bottomRight() const
0228 {
0229     return d_ptr->m_pModelAdapter->viewports().first()->indexAt(Qt::BottomRightCorner);
0230 }
0231 
0232 
0233 QRectF SingleModelViewBase::itemRect(const QModelIndex& i) const
0234 {
0235     return d_ptr->m_pModelAdapter->viewports().first()->itemRect(i);
0236 }