1 /*
2  * tilesetwangsetmodel.cpp
3  * Copyright 2017, Benjamin Trotter <bdtrotte@ucsc.edu>
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 "tilesetwangsetmodel.h"
22 
23 #include "changeevents.h"
24 #include "changewangsetdata.h"
25 #include "tile.h"
26 #include "tileset.h"
27 #include "tilesetdocument.h"
28 #include "wangoverlay.h"
29 #include "wangset.h"
30 
31 using namespace Tiled;
32 
TilesetWangSetModel(TilesetDocument * tilesetDocument,QObject * parent)33 TilesetWangSetModel::TilesetWangSetModel(TilesetDocument *tilesetDocument,
34                                          QObject *parent):
35     QAbstractListModel(parent),
36     mTilesetDocument(tilesetDocument)
37 {
38 }
39 
~TilesetWangSetModel()40 TilesetWangSetModel::~TilesetWangSetModel()
41 {
42 }
43 
index(WangSet * wangSet)44 QModelIndex TilesetWangSetModel::index(WangSet *wangSet)
45 {
46     Tileset *tileset = wangSet->tileset();
47     int row = tileset->wangSets().indexOf(wangSet);
48 
49     return index(row, 0);
50 }
51 
rowCount(const QModelIndex & parent) const52 int TilesetWangSetModel::rowCount(const QModelIndex &parent) const
53 {
54     if (!parent.isValid())
55         return mTilesetDocument->tileset()->wangSetCount();
56 
57     return 0;
58 }
59 
columnCount(const QModelIndex & parent) const60 int TilesetWangSetModel::columnCount(const QModelIndex &parent) const
61 {
62     Q_UNUSED(parent)
63     return 1;
64 }
65 
66 
data(const QModelIndex & index,int role) const67 QVariant TilesetWangSetModel::data(const QModelIndex &index, int role) const
68 {
69     if (WangSet *wangSet = wangSetAt(index)) {
70         switch (role) {
71         case Qt::DisplayRole:
72         case Qt::EditRole:
73             return wangSet->name();
74         case Qt::DecorationRole:
75             if (Tile *imageTile = wangSet->imageTile())
76                 return imageTile->image();
77             else
78                 return wangSetIcon(wangSet->type());
79             break;
80         case WangSetRole:
81             return QVariant::fromValue(wangSet);
82         case TilesetDocumentRole:
83             return QVariant::fromValue(mTilesetDocument);
84         }
85     }
86 
87     return QVariant();
88 }
89 
setData(const QModelIndex & index,const QVariant & value,int role)90 bool TilesetWangSetModel::setData(const QModelIndex &index,
91                                   const QVariant &value,
92                                   int role)
93 {
94     if (role == Qt::EditRole) {
95         const QString newName = value.toString();
96         WangSet *wangSet = wangSetAt(index);
97         if (wangSet->name() != newName) {
98             RenameWangSet *rename = new RenameWangSet(mTilesetDocument,
99                                                       wangSet,
100                                                       newName);
101             mTilesetDocument->undoStack()->push(rename);
102         }
103         return true;
104     }
105 
106     return false;
107 }
108 
flags(const QModelIndex & index) const109 Qt::ItemFlags TilesetWangSetModel::flags(const QModelIndex &index) const
110 {
111     Qt::ItemFlags rc = QAbstractItemModel::flags(index);
112     if (index.isValid())  // can edit wangSet names
113         rc |= Qt::ItemIsEditable;
114     return rc;
115 }
116 
wangSetAt(const QModelIndex & index) const117 WangSet *TilesetWangSetModel::wangSetAt(const QModelIndex &index) const
118 {
119     if (index.isValid())
120         return mTilesetDocument->tileset()->wangSet(index.row());
121 
122     return nullptr;
123 }
124 
insertWangSet(int index,std::unique_ptr<WangSet> wangSet)125 void TilesetWangSetModel::insertWangSet(int index, std::unique_ptr<WangSet> wangSet)
126 {
127     Tileset *tileset = mTilesetDocument->tileset().data();
128 
129     emit mTilesetDocument->changed(WangSetEvent(ChangeEvent::WangSetAboutToBeAdded, tileset, index));
130 
131     beginInsertRows(QModelIndex(), index, index);
132     tileset->insertWangSet(index, std::move(wangSet));
133     endInsertRows();
134 
135     emit mTilesetDocument->changed(WangSetEvent(ChangeEvent::WangSetAdded, tileset, index));
136     emit wangSetAdded(tileset, index);
137 }
138 
takeWangSetAt(int index)139 std::unique_ptr<WangSet> TilesetWangSetModel::takeWangSetAt(int index)
140 {
141     Tileset *tileset = mTilesetDocument->tileset().data();
142 
143     emit mTilesetDocument->changed(WangSetEvent(ChangeEvent::WangSetAboutToBeRemoved, tileset, index));
144 
145     beginRemoveRows(QModelIndex(), index, index);
146     std::unique_ptr<WangSet> wangSet = tileset->takeWangSetAt(index);
147     endRemoveRows();
148 
149     emit mTilesetDocument->changed(WangSetEvent(ChangeEvent::WangSetRemoved, tileset, index));
150     emit wangSetRemoved(wangSet.get());
151 
152     return wangSet;
153 }
154 
setWangSetName(WangSet * wangSet,const QString & name)155 void TilesetWangSetModel::setWangSetName(WangSet *wangSet, const QString &name)
156 {
157     Q_ASSERT(wangSet->tileset() == mTilesetDocument->tileset().data());
158     wangSet->setName(name);
159     emitWangSetChange(wangSet);
160 }
161 
setWangSetType(WangSet * wangSet,WangSet::Type type)162 void TilesetWangSetModel::setWangSetType(WangSet *wangSet, WangSet::Type type)
163 {
164     Q_ASSERT(wangSet->tileset() == mTilesetDocument->tileset().data());
165     wangSet->setType(type);
166     emit mTilesetDocument->changed(WangSetChangeEvent(wangSet, WangSetChangeEvent::TypeProperty));
167 }
168 
setWangSetColorCount(WangSet * wangSet,int value)169 void TilesetWangSetModel::setWangSetColorCount(WangSet *wangSet, int value)
170 {
171     Q_ASSERT(wangSet->tileset() == mTilesetDocument->tileset().data());
172     wangSet->setColorCount(value);
173     emitWangSetChange(wangSet);
174 }
175 
setWangSetImage(WangSet * wangSet,int tileId)176 void TilesetWangSetModel::setWangSetImage(WangSet *wangSet, int tileId)
177 {
178     Q_ASSERT(wangSet->tileset() == mTilesetDocument->tileset().data());
179     wangSet->setImageTileId(tileId);
180     emitWangSetChange(wangSet);
181 }
182 
insertWangColor(WangSet * wangSet,const QSharedPointer<WangColor> & wangColor)183 void TilesetWangSetModel::insertWangColor(WangSet *wangSet, const QSharedPointer<WangColor> &wangColor)
184 {
185     Q_ASSERT(wangSet->tileset() == mTilesetDocument->tileset().data());
186     wangSet->insertWangColor(wangColor);
187     emitWangSetChange(wangSet);
188 }
189 
takeWangColorAt(WangSet * wangSet,int color)190 QSharedPointer<WangColor> TilesetWangSetModel::takeWangColorAt(WangSet *wangSet, int color)
191 {
192     Q_ASSERT(wangSet->tileset() == mTilesetDocument->tileset().data());
193     emit mTilesetDocument->changed(WangColorEvent(ChangeEvent::WangColorAboutToBeRemoved, wangSet, color));
194     auto wangColor = wangSet->takeWangColorAt(color);
195     emit wangColorRemoved(wangColor.data());
196     emitWangSetChange(wangSet);
197     return wangColor;
198 }
199 
emitWangSetChange(WangSet * wangSet)200 void TilesetWangSetModel::emitWangSetChange(WangSet *wangSet)
201 {
202     const QModelIndex index = TilesetWangSetModel::index(wangSet);
203     emit dataChanged(index, index);
204     emit wangSetChanged(wangSet->tileset(), index.row());
205 }
206 
207 #include "moc_tilesetwangsetmodel.cpp"
208