diff --git a/src/singlemodelviewbase.cpp b/src/singlemodelviewbase.cpp index 9b349ba..0d0943c 100644 --- a/src/singlemodelviewbase.cpp +++ b/src/singlemodelviewbase.cpp @@ -1,163 +1,185 @@ /*************************************************************************** * Copyright (C) 2017 by Emmanuel Lepage Vallee * * Author : Emmanuel Lepage Vallee * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ #include "singlemodelviewbase.h" +// Qt +#include + // KQuickItemViews #include #include #include #include #include "private/viewport_p.h" #include "private/geostrategyselector_p.h" class SingleModelViewBasePrivate { public: bool m_IsSortingEnabled { false }; ModelAdapter *m_pModelAdapter { nullptr }; SingleModelViewBase* q_ptr; }; SingleModelViewBase::SingleModelViewBase(ItemFactoryBase *factory, QQuickItem* parent) : ViewBase(parent), d_ptr(new SingleModelViewBasePrivate()) { d_ptr->q_ptr = this; d_ptr->m_pModelAdapter = new ModelAdapter(this); addModelAdapter(d_ptr->m_pModelAdapter); d_ptr->m_pModelAdapter->viewports().first()->setItemFactory(factory); auto sm = d_ptr->m_pModelAdapter->selectionAdapter(); // Ok, connecting signals to signals is not a very good idea, I am lazy connect(sm, &SelectionAdapter::currentIndexChanged, this, &SingleModelViewBase::currentIndexChanged); connect(sm, &SelectionAdapter::selectionModelChanged, this, &SingleModelViewBase::selectionModelChanged); connect(d_ptr->m_pModelAdapter, &ModelAdapter::modelAboutToChange, this, &SingleModelViewBase::applyModelChanges); } SingleModelViewBase::~SingleModelViewBase() { delete d_ptr; } QQmlComponent* SingleModelViewBase::highlight() const { return d_ptr->m_pModelAdapter->selectionAdapter()->highlight(); } void SingleModelViewBase::setHighlight(QQmlComponent* h) { d_ptr->m_pModelAdapter->selectionAdapter()->setHighlight(h); } void SingleModelViewBase::setDelegate(QQmlComponent* delegate) { d_ptr->m_pModelAdapter->setDelegate(delegate); emit delegateChanged(delegate); refresh(); } QQmlComponent* SingleModelViewBase::delegate() const { return d_ptr->m_pModelAdapter->delegate(); } QSharedPointer SingleModelViewBase::selectionModel() const { return d_ptr->m_pModelAdapter->selectionAdapter()->selectionModel(); } QVariant SingleModelViewBase::model() const { return d_ptr->m_pModelAdapter->model(); } void SingleModelViewBase::setModel(const QVariant& m) { d_ptr->m_pModelAdapter->setModel(m); } void SingleModelViewBase::setSelectionModel(QSharedPointer m) { d_ptr->m_pModelAdapter->selectionAdapter()->setSelectionModel(m); } QAbstractItemModel *SingleModelViewBase::rawModel() const { return d_ptr->m_pModelAdapter->rawModel(); } void SingleModelViewBase::applyModelChanges(QAbstractItemModel* m) { if (d_ptr->m_IsSortingEnabled && m) { m->sort(0); } } bool SingleModelViewBase::isSortingEnabled() const { return d_ptr->m_IsSortingEnabled; } void SingleModelViewBase::setSortingEnabled(bool val) { d_ptr->m_IsSortingEnabled = val; if (d_ptr->m_IsSortingEnabled && rawModel()) { rawModel()->sort(0); } } QModelIndex SingleModelViewBase::currentIndex() const { return selectionModel()->currentIndex(); } void SingleModelViewBase::setCurrentIndex(const QModelIndex& index, QItemSelectionModel::SelectionFlags f) { selectionModel()->setCurrentIndex(index, f); } bool SingleModelViewBase::hasUniformRowHeight() const { return d_ptr->m_pModelAdapter->viewports().constFirst()->s_ptr-> m_pGeoAdapter->capabilities() & GeometryAdapter::Capabilities::HAS_UNIFORM_HEIGHT; } void SingleModelViewBase::setUniformRowHeight(bool value) { Q_UNUSED(value) //d_ptr->m_pModelAdapter->setUniformRowHeight(value); } bool SingleModelViewBase::hasUniformColumnWidth() const { return d_ptr->m_pModelAdapter->viewports().constFirst()->s_ptr-> m_pGeoAdapter->capabilities() & GeometryAdapter::Capabilities::HAS_UNIFORM_WIDTH; } void SingleModelViewBase::setUniformColumnColumnWidth(bool value) { Q_UNUSED(value) //d_ptr->m_pModelAdapter->setUniformColumnColumnWidth(value); } + +void SingleModelViewBase::moveTo(Qt::Edge e) +{ + QTimer::singleShot(0, [this, e]() { + //HACK This need the viewportAdapter to be optimized + switch(e) { + case Qt::TopEdge: + setCurrentY(0); + break; + case Qt::BottomEdge: { + int y = currentY(); + // Keep loading until it doesn't load anything else + do { + setCurrentY(999999); + } while (currentY() > y && (y = currentY())); + } + } + }); +} diff --git a/src/singlemodelviewbase.h b/src/singlemodelviewbase.h index b37495f..7280946 100644 --- a/src/singlemodelviewbase.h +++ b/src/singlemodelviewbase.h @@ -1,119 +1,121 @@ /*************************************************************************** * Copyright (C) 2017 by Emmanuel Lepage Vallee * * Author : Emmanuel Lepage Vallee * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ #ifndef SINGLEMODELVIEWBASE_H #define SINGLEMODELVIEWBASE_H #include class SingleModelViewBasePrivate; /** * Random code to get close to drop-in compatibility with both QML and QtWidgets * views. * * This library * tries to enforce smaller components with well defined scope. But that makes * its API larger and more complex. This class helps to collapse all the * concepts into a single thing. This removes some flexibility, but allows * the widgets to be (almost) drop-in replacements for the ones provided * by QtQuick2. */ class Q_DECL_EXPORT SingleModelViewBase : public ViewBase { Q_OBJECT public: Q_PROPERTY(QQmlComponent* highlight READ highlight WRITE setHighlight) Q_PROPERTY(QSharedPointer selectionModel READ selectionModel WRITE setSelectionModel NOTIFY selectionModelChanged) Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled) Q_PROPERTY(QModelIndex currentIndex READ currentIndex WRITE setCurrentIndex) Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) /// Assume each hierarchy level have the same height (for performance) Q_PROPERTY(bool uniformRowHeight READ hasUniformRowHeight WRITE setUniformRowHeight) /// Assume each column has the same width (for performance) Q_PROPERTY(bool uniformColumnWidth READ hasUniformColumnWidth WRITE setUniformColumnColumnWidth) /** * It is usually recommanded to use the template constructor unless there is * extra logic to be executed when an item is created. */ explicit SingleModelViewBase(ItemFactoryBase *factory, QQuickItem* parent = nullptr); template SingleModelViewBase(ItemFactory *b, QQuickItem* parent = nullptr) : SingleModelViewBase((ItemFactoryBase*) b, parent) {} virtual ~SingleModelViewBase(); QQmlComponent* highlight() const; void setHighlight(QQmlComponent* h); QVariant model() const; void setModel(const QVariant& m); void setDelegate(QQmlComponent* delegate); QQmlComponent* delegate() const; QSharedPointer selectionModel() const; void setSelectionModel(QSharedPointer m); QModelIndex currentIndex() const; Q_INVOKABLE void setCurrentIndex(const QModelIndex& index, QItemSelectionModel::SelectionFlags f = QItemSelectionModel::ClearAndSelect ); bool isSortingEnabled() const; void setSortingEnabled(bool val); bool hasUniformRowHeight() const; void setUniformRowHeight(bool value); bool hasUniformColumnWidth() const; void setUniformColumnColumnWidth(bool value); + Q_INVOKABLE void moveTo(Qt::Edge e); + protected Q_SLOTS: /** * Calling `setModel` doesn't do anything that takes effect immediately. * * Rather, it will either wait to the next event loop iteration to make * sure other properties have been applied. If no delegate is set, it will * also avoid loading the model internal representation because that would * be useless anyway. * * Override this method if extra steps are to be taken when replacing the * model. Do not forget to call the superclass method. */ virtual void applyModelChanges(QAbstractItemModel* m); protected: QAbstractItemModel *rawModel() const; Q_SIGNALS: void currentIndexChanged(const QModelIndex& index); void selectionModelChanged() const; void modelChanged(); void delegateChanged(QQmlComponent* delegate); // virtual void countChanged() override final; private: SingleModelViewBasePrivate* d_ptr; }; #endif