1 /* This file is part of Clementine. 2 Copyright 2010-2011, David Sansome <davidsansome@gmail.com> 3 Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com> 4 Copyright 2014, John Maguire <john.maguire@gmail.com> 5 6 Clementine is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 Clementine is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with Clementine. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef CORE_MERGEDPROXYMODEL_H_ 21 #define CORE_MERGEDPROXYMODEL_H_ 22 23 #include <memory> 24 25 #include <QAbstractProxyModel> 26 27 std::size_t hash_value(const QModelIndex& index); 28 29 class MergedProxyModelPrivate; 30 31 class MergedProxyModel : public QAbstractProxyModel { 32 Q_OBJECT 33 34 public: 35 explicit MergedProxyModel(QObject* parent = nullptr); 36 ~MergedProxyModel(); 37 38 // Make another model appear as a child of the given item in the source model. 39 void AddSubModel(const QModelIndex& source_parent, 40 QAbstractItemModel* submodel); 41 void RemoveSubModel(const QModelIndex& source_parent); 42 43 // Find the item in the source model that is the parent of the model 44 // containing proxy_index. If proxy_index is in the source model, then 45 // this just returns mapToSource(proxy_index). 46 QModelIndex FindSourceParent(const QModelIndex& proxy_index) const; 47 48 // QAbstractItemModel 49 QModelIndex index(int row, int column, const QModelIndex& parent) const; 50 QModelIndex parent(const QModelIndex& child) const; 51 int rowCount(const QModelIndex& parent) const; 52 int columnCount(const QModelIndex& parent) const; 53 QVariant data(const QModelIndex& proxyIndex, 54 int role = Qt::DisplayRole) const; 55 bool hasChildren(const QModelIndex& parent) const; 56 QMap<int, QVariant> itemData(const QModelIndex& proxyIndex) const; 57 Qt::ItemFlags flags(const QModelIndex& index) const; 58 bool setData(const QModelIndex& index, const QVariant& value, int role); 59 QStringList mimeTypes() const; 60 QMimeData* mimeData(const QModelIndexList& indexes) const; 61 bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, 62 int column, const QModelIndex& parent); 63 bool canFetchMore(const QModelIndex& parent) const; 64 void fetchMore(const QModelIndex& parent); 65 66 // QAbstractProxyModel 67 // Note that these implementations of map{To,From}Source will not always 68 // give you an index in sourceModel(), you might get an index in one of the 69 // child models instead. 70 QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; 71 QModelIndex mapToSource(const QModelIndex& proxyIndex) const; 72 void setSourceModel(QAbstractItemModel* sourceModel); 73 74 // Convenience functions that call map{To,From}Source multiple times. 75 QModelIndexList mapFromSource(const QModelIndexList& source_indexes) const; 76 QModelIndexList mapToSource(const QModelIndexList& proxy_indexes) const; 77 78 signals: 79 void SubModelReset(const QModelIndex& root, QAbstractItemModel* model); 80 81 private slots: 82 void SourceModelReset(); 83 void SubModelReset(); 84 85 void RowsAboutToBeInserted(const QModelIndex& source_parent, int start, 86 int end); 87 void RowsInserted(const QModelIndex& source_parent, int start, int end); 88 void RowsAboutToBeRemoved(const QModelIndex& source_parent, int start, 89 int end); 90 void RowsRemoved(const QModelIndex& source_parent, int start, int end); 91 void DataChanged(const QModelIndex& top_left, 92 const QModelIndex& bottom_right); 93 94 void LayoutAboutToBeChanged(); 95 void LayoutChanged(); 96 97 private: 98 QModelIndex GetActualSourceParent(const QModelIndex& source_parent, 99 QAbstractItemModel* model) const; 100 QAbstractItemModel* GetModel(const QModelIndex& source_index) const; 101 void DeleteAllMappings(); 102 bool IsKnownModel(const QAbstractItemModel* model) const; 103 104 QMap<QAbstractItemModel*, QPersistentModelIndex> merge_points_; 105 QAbstractItemModel* resetting_model_; 106 107 QMap<QAbstractItemModel*, QModelIndex> old_merge_points_; 108 109 std::unique_ptr<MergedProxyModelPrivate> p_; 110 }; 111 112 #endif // CORE_MERGEDPROXYMODEL_H_ 113