1 /*
2 
3 Pencil2D - Traditional Animation Software
4 Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5 Copyright (C) 2012-2020 Matthew Chiawen Chang
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 */
17 
18 #include "editor.h"
19 
20 #include <QApplication>
21 #include <QClipboard>
22 #include <QTimer>
23 #include <QImageReader>
24 #include <QDropEvent>
25 #include <QMimeData>
26 #include <QTemporaryDir>
27 
28 #include "object.h"
29 #include "vectorimage.h"
30 #include "bitmapimage.h"
31 #include "soundclip.h"
32 #include "layerbitmap.h"
33 #include "layervector.h"
34 #include "layercamera.h"
35 #include "backupelement.h"
36 
37 #include "colormanager.h"
38 #include "toolmanager.h"
39 #include "layermanager.h"
40 #include "playbackmanager.h"
41 #include "viewmanager.h"
42 #include "preferencemanager.h"
43 #include "soundmanager.h"
44 #include "selectionmanager.h"
45 
46 #include "scribblearea.h"
47 #include "timeline.h"
48 #include "util.h"
49 
50 
51 static BitmapImage g_clipboardBitmapImage;
52 static VectorImage g_clipboardVectorImage;
53 
54 
Editor(QObject * parent)55 Editor::Editor(QObject* parent) : QObject(parent)
56 {
57     mBackupIndex = -1;
58     clipboardBitmapOk = false;
59     clipboardVectorOk = false;
60     clipboardSoundClipOk = false;
61 }
62 
~Editor()63 Editor::~Editor()
64 {
65     // a lot more probably needs to be cleaned here...
66     clearUndoStack();
67     clearTemporary();
68 }
69 
init()70 bool Editor::init()
71 {
72     // Initialize managers
73     mColorManager = new ColorManager(this);
74     mLayerManager = new LayerManager(this);
75     mToolManager = new ToolManager(this);
76     mPlaybackManager = new PlaybackManager(this);
77     mViewManager = new ViewManager(this);
78     mPreferenceManager = new PreferenceManager(this);
79     mSoundManager = new SoundManager(this);
80     mSelectionManager = new SelectionManager(this);
81 
82     mAllManagers =
83     {
84         mColorManager,
85         mToolManager,
86         mLayerManager,
87         mPlaybackManager,
88         mViewManager,
89         mPreferenceManager,
90         mSoundManager,
91         mSelectionManager
92     };
93 
94     for (BaseManager* pManager : mAllManagers)
95     {
96         pManager->init();
97     }
98     //setAcceptDrops( true ); // TODO: drop event
99 
100     makeConnections();
101 
102     mIsAutosave = mPreferenceManager->isOn(SETTING::AUTO_SAVE);
103     mAutosaveNumber = mPreferenceManager->getInt(SETTING::AUTO_SAVE_NUMBER);
104 
105     return true;
106 }
107 
currentFrame()108 int Editor::currentFrame()
109 {
110     return mFrame;
111 }
112 
fps()113 int Editor::fps()
114 {
115     return mPlaybackManager->fps();
116 }
117 
setFps(int fps)118 void Editor::setFps(int fps)
119 {
120     mPreferenceManager->set(SETTING::FPS, fps);
121     emit fpsChanged(fps);
122 }
123 
makeConnections()124 void Editor::makeConnections()
125 {
126     connect(mPreferenceManager, &PreferenceManager::optionChanged, this, &Editor::settingUpdated);
127     connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &Editor::clipboardChanged);
128     // XXX: This is a hack to prevent crashes until #864 is done (see #1412)
129     connect(mLayerManager, &LayerManager::layerDeleted, this, &Editor::sanitizeBackupElementsAfterLayerDeletion);
130 }
131 
dragEnterEvent(QDragEnterEvent * event)132 void Editor::dragEnterEvent(QDragEnterEvent* event)
133 {
134     event->acceptProposedAction();
135 }
136 
dropEvent(QDropEvent * event)137 void Editor::dropEvent(QDropEvent* event)
138 {
139     if (event->mimeData()->hasUrls())
140     {
141         for (int i = 0; i < event->mimeData()->urls().size(); i++)
142         {
143             if (i > 0) scrubForward();
144             QUrl url = event->mimeData()->urls()[i];
145             QString filePath = url.toLocalFile();
146             if (filePath.endsWith(".png") || filePath.endsWith(".jpg") || filePath.endsWith(".jpeg"))
147             {
148                 importImage(filePath);
149             }
150             //if ( filePath.endsWith( ".aif" ) || filePath.endsWith( ".mp3" ) || filePath.endsWith( ".wav" ) )
151                 //importSound( filePath );
152         }
153     }
154 }
155 
settingUpdated(SETTING setting)156 void Editor::settingUpdated(SETTING setting)
157 {
158     switch (setting)
159     {
160     case SETTING::AUTO_SAVE:
161         mIsAutosave = mPreferenceManager->isOn(SETTING::AUTO_SAVE);
162         break;
163     case SETTING::AUTO_SAVE_NUMBER:
164         mAutosaveNumber = mPreferenceManager->getInt(SETTING::AUTO_SAVE_NUMBER);
165         break;
166     case SETTING::ONION_TYPE:
167         mScribbleArea->onOnionSkinTypeChanged();
168         emit updateTimeLine();
169         break;
170     case SETTING::FRAME_POOL_SIZE:
171         mObject->setActiveFramePoolSize(mPreferenceManager->getInt(SETTING::FRAME_POOL_SIZE));
172         break;
173     case SETTING::LAYER_VISIBILITY:
174         mScribbleArea->setLayerVisibility(static_cast<LayerVisibility>(mPreferenceManager->getInt(SETTING::LAYER_VISIBILITY)));
175         emit updateTimeLine();
176         break;
177     default:
178         break;
179     }
180 }
181 
currentBackup()182 BackupElement* Editor::currentBackup()
183 {
184     if (mBackupIndex >= 0)
185     {
186         return mBackupList[mBackupIndex];
187     }
188     else
189     {
190         return nullptr;
191     }
192 }
193 
backup(QString undoText)194 void Editor::backup(QString undoText)
195 {
196     KeyFrame* frame = nullptr;
197     if (mLastModifiedLayer > -1 && mLastModifiedFrame > 0)
198     {
199         if (layers()->currentLayer()->type() == Layer::SOUND)
200         {
201             frame = layers()->currentLayer()->getKeyFrameWhichCovers(mLastModifiedFrame);
202             if (frame != nullptr)
203             {
204                 backup(mLastModifiedLayer, frame->pos(), undoText);
205             }
206         }
207         else
208         {
209             backup(mLastModifiedLayer, mLastModifiedFrame, undoText);
210         }
211     }
212     if (mLastModifiedLayer != layers()->currentLayerIndex() || mLastModifiedFrame != currentFrame())
213     {
214         if (layers()->currentLayer()->type() == Layer::SOUND)
215         {
216             frame = layers()->currentLayer()->getKeyFrameWhichCovers(currentFrame());
217 
218             if (frame != nullptr)
219             {
220                 backup(layers()->currentLayerIndex(), frame->pos(), undoText);
221             }
222         }
223         else
224         {
225             backup(layers()->currentLayerIndex(), currentFrame(), undoText);
226         }
227     }
228 }
229 
backup(int backupLayer,int backupFrame,QString undoText)230 void Editor::backup(int backupLayer, int backupFrame, QString undoText)
231 {
232     while (mBackupList.size() - 1 > mBackupIndex && mBackupList.size() > 0)
233     {
234         delete mBackupList.takeLast();
235     }
236     while (mBackupList.size() > 19)   // we authorize only 20 levels of cancellation
237     {
238         delete mBackupList.takeFirst();
239         mBackupIndex--;
240     }
241 
242     Layer* layer = mObject->getLayer(backupLayer);
243     if (layer != nullptr)
244     {
245         if (layer->type() == Layer::BITMAP)
246         {
247             BitmapImage* bitmapImage = static_cast<BitmapImage*>(layer->getLastKeyFrameAtPosition(backupFrame));
248             if (currentFrame() == 1)
249             {
250                 int previous = layer->getPreviousKeyFramePosition(backupFrame);
251                 bitmapImage = static_cast<BitmapImage*>(layer->getKeyFrameAt(previous));
252             }
253             if (bitmapImage != nullptr)
254             {
255                 BackupBitmapElement* element = new BackupBitmapElement(bitmapImage);
256                 element->layer = backupLayer;
257                 element->frame = bitmapImage->pos();
258                 element->undoText = undoText;
259                 element->somethingSelected = select()->somethingSelected();
260                 element->mySelection = select()->mySelectionRect();
261                 element->myTransformedSelection = select()->myTransformedSelectionRect();
262                 element->myTempTransformedSelection = select()->myTempTransformedSelectionRect();
263                 element->rotationAngle = select()->myRotation();
264                 mBackupList.append(element);
265                 mBackupIndex++;
266             }
267         }
268         else if (layer->type() == Layer::VECTOR)
269         {
270             VectorImage* vectorImage = static_cast<VectorImage*>(layer->getLastKeyFrameAtPosition(mFrame));
271             if (vectorImage != nullptr)
272             {
273                 BackupVectorElement* element = new BackupVectorElement(vectorImage);
274                 element->layer = backupLayer;
275                 element->frame = vectorImage->pos();
276                 element->undoText = undoText;
277                 element->somethingSelected = select()->somethingSelected();
278                 element->mySelection = select()->mySelectionRect();
279                 element->myTransformedSelection = select()->myTransformedSelectionRect();
280                 element->myTempTransformedSelection = select()->myTempTransformedSelectionRect();
281                 element->rotationAngle = select()->myRotation();
282                 mBackupList.append(element);
283                 mBackupIndex++;
284             }
285         }
286         else if (layer->type() == Layer::SOUND)
287         {
288             int previous = layer->getPreviousKeyFramePosition(backupFrame);
289             KeyFrame* key = layer->getLastKeyFrameAtPosition(backupFrame);
290 
291             // in case tracks overlap, get previous frame
292             if (key == nullptr)
293             {
294                 KeyFrame* previousKey = layer->getKeyFrameAt(previous);
295                 key = previousKey;
296             }
297             if (key != nullptr) {
298                 SoundClip* clip = static_cast<SoundClip*>(key);
299                 if (clip)
300                 {
301                     BackupSoundElement* element = new BackupSoundElement(clip);
302                     element->layer = backupLayer;
303                     element->frame = backupFrame;
304                     element->undoText = undoText;
305                     element->fileName = clip->fileName();
306                     element->originalName = clip->soundClipName();
307                     mBackupList.append(element);
308                     mBackupIndex++;
309                 }
310             }
311         }
312     }
313 
314     updateAutoSaveCounter();
315 
316     emit updateBackup();
317 }
318 
sanitizeBackupElementsAfterLayerDeletion(int layerIndex)319 void Editor::sanitizeBackupElementsAfterLayerDeletion(int layerIndex)
320 {
321     for (int i = 0; i < mBackupList.size(); i++)
322     {
323         BackupElement *backupElement = mBackupList[i];
324         BackupBitmapElement *bitmapElement;
325         BackupVectorElement *vectorElement;
326         BackupSoundElement *soundElement;
327         switch (backupElement->type())
328         {
329         case BackupElement::BITMAP_MODIF:
330             bitmapElement = qobject_cast<BackupBitmapElement*>(backupElement);
331             Q_ASSERT(bitmapElement);
332             if (bitmapElement->layer > layerIndex)
333             {
334                 bitmapElement->layer--;
335                 continue;
336             }
337             else if (bitmapElement->layer != layerIndex)
338             {
339                 continue;
340             }
341             break;
342         case BackupElement::VECTOR_MODIF:
343             vectorElement = qobject_cast<BackupVectorElement*>(backupElement);
344             Q_ASSERT(vectorElement);
345             if (vectorElement->layer > layerIndex)
346             {
347                 vectorElement->layer--;
348                 continue;
349             }
350             else if (vectorElement->layer != layerIndex)
351             {
352                 continue;
353             }
354             break;
355         case BackupElement::SOUND_MODIF:
356             soundElement = qobject_cast<BackupSoundElement*>(backupElement);
357             Q_ASSERT(soundElement);
358             if (soundElement->layer > layerIndex)
359             {
360                 soundElement->layer--;
361                 continue;
362             }
363             else if (soundElement->layer != layerIndex)
364             {
365                 continue;
366             }
367             break;
368         default:
369             Q_UNREACHABLE();
370         }
371         if (i <= mBackupIndex)
372         {
373             mBackupIndex--;
374         }
375         delete mBackupList.takeAt(i);
376         i--;
377     }
378 }
379 
restoreKey()380 void Editor::restoreKey()
381 {
382     BackupElement* lastBackupElement = mBackupList[mBackupIndex];
383 
384     Layer* layer = nullptr;
385     int frame = 0;
386     int layerIndex = 0;
387     if (lastBackupElement->type() == BackupElement::BITMAP_MODIF)
388     {
389         BackupBitmapElement* lastBackupBitmapElement = static_cast<BackupBitmapElement*>(lastBackupElement);
390         layerIndex = lastBackupBitmapElement->layer;
391         frame = lastBackupBitmapElement->frame;
392         layer = object()->getLayer(layerIndex);
393         addKeyFrame(layerIndex, frame);
394         dynamic_cast<LayerBitmap*>(layer)->getBitmapImageAtFrame(frame)->paste(&lastBackupBitmapElement->bitmapImage);
395     }
396     if (lastBackupElement->type() == BackupElement::VECTOR_MODIF)
397     {
398         BackupVectorElement* lastBackupVectorElement = static_cast<BackupVectorElement*>(lastBackupElement);
399         layerIndex = lastBackupVectorElement->layer;
400         frame = lastBackupVectorElement->frame;
401         layer = object()->getLayer(layerIndex);
402         addKeyFrame(layerIndex, frame);
403         dynamic_cast<LayerVector*>(layer)->getVectorImageAtFrame(frame)->paste(lastBackupVectorElement->vectorImage);
404     }
405     if (lastBackupElement->type() == BackupElement::SOUND_MODIF)
406     {
407         QString strSoundFile;
408         BackupSoundElement* lastBackupSoundElement = static_cast<BackupSoundElement*>(lastBackupElement);
409         layerIndex = lastBackupSoundElement->layer;
410         frame = lastBackupSoundElement->frame;
411 
412         strSoundFile = lastBackupSoundElement->fileName;
413         if (strSoundFile.isEmpty()) return;
414         KeyFrame* key = addKeyFrame(layerIndex, frame);
415         SoundClip* clip = dynamic_cast<SoundClip*>(key);
416         if (clip)
417         {
418             Status st = sound()->loadSound(clip, lastBackupSoundElement->fileName);
419             clip->setSoundClipName(lastBackupSoundElement->originalName);
420             if (!st.ok())
421             {
422                 removeKey();
423                 emit layers()->currentLayerChanged(layers()->currentLayerIndex()); // trigger timeline repaint.
424             }
425         }
426     }
427 }
428 
undo()429 void Editor::undo()
430 {
431     if (mBackupList.size() > 0 && mBackupIndex > -1)
432     {
433         if (mBackupIndex == mBackupList.size() - 1)
434         {
435             BackupElement* lastBackupElement = mBackupList[mBackupIndex];
436             if (lastBackupElement->type() == BackupElement::BITMAP_MODIF)
437             {
438                 BackupBitmapElement* lastBackupBitmapElement = static_cast<BackupBitmapElement*>(lastBackupElement);
439                 backup(lastBackupBitmapElement->layer, lastBackupBitmapElement->frame, "NoOp");
440                 mBackupIndex--;
441             }
442             if (lastBackupElement->type() == BackupElement::VECTOR_MODIF)
443             {
444                 BackupVectorElement* lastBackupVectorElement = static_cast<BackupVectorElement*>(lastBackupElement);
445                 backup(lastBackupVectorElement->layer, lastBackupVectorElement->frame, "NoOp");
446                 mBackupIndex--;
447             }
448             if (lastBackupElement->type() == BackupElement::SOUND_MODIF)
449             {
450                 BackupSoundElement* lastBackupSoundElement = static_cast<BackupSoundElement*>(lastBackupElement);
451                 backup(lastBackupSoundElement->layer, lastBackupSoundElement->frame, "NoOp");
452                 mBackupIndex--;
453             }
454         }
455 
456         qDebug() << "Undo" << mBackupIndex;
457         mBackupList[mBackupIndex]->restore(this);
458         mBackupIndex--;
459         mScribbleArea->cancelTransformedSelection();
460 
461         Layer* layer = layers()->currentLayer();
462         if (layer == nullptr) { return; }
463 
464         select()->resetSelectionTransform();
465         if (layer->type() == Layer::VECTOR)
466         {
467             VectorImage *vectorImage = static_cast<VectorImage*>(layer->getKeyFrameAt(mFrame));
468             vectorImage->calculateSelectionRect();
469             select()->setSelection(vectorImage->getSelectionRect(), false);
470         }
471         emit updateBackup();
472     }
473 }
474 
redo()475 void Editor::redo()
476 {
477     if (mBackupList.size() > 0 && mBackupIndex < mBackupList.size() - 2)
478     {
479         mBackupIndex++;
480 
481         mBackupList[mBackupIndex + 1]->restore(this);
482         emit updateBackup();
483     }
484 }
485 
clearUndoStack()486 void Editor::clearUndoStack()
487 {
488     mBackupIndex = -1;
489     while (!mBackupList.isEmpty())
490     {
491         delete mBackupList.takeLast();
492     }
493     mLastModifiedLayer = -1;
494     mLastModifiedFrame = -1;
495 }
496 
updateAutoSaveCounter()497 void Editor::updateAutoSaveCounter()
498 {
499     if (mIsAutosave == false)
500         return;
501 
502     mAutosaveCounter++;
503     if (mAutosaveCounter >= mAutosaveNumber)
504     {
505         resetAutoSaveCounter();
506         emit needSave();
507     }
508 }
509 
resetAutoSaveCounter()510 void Editor::resetAutoSaveCounter()
511 {
512     mAutosaveCounter = 0;
513 }
514 
cut()515 void Editor::cut()
516 {
517     copy();
518     mScribbleArea->deleteSelection();
519     deselectAll();
520 }
521 
copy()522 void Editor::copy()
523 {
524     Layer* layer = mObject->getLayer(layers()->currentLayerIndex());
525     if (layer == nullptr)
526     {
527         return;
528     }
529 
530     if (layer->type() == Layer::BITMAP)
531     {
532         LayerBitmap* layerBitmap = static_cast<LayerBitmap*>(layer);
533         BitmapImage* bitmapImage = layerBitmap->getLastBitmapImageAtFrame(currentFrame(), 0);
534         if (bitmapImage == nullptr) { return; }
535         if (select()->somethingSelected())
536         {
537             g_clipboardBitmapImage = bitmapImage->copy(select()->mySelectionRect().toRect());  // copy part of the image
538         }
539         else
540         {
541             g_clipboardBitmapImage = *bitmapImage;  // copy the whole image
542         }
543         clipboardBitmapOk = true;
544         if (g_clipboardBitmapImage.image() != nullptr)
545             QApplication::clipboard()->setImage(*g_clipboardBitmapImage.image());
546     }
547     if (layer->type() == Layer::VECTOR)
548     {
549         clipboardVectorOk = true;
550         VectorImage *vectorImage = static_cast<VectorImage*>(layer->getLastKeyFrameAtPosition(currentFrame()));
551         if (vectorImage == nullptr) { return; }
552         g_clipboardVectorImage = *vectorImage;  // copy the image
553     }
554 }
555 
paste()556 void Editor::paste()
557 {
558     Layer* layer = mObject->getLayer(layers()->currentLayerIndex());
559     if (layer != nullptr)
560     {
561         if (layer->type() == Layer::BITMAP && g_clipboardBitmapImage.image() != nullptr)
562         {
563             backup(tr("Paste"));
564 
565             BitmapImage tobePasted = g_clipboardBitmapImage.copy();
566             qDebug() << "to be pasted --->" << tobePasted.image()->size();
567             if (select()->somethingSelected())
568             {
569                 QRectF selection = select()->mySelectionRect();
570                 if (g_clipboardBitmapImage.width() <= selection.width() && g_clipboardBitmapImage.height() <= selection.height())
571                 {
572                     tobePasted.moveTopLeft(selection.topLeft());
573                 }
574                 else
575                 {
576                     tobePasted.transform(selection, true);
577                 }
578             }
579             mScribbleArea->handleDrawingOnEmptyFrame();
580             BitmapImage *bitmapImage = static_cast<BitmapImage*>(layer->getLastKeyFrameAtPosition(currentFrame()));
581             Q_CHECK_PTR(bitmapImage);
582             bitmapImage->paste(&tobePasted); // paste the clipboard
583         }
584         else if (layer->type() == Layer::VECTOR && clipboardVectorOk)
585         {
586             backup(tr("Paste"));
587             deselectAll();
588             mScribbleArea->handleDrawingOnEmptyFrame();
589             VectorImage* vectorImage = static_cast<VectorImage*>(layer->getLastKeyFrameAtPosition(currentFrame()));
590             Q_CHECK_PTR(vectorImage);
591             vectorImage->paste(g_clipboardVectorImage);  // paste the clipboard
592             select()->setSelection(vectorImage->getSelectionRect(), false);
593         }
594     }
595     emit frameModified(mFrame);
596 }
597 
flipSelection(bool flipVertical)598 void Editor::flipSelection(bool flipVertical)
599 {
600     mScribbleArea->flipSelection(flipVertical);
601 }
602 
clipboardChanged()603 void Editor::clipboardChanged()
604 {
605     if (clipboardBitmapOk == false)
606     {
607         g_clipboardBitmapImage.setImage(new QImage(QApplication::clipboard()->image()));
608         g_clipboardBitmapImage.bounds() = QRect(g_clipboardBitmapImage.topLeft(), g_clipboardBitmapImage.image()->size());
609         //qDebug() << "New clipboard image" << g_clipboardBitmapImage.image()->size();
610     }
611     else
612     {
613         clipboardBitmapOk = false;
614         //qDebug() << "The image has been saved in the clipboard";
615     }
616 }
617 
setLayerVisibility(LayerVisibility visibility)618 void Editor::setLayerVisibility(LayerVisibility visibility) {
619     mScribbleArea->setLayerVisibility(visibility);
620     emit updateTimeLine();
621 }
622 
notifyAnimationLengthChanged()623 void Editor::notifyAnimationLengthChanged()
624 {
625     layers()->notifyAnimationLengthChanged();
626 }
627 
layerVisibility()628 LayerVisibility Editor::layerVisibility()
629 {
630     return mScribbleArea->getLayerVisibility();
631 }
632 
increaseLayerVisibilityIndex()633 void Editor::increaseLayerVisibilityIndex()
634 {
635     mScribbleArea->increaseLayerVisibilityIndex();
636     emit updateTimeLine();
637 }
638 
decreaseLayerVisibilityIndex()639 void Editor::decreaseLayerVisibilityIndex()
640 {
641     mScribbleArea->decreaseLayerVisibilityIndex();
642     emit updateTimeLine();
643 }
644 
toggleOnionSkinType()645 void Editor::toggleOnionSkinType()
646 {
647     QString onionSkinState = mPreferenceManager->getString(SETTING::ONION_TYPE);
648     QString newState;
649     if (onionSkinState == "relative")
650     {
651         newState = "absolute";
652     }
653     else
654     {
655         newState = "relative";
656     }
657 
658     mPreferenceManager->set(SETTING::ONION_TYPE, newState);
659 }
660 
addTemporaryDir(QTemporaryDir * const dir)661 void Editor::addTemporaryDir(QTemporaryDir* const dir)
662 {
663     mTemporaryDirs.append(dir);
664 }
665 
clearTemporary()666 void Editor::clearTemporary()
667 {
668     while(!mTemporaryDirs.isEmpty())
669     {
670         QTemporaryDir* t = mTemporaryDirs.takeLast();
671         t->remove();
672         delete t;
673     }
674 }
675 
setObject(Object * newObject)676 Status Editor::setObject(Object* newObject)
677 {
678     if (newObject == nullptr)
679     {
680         Q_ASSERT(false);
681         return Status::INVALID_ARGUMENT;
682     }
683 
684     if (newObject == mObject.get())
685     {
686         return Status::SAFE;
687     }
688 
689     clearUndoStack();
690     mObject.reset(newObject);
691 
692     g_clipboardVectorImage.setObject(newObject);
693 
694     updateObject();
695 
696     // Make sure that object is fully loaded before calling managers.
697     for (BaseManager* m : mAllManagers)
698     {
699         m->load(mObject.get());
700     }
701 
702     if (mViewManager)
703     {
704         connect(newObject, &Object::layerViewChanged, mViewManager, &ViewManager::viewChanged);
705     }
706 
707     emit objectLoaded();
708 
709     return Status::OK;
710 }
711 
updateObject()712 void Editor::updateObject()
713 {
714     setCurrentLayerIndex(mObject->data()->getCurrentLayer());
715     scrubTo(mObject->data()->getCurrentFrame());
716 
717     mAutosaveCounter = 0;
718     mAutosaveNeverAskAgain = false;
719 
720     emit objectChanged();
721 
722     if (mPreferenceManager)
723     {
724         mObject->setActiveFramePoolSize(mPreferenceManager->getInt(SETTING::FRAME_POOL_SIZE));
725     }
726 
727     emit updateLayerCount();
728 }
729 
importBitmapImage(QString filePath,int space)730 bool Editor::importBitmapImage(QString filePath, int space)
731 {
732     QImageReader reader(filePath);
733 
734     Q_ASSERT(layers()->currentLayer()->type() == Layer::BITMAP);
735     auto layer = static_cast<LayerBitmap*>(layers()->currentLayer());
736 
737     QImage img(reader.size(), QImage::Format_ARGB32_Premultiplied);
738     if (img.isNull())
739     {
740         return false;
741     }
742 
743     const QPoint pos(view()->getImportView().dx() - (img.width() / 2),
744                      view()->getImportView().dy() - (img.height() / 2));
745 
746     while (reader.read(&img))
747     {
748         if (!layer->keyExists(currentFrame()))
749         {
750             addNewKey();
751         }
752         BitmapImage* bitmapImage = layer->getBitmapImageAtFrame(currentFrame());
753         BitmapImage importedBitmapImage(pos, img);
754         bitmapImage->paste(&importedBitmapImage);
755 
756         if (space > 1) {
757             scrubTo(currentFrame() + space);
758         } else {
759             scrubTo(currentFrame() + 1);
760         }
761 
762         backup(tr("Import Image"));
763 
764         // Workaround for tiff import getting stuck in this loop
765         if (!reader.supportsAnimation())
766         {
767             break;
768         }
769     }
770 
771     return true;
772 }
773 
importVectorImage(QString filePath)774 bool Editor::importVectorImage(QString filePath)
775 {
776     Q_ASSERT(layers()->currentLayer()->type() == Layer::VECTOR);
777 
778     auto layer = static_cast<LayerVector*>(layers()->currentLayer());
779 
780     VectorImage* vectorImage = layer->getVectorImageAtFrame(currentFrame());
781     if (vectorImage == nullptr)
782     {
783         addNewKey();
784         vectorImage = layer->getVectorImageAtFrame(currentFrame());
785     }
786 
787     VectorImage importedVectorImage;
788     bool ok = importedVectorImage.read(filePath);
789     if (ok)
790     {
791         importedVectorImage.selectAll();
792         vectorImage->paste(importedVectorImage);
793 
794         backup(tr("Import Image"));
795     }
796 
797     return ok;
798 }
799 
createNewBitmapLayer(const QString & name)800 void Editor::createNewBitmapLayer(const QString& name)
801 {
802     Layer* layer = layers()->createBitmapLayer(name);
803     layers()->setCurrentLayer(layer);
804 }
805 
createNewVectorLayer(const QString & name)806 void Editor::createNewVectorLayer(const QString& name)
807 {
808     Layer* layer = layers()->createVectorLayer(name);
809     layers()->setCurrentLayer(layer);
810 }
811 
createNewSoundLayer(const QString & name)812 void Editor::createNewSoundLayer(const QString& name)
813 {
814     Layer* layer = layers()->createVectorLayer(name);
815     layers()->setCurrentLayer(layer);
816 }
817 
createNewCameraLayer(const QString & name)818 void Editor::createNewCameraLayer(const QString& name)
819 {
820     Layer* layer = layers()->createCameraLayer(name);
821     layers()->setCurrentLayer(layer);
822 }
823 
importImage(QString filePath)824 bool Editor::importImage(QString filePath)
825 {
826     Layer* layer = layers()->currentLayer();
827 
828     if (view()->getImportFollowsCamera())
829     {
830         LayerCamera* camera = static_cast<LayerCamera*>(layers()->getLastCameraLayer());
831         QTransform transform = camera->getViewAtFrame(currentFrame());
832         view()->setImportView(transform);
833     }
834     switch (layer->type())
835     {
836     case Layer::BITMAP:
837         return importBitmapImage(filePath);
838 
839     case Layer::VECTOR:
840         return importVectorImage(filePath);
841 
842     default:
843     {
844         //mLastError = Status::ERROR_INVALID_LAYER_TYPE;
845         return false;
846     }
847     }
848 }
849 
importGIF(QString filePath,int numOfImages)850 bool Editor::importGIF(QString filePath, int numOfImages)
851 {
852     Layer* layer = layers()->currentLayer();
853     if (layer->type() == Layer::BITMAP)
854     {
855         return importBitmapImage(filePath, numOfImages);
856     }
857     return false;
858 }
859 
viewScaleInversed()860 qreal Editor::viewScaleInversed()
861 {
862     return view()->getViewInverse().m11();
863 }
864 
selectAll()865 void Editor::selectAll()
866 {
867     Layer* layer = layers()->currentLayer();
868 
869     QRectF rect;
870     if (layer->type() == Layer::BITMAP)
871     {
872         // Selects the drawn area (bigger or smaller than the screen). It may be more accurate to select all this way
873         // as the drawing area is not limited
874         BitmapImage *bitmapImage = static_cast<BitmapImage*>(layer->getLastKeyFrameAtPosition(mFrame));
875         if (bitmapImage == nullptr) { return; }
876 
877         rect = bitmapImage->bounds();
878     }
879     else if (layer->type() == Layer::VECTOR)
880     {
881         VectorImage *vectorImage = static_cast<VectorImage*>(layer->getLastKeyFrameAtPosition(mFrame));
882         if (vectorImage != nullptr)
883         {
884             vectorImage->selectAll();
885             rect = vectorImage->getSelectionRect();
886         }
887     }
888     select()->setSelection(rect, false);
889 }
890 
deselectAll()891 void Editor::deselectAll()
892 {
893     Layer* layer = layers()->currentLayer();
894     if (layer == nullptr) { return; }
895 
896     if (layer->type() == Layer::VECTOR)
897     {
898         VectorImage *vectorImage = static_cast<VectorImage*>(layer->getLastKeyFrameAtPosition(mFrame));
899         if (vectorImage != nullptr)
900         {
901             vectorImage->deselectAll();
902         }
903     }
904 
905     select()->resetSelectionProperties();
906 }
907 
updateFrame(int frameNumber)908 void Editor::updateFrame(int frameNumber)
909 {
910     mScribbleArea->updateFrame(frameNumber);
911 }
912 
updateCurrentFrame()913 void Editor::updateCurrentFrame()
914 {
915     mScribbleArea->updateCurrentFrame();
916 }
917 
setCurrentLayerIndex(int i)918 void Editor::setCurrentLayerIndex(int i)
919 {
920     mCurrentLayerIndex = i;
921 
922     Layer* layer = mObject->getLayer(i);
923     for (auto mgr : mAllManagers)
924     {
925         mgr->workingLayerChanged(layer);
926     }
927 }
928 
scrubTo(int frame)929 void Editor::scrubTo(int frame)
930 {
931     if (frame < 1) { frame = 1; }
932     mFrame = frame;
933 
934     emit scrubbed(frame);
935 
936     // FIXME: should not emit Timeline update here.
937     // Editor must be an individual class.
938     // Will remove all Timeline related code in Editor class.
939     if (mPlaybackManager && !mPlaybackManager->isPlaying())
940     {
941         emit updateTimeLine(); // needs to update the timeline to update onion skin positions
942     }
943     mObject->updateActiveFrames(frame);
944 }
945 
scrubForward()946 void Editor::scrubForward()
947 {
948     int nextFrame = mFrame + 1;
949     if (!playback()->isPlaying()) {
950         playback()->playScrub(nextFrame);
951     }
952     scrubTo(nextFrame);
953 }
954 
scrubBackward()955 void Editor::scrubBackward()
956 {
957     if (currentFrame() > 1)
958     {
959         int previousFrame = mFrame - 1;
960         if (!playback()->isPlaying()) {
961             playback()->playScrub(previousFrame);
962         }
963         scrubTo(previousFrame);
964     }
965 }
966 
addNewKey()967 KeyFrame* Editor::addNewKey()
968 {
969     return addKeyFrame(layers()->currentLayerIndex(), currentFrame());
970 }
971 
addKeyFrame(int layerNumber,int frameIndex)972 KeyFrame* Editor::addKeyFrame(int layerNumber, int frameIndex)
973 {
974     Layer* layer = mObject->getLayer(layerNumber);
975     if (layer == nullptr)
976     {
977         Q_ASSERT(false);
978         return nullptr;
979     }
980 
981     if (!layer->visible())
982     {
983         mScribbleArea->showLayerNotVisibleWarning();
984         return nullptr;
985     }
986 
987     // Find next available space for a keyframe (where either no key exists or there is an empty sound key)
988     while (layer->keyExists(frameIndex))
989     {
990         if (layer->type() == Layer::SOUND
991             && layer->getKeyFrameAt(frameIndex)->fileName().isEmpty()
992             && layer->removeKeyFrame(frameIndex))
993         {
994             break;
995         }
996         else
997         {
998             frameIndex += 1;
999         }
1000     }
1001 
1002     bool ok = layer->addNewKeyFrameAt(frameIndex);
1003     if (ok)
1004     {
1005         scrubTo(frameIndex); // currentFrameChanged() emit inside.
1006         emit frameModified(frameIndex);
1007         layers()->notifyAnimationLengthChanged();
1008     }
1009     return layer->getKeyFrameAt(frameIndex);
1010 }
1011 
removeKey()1012 void Editor::removeKey()
1013 {
1014     Layer* layer = layers()->currentLayer();
1015     Q_ASSERT(layer != nullptr);
1016 
1017     if (!layer->visible())
1018     {
1019         mScribbleArea->showLayerNotVisibleWarning();
1020         return;
1021     }
1022 
1023     if (!layer->keyExistsWhichCovers(currentFrame()))
1024     {
1025         return;
1026     }
1027 
1028     backup(tr("Remove frame"));
1029 
1030     deselectAll();
1031     layer->removeKeyFrame(currentFrame());
1032 
1033     scrubBackward();
1034     layers()->notifyAnimationLengthChanged();
1035     emit layers()->currentLayerChanged(layers()->currentLayerIndex()); // trigger timeline repaint.
1036 }
1037 
scrubNextKeyFrame()1038 void Editor::scrubNextKeyFrame()
1039 {
1040     Layer* layer = layers()->currentLayer();
1041     Q_ASSERT(layer);
1042 
1043     int nextPosition = layer->getNextKeyFramePosition(currentFrame());
1044     scrubTo(nextPosition);
1045 }
1046 
scrubPreviousKeyFrame()1047 void Editor::scrubPreviousKeyFrame()
1048 {
1049     Layer* layer = mObject->getLayer(layers()->currentLayerIndex());
1050     Q_ASSERT(layer);
1051 
1052     int prevPosition = layer->getPreviousKeyFramePosition(currentFrame());
1053     scrubTo(prevPosition);
1054 }
1055 
switchVisibilityOfLayer(int layerNumber)1056 void Editor::switchVisibilityOfLayer(int layerNumber)
1057 {
1058     Layer* layer = mObject->getLayer(layerNumber);
1059     if (layer != nullptr) layer->switchVisibility();
1060     mScribbleArea->onLayerChanged();
1061 
1062     emit updateTimeLine();
1063 }
1064 
swapLayers(int i,int j)1065 void Editor::swapLayers(int i, int j)
1066 {
1067     mObject->swapLayers(i, j);
1068     if (j < i)
1069     {
1070         layers()->setCurrentLayer(j + 1);
1071     }
1072     else
1073     {
1074         layers()->setCurrentLayer(j - 1);
1075     }
1076     emit updateTimeLine();
1077     mScribbleArea->onLayerChanged();
1078 }
1079 
pegBarAlignment(QStringList layers)1080 Status Editor::pegBarAlignment(QStringList layers)
1081 {
1082     PegbarResult retLeft;
1083     PegbarResult retRight;
1084 
1085     LayerBitmap* layerbitmap = static_cast<LayerBitmap*>(mLayerManager->currentLayer());
1086     BitmapImage* img = layerbitmap->getBitmapImageAtFrame(currentFrame());
1087     QRectF rect = select()->mySelectionRect();
1088     retLeft = img->findLeft(rect, 121);
1089     retRight = img->findTop(rect, 121);
1090     if (STATUS_FAILED(retLeft.errorcode) || STATUS_FAILED(retRight.errorcode))
1091     {
1092         return Status(Status::FAIL, "", tr("Peg hole not found!\nCheck selection, and please try again.", "PegBar error message"));
1093     }
1094     const int peg_x = retLeft.value;
1095     const int peg_y = retRight.value;
1096 
1097     // move other layers
1098     for (int i = 0; i < layers.count(); i++)
1099     {
1100         layerbitmap = static_cast<LayerBitmap*>(mLayerManager->findLayerByName(layers.at(i)));
1101         for (int k = layerbitmap->firstKeyFramePosition(); k <= layerbitmap->getMaxKeyFramePosition(); k++)
1102         {
1103             if (layerbitmap->keyExists(k))
1104             {
1105                 img = layerbitmap->getBitmapImageAtFrame(k);
1106                 retLeft = img->findLeft(rect, 121);
1107                 const QString errorDescription = tr("Peg bar not found at %1, %2").arg(layerbitmap->name()).arg(k);
1108                 if (STATUS_FAILED(retLeft.errorcode))
1109                 {
1110                     return Status(retLeft.errorcode, "", errorDescription);
1111                 }
1112                 retRight = img->findTop(rect, 121);
1113                 if (STATUS_FAILED(retRight.errorcode))
1114                 {
1115                     return Status(retRight.errorcode, "", errorDescription);
1116                 }
1117                 img->moveTopLeft(QPoint(img->left() + (peg_x - retLeft.value), img->top() + (peg_y - retRight.value)));
1118             }
1119         }
1120     }
1121     deselectAll();
1122 
1123     return retLeft.errorcode;
1124 }
1125 
prepareSave()1126 void Editor::prepareSave()
1127 {
1128     for (auto mgr : mAllManagers)
1129     {
1130         mgr->save(mObject.get());
1131     }
1132 }
1133 
clearCurrentFrame()1134 void Editor::clearCurrentFrame()
1135 {
1136     mScribbleArea->clearImage();
1137 }
1138