1 /*
2  *  Copyright (c) 2015 Dmitry Kazakov <dimula73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "kis_asl_callback_object_catcher.h"
20 
21 #include <QHash>
22 
23 #include <QString>
24 #include <QPointF>
25 #include <QColor>
26 
27 #include "kis_debug.h"
28 
29 typedef QHash<QString, ASLCallbackDouble> MapHashDouble;
30 typedef QHash<QString, ASLCallbackInteger> MapHashInt;
31 
32 struct EnumMapping {
EnumMappingEnumMapping33     EnumMapping(const QString &_typeId, ASLCallbackString _map)
34         : typeId(_typeId),
35           map(_map)
36         {
37         }
38 
39     QString typeId;
40     ASLCallbackString map;
41 };
42 
43 typedef QHash<QString, EnumMapping> MapHashEnum;
44 
45 struct UnitFloatMapping {
UnitFloatMappingUnitFloatMapping46     UnitFloatMapping(const QString &_unit, ASLCallbackDouble _map)
47         : unit(_unit),
48           map(_map)
49         {
50         }
51 
52     QString unit;
53     ASLCallbackDouble map;
54 };
55 
56 typedef QHash<QString, UnitFloatMapping> MapHashUnitFloat;
57 
58 typedef QHash<QString, ASLCallbackString> MapHashText;
59 typedef QHash<QString, ASLCallbackBoolean> MapHashBoolean;
60 typedef QHash<QString, ASLCallbackColor> MapHashColor;
61 typedef QHash<QString, ASLCallbackPoint> MapHashPoint;
62 typedef QHash<QString, ASLCallbackCurve> MapHashCurve;
63 typedef QHash<QString, ASLCallbackPattern> MapHashPattern;
64 typedef QHash<QString, ASLCallbackPatternRef> MapHashPatternRef;
65 typedef QHash<QString, ASLCallbackGradient> MapHashGradient;
66 
67 struct KisAslCallbackObjectCatcher::Private
68 {
69     MapHashDouble mapDouble;
70     MapHashInt mapInteger;
71     MapHashEnum mapEnum;
72     MapHashUnitFloat mapUnitFloat;
73     MapHashText mapText;
74     MapHashBoolean mapBoolean;
75     MapHashColor mapColor;
76     MapHashPoint mapPoint;
77     MapHashCurve mapCurve;
78     MapHashPattern mapPattern;
79     MapHashPatternRef mapPatternRef;
80     MapHashGradient mapGradient;
81 
82     ASLCallbackNewStyle newStyleCallback;
83 };
84 
85 
KisAslCallbackObjectCatcher()86 KisAslCallbackObjectCatcher::KisAslCallbackObjectCatcher()
87     : m_d(new Private)
88 {
89 }
90 
~KisAslCallbackObjectCatcher()91 KisAslCallbackObjectCatcher::~KisAslCallbackObjectCatcher()
92 {
93 }
94 
95 template <class HashType, typename T>
passToCallback(const QString & path,const HashType & hash,const T & value)96 inline void passToCallback(const QString &path, const HashType &hash, const T &value)
97 {
98     typename HashType::const_iterator it = hash.constFind(path);
99     if (it != hash.constEnd()) {
100         (*it)(value);
101     }
102 }
103 
addDouble(const QString & path,double value)104 void KisAslCallbackObjectCatcher::addDouble(const QString &path, double value)
105 {
106     passToCallback(path, m_d->mapDouble, value);
107 }
108 
addInteger(const QString & path,int value)109 void KisAslCallbackObjectCatcher::addInteger(const QString &path, int value)
110 {
111     passToCallback(path, m_d->mapInteger, value);
112 }
113 
addEnum(const QString & path,const QString & typeId,const QString & value)114 void KisAslCallbackObjectCatcher::addEnum(const QString &path, const QString &typeId, const QString &value)
115 {
116     MapHashEnum::const_iterator it = m_d->mapEnum.constFind(path);
117     if (it != m_d->mapEnum.constEnd()) {
118         if (it->typeId == typeId) {
119             it->map(value);
120         } else {
121             warnKrita << "KisAslCallbackObjectCatcher::addEnum: inconsistent typeId"  << ppVar(typeId) << ppVar(it->typeId);
122         }
123     }
124 }
125 
addUnitFloat(const QString & path,const QString & unit,double value)126 void KisAslCallbackObjectCatcher::addUnitFloat(const QString &path, const QString &unit, double value)
127 {
128     MapHashUnitFloat::const_iterator it = m_d->mapUnitFloat.constFind(path);
129     if (it != m_d->mapUnitFloat.constEnd()) {
130         if (it->unit == unit) {
131             it->map(value);
132         } else {
133             warnKrita << "KisAslCallbackObjectCatcher::addUnitFloat: inconsistent unit"  << ppVar(unit) << ppVar(it->unit);
134         }
135     }
136 }
137 
addText(const QString & path,const QString & value)138 void KisAslCallbackObjectCatcher::addText(const QString &path, const QString &value)
139 {
140     passToCallback(path, m_d->mapText, value);
141 }
142 
addBoolean(const QString & path,bool value)143 void KisAslCallbackObjectCatcher::addBoolean(const QString &path, bool value)
144 {
145     passToCallback(path, m_d->mapBoolean, value);
146 }
147 
addColor(const QString & path,const QColor & value)148 void KisAslCallbackObjectCatcher::addColor(const QString &path, const QColor &value)
149 {
150     passToCallback(path, m_d->mapColor, value);
151 }
152 
addPoint(const QString & path,const QPointF & value)153 void KisAslCallbackObjectCatcher::addPoint(const QString &path, const QPointF &value)
154 {
155     passToCallback(path, m_d->mapPoint, value);
156 }
157 
addCurve(const QString & path,const QString & name,const QVector<QPointF> & points)158 void KisAslCallbackObjectCatcher::addCurve(const QString &path, const QString &name, const QVector<QPointF> &points)
159 {
160     MapHashCurve::const_iterator it = m_d->mapCurve.constFind(path);
161     if (it != m_d->mapCurve.constEnd()) {
162         (*it)(name, points);
163     }
164 }
165 
addPattern(const QString & path,const KoPattern * value)166 void KisAslCallbackObjectCatcher::addPattern(const QString &path, const KoPattern *value)
167 {
168     passToCallback(path, m_d->mapPattern, value);
169 }
170 
addPatternRef(const QString & path,const QString & patternUuid,const QString & patternName)171 void KisAslCallbackObjectCatcher::addPatternRef(const QString &path, const QString &patternUuid, const QString &patternName)
172 {
173     MapHashPatternRef::const_iterator it = m_d->mapPatternRef.constFind(path);
174     if (it != m_d->mapPatternRef.constEnd()) {
175         (*it)(patternUuid, patternName);
176     }
177 }
178 
addGradient(const QString & path,KoAbstractGradientSP value)179 void KisAslCallbackObjectCatcher::addGradient(const QString &path, KoAbstractGradientSP value)
180 {
181     passToCallback(path, m_d->mapGradient, value);
182 }
183 
newStyleStarted()184 void KisAslCallbackObjectCatcher::newStyleStarted()
185 {
186     if (m_d->newStyleCallback) {
187         m_d->newStyleCallback();
188     }
189 }
190 
191 /*****************************************************************/
192 /*      Subscription methods                                      */
193 /*****************************************************************/
194 
subscribeDouble(const QString & path,ASLCallbackDouble callback)195 void KisAslCallbackObjectCatcher::subscribeDouble(const QString &path, ASLCallbackDouble callback)
196 {
197     m_d->mapDouble.insert(path, callback);
198 }
199 
subscribeInteger(const QString & path,ASLCallbackInteger callback)200 void KisAslCallbackObjectCatcher::subscribeInteger(const QString &path, ASLCallbackInteger callback)
201 {
202     m_d->mapInteger.insert(path, callback);
203 }
204 
subscribeEnum(const QString & path,const QString & typeId,ASLCallbackString callback)205 void KisAslCallbackObjectCatcher::subscribeEnum(const QString &path, const QString &typeId, ASLCallbackString callback)
206 {
207     m_d->mapEnum.insert(path, EnumMapping(typeId, callback));
208 }
209 
subscribeUnitFloat(const QString & path,const QString & unit,ASLCallbackDouble callback)210 void KisAslCallbackObjectCatcher::subscribeUnitFloat(const QString &path, const QString &unit, ASLCallbackDouble callback)
211 {
212     m_d->mapUnitFloat.insert(path, UnitFloatMapping(unit, callback));
213 }
214 
subscribeText(const QString & path,ASLCallbackString callback)215 void KisAslCallbackObjectCatcher::subscribeText(const QString &path, ASLCallbackString callback)
216 {
217     m_d->mapText.insert(path, callback);
218 }
219 
subscribeBoolean(const QString & path,ASLCallbackBoolean callback)220 void KisAslCallbackObjectCatcher::subscribeBoolean(const QString &path, ASLCallbackBoolean callback)
221 {
222     m_d->mapBoolean.insert(path, callback);
223 }
224 
subscribeColor(const QString & path,ASLCallbackColor callback)225 void KisAslCallbackObjectCatcher::subscribeColor(const QString &path, ASLCallbackColor callback)
226 {
227     m_d->mapColor.insert(path, callback);
228 }
229 
subscribePoint(const QString & path,ASLCallbackPoint callback)230 void KisAslCallbackObjectCatcher::subscribePoint(const QString &path, ASLCallbackPoint callback)
231 {
232     m_d->mapPoint.insert(path, callback);
233 }
234 
subscribeCurve(const QString & path,ASLCallbackCurve callback)235 void KisAslCallbackObjectCatcher::subscribeCurve(const QString &path, ASLCallbackCurve callback)
236 {
237     m_d->mapCurve.insert(path, callback);
238 }
239 
subscribePattern(const QString & path,ASLCallbackPattern callback)240 void KisAslCallbackObjectCatcher::subscribePattern(const QString &path, ASLCallbackPattern callback)
241 {
242     m_d->mapPattern.insert(path, callback);
243 }
244 
subscribePatternRef(const QString & path,ASLCallbackPatternRef callback)245 void KisAslCallbackObjectCatcher::subscribePatternRef(const QString &path, ASLCallbackPatternRef callback)
246 {
247     m_d->mapPatternRef.insert(path, callback);
248 }
249 
subscribeGradient(const QString & path,ASLCallbackGradient callback)250 void KisAslCallbackObjectCatcher::subscribeGradient(const QString &path, ASLCallbackGradient callback)
251 {
252     m_d->mapGradient.insert(path, callback);
253 }
254 
subscribeNewStyleStarted(ASLCallbackNewStyle callback)255 void KisAslCallbackObjectCatcher::subscribeNewStyleStarted(ASLCallbackNewStyle callback)
256 {
257     m_d->newStyleCallback = callback;
258 }
259