1 /*
2  * tilesetdocumentsmodel.cpp
3  * Copyright 2017, Thorbjørn Lindeijer <bjorn@lindeijer.nl>
4  *
5  * This file is part of Tiled.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "tilesetdocumentsmodel.h"
22 
23 #include "documentmanager.h"
24 #include "mapdocument.h"
25 #include "tilesetdocument.h"
26 #include "tileset.h"
27 
28 #include <algorithm>
29 
30 namespace Tiled {
31 
TilesetDocumentsModel(QObject * parent)32 TilesetDocumentsModel::TilesetDocumentsModel(QObject *parent)
33     : QAbstractListModel(parent)
34 {
35 }
36 
rowCount(const QModelIndex & parent) const37 int TilesetDocumentsModel::rowCount(const QModelIndex &parent) const
38 {
39     return parent.isValid() ? 0 : mTilesetDocuments.size();
40 }
41 
data(const QModelIndex & index,int role) const42 QVariant TilesetDocumentsModel::data(const QModelIndex &index, int role) const
43 {
44     const auto &document = mTilesetDocuments.at(index.row());
45 
46     switch (role) {
47     case TilesetDocumentRole:
48         return QVariant::fromValue(document.data());
49     case TilesetRole:
50         return QVariant::fromValue(document->tileset());
51     case Qt::DisplayRole:
52         return document->tileset()->name();
53     case Qt::ToolTipRole:
54         return document->fileName();
55     }
56 
57     return QVariant();
58 }
59 
insert(int index,TilesetDocument * tilesetDocument)60 void TilesetDocumentsModel::insert(int index, TilesetDocument *tilesetDocument)
61 {
62     beginInsertRows(QModelIndex(), index, index);
63     mTilesetDocuments.insert(index, tilesetDocument->sharedFromThis());
64     endInsertRows();
65 
66     connect(tilesetDocument, &TilesetDocument::tilesetNameChanged,
67             this, &TilesetDocumentsModel::tilesetNameChanged);
68     connect(tilesetDocument, &TilesetDocument::fileNameChanged,
69             this, &TilesetDocumentsModel::tilesetFileNameChanged);
70 }
71 
remove(int index)72 void TilesetDocumentsModel::remove(int index)
73 {
74     beginRemoveRows(QModelIndex(), index, index);
75     auto tilesetDocument = mTilesetDocuments.takeAt(index);
76     endRemoveRows();
77 
78     tilesetDocument->disconnect(this);
79 }
80 
tilesetNameChanged(Tileset * tileset)81 void TilesetDocumentsModel::tilesetNameChanged(Tileset *tileset)
82 {
83     for (int i = 0; i < mTilesetDocuments.size(); ++i) {
84         const auto &doc = mTilesetDocuments.at(i);
85         if (doc->tileset() == tileset) {
86             const QModelIndex dataIndex = index(i, 0, QModelIndex());
87             emit dataChanged(dataIndex, dataIndex, { Qt::DisplayRole });
88             break;
89         }
90     }
91 }
92 
tilesetFileNameChanged()93 void TilesetDocumentsModel::tilesetFileNameChanged()
94 {
95     TilesetDocument *tilesetDocument = static_cast<TilesetDocument*>(sender());
96     for (int i = 0; i < mTilesetDocuments.size(); ++i) {
97         if (mTilesetDocuments.at(i) == tilesetDocument) {
98             const QModelIndex dataIndex = index(i, 0, QModelIndex());
99             emit dataChanged(dataIndex, dataIndex, { Qt::ToolTipRole });
100             break;
101         }
102     }
103 }
104 
105 
TilesetDocumentsFilterModel(QObject * parent)106 TilesetDocumentsFilterModel::TilesetDocumentsFilterModel(QObject *parent)
107     : QSortFilterProxyModel(parent)
108     , mMapDocument(nullptr)
109 {
110     setSortLocaleAware(true);
111     setSourceModel(DocumentManager::instance()->tilesetDocumentsModel());
112     sort(0);
113 }
114 
setMapDocument(MapDocument * mapDocument)115 void TilesetDocumentsFilterModel::setMapDocument(MapDocument *mapDocument)
116 {
117     if (mMapDocument == mapDocument)
118         return;
119 
120     mMapDocument = mapDocument;
121     invalidateFilter();
122 }
123 
filterAcceptsRow(int sourceRow,const QModelIndex & sourceParent) const124 bool TilesetDocumentsFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
125 {
126     const auto sm = sourceModel();
127     const auto index = sm->index(sourceRow, 0, sourceParent);
128     const QVariant variant = sm->data(index, TilesetDocumentsModel::TilesetDocumentRole);
129     const TilesetDocument *tilesetDocument = variant.value<TilesetDocument *>();
130     Q_ASSERT(tilesetDocument);
131 
132     const bool accepted = !tilesetDocument->isEmbedded()
133             || tilesetDocument->mapDocuments().first() == mMapDocument;
134     return accepted;
135 }
136 
137 } // namespace Tiled
138