diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bc8b12..d318c4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,179 +1,225 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.0) -PROJECT(kquickview) +PROJECT(kquickitemviews) IF(POLICY CMP0063) CMAKE_POLICY(SET CMP0063 NEW) ENDIF(POLICY CMP0063) FIND_PACKAGE(ECM 1.1.0 REQUIRED NO_MODULE) LIST(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}") OPTION(BUILD_SHARED_LIBS "" OFF ) INCLUDE(ECMInstallIcons) INCLUDE(ECMOptionalAddSubdirectory) INCLUDE(KDEInstallDirs) INCLUDE(KDECMakeSettings) INCLUDE(KDECompilerSettings) if(NOT BUILD_SHARED_LIBS) set(STATIC_LIBRARY 1) else() set(STATIC_LIBRARY 0) endif() SET(CMAKE_AUTOMOC ON) SET(CMAKE_AUTORCC ON) SET(CMAKE_CXX_STANDARD 14) # if(STATIC_LIBRARY) add_definitions(-DQT_PLUGIN) add_definitions(-DQT_STATICPLUGIN=1) # else(STATIC_LIBRARY) # if (BUILD_TESTING) # add_subdirectory(autotests) # endif() # endif(STATIC_LIBRARY) FIND_PACKAGE(Qt5 CONFIG REQUIRED Core Gui Quick QuickControls2 ) add_definitions(-isystem ${Qt5Core_PRIVATE_INCLUDE_DIRS}) if("${CMAKE_BUILD_TYPE}" MATCHES "DEBUG") add_definitions(-DENABLE_EXTRA_VALIDATION=1) endif() SET(GENERIC_LIB_VERSION "1.0.0") #File to compile -SET( kquickview_LIB_SRCS +SET( kquickitemviews_LIB_SRCS # Adapters src/adapters/abstractitemadapter.cpp src/adapters/decorationadapter.cpp src/adapters/modeladapter.cpp src/adapters/scrollbaradapter.cpp src/adapters/selectionadapter.cpp src/adapters/geometryadapter.cpp # Building blocks src/flickablescrollbar.cpp src/plugin.cpp src/proxies/sizehintproxymodel.cpp src/singlemodelviewbase.cpp src/viewbase.cpp src/viewport.cpp src/contextadapterfactory.cpp src/qmodelindexwatcher.cpp src/qmodelindexbinder.cpp src/delegatechoice.cpp src/delegatechooser.cpp # Views src/views/comboboxview.cpp src/views/flickable.cpp src/views/hierarchyview.cpp src/views/listview.cpp src/views/treeview.cpp src/views/indexview.cpp # State trackers src/private/statetracker/index_p.cpp src/private/statetracker/geometry_p.cpp src/private/statetracker/proximity_p.cpp src/private/statetracker/model_p.cpp src/private/statetracker/modelitem_p.cpp src/private/statetracker/selection_p.cpp src/private/statetracker/content_p.cpp src/private/statetracker/continuity_p.cpp src/private/runtimetests_p.cpp src/private/indexmetadata_p.cpp src/private/geostrategyselector_p.cpp # Geometry strategies src/strategies/justintime.cpp src/strategies/proxy.cpp src/strategies/role.cpp src/strategies/delegate.cpp src/strategies/uniform.cpp src/strategies/aheadoftime.cpp ) -set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.playground.kquickview) +set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.playground.kquickitemviews) -add_library(kquickview STATIC ${kquickview_LIB_SRCS} ) +add_library(kquickitemviews STATIC ${kquickitemviews_LIB_SRCS} ) -target_link_libraries( kquickview +target_link_libraries( kquickitemviews Qt5::Core Qt5::Gui Qt5::Quick Qt5::QuickControls2 ) -SET( kquickview_LIB_HDRS +SET( kquickitemviews_adapters_LIB_HDRS adapters/abstractitemadapter.h adapters/contextadapter.h adapters/decorationadapter.h adapters/modeladapter.h adapters/scrollbaradapter.h adapters/selectionadapter.h adapters/geometryadapter.h - extensions/contextextension.h - flickablescrollbar.h - plugin.h - proxies/sizehintproxymodel.h - singlemodelviewbase.h - contextadapterfactory.h - qmodelindexwatcher.h - qmodelindexbinder.h - viewbase.h +) + +SET( kquickitemviews_views_LIB_HDRS views/comboboxview.h views/flickable.h views/indexview.h views/hierarchyview.h views/listview.h views/treeview.h - viewport.h - delegatechoice.h - delegatechooser.h +) - # Geometry strategies +SET( kquickitemviews_strategies_LIB_HDRS strategies/justintime.h strategies/proxy.h strategies/role.h strategies/delegate.h strategies/aheadoftime.h strategies/uniform.h ) +SET( kquickitemviews_extensions_LIB_HDRS + extensions/contextextension.h +) + + +SET( kquickitemviews_proxies_LIB_HDRS + proxies/sizehintproxymodel.h +) + +SET( kquickitemviews_LIB_HDRS + flickablescrollbar.h + plugin.h + singlemodelviewbase.h + contextadapterfactory.h + qmodelindexwatcher.h + qmodelindexbinder.h + viewbase.h + viewport.h + delegatechoice.h + delegatechooser.h +) + # Create include file aliases -foreach(header ${kquickview_LIB_HDRS}) +foreach(header ${kquickitemviews_adapters_LIB_HDRS}) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/${header} + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bobcat/KQuickItemViews/adapters/ + ) +endforeach() +foreach(header ${kquickitemviews_views_LIB_HDRS}) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/${header} - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/api/KQuickView/ + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bobcat/KQuickItemViews/views/ + ) +endforeach() +foreach(header ${kquickitemviews_strategies_LIB_HDRS}) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/${header} + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bobcat/KQuickItemViews/strategies + ) +endforeach() +foreach(header ${kquickitemviews_extensions_LIB_HDRS}) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/${header} + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bobcat/KQuickItemViews/extensions + ) +endforeach() +foreach(header ${kquickitemviews_proxies_LIB_HDRS}) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/${header} + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bobcat/KQuickItemViews/proxies + ) +endforeach() +foreach(header ${kquickitemviews_LIB_HDRS}) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/${header} + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bobcat/KQuickItemViews/ ) endforeach() -target_include_directories(kquickview PUBLIC - "${CMAKE_CURRENT_SOURCE_DIR}/src;${CMAKE_CURRENT_BINARY_DIR}/api" +target_include_directories(kquickitemviews PUBLIC + $ + $ ) -set_target_properties(kquickview +# target_include_directories(mylib PUBLIC +# $ +# $ # /bobcat/mylib +# ) + +set_target_properties(kquickitemviews PROPERTIES INCLUDE_DIRECTORIES - "${CMAKE_CURRENT_BINARY_DIR}/api;${CMAKE_CURRENT_SOURCE_DIR}/src" + "${CMAKE_CURRENT_SOURCE_DIR}/src;${CMAKE_CURRENT_SOURCE_DIR}/bobcat/" ) -set_target_properties(kquickview PROPERTIES +set_target_properties(kquickitemviews PROPERTIES PUBLIC_HEADER - "${CMAKE_CURRENT_BINARY_DIR}/api;${CMAKE_CURRENT_SOURCE_DIR}/src" + "${CMAKE_CURRENT_BINARY_DIR}/bobcat/" ) add_subdirectory(tests) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/api/) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/private/) +include_directories("${CMAKE_CURRENT_BINARY_DIR}/bobcat") diff --git a/src/adapters/abstractitemadapter.h b/src/adapters/abstractitemadapter.h index 27c0699..a8d705e 100644 --- a/src/adapters/abstractitemadapter.h +++ b/src/adapters/abstractitemadapter.h @@ -1,266 +1,269 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_ABSTRACTITEMADAPTER_H +#define KQUICKITEMVIEWS_ABSTRACTITEMADAPTER_H #include #include class QQuickItem; class QQmlContext; class AbstractItemAdapterPrivate; namespace StateTracker { class ViewItem; class ModelItem; } class ViewBase; class Viewport; class ContextExtension; /** * This class must be extended by the views to bind QModelIndex with a GUI element. * * This is the class implementation should use to navigate the model indices. It * provides a simple geometric linked list between indices and provide built-in * memory management, including recycling. * * This is optionally a template class to avoid having to perform static casts * when implementing. * * All moderately cartesian views such as list, table, trees and most charts * should use this class along with `ViewBase`. Graphs and advanced * visualizations should probably use a lower level API. * * These objects are created if and only if those 2 conditions are met: * * * The QModelIndex is currently part of a tracked range (see Viewport). * * It didn't fail to load. * * If the overloaded functions returns false, then the consumer of this * class should no longer use the object as it may have been deleted or * recycled. * * Note that this should **NEVER** be stored and an instance may be reused for * other indices or deleted without prior notice. The memory management of this * class is designed for high performance, not ease of use. If you are * implementing views in C++, then this is probably what you want, so think * twice before cursing at how low level this is. * * Note that this object usage should be strictly limited to its overloaded * functions and external usage (from the view class or elsewhere) is * strongly discouraged. If you think the provided interface isn't enough, * report a bug rather than work around it to avoid crashes. */ class AbstractItemAdapter { friend struct StateTracker::ModelItem; //state tracking friend class StateTracker::ViewItem; //its internally shared properties friend class AbstractItemAdapterPrivate; // like (Q_DECLARE_PRIVATE) public: explicit AbstractItemAdapter(Viewport* r); virtual ~AbstractItemAdapter(); ViewBase* view() const; /** * The QML context for the `item`. * * This is lazy loaded. */ virtual QQmlContext *context() const; /** * The QQuickItem used for this item. * * By default, it will create a container in which another item will * be placed. This isn't as optimial as placing the item directly, but * allows for a lot of boilerplate code to be handled internally. */ virtual QQuickItem *item() const; Viewport *viewport() const; /** * The external state if the item. * * This is different from the internal state and only has a subset the * consumer (views) care about. Note that internally, it can be part of a * recycling pool or other types of caches. */ enum class State { BUFFER , /*!< Is close enough to the visible area to have been loaded */ VISIBLE, /*!< Is currently displayed */ INVALID, /*!< You should not use this instance */ }; /** * Get the nearby element on the edge of this item. * * Note that this applies a Cartesian projection on the whole model, so * a nearby element can be a parent, children or sibling. Also note that * elements are lazy loaded and recycled, so there is no guarantee that * the element will exits and it should never be stored. */ AbstractItemAdapter *next(Qt::Edge e) const; /** * This method return the item representing the QModelIndex parent. * * It will return it **ONLY IF THE PARENT IS PART OF THE VISIBLE RANGE**. */ AbstractItemAdapter* parent() const; /** * The item row. * * Note that this doesn't always match QModelIndex::row() because this * value is updated when the `rowsAboutToBeModed` signal is sent rather * than after the change takes effect. */ int row() const; /** * The item column. * * Note that this doesn't always match QModelIndex::column() because this * value is updated when the `columnsAboutToBeModed` signal is sent rather * than after the change takes effect. */ int column() const; /** * The model index. * * Please do not use .row() and .column() on the index and rather use * ::row() and ::column() provided by this class. Otherwise items being * moved wont be rendered correctly. */ QPersistentModelIndex index() const; // Actions /** * Force the position to be computed again. * * The item position is managed by the implementation. However external * events such as resizing the window or switching from mobile to desktop * mode can require the position to be reconsidered. * * This will call `AbstractItemAdapter::move` and all the actions such * as moving the children items, updating the visible range and general * housekeeping tasks so the view implementation does not have to care * about them. */ void resetPosition(); struct SelectionLocker {}; /** * Get a pointer for this item. * * The SelectionLocker (first element of the pair) will be nullptr if the * item no longer belong to the same QModelIndex as when it was acquired. * * Keep in mind that these objects are recycled, so comparing the * AbstractItemAdapter pointer tells nothing. * * **DO NOT STORE IT AS A QSharedPointer**. This is only intended to be * stored as a QWeakPointer. It will */ QPair, AbstractItemAdapter*> weakReference() const; /** * The size and position necessary to draw this item. * * The default implementation uses the item() geometry. */ virtual QRectF geometry() const; QRectF decoratedGeometry() const; /** * In many case, it is useful or necessary to place additional components * or just empty space around a delegate instance. * * This can be, for example, the treeview vertical indentation/expand * indicator or the listview category delegate. * * Note that the top and bottom edge decoration include the width of the * left and right ones. */ qreal borderDecoration(Qt::Edge e) const; void setBorderDecoration(Qt::Edge e, qreal r); /** * Set if the children of this item should be skipped from the view. */ void setCollapsed(bool v); bool isCollapsed() const; /** * Implement this function when selecting an item require extra operations * to be executed. * * The default implementation does nothing. */ virtual void setSelected(bool s); void updateGeometry(); virtual QSizeF sizeHint() const; void dismissCacheEntry(ContextExtension* e, int id); // Shared private data StateTracker::ViewItem *s_ptr; protected: /** * This instance is about to be added to the view. * * The default implementation calls move, but some views might need to * perform extra operations only when the item is added to the viewport. */ virtual bool attach (); /** * Update the delegate instance when the model index changes. * * The default implementation refreshes the role values to the context. */ virtual bool refresh(); /** * Move the delegate instance when it moves itself or its siblings change. */ virtual bool move () = 0; /** * This instance is about to be recycled, if it holds a state, remove it. * * The default implementation does nothing. */ virtual bool flush (); /** * This instance is going to be removed from the view. */ virtual bool remove () = 0; private: AbstractItemAdapterPrivate* d_ptr; }; + +#endif diff --git a/src/adapters/contextadapter.h b/src/adapters/contextadapter.h index 0c8c70d..eae0bfe 100644 --- a/src/adapters/contextadapter.h +++ b/src/adapters/contextadapter.h @@ -1,94 +1,97 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_CONTEXTADAPTER_H +#define KQUICKITEMVIEWS_CONTEXTADAPTER_H // Qt #include class QQmlContext; // KQuickItemViews class AbstractItemAdapter; class ContextAdapterFactory; class DynamicContext; class ContextExtension; /** * Calling `context()` on an instance of this object will create a * QQmlContext reflecting the model roles (and other property groups). * * One instance needs exists per context. It is possible to replace the * QModelIndex later on as needs suit. The two main use cases are to * either track multiple QModelIndex at once and display them or use a * single instance along with some QQmlExpression to add "just-in-time" * properties to objects (like QItemDelegate or * QSortFilterProxyModel::acceptRow) * * These objects MUST BE CREATED AFTER the last call to addContextExtension * has been made and the model(index) has been set. */ class ContextAdapter { friend class AbstractItemAdapter; friend class ContextAdapterFactory; //factory public: virtual ~ContextAdapter(); bool isCacheEnabled() const; void setCacheEnabled(bool v); bool isActive() const; virtual QModelIndex index() const; void setModelIndex(const QModelIndex& index); virtual QQmlContext* context() const final; virtual AbstractItemAdapter* item() const; /** * Clear the cache entry and send the notify signal on the property `id` * from the extension `e`. */ void dismissCache(ContextExtension* e, int id); /** * Notify the adapter some QModelIndex roles changed. * * @return True when the updated roles affect the adapter, false otherwise. */ bool updateRoles(const QVector &modified) const; /** * Clear the cache of role values. * * To improve performance, QAbstractItemModel::data is only called once * unless dataChanged() is called. The value is then stored in the QML * context. Call this to manually invalidate the cache and for roles to be * reloaded. */ void flushCache(); QObject *contextObject() const; protected: explicit ContextAdapter(QQmlContext *parentContext = nullptr); private: DynamicContext* d_ptr {nullptr}; }; Q_DECLARE_METATYPE(ContextAdapter*) + +#endif diff --git a/src/adapters/decorationadapter.h b/src/adapters/decorationadapter.h index 8b6aab5..15748cd 100644 --- a/src/adapters/decorationadapter.h +++ b/src/adapters/decorationadapter.h @@ -1,54 +1,57 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_DECORATIONADAPTER_H +#define KQUICKITEMVIEWS_DECORATIONADAPTER_H // Qt #include #include #include class DecorationAdapterPrivate; class DecorationAdapter : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(QVariant pixmap READ pixmap WRITE setPixmap NOTIFY changed) Q_PROPERTY(QString themeFallback READ themeFallback WRITE setThemeFallback NOTIFY changed) Q_PROPERTY(bool hasPixmap READ hasPixmap NOTIFY changed) public: explicit DecorationAdapter(QQuickItem* parent = nullptr); virtual ~DecorationAdapter(); QPixmap pixmap() const; void setPixmap(const QVariant& var); QString themeFallback() const; void setThemeFallback(const QString& s); bool hasPixmap() const; virtual void paint(QPainter *painter) override; Q_SIGNALS: void changed(); private: DecorationAdapterPrivate *d_ptr; Q_DECLARE_PRIVATE(DecorationAdapter) }; + +#endif diff --git a/src/adapters/geometryadapter.h b/src/adapters/geometryadapter.h index fa9ecb9..10439e5 100644 --- a/src/adapters/geometryadapter.h +++ b/src/adapters/geometryadapter.h @@ -1,144 +1,147 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_GEOMETRYADAPTER_H +#define KQUICKITEMVIEWS_GEOMETRYADAPTER_H #include #include #include class GeometryAdapterPrivate; class AbstractItemAdapter; class Viewport; /** * Add strategies to get the size (and optionally position) hints. * * One size don't fit everything here. QtWidgets had a `sizeHint` method. * However getting this information in QML is a lot harder for many reasons. */ class Q_DECL_EXPORT GeometryAdapter : public QObject { Q_OBJECT public: Q_INVOKABLE explicit GeometryAdapter(Viewport *parent = nullptr); virtual ~GeometryAdapter(); /** * Features this adapter provide and requires. */ enum Capabilities { NONE = 0x0 << 0, /** * Most GeometryAdapter only provide size hints. * * However some views might not have built-in layouts and then the position * is also necessary. * * This property only state that the adapter *can* provide positions. * `alwaysHasPositionHints` will tell if this is always the case. */ HAS_POSITION_HINTS = 0x1 << 0, /** * Allow the view to skip the GeometryAdapter when they only need the height. * * It will be called once, then the view will assume the result will always * be the same. */ HAS_UNIFORM_HEIGHT = 0x1 << 1, /** * Allow the view to skip the GeometryAdapter when they only need the width. * * It will be called once, then the view will assume the result will always * be the same. */ HAS_UNIFORM_WIDTH = 0x1 << 2, /** * The sizeHint will *always* return a valid size. * * Some GeometryAdapter may only provide size hints when some preconditions * are met. For example something that depends on the current delegate * will only work once the delegate is created. */ ALWAYS_HAS_SIZE_HINTS = 0x1 << 3, /** @see alwaysHasSizeHints */ ALWAYS_HAS_POSITION_HINTS = 0x1 << 4, /** * This GeometryAdapter allows to query the size before creating a * delegate instance. */ HAS_AHEAD_OF_TIME = 0x1 << 5, /** * This GeometryAdapter requires the view to track each QQuickItem * delegate geometry. */ TRACKS_QQUICKITEM_GEOMETRY= 0x1 << 6, /** * This GeometryAdapter requires a single delegate instance to work. */ REQUIRES_SINGLE_INSTANCE = 0x1 << 7, }; // Q_FLAGS(Capabilities) Q_PROPERTY(int capabilities READ capabilities NOTIFY flagsChanged) virtual int capabilities() const; /** * Get the size hints for an AbstractItemAdapter. */ Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const; /** * Get the position hints for an AbstractItemAdapter. */ Q_INVOKABLE virtual QPointF positionHint(const QModelIndex &index, AbstractItemAdapter *adapter) const; Viewport *viewport() const; protected: /** * Set the flags to be used by the internal optimization engine. */ void setCapabilities(int f); void addCapabilities(int f); void removeCapabilities(int f); Q_SIGNALS: /** * Tell the view to disregard previously returned values and start over. */ void dismissResult(); void flagsChanged(); private: GeometryAdapterPrivate *d_ptr; Q_DECLARE_PRIVATE(GeometryAdapter) }; + +#endif diff --git a/src/adapters/modeladapter.h b/src/adapters/modeladapter.h index 0e44e57..77eb56f 100644 --- a/src/adapters/modeladapter.h +++ b/src/adapters/modeladapter.h @@ -1,126 +1,129 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_MODELADAPTER_H +#define KQUICKITEMVIEWS_MODELADAPTER_H #include // KQuickItemViews class SelectionAdapter; class ContextAdapterFactory; class Viewport; class ViewBase; class AbstractItemAdapter; class ModelAdapterPrivate; // Qt class QQmlComponent; class QAbstractItemModel; /** * Wrapper object to assign a model to a view. * * It supports both QSharedPointer based models and "raw" QAbstractItemModel. * * This class also allow multiple properties to be attached to the model, such * as a GUI delegate. */ class Q_DECL_EXPORT ModelAdapter : public QObject { Q_OBJECT public: Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(bool empty READ isEmpty NOTIFY contentChanged) /// The view can be collapsed Q_PROPERTY(bool collapsable READ isCollapsable WRITE setCollapsable) /// Everything is collapsed or has no children Q_PROPERTY(bool collapsed READ isCollapsed NOTIFY collapsedChanged) /// Expand all elements by default Q_PROPERTY(bool autoExpand READ isAutoExpand WRITE setAutoExpand) /// The maximum depth of a tree (for performance) Q_PROPERTY(int maxDepth READ maxDepth WRITE setMaxDepth) /// Recycle existing QQuickItem delegates for new QModelIndex (for performance) Q_PROPERTY(RecyclingMode recyclingMode READ recyclingMode WRITE setRecyclingMode) /// The number of elements to be preloaded outside of the visible area (for latency) Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer) /// The number of delegates to be kept in a recycling pool (for performance) Q_PROPERTY(int poolSize READ poolSize WRITE setPoolSize) enum RecyclingMode { NoRecycling , /*!< Destroy and create new QQuickItems all the time */ RecyclePerDepth, /*!< Keep different pools buffer for each levels of children */ AlwaysRecycle , /*!< Assume all depth level use the same delegate */ }; Q_ENUM(RecyclingMode) explicit ModelAdapter(ViewBase *parent = nullptr); virtual ~ModelAdapter(); QVariant model() const; void setModel(const QVariant& var); virtual void setDelegate(QQmlComponent* delegate); QQmlComponent* delegate() const; bool isCollapsable() const; void setCollapsable(bool value); bool isAutoExpand() const; void setAutoExpand(bool value); int maxDepth() const; void setMaxDepth(int depth); int cacheBuffer() const; void setCacheBuffer(int value); int poolSize() const; void setPoolSize(int value); RecyclingMode recyclingMode() const; void setRecyclingMode(RecyclingMode mode); bool isEmpty() const; bool isCollapsed() const; SelectionAdapter* selectionAdapter() const; ContextAdapterFactory* contextAdapterFactory() const; QVector viewports() const; QAbstractItemModel *rawModel() const; ViewBase *view() const; protected: // Rather then scope-creeping this class, all selection related elements // are implemented independently. void setSelectionAdapter(SelectionAdapter* v); Q_SIGNALS: void modelAboutToChange(QAbstractItemModel* m, QAbstractItemModel* old); void modelChanged(QAbstractItemModel* m, QAbstractItemModel* old); void delegateChanged(QQmlComponent* delegate); void contentChanged(); void collapsedChanged(); private: ModelAdapterPrivate *d_ptr; }; + +#endif diff --git a/src/adapters/scrollbaradapter.h b/src/adapters/scrollbaradapter.h index 8316747..c4df00f 100644 --- a/src/adapters/scrollbaradapter.h +++ b/src/adapters/scrollbaradapter.h @@ -1,54 +1,57 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_SCROLLBARADAPTER_H +#define KQUICKITEMVIEWS_SCROLLBARADAPTER_H // Qt #include #include class QQuickItem; class QAbstractItemModel; class ScrollBarAdapterPrivate; class ScrollBarAdapter : public QObject { Q_OBJECT public: explicit ScrollBarAdapter(QObject* parent = nullptr); virtual ~ScrollBarAdapter(); Q_PROPERTY(QSharedPointer model READ model WRITE setModel) Q_PROPERTY(QQuickItem* target READ target WRITE setTarget) QSharedPointer model() const; void setModel(QSharedPointer m); QQuickItem* target() const; void setTarget(QQuickItem* item); private Q_SLOTS: void rowsInserted(); private: ScrollBarAdapterPrivate* d_ptr; Q_DECLARE_PRIVATE(ScrollBarAdapter) }; Q_DECLARE_METATYPE(ScrollBarAdapter*) Q_DECLARE_METATYPE(QSharedPointer) + +#endif diff --git a/src/adapters/selectionadapter.h b/src/adapters/selectionadapter.h index 989f191..1836cfa 100644 --- a/src/adapters/selectionadapter.h +++ b/src/adapters/selectionadapter.h @@ -1,66 +1,69 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_SELECTIONADAPTER_H +#define KQUICKITEMVIEWS_SELECTIONADAPTER_H // Qt #include class QItemSelectionModel; class QQmlComponent; // KQuickItemViews #include class SelectionAdapterSyncInterface; class SelectionAdapterPrivate; class ContextExtension; namespace StateTracker { class ViewItem; } /** * This class adds support for multi-selection using selection models. * * It must be attached to a single instance of a `ViewBase` object. */ class SelectionAdapter : public QObject { Q_OBJECT friend class ModelAdapter; // Notify of all relevant events friend class ModelAdapterPrivate; // Notify of all relevant events friend class StateTracker::ViewItem; // Notify of all relevant events friend class SelectionAdapterSyncInterface; // Its own internals public: explicit SelectionAdapter(QObject* parent = nullptr); virtual ~SelectionAdapter(); QQmlComponent* highlight() const; void setHighlight(QQmlComponent* h); QSharedPointer selectionModel() const; void setSelectionModel(QSharedPointer sm); ContextExtension *contextExtension() const; Q_SIGNALS: void currentIndexChanged(const QModelIndex& index); void selectionModelChanged() const; private: SelectionAdapterSyncInterface* s_ptr; SelectionAdapterPrivate* d_ptr; Q_DECLARE_PRIVATE(SelectionAdapter); }; + +#endif diff --git a/src/adapters/viewportadapter.h b/src/adapters/viewportadapter.h index b2b86bd..0612b05 100644 --- a/src/adapters/viewportadapter.h +++ b/src/adapters/viewportadapter.h @@ -1,41 +1,44 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_VIEWPORTADAPTER_H +#define KQUICKITEMVIEWS_VIEWPORTADAPTER_H class ViewportAdapterPrivate; //WARNING on hold for now, nothing is implemented properly /** * Define which QModelIndex get to be loaded at any given time and keep track * of the view size. */ class Q_DECL_EXPORT ViewportAdapter : public QObject { Q_OBJECT public: Q_INVOKABLE explicit ViewportAdapter(QObject *parent = nullptr){Q_UNUSED(parent)} virtual ~ViewportAdapter(){} bool isTotalSizeKnown() const{return false;}; void setModel(QAbstractItemModel *m){Q_UNUSED(m)}; private: ViewportAdapterPrivate *d_ptr; }; + +#endif diff --git a/src/contextadapterfactory.h b/src/contextadapterfactory.h index 0f21d4c..fba2057 100644 --- a/src/contextadapterfactory.h +++ b/src/contextadapterfactory.h @@ -1,99 +1,102 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_CONTEXTADAPTERFACTORY_H +#define KQUICKITEMVIEWS_CONTEXTADAPTERFACTORY_H // Qt #include class QAbstractItemModel; class QQmlContext; class QQuickItem; // LibStdC++ #include // KQuickItemViews class ContextAdapterFactoryPrivate; class ContextExtension; class ContextAdapter; /** * This class manage the content of the AbstractItemAdapter::context(). * * It dynamically compute the roles used by the delegate and optimize * the updates. * * This avoids calling setProperty on every single role and refresh them in * every single `emit dataChanged`. * * `applyRoles` can be re-implemented to either add more properties to the * context or to convert some roles into a format easier to consume from QML. */ class Q_DECL_EXPORT ContextAdapterFactory { friend class ContextAdapter; // Public API friend class DynamicContext; // call finish() public: /** * This constructor has an optional template parameter to specify a * different class to be built by the factory. By default it builds a * plain ContextAdapter */ template explicit ContextAdapterFactory() : ContextAdapterFactory([](QQmlContext* c)->ContextAdapter*{return new T(c);}){} virtual ~ContextAdapterFactory(); QAbstractItemModel *model() const; void setModel(QAbstractItemModel *m); /** * Add more properties to the context. * * This must be called from the view constructor. If called later, it will * Q_ASSERT. * * Implementations must subclass ContextExtension to use this. */ void addContextExtension(ContextExtension* pg); QSet usedRoles() const; /** * Create a context adapter. * * This can only be done after the last context extension is added. */ ContextAdapter* createAdapter(QQmlContext *parentContext = nullptr) const; /** * Alternate version of createAdapter with the ability to create derivative * of the ContextAdapter. */ template T* createAdapter(QQmlContext *p = nullptr) const { return static_cast(createAdapter([](QQmlContext* c)->ContextAdapter*{return new T(c);}, p)); } private: using FactoryFunctor = std::function; ContextAdapterFactory(FactoryFunctor f); ContextAdapter* createAdapter(FactoryFunctor, QQmlContext*) const; ContextAdapterFactoryPrivate* d_ptr; Q_DECLARE_PRIVATE(ContextAdapterFactory); }; + +#endif diff --git a/src/delegatechoice.h b/src/delegatechoice.h index 7c45819..591c587 100644 --- a/src/delegatechoice.h +++ b/src/delegatechoice.h @@ -1,82 +1,85 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_DELEGATECHOICE_H +#define KQUICKITEMVIEWS_DELEGATECHOICE_H // Qt #include #include #include class DelegateChoicePrivate; class Q_DECL_EXPORT DelegateChoice : public QObject { Q_OBJECT public: Q_PROPERTY(int column READ column WRITE setColumn NOTIFY changed) Q_PROPERTY(int row READ row WRITE setRow NOTIFY changed) Q_PROPERTY(int depth READ depth WRITE setDepth NOTIFY changed) /// Either an `int` or a `QModelIndex` Q_PROPERTY(QVariant index READ index WRITE setIndex NOTIFY changed) Q_PROPERTY(QVariant roleValue READ roleValue WRITE setRoleValue NOTIFY changed) Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY changed) /** * A JavaScript expression with access to all role values. */ Q_PROPERTY(QQmlScriptString when READ when WRITE setWhen NOTIFY changed) explicit DelegateChoice(QObject *parent = nullptr); virtual ~DelegateChoice(); int column() const; void setColumn(int c); int row() const; void setRow(int r); int depth() const; void setDepth(int d); QVariant index() const; void setIndex(const QVariant& i); QQmlComponent *delegate() const; void setDelegate(QQmlComponent *d); QQmlScriptString when() const; void setWhen(const QQmlScriptString &w); QVariant roleValue() const; void setRoleValue(const QVariant &v); protected: virtual bool evaluateIndex(const QModelIndex& idx); virtual bool evaluateRow(int row, const QModelIndex& parent); virtual bool evaluateColumn(int row, const QModelIndex& parent); Q_SIGNALS: void changed(); private: DelegateChoicePrivate *d_ptr; Q_DECLARE_PRIVATE(DelegateChoice) }; + +#endif diff --git a/src/delegatechooser.h b/src/delegatechooser.h index 2581a25..c17f546 100644 --- a/src/delegatechooser.h +++ b/src/delegatechooser.h @@ -1,68 +1,71 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_DELEGATECHOOSER_H +#define KQUICKITEMVIEWS_DELEGATECHOOSER_H // Qt #include #include // KQuickItemViews #include class DelegateChooserPrivate; class Q_DECL_EXPORT DelegateChooser : public QObject { Q_OBJECT Q_CLASSINFO("DefaultProperty", "choices") public: enum class Modes { Undefined, Columns, Rows, Indices, Expression, }; Q_ENUM(Modes) Q_PROPERTY(Modes mode READ mode NOTIFY changed) Q_PROPERTY(QQmlListProperty choices READ choices NOTIFY changed) Q_PROPERTY(QString role READ role WRITE setRole NOTIFY changed) QString role() const; void setRole(const QString &role); QQmlListProperty choices(); Modes mode() const; void setMode(Modes m); protected: virtual bool evaluateIndex(const QModelIndex& idx); virtual bool evaluateRow(int row, const QModelIndex& parent); virtual bool evaluateColumn(int row, const QModelIndex& parent); Q_SIGNALS: void changed(); private: DelegateChooserPrivate *d_ptr; Q_DECLARE_PRIVATE(DelegateChooser) }; + +#endif diff --git a/src/extensions/contextextension.h b/src/extensions/contextextension.h index ac7ba5d..c522394 100644 --- a/src/extensions/contextextension.h +++ b/src/extensions/contextextension.h @@ -1,102 +1,105 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_CONTEXTEXTENSION_H +#define KQUICKITEMVIEWS_CONTEXTEXTENSION_H // Qt #include #include #include class ContextExtensionPrivate; /** * Add more properties to the QML context. * * This allows to add a predefined set of extra properties to the QML * context. It does *not* support adding more properties at runtime. * * The memory ownership is not transferred, do not re-use the instance * across many views (it will crash). */ class ContextExtension { public: explicit ContextExtension(); virtual ~ContextExtension() {} /** * Return a list of properties. * * This **MUST NEVER CHANGE** and needs to always return the same * vector. Implementations should use a `static` QVector. * * The property index is what's passed to getProperty, setProperty * and is the argument of changeProperty. */ virtual QVector& propertyNames() const; /** * The default implementation returns propertyNames().size() * * Implementing this rather than using `propertyNames` makes sense * when the properties contained in an existing data structure or * associated with extra metadata. */ virtual uint size() const; /** * The default implementation returns propertyNames()[id]; * * Implementing this rather than using `propertyNames` makes sense * when the properties contained in an existing data structure or * associated with extra metadata. */ virtual QByteArray getPropertyName(uint id) const; /** * Some variants, like QModelIndex ones, cannot be cached and will * most likely point to invalid memory. * * If the group has such properties, implement this function. Note * that the return value cannot change. * * The default implementation always returns true. */ virtual bool supportCaching(uint id) const; /** * The id comes from propertyNames. * * It is recommended to use a switch statement or if/else_if for the * implementation and avoid QHash (or worst). */ virtual QVariant getProperty(AbstractItemAdapter* item, uint id, const QModelIndex& index) const = 0; /** * Optionally make the property read/write. */ virtual void setProperty(AbstractItemAdapter* item, uint id, const QVariant& value) const; /** * Notify that content of this property has changed. */ void changeProperty(AbstractItemAdapter* item, uint id); ContextExtensionPrivate *d_ptr; }; + +#endif diff --git a/src/flickablescrollbar.h b/src/flickablescrollbar.h index f87d57d..aca5f50 100644 --- a/src/flickablescrollbar.h +++ b/src/flickablescrollbar.h @@ -1,69 +1,72 @@ /*************************************************************************** * Copyright (C) 2017-2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_FLICKABLESCROLLBAR_H +#define KQUICKITEMVIEWS_FLICKABLESCROLLBAR_H // Qt #include // KQuickItemViews class FlickableScrollBarPrivate; /** * A scrollbar widget designed for the Simpleflickable based views. * * In theory it works with the QtQuick2.FlickableView based ones too, but it's * unsupported. * * The idea is to have both a desktop and mobile mode and good support for * categorized views. The shell is C++, but the widget implementation is * pure QML. * * The idea is that with the categories and everything being known internally * by the Simpleflickable views, having everything reverse engineered by QML * widget doesn't scale. It always requires to be fixed to match the internal * changes. */ class Q_DECL_EXPORT FlickableScrollBar : public QQuickItem { Q_OBJECT public: Q_PROPERTY(QObject* view READ view WRITE setView) Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(qreal handleHeight READ handleHeight NOTIFY handleHeightChanged) Q_PROPERTY(bool handleVisible READ isHandleVisible NOTIFY handleHeightChanged) explicit FlickableScrollBar(QQuickItem* parent = nullptr); virtual ~FlickableScrollBar(); QObject* view() const; void setView(QObject* v); qreal handleHeight() const; bool isHandleVisible() const; qreal position() const; void setPosition(qreal p); Q_SIGNALS: void handleHeightChanged(); void positionChanged(); private: FlickableScrollBarPrivate* d_ptr; Q_DECLARE_PRIVATE(FlickableScrollBar) }; + +#endif diff --git a/src/plugin.h b/src/plugin.h index aeb7f5a..46313f6 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -1,33 +1,36 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_PLUGIN_H +#define KQUICKITEMVIEWS_PLUGIN_H #include #include //![plugin] class Q_DECL_EXPORT KQuickView final : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kde.playground.kquickview" FILE "kquickview.json") public: void registerTypes(const char *uri) override; virtual void initializeEngine(QQmlEngine *engine, const char *uri) override; }; //![plugin] + +#endif diff --git a/src/private/geoutils_p.h b/src/private/geoutils_p.h index ada89a8..68a1c8f 100644 --- a/src/private/geoutils_p.h +++ b/src/private/geoutils_p.h @@ -1,110 +1,113 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_GEOUTILS_P_H +#define KQUICKITEMVIEWS_GEOUTILS_P_H class GeoUtils { public: enum class Pos {Top, Left, Right, Bottom}; // static QPair fromGravity() const; static constexpr Qt::Edge fromPos(Pos p) { return edgeMap[(int)p]; } static constexpr Pos fromEdge(Qt::Edge e) { switch(e) { case Qt::TopEdge: return Pos::Top; case Qt::LeftEdge: return Pos::Left; case Qt::RightEdge: return Pos::Right; case Qt::BottomEdge: return Pos::Bottom; } return {}; } private: static constexpr const Qt::Edge edgeMap[] = { Qt::TopEdge, Qt::LeftEdge, Qt::RightEdge, Qt::BottomEdge }; // Qt::TopEdge, Qt::LeftEdge, Qt::RightEdge, Qt::BottomEdge }; template class GeoRect { public: T get(Qt::Edge e) const { return get(GeoUtils::fromEdge(e)); } T get(GeoUtils::Pos p) const { return m_lRect[(int)p]; } void set(T v, Qt::Edge e) { set(v, GeoUtils::fromEdge(e)); } void set(T v, GeoUtils::Pos p) { m_lRect[(int)p] = v; } //TODO implement operator[] private: T m_lRect[4] = {{}, {}, {}, {}}; }; // QPair ViewportPrivate::fromGravity() const // { // switch (m_pModelAdapter->view()->gravity()) { // case Qt::Corner::TopLeftCorner: // return {Qt::Edge::TopEdge, Qt::Edge::LeftEdge}; // case Qt::Corner::TopRightCorner: // return {Qt::Edge::TopEdge, Qt::Edge::RightEdge}; // case Qt::Corner::BottomLeftCorner: // return {Qt::Edge::BottomEdge, Qt::Edge::LeftEdge}; // case Qt::Corner::BottomRightCorner: // return {Qt::Edge::BottomEdge, Qt::Edge::RightEdge}; // } // // Q_ASSERT(false); // return {}; // } // static Pos edgeToPos(Qt::Edge e) // { // switch(e) { // case Qt::TopEdge: // return Pos::Top; // case Qt::LeftEdge: // return Pos::Left; // case Qt::RightEdge: // return Pos::Right; // case Qt::BottomEdge: // return Pos::Bottom; // } // // Q_ASSERT(false); // // return {}; // } + +#endif diff --git a/src/private/indexmetadata_p.h b/src/private/indexmetadata_p.h index 8736f87..effa3a0 100644 --- a/src/private/indexmetadata_p.h +++ b/src/private/indexmetadata_p.h @@ -1,207 +1,210 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_INDEXMETADATA_P_H +#define KQUICKITEMVIEWS_INDEXMETADATA_P_H // Qt #include #include #include namespace StateTracker { class ViewItem; class Geometry; class ModelItem; class Proximity; class Index; class Selection; } class ContextAdapter; class Viewport; class SelectionAdapter; class IndexMetadataPrivate; /** * The shared view of a QModelIndex between the various adapters. The * StateTracker::Content has `StateTracker::ModelItem` and the AbstractItemAdapter * has the `StateTracker::ViewItem`. Both are the QModelIndex from their point of view * (model for the former and view for the later). * * This class is the glue between those vision of the QModelIndex and holds * the little they can share. * * Also note that the StateTracker::ModelItem and AbstractItemAdapter have very * different life cycle. It is why a more neutral entity is needed to bridge * them across the adapters. * * Note that some methods of this class are implemented in other "cpp" files * to give them the visibility of some otherwise private structures. This was * done to limit the proliferation of under-used _p.h classes and make them * easier to modify as time goes by. */ class IndexMetadata final { public: explicit IndexMetadata(StateTracker::Index *idxT, Viewport *p); ~IndexMetadata(); /** * The actions to perform on the model change tracking state machine. */ enum class LoadAction { SHOW = 0, /*!< Make visible on screen (or buffer) */ HIDE = 1, /*!< Remove from the screen (or buffer) */ ATTACH = 2, /*!< Track, but do not show */ DETACH = 3, /*!< Stop tracking for changes */ UPDATE = 4, /*!< Update the element */ MOVE = 5, /*!< Update the depth and lookup */ RESET = 6, /*!< Flush the visual item */ REPARENT = 7, /*!< Move in the item tree */ }; /** * The actions to perform on the geometry tracking state machine. */ enum class GeometryAction { MOVE , /*!< When moved */ RESIZE , /*!< When the content size changes */ PLACE , /*!< When setting the position */ RESET , /*!< The delegate, layout changes, or pooled */ MODIFY , /*!< When the QModelIndex role changes */ DECORATE, /*!< When the decoration size changes */ VIEW , /*!< When the geometry is accessed */ }; /** * Actions to perform on the view (widget) state tracker. */ enum class ViewAction { ATTACH , /*!< Activate the element (do not sync it) */ ENTER_BUFFER, /*!< Sync all roles */ ENTER_VIEW , /*!< NOP (todo) */ UPDATE , /*!< Reload the roles */ MOVE , /*!< Move to a new position */ LEAVE_BUFFER, /*!< Stop keeping track of data changes */ DETACH , /*!< Delete */ }; /** * The actions associated with the state of the (cartesian) siblings status * if this index. */ enum class ProximityAction { QUERY , /*!< */ DISCARD, /*!< */ MOVE , /*!< */ }; /** * */ enum class EdgeType { FREE , /*!< */ VISIBLE , /*!< */ BUFFERED, /*!< */ NONE , /*!< */ }; // Getters QRectF decoratedGeometry() const; QModelIndex index() const; StateTracker::ViewItem *viewTracker () const; StateTracker::Index *indexTracker () const; StateTracker::ModelItem *modelTracker () const; StateTracker::Proximity *proximityTracker() const; StateTracker::Geometry *geometryTracker () const; StateTracker::Selection *selectionTracker() const; ContextAdapter *contextAdapter () const; // Mutator bool performAction(ViewAction a); bool performAction(LoadAction a); bool performAction(GeometryAction a); bool performAction(ProximityAction a, Qt::Edge e); bool performAction(QItemSelectionModel::SelectionFlag f, SelectionAdapter *ad); // Navigation IndexMetadata *up () const; //DEPRECATED remove, use `next(Qt::Edge)` IndexMetadata *down () const; //DEPRECATED remove, use `next(Qt::Edge)` IndexMetadata *left () const; //DEPRECATED remove, use `next(Qt::Edge)` IndexMetadata *right() const; //DEPRECATED remove, use `next(Qt::Edge)` IndexMetadata *next(Qt::Edge e) const; bool isTopItem() const; /** * Check if the expected geometry and current geometry match. * * @return True if the view delegate (widget) is in the expected position. */ bool isInSync() const; void setViewTracker(StateTracker::ViewItem *i); /** * Return true when the metadata is complete enough to be displayed. * * This means the following thing: * * * The QModelIndex is valid * * The position is known * * The size is known */ bool isValid() const; /** * If the object is considered visible by the viewport. * * Note that it doesn't always means it is directly in on screen. It can * be shadowed by something else, 99% out of view or the view decided not * to actually display it. * * It only means the engine fully tracks it and assumes the tracking * overhead isn't wasted. */ bool isVisible() const; QSizeF sizeHint(); qreal borderDecoration(Qt::Edge e) const; void setBorderDecoration(Qt::Edge e, qreal r); void setSize(const QSizeF& s); void setPosition(const QPointF& p); bool isCollapsed() const; void setCollapsed(bool c); Viewport *viewport() const; private: IndexMetadataPrivate *d_ptr; }; /** * Allow daisy-chaining when the return value isn't used. */ template inline IndexMetadata *operator<<(IndexMetadata* md, A a) { md->performAction(a); return md; } + +#endif diff --git a/src/private/runtimetests_p.h b/src/private/runtimetests_p.h index 829cdc2..8766468 100644 --- a/src/private/runtimetests_p.h +++ b/src/private/runtimetests_p.h @@ -1,21 +1,24 @@ -#pragma once +#ifndef KQUICKITEMVIEWS_RUNTIMETESTS_P_H +#define KQUICKITEMVIEWS_RUNTIMETESTS_P_H void _test_validateTree(StateTracker::Content *self, StateTracker::Index* p); void _test_validateLinkedList(StateTracker::Content *self, bool skipVItemState = false); void _test_validateViewport(StateTracker::Content *self, bool skipVItemState = false); void _test_validate_edges(StateTracker::Content *self); void _test_validate_move( StateTracker::Content *self, StateTracker::Index* parentTTI, StateTracker::Index* startTTI, StateTracker::Index* endTTI, StateTracker::Index* newPrevTTI, StateTracker::Index* newNextTTI, int row); void _test_validate_edges_simple(StateTracker::Content *self); void _test_validate_geometry_cache(StateTracker::Content *self); void _test_print_state(StateTracker::Content *self); void _test_validateUnloaded(StateTracker::Content *self, const QModelIndex& parent, int first, int last); void _test_validateContinuity(StateTracker::Content *self); void _test_validateAtEnd(StateTracker::Content *self); void _test_validateModelAboutToReplace(StateTracker::Content *self); + +#endif diff --git a/src/private/statetracker/content_p.h b/src/private/statetracker/content_p.h index a2de0b0..c40ce18 100644 --- a/src/private/statetracker/content_p.h +++ b/src/private/statetracker/content_p.h @@ -1,94 +1,97 @@ /*************************************************************************** * Copyright (C) 2017-2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_CONTENT_P_H +#define KQUICKITEMVIEWS_CONTENT_P_H // Qt #include #include // KQuickViews class ContentPrivate; class Viewport; class ModelRect; #include #include "modelitem_p.h" namespace StateTracker { struct ModelItem; struct Model; /** * Listen to the model changes and forward those changes to the other relevant * state trackers. */ class Content final : public QObject { Q_OBJECT public: enum class Event { ENTER_STATE, LEAVE_STATE, }; explicit Content(Viewport* parent = nullptr); virtual ~Content(); // Edges management void setAvailableEdges(Qt::Edges edges, IndexMetadata::EdgeType type); Qt::Edges availableEdges(IndexMetadata::EdgeType type) const; IndexMetadata *getEdge(IndexMetadata::EdgeType t, Qt::Edge e) const; void setEdge(IndexMetadata::EdgeType et, StateTracker::Index* tti, Qt::Edge e); ModelRect* edges(IndexMetadata::EdgeType e) const; // Getter StateTracker::Index *root () const; StateTracker::Index *lastItem () const; StateTracker::Index *firstItem () const; StateTracker::Model *modelTracker() const; // Mutator void connectModel(QAbstractItemModel *m); void disconnectModel(QAbstractItemModel *m); void resetRoot(); void resetEdges(); void perfromStateChange(Event e, IndexMetadata *md, StateTracker::ModelItem::State s); void forceInsert(const QModelIndex& idx); void forceInsert(const QModelIndex& parent, int first, int last); // Helpers IndexMetadata *metadataForIndex(const QModelIndex& idx) const; bool isActive(const QModelIndex& parent, int first, int last); Index *find(Index *i, Qt::Edge direction, std::function) const; Q_SIGNALS: void contentChanged(); private: ContentPrivate* d_ptr; }; } // Inject some extra validation when executed in debug mode. #ifdef ENABLE_EXTRA_VALIDATION #define _DO_TEST(f, ...) f(__VA_ARGS__); #include #else #define _DO_TEST(f, ...) /*NOP*/; #endif + +#endif diff --git a/src/private/statetracker/continuity_p.h b/src/private/statetracker/continuity_p.h index c513f22..e86bc27 100644 --- a/src/private/statetracker/continuity_p.h +++ b/src/private/statetracker/continuity_p.h @@ -1,76 +1,79 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_CONTINUITY_P_H +#define KQUICKITEMVIEWS_CONTINUITY_P_H namespace StateTracker { class Index; /** * This bare-bone state tracker helps to track the continuity between the * ELEMENTS WITH THE SAME PARENT. * * The use case for this is to prevent the O(N) operation of the list of * elements to check if there is missing holes in them. This could be done with * simple artmetic on the row of the last child, first child and the number of * children, but this would not handle the corner cases where there multiple * "holes". It would also not allow to know where the hole(s) are without * looping. * * This may seem overkill to waste memory tracking this, but there is 2 reasons * why it isn't such a bad idea: * * * Some ViewportStategies need to know this in every frame (fps) of a scroll * operation with tight frame duration deadlines. * * If the viewport loads a full list model, the "N" of "O(N)" can be very * large. * * @todo This should, once fully implemented, go hand in hand with * StateTracker::Proximity to avoid useless rowCount other overhead in * StateTracker::Content and make methods such as `isActive` reliable. * * @todo Slicing a StateTracker::Continuity is currently rather expensive. This * can be brought down to "O(N*log(N))" by using double pointers to create * "pages" of a size representative of the total number of elements. However * this will take more memory and has an overhead in itself. It wont be done * unless it is proven to be significantly faster for real-world models. */ class Continuity final { friend class Index; // Factory, call private API public: Index *first() const; Index *last () const; int size() const; private: explicit Continuity(Index *first); StateTracker::Index *m_pFirst {nullptr}; StateTracker::Index *m_pLast {nullptr}; static void split(StateTracker::Index *at); static void merge(StateTracker::Index *one, StateTracker::Index *two); static void remove(Index *i); static void setContinuity(Index *i, Continuity *c); static Continuity *select(StateTracker::Index *i); }; } + +#endif diff --git a/src/private/statetracker/geometry_p.h b/src/private/statetracker/geometry_p.h index fc60978..d5cd80d 100644 --- a/src/private/statetracker/geometry_p.h +++ b/src/private/statetracker/geometry_p.h @@ -1,104 +1,107 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_GEOMETRY_P_H +#define KQUICKITEMVIEWS_GEOMETRY_P_H // Qt #include #include #include #include namespace StateTracker { /** * Computing the absolute geometry of items isn't always trivial. * * There is always the case where you known part of the answer (point or size) * and/or where the item moves and the size is valid but not the position. * * If there is no scrollbar, having the absolute position right isn't * necessary as long as the relative one is correct. * * This structure tries to allow delaying the geometry computation as late * as possible. * * The geometry is built using 3 components: * * * The content size * * The outer decoration size * * The position * * What this entity doesn't known (and should not ever know) * * * Anything related about its neighbor. * */ struct Geometry { enum class State { INIT , /*!< The value has not been computed */ SIZE , /*!< The size had been computed */ POSITION, /*!< The position has been computed */ PENDING , /*!< Has all information, but not assembled */ VALID , /*!< The geometry has been computed */ }; State performAction(IndexMetadata::GeometryAction); QPointF position() const; void setPosition(const QPointF& pos); QSizeF size() const; void setSize(const QSizeF& size); QRectF decoratedGeometry() const; QRectF contentGeometry() const; qreal borderDecoration(Qt::Edge e) const; void setBorderDecoration(Qt::Edge e, qreal r); State state() const; private: QRectF rawGeometry() const; QPointF m_Position; QSizeF m_Size; GeoRect m_lBorderDecoration; typedef void(Geometry::*StateF)(); static const State m_fStateMap [5][7]; static const StateF m_fStateMachine[5][7]; // Actions void nothing(); void invalidate(); void error(); void dropCache(); void dropSize(); void dropPos(); void buildCache(); State m_State {State::INIT}; }; } + +#endif diff --git a/src/private/statetracker/index_p.h b/src/private/statetracker/index_p.h index 974547d..96e38bd 100644 --- a/src/private/statetracker/index_p.h +++ b/src/private/statetracker/index_p.h @@ -1,170 +1,173 @@ /*************************************************************************** * Copyright (C) 2017-2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_INDEX_P_H +#define KQUICKITEMVIEWS_INDEX_P_H #include #include #include #include class Viewport; namespace StateTracker { class Continuity; /** * Internal navigation structure designed to support partial tree loading. * * This isn't intended to be used directly. It exists as its own class because * previous iterations were embedded within the model event slots and it made * it generally unmaintainable. The idea is to provide atomic and batch * operations that can be unit tested individually (eventually). * * * Support continuous but incomplete sets of indices * * Support indices currently being moved or removed * * Support moving and reparenting * * Provide both a geometric/cartesian and tree navigation API. */ class Index { friend class Continuity; //Manage the m_pContinuity public: enum class LifeCycleState { NEW , /*!< Not part of a tree yet */ NORMAL , /*!< There is a valid index and a parent node */ TRANSITION , /*!< Between rowsAbouttoMove and rowsMoved (and removed) */ ROOT , /*!< This is the root element */ }; explicit Index(Viewport *p) : m_Geometry(this, p) {} virtual ~Index(); static void insertChildBefore(Index* self, StateTracker::Index* other, StateTracker::Index* parent); static void insertChildAfter(Index* self, StateTracker::Index* other, StateTracker::Index* parent); Index *firstChild() const; Index *lastChild () const; Index *nextSibling () const; Index *previousSibling() const; Index *parent() const; // Geometric navigation Index* up () const; //TODO remove Index* down () const; //TODO remove Index* left () const; //TODO remove Index* right() const; //TODO remove Index* next(Qt::Edge e) const; int depth() const; int effectiveRow() const; int effectiveColumn() const; QPersistentModelIndex effectiveParentIndex() const; virtual void remove(bool reparent = false); static void bridgeGap(Index* first, StateTracker::Index* second); Index *childrenLookup(const QPersistentModelIndex &index) const; bool hasChildren(Index *child) const; int loadedChildrenCount() const; QList allLoadedChildren() const; bool withinRange(QAbstractItemModel* m, int last, int first) const; void resetTemporaryIndex(); bool hasTemporaryIndex(); void setTemporaryIndex(const QModelIndex& newParent, int row, int column); /** Return true when both elements have the same parent and are continuous. * If other is `nullptr` and `i` is first (or last), then that's also true */ bool isNeighbor(Index *other) const; QPersistentModelIndex index() const; void setModelIndex(const QPersistentModelIndex& idx); LifeCycleState lifeCycleState() const {return m_LifeCycleState;} IndexMetadata *metadata() const; //TODO have one for vertical and horizontal axis Continuity *continuityTracker() const; // Runtime tests #ifdef ENABLE_EXTRA_VALIDATION void _test_validate_chain() const; static void _test_bridgeGap(Index *first, Index *second); #endif private: // Because slotRowsMoved is called before the change take effect, cache // the "new real row and column" since the current index()->row() is now // garbage. int m_MoveToRow {-1}; int m_MoveToColumn {-1}; QPersistentModelIndex m_MoveToParent; uint m_Depth {0}; LifeCycleState m_LifeCycleState {LifeCycleState::NEW}; Index* m_tSiblings[2] = {nullptr, nullptr}; Index* m_tChildren[2] = {nullptr, nullptr}; // Keep the parent to be able to get back to the root Index* m_pParent {nullptr}; QPersistentModelIndex m_Index; //TODO use a btree, not an hash QHash m_hLookup; mutable IndexMetadata m_Geometry; Continuity *m_pContinuity {nullptr}; }; } /** * TODO get rid of this and implement paging * * Keep track of state "edges". * * This allows to manipulate rectangles of QModelIndex similar to QtCore * dataChanged and other signals. */ class ModelRect final { public: StateTracker::Index* getEdge(Qt::Edge e) const; void setEdge(StateTracker::Index* tti, Qt::Edge e); Qt::Edges m_Edges {Qt::TopEdge|Qt::LeftEdge|Qt::RightEdge|Qt::BottomEdge}; private: GeoRect m_lpEdges; //TODO port to ModelRect }; // Inject some extra validation when executed in debug mode. #ifdef ENABLE_EXTRA_VALIDATION #define _DO_TEST_IDX(f, self, ...) self->f(__VA_ARGS__); #define _DO_TEST_IDX_STATIC(f, ...) f(__VA_ARGS__); #else #define _DO_TEST_IDX(f, self, ...) /*NOP*/; #define _DO_TEST_IDX_STATIC(f, ...) /*NOP*/; #endif + +#endif diff --git a/src/private/statetracker/model_p.h b/src/private/statetracker/model_p.h index 54f0f0b..2bf3c42 100644 --- a/src/private/statetracker/model_p.h +++ b/src/private/statetracker/model_p.h @@ -1,98 +1,101 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_MODEL_P_H +#define KQUICKITEMVIEWS_MODEL_P_H class QAbstractItemModel; namespace StateTracker { class Content; class Model { public: explicit Model(StateTracker::Content* q); enum class State { NO_MODEL , /*!< The model is not set, there is nothing to do */ PAUSED , /*!< The model is set, but the reflector is not listening */ POPULATED, /*!< The initial insertion has been done, it is ready for tracking */ TRACKING , /*!< The model is set and the reflector is listening to changes */ RESETING , /*!< The model is undergoing a reset process */ MUTATING , /*!< Insertion events are not re-entrant, prevent this */ }; enum class Action { POPULATE, /*!< Fetch the model content and fill the view */ DISABLE , /*!< Disconnect the model tracking */ ENABLE , /*!< Connect the pending model */ RESET , /*!< Remove the delegates but keep the trackers*/ FREE , /*!< Free the whole tracking tree */ MOVE , /*!< Try to fix the viewport with content */ TRIM , /*!< Remove the elements until the edge is free*/ }; /** * Manipulate the tracking state. */ State performAction(Action); State state() const; QAbstractItemModel *trackedModel () const; QAbstractItemModel *modelCandidate() const; void setModel(QAbstractItemModel* m); private: typedef void(StateTracker::Model::*StateF)(); // Attributes State m_State {State::NO_MODEL}; QAbstractItemModel* m_pModel {nullptr}; QAbstractItemModel* m_pTrackedModel {nullptr}; // Actions, do not call directly void track(); void untrack(); void nothing(); void reset(); void free(); void error(); void populate(); void fill(); void trim(); static const State m_fStateMap [6][7]; static const StateF m_fStateMachine[6][7]; StateTracker::Content *q_ptr; }; /** * Allow daisy-chaining when the return value isn't used. */ template inline Model *operator<<(Model* md, A a) { md->performAction(a); return md; } } + +#endif diff --git a/src/private/statetracker/modelitem_p.h b/src/private/statetracker/modelitem_p.h index 21040b7..44ad450 100644 --- a/src/private/statetracker/modelitem_p.h +++ b/src/private/statetracker/modelitem_p.h @@ -1,89 +1,92 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_MODELITEM_P_H +#define KQUICKITEMVIEWS_MODELITEM_P_H #include #include class Viewport; namespace StateTracker { class Content; /** * Hold the metadata associated with the QModelIndex. */ struct ModelItem final : public StateTracker::Index { friend class ::IndexMetadata; //access the state machine explicit ModelItem(Viewport *v); virtual ~ModelItem() {} enum class State { NEW = 0, /*!< During creation, not part of the tree yet */ BUFFER = 1, /*!< Not in the viewport, but close */ REMOVED = 2, /*!< Currently in a removal transaction */ REACHABLE = 3, /*!< The [grand]parent of visible indexes */ VISIBLE = 4, /*!< The element is visible on screen */ ERROR = 5, /*!< Something went wrong */ DANGLING = 6, /*!< Being destroyed */ MOVING = 7, /*!< Currently undergoing a move operation */ }; typedef bool(ModelItem::*StateF)(); StateTracker::ModelItem* load(Qt::Edge e) const; // Getter IndexMetadata::EdgeType isTopEdge () const; IndexMetadata::EdgeType isBottomEdge() const; State state() const; // Mutator void rebuildState(); //TODO refactor once the class are split virtual void remove(bool reparent = false) override; private: // Actions bool nothing(); bool error (); bool show (); bool hide (); bool remove2(); bool attach (); bool detach (); bool refresh(); bool move (); bool destroy(); bool reset (); // Attributes State m_State {State::BUFFER}; static const State m_fStateMap [8][8]; static const StateF m_fStateMachine[8][8]; StateTracker::Content* q_ptr; }; } + +#endif diff --git a/src/private/statetracker/proximity_p.h b/src/private/statetracker/proximity_p.h index 9711f31..88392d5 100644 --- a/src/private/statetracker/proximity_p.h +++ b/src/private/statetracker/proximity_p.h @@ -1,64 +1,67 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_PROXIMITY_P_H +#define KQUICKITEMVIEWS_PROXIMITY_P_H #include #include #include class ProximityPrivate; namespace StateTracker { class Index; /** * Track if the elements next to this one are loaded. * * This tries to prevent accidental "holes" with unloaded elements between * two visible ones. * * This state tracker doesn't know about what's loaded and what's not. To * make it work, it is important to send all relevent events otherwise it will * go out of sync and start doing useless model queries (but hopefully nothing * worst). */ class Proximity { public: explicit Proximity(IndexMetadata *q, StateTracker::Index *self); enum class State { UNKNOWN , /*!< The information is not availablr */ LOADED , /*!< The edges are valid */ MOVED , /*!< It was valid, but some elements moved */ UNLOADED, /*!< It is known that some edges are not loaded */ }; void performAction(IndexMetadata::ProximityAction a, Qt::Edge e); bool canLoadMore(Qt::Edge e); QModelIndexList getNext(Qt::Edge e); private: ProximityPrivate *d_ptr; }; } + +#endif diff --git a/src/private/statetracker/selection_p.h b/src/private/statetracker/selection_p.h index e0238d6..d5320a0 100644 --- a/src/private/statetracker/selection_p.h +++ b/src/private/statetracker/selection_p.h @@ -1,63 +1,66 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_SELECTION_P_H +#define KQUICKITEMVIEWS_SELECTION_P_H // Qt #include #include #include class SelectionAdapter; namespace StateTracker { /** * WORK IN PROGRESS * * Keep track of the selection status. * * This support both currentIndex and multi-selection modes and supports * multiple selection models on the same more. */ struct Selection { enum class State { NONE , /*!< No selection model hold a selection on this item */ CURRENT_INDEX , /*!< A single selection model sets it as currentIndex */ MULTIPLE , /*!< A single selection model mutli-select the item */ MIXED_CURRENT_INDEX, /*!< Multiple sel. model select this item, at least 1 as current index */ MIXED_MULTIPLE , /*!< Multiple selection models multi-select this index */ }; bool performAction(QItemSelectionModel::SelectionFlag f, SelectionAdapter *ad); State state() const; private: typedef void(Geometry::*StateF)(); /*static const State m_fStateMap [5][7]; static const StateF m_fStateMachine[5][7];*/ // Actions //TODO State m_State {State::NONE}; }; } + +#endif diff --git a/src/private/statetracker/viewitem_p.h b/src/private/statetracker/viewitem_p.h index e6b4627..190bf09 100644 --- a/src/private/statetracker/viewitem_p.h +++ b/src/private/statetracker/viewitem_p.h @@ -1,109 +1,112 @@ /*************************************************************************** * Copyright (C) 2017-2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_VIEWITEM_P_H +#define KQUICKITEMVIEWS_VIEWITEM_P_H // KQuickItemViews #include "private/statetracker/viewitem_p.h" #include #include class ViewBase; class ViewItemContextAdapter; class ContextAdapter; class Viewport; // Qt class QQuickItem; #include namespace StateTracker { class Content; /** * Polymorphic tree item for the ViewBase. * * Classes implementing ViewBase need to provide an implementation of the pure * virtual functions. It is useful, for example, to manage both a raster and * QQuickItem based version of a view. * * The state is managed by the ViewBase and it's own protected virtual methods. */ class ViewItem { public: explicit ViewItem(Viewport* r) : m_pViewport(r) {} virtual ~ViewItem() { m_pMetadata->setViewTracker(nullptr); } enum class State { POOLING , /*!< Being currently removed from view */ POOLED , /*!< Not currently in use, either new or waiting for re-use */ BUFFER , /*!< Not currently on screen, pre-loaded for performance */ ACTIVE , /*!< Visible */ FAILED , /*!< Loading the item was attempted, but failed */ DANGLING, /*!< Pending deletion, invalid pointers */ ERROR , /*!< Something went wrong */ }; /// Call to notify that the geometry changed (for the selection delegate) void updateGeometry(); void setCollapsed(bool v); bool isCollapsed() const; // Spacial navigation ViewItem* up () const; //DEPRECATED ViewItem* down () const; //DEPRECATED ViewItem* left () const { return nullptr ;} //DEPRECATED ViewItem* right() const { return nullptr ;} //DEPRECATED ViewItem *next(Qt::Edge e) const; int row () const; int column() const; int depth () const; //TODO firstChild, lastChild, parent // Getters QPersistentModelIndex index() const; /// Allow implementations to be notified when it becomes selected virtual void setSelected(bool) final; /// Geometry relative to the ViewBase::view() virtual QRectF currentGeometry() const final; virtual QQuickItem* item() const final; QQmlContext *context() const; Viewport *m_pViewport {nullptr}; IndexMetadata *m_pMetadata {nullptr}; bool performAction(IndexMetadata::ViewAction a); State state() const; AbstractItemAdapter* d_ptr; private: State m_State {State::POOLED}; }; } + +#endif diff --git a/src/private/viewport_p.h b/src/private/viewport_p.h index 1715e48..ce0febd 100644 --- a/src/private/viewport_p.h +++ b/src/private/viewport_p.h @@ -1,92 +1,95 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_VIEWPORT_P_H +#define KQUICKITEMVIEWS_VIEWPORT_P_H // Qt class QQmlComponent; class QQmlEngine; // KItemViews class Viewport; class IndexMetadata; class AbstractItemAdapter; class GeoStrategySelector; class ViewBaseItemVariables; namespace StateTracker { class Content; } #include #include #include "statetracker/geometry_p.h" /** * In order to keep the separation of concerns design goal intact, this * interface between the StateTracker::Content and Viewport internal * metadata without exposing them. */ class ViewportSync final { public: /** * From the model or feedback loop */ void updateGeometry(IndexMetadata* item); /** * From the widget */ void geometryUpdated(IndexMetadata* item); /** * From the model or feedback loop */ void notifyRemoval(IndexMetadata* item); /** * From the model or feedback loop */ void notifyInsert(IndexMetadata* item); /** * From the model when the QModelIndex role change */ void notifyChange(IndexMetadata* item); /** * Manually trigger the sizes and positions to be updated. */ void refreshVisible(); QQmlEngine *engine(); QQmlComponent *component(); IndexMetadata *metadataForIndex(const QModelIndex& idx) const; Viewport *q_ptr; StateTracker::Content *m_pReflector {nullptr}; GeoStrategySelector *m_pGeoAdapter { nullptr }; std::function m_fFactory; private: QQmlEngine *m_pEngine {nullptr}; QQmlComponent *m_pComponent {nullptr}; }; + +#endif diff --git a/src/proxies/sizehintproxymodel.h b/src/proxies/sizehintproxymodel.h index d9bbda1..8c1b083 100644 --- a/src/proxies/sizehintproxymodel.h +++ b/src/proxies/sizehintproxymodel.h @@ -1,120 +1,123 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_SIZEHINTPROXYMODEL_H +#define KQUICKITEMVIEWS_SIZEHINTPROXYMODEL_H // Qt #include #include #include #include class SizeHintProxyModelPrivate; /** * This proxy model allows to predict the final size of a view delegate. * * This model needs to be implemented when both of the following things are * used: * * * A scrollbar or anything that depends on `contentHeight` being correct * * A non uniform delegate size * * Back in the QtWidgets days, the QItemDelegate/QStyledItemDelegate had the * `sizeHint` method. It was easy to use because it was the same class that * performed the painting so it had all the necessary knowledge to return * the correct value. In QML, however, it's not the case. Predicting the size * may or may not require knowledge of the style that are not officially in * public APIs. That being said, it should usually be possible to gather the * data in one way or another. * * This class is part of the public C++ API so the `sizeHint` method can be * re-implemented. Otherwise it is specified in JavaScript. */ class Q_DECL_EXPORT SizeHintProxyModel : public QIdentityProxyModel { Q_OBJECT public: /** * Return the width for a QModelIndex. * * All roles and all constants constants are exposed as variables in the * expression. */ Q_PROPERTY(QQmlScriptString widthHint READ widthHint WRITE setWidthHint) /** * Return the width for a QModelIndex. * * All roles and all constants constants are exposed as variables in the * expression. */ Q_PROPERTY(QQmlScriptString heightHint READ heightHint WRITE setHeightHint) /** * Add variables to the sizeHint callback context that likely wont change * over time. This is useful to store font metrics and static sizes. * * The function is called when the model changes or invalidateContext is * called. */ Q_PROPERTY(QJSValue constants READ constants WRITE setConstants) /** * When `dataChanged` on the model is called with a list of invalidated roles * matching the entries in this list, assume the size hint needs to be * recomputed. * * When used with the other KQuickView views, they will be notified. * * Note that the constants wont be invalidated. */ Q_PROPERTY(QStringList invalidationRoles READ invalidationRoles WRITE setInvalidationRoles) explicit SizeHintProxyModel(QObject* parent = nullptr); virtual ~SizeHintProxyModel(); virtual void setSourceModel(QAbstractItemModel *newSourceModel) override; QQmlScriptString widthHint() const; void setWidthHint(const QQmlScriptString& value); QQmlScriptString heightHint() const; void setHeightHint(const QQmlScriptString& value); QJSValue constants() const; void setConstants(const QJSValue& value); QStringList invalidationRoles() const; void setInvalidationRoles(const QStringList& l); Q_INVOKABLE QSizeF sizeHintForIndex(const QModelIndex& idx); Q_INVOKABLE QVariant getRoleValue(const QModelIndex& idx, const QString& roleName) const; public Q_SLOTS: /** * Call this when the values in the constants may have changed. */ void invalidateConstants(); private: SizeHintProxyModelPrivate* d_ptr; Q_DECLARE_PRIVATE(SizeHintProxyModel) }; Q_DECLARE_METATYPE(SizeHintProxyModel*) + +#endif diff --git a/src/qmodelindexbinder.h b/src/qmodelindexbinder.h index ecf6c4c..32ffbff 100644 --- a/src/qmodelindexbinder.h +++ b/src/qmodelindexbinder.h @@ -1,110 +1,113 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_QMODELINDEXBINDER_H +#define KQUICKITEMVIEWS_QMODELINDEXBINDER_H #include class QModelIndexBinderPrivate; /** * * Bind a children component property with a QModelIndex role. * * It is intended to be used within an IndexView. * * @todo auto-create as attached properties in IndexView */ class Q_DECL_EXPORT QModelIndexBinder : public QQuickItem { Q_OBJECT public: /** * Only call setData after `delay` milliseconds. */ Q_PROPERTY(int delay READ delay WRITE setDelay NOTIFY changed) /** * The name of the role to sychronize. */ Q_PROPERTY(QString modelRole READ modelRole WRITE setModelRole NOTIFY changed) /** * The (child) object property to bind with the role. */ Q_PROPERTY(QString objectProperty READ objectProperty WRITE setObjectProperty NOTIFY changed) /** * Automatically call setData when the data is modified. */ Q_PROPERTY(bool autoSave READ autoSave WRITE setAutoSave NOTIFY changed) /** * If the model data match the local one. */ Q_PROPERTY(bool synchronized READ isSynchronized NOTIFY changed) // The content of the container Q_PROPERTY(QObject* _object READ _object WRITE _setObject NOTIFY changed) Q_CLASSINFO("DefaultProperty", "_object") explicit QModelIndexBinder(QQuickItem *parent = nullptr); virtual ~QModelIndexBinder(); QString modelRole() const; void setModelRole(const QString& role); QString objectProperty() const; void setObjectProperty(const QString& op); QObject *_object() const; void _setObject(QObject *o); int delay() const; void setDelay(int d); bool autoSave() const; void setAutoSave(bool v); bool isSynchronized() const; /** * Reset the local property to match the model data. */ Q_INVOKABLE void reset() const; /** * Call `setData` now. */ Q_INVOKABLE bool applyNow() const; static QModelIndexBinder *qmlAttachedProperties(QObject *object); Q_SIGNALS: void changed(); protected: // This is the attached contructor QModelIndexBinder(QObject *o); private: QModelIndexBinderPrivate *d_ptr; Q_DECLARE_PRIVATE(QModelIndexBinder) }; QML_DECLARE_TYPEINFO(QModelIndexBinder, QML_HAS_ATTACHED_PROPERTIES) + +#endif diff --git a/src/qmodelindexwatcher.h b/src/qmodelindexwatcher.h index e290310..e14e096 100644 --- a/src/qmodelindexwatcher.h +++ b/src/qmodelindexwatcher.h @@ -1,57 +1,60 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_QMODELINDEXWATCHER_H +#define KQUICKITEMVIEWS_QMODELINDEXWATCHER_H #include #include class QAbstractItemModel; class QModelIndexWatcherPrivate; /** * This class allows to get events on a QModelIndex from QML. */ class Q_DECL_EXPORT QModelIndexWatcher : public QObject { Q_OBJECT public: explicit QModelIndexWatcher(QObject *parent = nullptr); virtual ~QModelIndexWatcher(); Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) Q_PROPERTY(QModelIndex modelIndex READ modelIndex WRITE setModelIndex NOTIFY indexChanged) Q_PROPERTY(QAbstractItemModel* model READ model NOTIFY validChanged) QModelIndex modelIndex() const; void setModelIndex(const QModelIndex &index); QAbstractItemModel *model() const; bool isValid() const; Q_SIGNALS: void removed(); void moved(); void dataChanged(const QVector& roles); void validChanged(); void indexChanged(); private: QModelIndexWatcherPrivate *d_ptr; Q_DECLARE_PRIVATE(QModelIndexWatcher) }; + +#endif diff --git a/src/singlemodelviewbase.cpp b/src/singlemodelviewbase.cpp index c77c5d2..9b349ba 100644 --- a/src/singlemodelviewbase.cpp +++ b/src/singlemodelviewbase.cpp @@ -1,163 +1,163 @@ /*************************************************************************** * 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" // KQuickItemViews -#include "adapters/selectionadapter.h" -#include "adapters/contextadapter.h" -#include "adapters/modeladapter.h" -#include "viewport.h" +#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); } diff --git a/src/singlemodelviewbase.h b/src/singlemodelviewbase.h index 59721f7..b37495f 100644 --- a/src/singlemodelviewbase.h +++ b/src/singlemodelviewbase.h @@ -1,116 +1,119 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef SINGLEMODELVIEWBASE_H +#define SINGLEMODELVIEWBASE_H -#include +#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); 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 diff --git a/src/strategies/aheadoftime.h b/src/strategies/aheadoftime.h index 6c84183..fdd36fe 100644 --- a/src/strategies/aheadoftime.h +++ b/src/strategies/aheadoftime.h @@ -1,39 +1,42 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_AHEADOFTIME_H +#define KQUICKITEMVIEWS_AHEADOFTIME_H #include class Viewport; namespace GeometryStrategies { /** * */ class Q_DECL_EXPORT AheadOfTime : public GeometryAdapter { Q_OBJECT public: explicit AheadOfTime(Viewport *parent = nullptr); virtual ~AheadOfTime(); Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; }; } + +#endif diff --git a/src/strategies/delegate.h b/src/strategies/delegate.h index 19886b4..f76c416 100644 --- a/src/strategies/delegate.h +++ b/src/strategies/delegate.h @@ -1,39 +1,42 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_DELEGATE_H +#define KQUICKITEMVIEWS_DELEGATE_H #include class Viewport; namespace GeometryStrategies { /** * */ class Q_DECL_EXPORT Delegate : public GeometryAdapter { Q_OBJECT public: explicit Delegate(Viewport *parent = nullptr); virtual ~Delegate(); Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; }; } + +#endif diff --git a/src/strategies/justintime.h b/src/strategies/justintime.h index 2edd0f9..1b6a692 100644 --- a/src/strategies/justintime.h +++ b/src/strategies/justintime.h @@ -1,39 +1,42 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_JUSTINTIME_H +#define KQUICKITEMVIEWS_JUSTINTIME_H #include class Viewport; namespace GeometryStrategies { /** * */ class Q_DECL_EXPORT JustInTime : public GeometryAdapter { Q_OBJECT public: explicit JustInTime(Viewport *parent = nullptr); virtual ~JustInTime(); Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; }; } + +#endif diff --git a/src/strategies/proxy.h b/src/strategies/proxy.h index 59a84e0..c012408 100644 --- a/src/strategies/proxy.h +++ b/src/strategies/proxy.h @@ -1,39 +1,42 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_PROXY_H +#define KQUICKITEMVIEWS_PROXY_H class Viewport; #include namespace GeometryStrategies { /** * */ class Q_DECL_EXPORT Proxy : public GeometryAdapter { Q_OBJECT public: explicit Proxy(Viewport *parent = nullptr); virtual ~Proxy(); Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; }; } + +#endif diff --git a/src/strategies/role.h b/src/strategies/role.h index 79d2677..713b457 100644 --- a/src/strategies/role.h +++ b/src/strategies/role.h @@ -1,56 +1,59 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_ROLE_H +#define KQUICKITEMVIEWS_ROLE_H #include class Viewport; class RoleStrategiesPrivate; namespace GeometryStrategies { /** * A GeometryAdapter to use size hints provided by the model as a role. */ class Q_DECL_EXPORT Role : public GeometryAdapter { Q_OBJECT public: explicit Role(Viewport *parent = nullptr); virtual ~Role(); Q_PROPERTY(int role READ role WRITE setRole NOTIFY roleChanged) Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleChanged) int role() const; void setRole(int role); QString roleName() const; void setRoleName(const QString& roleName); Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; Q_SIGNALS: void roleChanged(); private: RoleStrategiesPrivate *d_ptr; }; } + +#endif diff --git a/src/strategies/uniform.h b/src/strategies/uniform.h index b4d9e3d..a3abd8c 100644 --- a/src/strategies/uniform.h +++ b/src/strategies/uniform.h @@ -1,39 +1,42 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_UNIFORM_H +#define KQUICKITEMVIEWS_UNIFORM_H #include class Viewport; namespace GeometryStrategies { /** * */ class Q_DECL_EXPORT Uniform : public GeometryAdapter { Q_OBJECT public: explicit Uniform(Viewport *parent = nullptr); virtual ~Uniform(); Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; }; } + +#endif diff --git a/src/viewbase.h b/src/viewbase.h index 07fc362..18dd203 100644 --- a/src/viewbase.h +++ b/src/viewbase.h @@ -1,104 +1,108 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef VIEWBASE_H +#define VIEWBASE_H -#include +// KQuickItemViews +#include // Qt #include #include class QQmlComponent; // KQuickItemViews class ViewBasePrivate; class AbstractItemAdapter; class ModelAdapter; class Viewport; /** * Second generation of QtQuick treeview. * * The first one was designed for the chat view. It had a limited number of * requirement when it came to QtModel. However it required total control of * the layout. * * This is the opposite use case. The layout is classic, but the model support * has to be complete. Performance and lazy loading is also more important. * * It require less work to write a new treeview than refector the first one to * support the additional requirements. In the long run, the first generation * could be folded into this widget (if it ever makes sense, otherwise they will * keep diverging). */ class Q_DECL_EXPORT ViewBase : public Flickable { Q_OBJECT public: struct ItemFactoryBase { virtual AbstractItemAdapter* create(Viewport* r) const = 0; virtual ~ItemFactoryBase() {} }; template struct ItemFactory final : public ItemFactoryBase { virtual AbstractItemAdapter* create(Viewport* r) const override { return new T(r); } }; Q_PROPERTY(bool empty READ isEmpty NOTIFY contentChanged) Q_PROPERTY(Qt::Corner gravity READ gravity WRITE setGravity) Qt::Corner gravity() const; void setGravity(Qt::Corner g); explicit ViewBase(QQuickItem* parent = nullptr); virtual ~ViewBase(); QVector modelAdapters() const; bool isEmpty() const; protected: virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; /// To be used with moderation. Necessary when the delegate is replaced. void reload(); /** * Extend this function when tasks need to be taken care of when an * exlicit refresh is needed. Remember to call the parent class * ::refresh() from the extended one. * * It is called, for example, when the model change. */ virtual void refresh() final; void addModelAdapter(ModelAdapter* a); void removeModelAdapter(ModelAdapter* a); Q_SIGNALS: void contentChanged(); private: ViewBasePrivate* d_ptr; Q_DECLARE_PRIVATE(ViewBase) }; Q_DECLARE_METATYPE(QSharedPointer) + +#endif diff --git a/src/viewport.h b/src/viewport.h index 2d31ee9..47bc9c1 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -1,78 +1,81 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef KQUICKITEMVIEWS_VIEWPORT_H +#define KQUICKITEMVIEWS_VIEWPORT_H // Qt #include #include // KQuickItemViews #include class ViewportPrivate; class ViewportSync; class AbstractItemAdapter; /** * This class exposes a way to track and iterate a subset of the model. * * It prevents all of the model reflection to have to be loaded in memory * and offers a simpler API to access the loaded sections. * * This class is for internal use and should not be used by views. Please use * `ViewBase` for all relevant use cases. */ class Q_DECL_EXPORT Viewport : public QObject { friend class AbstractItemAdapter; // for the getters defined in viewport.cpp friend class ViewportSync; // its own internal API Q_OBJECT public: explicit Viewport(ModelAdapter* ma); virtual ~Viewport(); /** * Get the current (cartesian) rectangle represented by this range. */ QRectF currentRect() const; //SizeHintStrategy sizeHintStrategy() const; //void setSizeHintStrategy(SizeHintStrategy s); ModelAdapter *modelAdapter() const; QSizeF size() const; QPointF position() const; QSizeF totalSize() const; Qt::Edges availableEdges() const; void setItemFactory(ViewBase::ItemFactoryBase *factory); void resize(const QRectF& rect); ViewportSync *s_ptr; Q_SIGNALS: void contentChanged(); public: ViewportPrivate *d_ptr; }; + +#endif diff --git a/src/views/comboboxview.h b/src/views/comboboxview.h index e187084..a073a2a 100644 --- a/src/views/comboboxview.h +++ b/src/views/comboboxview.h @@ -1,45 +1,48 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef COMBOBOXVIEW_H +#define COMBOBOXVIEW_H // Qt #include #include class ComboBoxViewPrivate; /** * Extended QtQuickControls2 ComboBox with proper selection model support. */ class Q_DECL_EXPORT ComboBoxView : public QQuickItem { Q_OBJECT public: Q_PROPERTY(QItemSelectionModel* selectionModel READ selectionModel WRITE setSelectionModel) explicit ComboBoxView(QQuickItem* parent = nullptr); virtual ~ComboBoxView(); QItemSelectionModel* selectionModel() const; void setSelectionModel(QItemSelectionModel* s); private: ComboBoxViewPrivate* d_ptr; Q_DECLARE_PRIVATE(ComboBoxView) }; // Q_DECLARE_METATYPE(ComboBoxView*) + +#endif diff --git a/src/views/flickable.h b/src/views/flickable.h index 2e01c9c..3275a9f 100644 --- a/src/views/flickable.h +++ b/src/views/flickable.h @@ -1,104 +1,107 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef FLICKABLE_H +#define FLICKABLE_H #include class FlickablePrivate; /** * This file re-implements the flickable view. * * It is necessary to avoid a dependency on Qt private APIs in order to * re-implement higher level views such as the tree view. The upstream code * could also hardly have been copy/pasted in this project as it depends on * yet more hidden APIs and the code (along with dependencies) is over an order * or magnitude larger than this implementation. It would have been a * maintainability nightmare. * * This implementation is API compatible with a small subset of the Flickable * properties and uses a 200 lines of code inertial state machine instead of * 1.5k line of vomit code to do the exact same job. */ class Q_DECL_EXPORT Flickable : public QQuickItem { Q_OBJECT public: // Implement some of the QtQuick2.Flickable API Q_PROPERTY(qreal contentY READ currentY WRITE setCurrentY NOTIFY currentYChanged) Q_PROPERTY(qreal contentHeight READ contentHeight NOTIFY contentHeightChanged ) Q_PROPERTY(bool dragging READ isDragging NOTIFY draggingChanged) Q_PROPERTY(bool flicking READ isDragging NOTIFY movingChanged) Q_PROPERTY(bool moving READ isDragging NOTIFY movingChanged) Q_PROPERTY(bool movingHorizontally READ isDragging NOTIFY movingChanged) Q_PROPERTY(bool draggingHorizontally READ isDragging NOTIFY draggingChanged) Q_PROPERTY(bool flickingHorizontally READ isDragging NOTIFY movingChanged) Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration) Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive) Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity) /** * The geometry of the content subset currently displayed be the Flickable. * * It is usually {0, currentY, height, width}. */ Q_PROPERTY(QRectF viewport READ viewport NOTIFY viewportChanged) explicit Flickable(QQuickItem* parent = nullptr); virtual ~Flickable(); qreal currentY() const; virtual void setCurrentY(qreal y); QRectF viewport() const; qreal contentHeight() const; QQuickItem* contentItem(); bool isDragging() const; bool isMoving() const; qreal flickDeceleration() const; void setFlickDeceleration(qreal v); bool isInteractive() const; void setInteractive(bool v); qreal maximumFlickVelocity() const; void setMaximumFlickVelocity(qreal v); QQmlContext* rootContext() const; Q_SIGNALS: void contentHeightChanged(qreal height); void currentYChanged(qreal y); void percentageChanged(qreal percent); void draggingChanged(bool dragging); void movingChanged(bool dragging); void viewportChanged(const QRectF &view); protected: bool event(QEvent *ev) override; bool childMouseEventFilter(QQuickItem *, QEvent *) override; void geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) override; private: FlickablePrivate* d_ptr; Q_DECLARE_PRIVATE(Flickable) }; + +#endif diff --git a/src/views/hierarchyview.h b/src/views/hierarchyview.h index 0dffa3b..66c0245 100644 --- a/src/views/hierarchyview.h +++ b/src/views/hierarchyview.h @@ -1,55 +1,57 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef HIERARCHYVIEW_H +#define HIERARCHYVIEW_H -#include +// KQuickItemViews +#include +class HierarchyViewPrivate; // Qt class QQuickItem; -// KQuickItemViews -class HierarchyViewPrivate; - /** * Second generation of QtQuick treeview. * * The first one was designed for the chat view. It had a limited number of * requirements when it came to QtModel. However it required total control of * the layout. * * This is the opposite use case. The layout is classic, but the model support * has to be complete. Performance and lazy loading is also more important. * * It require less work to write a new treeview than refector the first one to * support the additional requirements. In the long run, the first generation * could be folded into this widget (if it ever makes sense, otherwise they will * keep diverging). */ class Q_DECL_EXPORT HierarchyView : public SingleModelViewBase { Q_OBJECT friend class HierarchyViewItem; public: explicit HierarchyView(QQuickItem* parent = nullptr); virtual ~HierarchyView(); private: HierarchyViewPrivate* d_ptr; Q_DECLARE_PRIVATE(HierarchyView) }; + +#endif diff --git a/src/views/indexview.h b/src/views/indexview.h index e431929..c56c0f5 100644 --- a/src/views/indexview.h +++ b/src/views/indexview.h @@ -1,68 +1,71 @@ /*************************************************************************** * Copyright (C) 2018 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 . * **************************************************************************/ -#pragma once +#ifndef INDEXVIEW_H +#define INDEXVIEW_H #include #include class QAbstractItemModel; class IndexViewPrivate; /** * This view has a single delegate instance and display data for a single * QModelIndex. * * This is useful for mobile application pages to get more information out of * a list item. It allows for more compact list while avoiding the boilerplate * of having a non-model component. * * It can also be used to create the equivalent of "editor widgets" from the * QtWidgets era. * * The IndexView will take the implicit width and height of the component * unless it is resized or in a managed layout, where it will resize the * delegate. */ class Q_DECL_EXPORT IndexView : public QQuickItem { Q_OBJECT public: explicit IndexView(QQuickItem *parent = nullptr); virtual ~IndexView(); Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(QModelIndex modelIndex READ modelIndex WRITE setModelIndex NOTIFY indexChanged) Q_PROPERTY(QAbstractItemModel* model READ model NOTIFY indexChanged) virtual void setDelegate(QQmlComponent* delegate); QQmlComponent* delegate() const; QAbstractItemModel *model() const; QModelIndex modelIndex() const; void setModelIndex(const QModelIndex &index); Q_SIGNALS: void delegateChanged(QQmlComponent* delegate); void indexChanged(); private: IndexViewPrivate *d_ptr; Q_DECLARE_PRIVATE(IndexView) }; + +#endif diff --git a/src/views/listview.h b/src/views/listview.h index 5161dd4..ab89644 100644 --- a/src/views/listview.h +++ b/src/views/listview.h @@ -1,118 +1,120 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once - -#include - -// Qt -class QQuickItem; +#ifndef LISTVIEW_H +#define LISTVIEW_H // KQuickItemViews +#include class ListViewPrivate; class ListView; +// Qt +class QQuickItem; + /** * Equivalent of the QtQuick.ListView.Section class to keep the API mostly * compatible. * * A section model can be set. If it does, this class doesn't do *any* check if * the section model matches the sections. It is entirely the responsibility of * the programmer to provide a valid/compatible model. */ class Q_DECL_EXPORT ListViewSections : public QObject { Q_OBJECT friend class ListView; public: Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate) Q_PROPERTY(QString property READ property WRITE setProperty) Q_PROPERTY(QStringList roles READ roles WRITE setRoles ) Q_PROPERTY(int role READ role ) Q_PROPERTY(QSharedPointer model READ model WRITE setModel) explicit ListViewSections(ListView* parent); virtual ~ListViewSections(); QQmlComponent* delegate() const; void setDelegate(QQmlComponent* component); QString property() const; void setProperty(const QString& property); QStringList roles() const; void setRoles(const QStringList& list); QSharedPointer model() const; void setModel(const QSharedPointer& m); int role() const; private: ListViewPrivate* d_ptr; }; Q_DECLARE_METATYPE(ListViewSections*) /** * Re-implementation of QtQuick.ListView. * * Why: * * * The original is not capable of generating a proper "table of content" and * scrollbar. * * The "section" support of the original system is limited to a single string, * this is useless for some use cases. * * The section didn't support getting the metadata, such as the number of * entries (lazy loaded, of course). * * Real drag and drop (QMimeData and models) are not supported * * Models are generally badly supported. * * The QtQuick.ListView is remotely close enough to a drop-in replacement for * QtWidgets::QListView. Stable and mature models should not require modifications * to acknowledge misguided QtQuick.ListView changes. */ class Q_DECL_EXPORT ListView : public SingleModelViewBase { Q_OBJECT friend class ListViewItem; friend class ListViewSections; public: Q_PROPERTY(ListViewSections* section READ section CONSTANT) Q_PROPERTY(int count READ count /*NOTIFY contentChanged*/) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY indexChanged) explicit ListView(QQuickItem* parent = nullptr); virtual ~ListView(); ListViewSections* section() const; int count() const; int currentIndex() const; void setCurrentIndex(int index); Q_SIGNALS: void indexChanged(int index); private: ListViewPrivate* d_ptr; Q_DECLARE_PRIVATE(ListView) }; + +#endif diff --git a/src/views/treeview.h b/src/views/treeview.h index 7bebeb0..745eb36 100644 --- a/src/views/treeview.h +++ b/src/views/treeview.h @@ -1,55 +1,58 @@ /*************************************************************************** * 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 . * **************************************************************************/ -#pragma once +#ifndef TREEVIEW_H +#define TREEVIEW_H -#include +#include // Qt class QQuickItem; // KQuickItemViews class TreeViewPrivate; /** * Second generation of QtQuick treeview. * * The first one was designed for the chat view. It had a limited number of * requirements when it came to QtModel. However it required total control of * the layout. * * This is the opposite use case. The layout is classic, but the model support * has to be complete. Performance and lazy loading is also more important. * * It require less work to write a new treeview than refector the first one to * support the additional requirements. In the long run, the first generation * could be folded into this widget (if it ever makes sense, otherwise they will * keep diverging). */ class Q_DECL_EXPORT TreeView : public SingleModelViewBase { Q_OBJECT friend class TreeViewItem; public: explicit TreeView(QQuickItem* parent = nullptr); virtual ~TreeView(); private: TreeViewPrivate* d_ptr; Q_DECLARE_PRIVATE(TreeView) }; + +#endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6a58a9d..adba5be 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,54 +1,54 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.1) ADD_DEFINITIONS("-std=c++11") PROJECT(modelviewtester) SET(QT_MIN_VERSION "5.7.0") SET(KF5_DEP_VERSION "5.50.0" ) set(CMAKE_BUILD_TYPE DEBUG) option(BUILD_COVERAGE ON) IF(POLICY CMP0063) CMAKE_POLICY(SET CMP0063 NEW) ENDIF(POLICY CMP0063) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Quick QuickWidgets Widgets QuickControls2 ) # Kirigami is used for the menu and manual testing steps find_package(KF5 "${KF5_DEP_VERSION}" REQUIRED COMPONENTS Kirigami2 ) INCLUDE_DIRECTORIES(SYSTEM ${Qt5Core_INCLUDES}) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/qmlwidgets/) -INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) +# INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/qmlwidgets/) +# INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) SET(modelviewtester_SRC modelviewtester.cpp testmain.cpp ) QT5_ADD_RESOURCES(modelviewtester_SRC modeltest.qrc ) set(CMAKE_AUTOMOC ON) ADD_EXECUTABLE( modelviewtester ${modelviewtester_SRC} ) TARGET_LINK_LIBRARIES( modelviewtester - kquickview + kquickitemviews KF5::Kirigami2 Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Quick ) diff --git a/tests/testmain.cpp b/tests/testmain.cpp index 933fa80..9770e35 100644 --- a/tests/testmain.cpp +++ b/tests/testmain.cpp @@ -1,60 +1,60 @@ /*************************************************************************** * 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 . * **************************************************************************/ //Qt #include #include #include #include #include #include #include #include #include "modelviewtester.h" -#include -#include -#include +#include +#include +#include int main(int argc, char **argv) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; qmlRegisterType("RingQmlWidgets", 1, 0, "ModelViewTester"); qmlRegisterType("RingQmlWidgets", 1, 0, "HierarchyView"); qmlRegisterType("RingQmlWidgets", 1, 0, "QuickTreeView"); qmlRegisterType("RingQmlWidgets", 1, 0, "QuickListView"); // view.setResizeMode(QQuickView::SizeRootObjectToView); engine.load(QUrl("qrc:///modeltest.qml")); if (engine.rootObjects().isEmpty()) { qDebug() << "\n\nFAILED TO LOAD"; return -1; } return app.exec(); } #include