1 /*
2  *  Copyright (c) 2015 Jouni Pentikäinen <joupent@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_animation_importer.h"
20 
21 #include <QStatusBar>
22 
23 #include "KoColorSpace.h"
24 #include <KoUpdater.h>
25 #include <QApplication>
26 #include "KisPart.h"
27 #include "KisDocument.h"
28 #include "kis_image.h"
29 #include "kis_undo_adapter.h"
30 #include "kis_paint_layer.h"
31 #include "kis_group_layer.h"
32 #include "kis_raster_keyframe_channel.h"
33 #include "commands/kis_image_layer_add_command.h"
34 
35 struct KisAnimationImporter::Private
36 {
37     KisImageSP image;
38     KisDocument *document;
39     bool stop;
40     KoUpdaterPtr updater;
41 };
42 
KisAnimationImporter(KisImageSP image,KoUpdaterPtr updater)43 KisAnimationImporter::KisAnimationImporter(KisImageSP image, KoUpdaterPtr updater)
44     : m_d(new Private())
45 {
46     m_d->document = 0;
47     m_d->image = image;
48     m_d->stop = false;
49     m_d->updater = updater;
50 }
51 
KisAnimationImporter(KisDocument * document)52 KisAnimationImporter::KisAnimationImporter(KisDocument* document)
53     : m_d(new Private())
54 {
55     m_d->document= document;
56     m_d->image = document->image();
57     m_d->stop = false;
58 }
59 
~KisAnimationImporter()60 KisAnimationImporter::~KisAnimationImporter()
61 {}
62 
import(QStringList files,int firstFrame,int step)63 KisImportExportErrorCode KisAnimationImporter::import(QStringList files, int firstFrame, int step)
64 {
65     Q_ASSERT(step > 0);
66 
67     KisUndoAdapter *undo = m_d->image->undoAdapter();
68     undo->beginMacro(kundo2_i18n("Import animation"));
69 
70     QScopedPointer<KisDocument> importDoc(KisPart::instance()->createDocument());
71     importDoc->setFileBatchMode(true);
72 
73     KisImportExportErrorCode status = ImportExportCodes::OK;
74     int frame = firstFrame;
75     int filesProcessed = 0;
76 
77     if (m_d->updater) {
78         m_d->updater->setRange(0, files.size());
79     }
80 
81     KisRasterKeyframeChannel *contentChannel = 0;
82     Q_FOREACH(QString file, files) {
83         bool successfullyLoaded = importDoc->openUrl(QUrl::fromLocalFile(file), KisDocument::DontAddToRecent);
84         if (!successfullyLoaded) {
85             status = ImportExportCodes::InternalError;
86             break;
87         }
88 
89         if (frame == firstFrame) {
90             const KoColorSpace *cs = importDoc->image()->colorSpace();
91             KisPaintLayerSP paintLayer = new KisPaintLayer(m_d->image, m_d->image->nextLayerName(), OPACITY_OPAQUE_U8, cs);
92             undo->addCommand(new KisImageLayerAddCommand(m_d->image, paintLayer, m_d->image->rootLayer(), m_d->image->rootLayer()->childCount()));
93 
94             paintLayer->enableAnimation();
95             contentChannel = qobject_cast<KisRasterKeyframeChannel*>(paintLayer->getKeyframeChannel(KisKeyframeChannel::Content.id(), true));
96         }
97 
98         if (m_d->updater) {
99             if (m_d->updater->interrupted()) {
100                 m_d->stop = true;
101             } else {
102                 m_d->updater->setValue(filesProcessed + 1);
103 
104                 // the updater doesn't call that automatically,
105                 // it is "threaded" by default
106                 qApp->processEvents();
107             }
108         }
109 
110         if (m_d->stop) {
111             status = ImportExportCodes::Cancelled;
112             break;
113         }
114 
115         contentChannel->importFrame(frame, importDoc->image()->projection(), NULL);
116         frame += step;
117         filesProcessed++;
118     }
119 
120     undo->endMacro();
121 
122     return status;
123 }
124 
cancel()125 void KisAnimationImporter::cancel()
126 {
127     m_d->stop = true;
128 }
129