Warning, file /graphics/glaxnimate/src/gui/item_models/proxy_base.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 
0007 #pragma once
0008 #include <QIdentityProxyModel>
0009 #include "document_model_base.hpp"
0010 
0011 namespace glaxnimate::gui::item_models {
0012 
0013 namespace detail {
0014 
0015 template<class T>
0016 inline std::enable_if_t<!std::is_same_v<std::decay_t<T>, QModelIndex>, T>
0017 forward(const QAbstractProxyModel*, T v)
0018 {
0019     return v;
0020 }
0021 
0022 template<class T>
0023 inline std::enable_if_t<std::is_same_v<std::decay_t<T>, QModelIndex>, QModelIndex>
0024 forward(const QAbstractProxyModel* proxy, T v)
0025 {
0026     return proxy->mapFromSource(v);
0027 }
0028 
0029 
0030 template<class T>
0031 inline std::enable_if_t<!std::is_same_v<std::decay_t<T>, QModelIndex>, T>
0032 reverse(const QAbstractProxyModel*, T v)
0033 {
0034     return v;
0035 }
0036 
0037 template<class T>
0038 inline std::enable_if_t<std::is_same_v<std::decay_t<T>, QModelIndex>, QModelIndex>
0039 reverse(const QAbstractProxyModel* proxy, T v)
0040 {
0041     return proxy->mapToSource(v);
0042 }
0043 
0044 } // namespace detail
0045 
0046 class ProxyBase : public QIdentityProxyModel
0047 {
0048 public:
0049     using QIdentityProxyModel::QIdentityProxyModel;
0050 
0051     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
0052     {
0053         return forward_impl<QModelIndex>(&QAbstractItemModel::index, row, column, parent);
0054     }
0055 
0056     QModelIndex parent(const QModelIndex &child) const override
0057     {
0058         return forward_impl<QModelIndex>(&QAbstractItemModel::parent, child);
0059     }
0060 
0061     int rowCount(const QModelIndex &parent = QModelIndex()) const override
0062     {
0063         return forward_impl<int>(&QAbstractItemModel::rowCount, parent);
0064     }
0065 
0066     int columnCount(const QModelIndex &parent = QModelIndex()) const override
0067     {
0068         return forward_impl<int>(&QAbstractItemModel::columnCount, parent);
0069     }
0070 
0071 protected:
0072     // Qt cheats by befriending the proxy models... so we need to cheat too
0073     DocumentModelBase* friendly_model() const
0074     {
0075         return static_cast<DocumentModelBase*>(sourceModel());
0076     }
0077 
0078     QModelIndex create_source_index(int row, int column, quintptr id) const
0079     {
0080         return friendly_model()->createIndex(row, column, id);
0081     }
0082 
0083     template<class Signal, class Derived, class Ret, class... Args>
0084     void reconnect(Signal func, Ret (Derived::*slot)(Args...))
0085     {
0086         disconnect(sourceModel(), func, this, nullptr);
0087         connect(sourceModel(), func, static_cast<Derived*>(this), slot);
0088     }
0089 
0090 private:
0091     template<class Ret, class... Args, class... ActualArgs>
0092     Ret forward_impl(Ret (QAbstractItemModel::*method)(Args...) const, ActualArgs... args) const
0093     {
0094         return detail::forward<Ret>(this, (sourceModel()->*method)(detail::reverse<Args>(this, args)...));
0095     }
0096 };
0097 
0098 } // namespace glaxnimate::gui::item_models