58{
59 int idx;
60 int start, end;
62 QByteArray ba;
63
66
68
69 KisCursorOverrideLock cursorLock(Qt::WaitCursor);
70
71
72
73
74
75
77
78 if (path.right(4).toUpper() == ".CSV")
79 path = path.left(path.size() - 4);
80 else {
81
82
83
85 path = path.left(path.size() - 4);
86 }
87 }
88 path.append(".frames");
89
90
91
92 QDir dir(path);
93 if (!dir.exists()) {
94 dir.mkpath(".");
95 }
96
97 path.append("/");
98
100
101
102
103
104 idx = 0;
105
106 while (node) {
107 if (node->inherits("KisLayer")) {
108 KisLayer* paintLayer = qobject_cast<KisLayer*>(node.
data());
110 layers.prepend(layerRecord);
111
112 layerRecord->
name = paintLayer->
name();
113 layerRecord->
name.replace(QRegularExpression(
"[\"\\r\\n]"),
"_");
114
115 if (layerRecord->
name.isEmpty())
116 layerRecord->
name= QString(
"Unnamed-%1").arg(idx);
117
121 layerRecord->
layer = paintLayer;
123 layerRecord->
last =
"";
124 layerRecord->
frame = 0;
125 idx++;
126 }
128 }
129
131
133
136
137 if (end < start) end = start;
138 } else {
139
140 end = start;
141 int keyframeTime;
142
143 for (idx = 0; idx < layers.size(); idx++) {
145
146 if (channel) {
148
149 if ( (channel->
keyframeAt(keyframeTime)) && (keyframeTime > end) )
150 end = keyframeTime;
151 }
152 }
153 }
154
155
158
160
162
163
164
165
166 }
167 int frame = start;
168 int step = 0;
169
170 do {
171 qApp->processEvents();
172
175 break;
176 }
177
178 switch(step) {
179
180 case 0 :
181 if (io->write("UTF-8, TVPaint, \"CSV 1.0\"\r\n") < 0) {
183 }
184 break;
185
186 case 1 :
187 if (io->write("Project Name, Width, Height, Frame Count, Layer Count, Frame Rate, Pixel Aspect Ratio, Field Mode\r\n") < 0) {
189 }
190 break;
191
192 case 2 :
193 ba = QString(
"\"%1\", ").arg(
m_image->objectName()).toUtf8();
194 if (io->write(ba.data()) < 0) {
196 break;
197 }
199 if (io->write(ba.data()) < 0) {
201 break;
202 }
203
204 ba = QString("%1, %2, ").arg(end - start + 1).arg(layers.size()).toUtf8();
205 if (io->write(ba.data()) < 0) {
207 break;
208 }
209
210 ba = QString(
"%1, ").arg((
double)(animation->
framerate()),0,
'f',6).toUtf8();
211 if (io->write(ba.data()) < 0) {
213 break;
214 }
216 if (io->write(ba.data()) < 0) {
218 break;
219 }
220 break;
221
222 case 3 :
223 if (io->write("#Layers") < 0) {
225 break;
226 }
227
228 for (idx = 0; idx < layers.size(); idx++) {
229 ba = QString(", \"%1\"").arg(layers.at(idx)->name).toUtf8();
230 if (io->write(ba.data()) < 0)
231 break;
232 }
233 break;
234
235 case 4 :
236 if (io->write("\r\n#Density") < 0) {
238 break;
239 }
240 for (idx = 0; idx < layers.size(); idx++) {
241 ba = QString(", %1").arg((double)(layers.at(idx)->density), 0, 'f', 6).toUtf8();
242 if (io->write(ba.data()) < 0)
243 break;
244 }
245 break;
246
247 case 5 :
248 if (io->write("\r\n#Blending") < 0) {
250 break;
251 }
252 for (idx = 0; idx < layers.size(); idx++) {
253 ba = QString(", \"%1\"").arg(layers.at(idx)->blending).toUtf8();
254 if (io->write(ba.data()) < 0)
255 break;
256 }
257 break;
258
259 case 6 :
260 if (io->write("\r\n#Visible") < 0) {
262 break;
263 }
264 for (idx = 0; idx < layers.size(); idx++) {
265 ba = QString(", %1").arg(layers.at(idx)->visible).toUtf8();
266 if (io->write(ba.data()) < 0)
267 break;
268 }
269 if (idx < layers.size()) {
271 }
272 break;
273
274 default :
275
276 if (frame > end) {
277 if (io->write("\r\n") < 0)
279
280 step = 8;
281 break;
282 }
283
284 ba = QString("\r\n#%1").arg(frame, 5, 10, QChar('0')).toUtf8();
285 if (io->write(ba.data()) < 0) {
287 break;
288 }
289
290 for (idx = 0; idx < layers.size(); idx++) {
293
294 if (channel) {
295 if (frame == start) {
297 } else {
299 }
300 } else {
301 keyframe.clear();
302 }
303
304 if ( keyframe || (frame == start) ) {
305
307
308
309 }
310 retval =
getLayer(layer, exportDoc.data(), keyframe, path, frame, idx);
311
313 break;
314 }
315 ba = QString(
", \"%1\"").arg(layer->
last).toUtf8();
316
317 if (io->write(ba.data()) < 0)
318 break;
319 }
320 if (idx < layers.size())
322
323 frame++;
324 step = 6;
325 break;
326 }
327 step++;
328 }
while((retval.
isOk()) && (step < 8));
329
330 qDeleteAll(layers);
331
332
333
335
336
337
338 }
339
340 return retval;
341}
KisRasterKeyframeChannel * channel
QString convertToBlending(const QString &)
void createTempImage(KisDocument *)
KisImportExportErrorCode getLayer(CSVLayerRecord *, KisDocument *, KisKeyframeSP, const QString &, int, int)
QString localFilePath() const
const KisTimeSpan & documentPlaybackRange() const
documentPlaybackRange
KisImageAnimationInterface * animationInterface() const
KisKeyframeSP keyframeAt(int time) const
Get a keyframe at specified time. Used primarily when the value of a given keyframe is needed.
KisKeyframeSP activeKeyframeAt(int time) const
int lastKeyframeTime() const
KisRasterKeyframeChannel * keyframeChannel() const
static KisPart * instance()
The KisRasterKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisRas...
#define KIS_SAFE_ASSERT_RECOVER(cond)
KisDocument * createDocument(QList< KisNodeSP > nodes, KisImageSP srcImage, const QRect &copiedBounds)
const QString & compositeOpId() const
virtual bool visible(bool recursive=false) const
KisPaintDeviceSP original() const override=0
KisNodeSP firstChild() const
KisNodeSP nextSibling() const