1 
2 
3 #include "tapp.h"
4 
5 // Tnz6 includes
6 #include "cleanupsettingspopup.h"
7 #include "iocommand.h"
8 #include "mainwindow.h"
9 #include "cellselection.h"
10 
11 // TnzTools includes
12 #include "tools/tool.h"
13 #include "tools/toolhandle.h"
14 #include "tools/toolcommandids.h"
15 
16 // TnzQt includes
17 #include "toonzqt/tselectionhandle.h"
18 #include "toonzqt/icongenerator.h"
19 #include "toonzqt/dvdialog.h"
20 #include "toonzqt/gutil.h"
21 
22 // TnzLib includes
23 #include "toonz/tframehandle.h"
24 #include "toonz/tcolumnhandle.h"
25 #include "toonz/tscenehandle.h"
26 #include "toonz/txsheethandle.h"
27 #include "toonz/txshlevelhandle.h"
28 #include "toonz/tstageobject.h"
29 #include "toonz/tobjecthandle.h"
30 #include "toonz/tonionskinmaskhandle.h"
31 #include "toonz/tfxhandle.h"
32 #include "toonz/tpalettehandle.h"
33 #include "toonz/sceneproperties.h"
34 #include "toonz/cleanupparameters.h"
35 #include "toonz/stage2.h"
36 #include "toutputproperties.h"
37 #include "toonz/palettecontroller.h"
38 #include "toonz/levelset.h"
39 #include "toonz/toonzscene.h"
40 #include "toonz/txshlevel.h"
41 #include "toonz/txshcell.h"
42 #include "toonz/txshsimplelevel.h"
43 #include "toonz/txshpalettelevel.h"
44 #include "toonz/txshleveltypes.h"
45 #include "toonz/tcamera.h"
46 #include "toonz/preferences.h"
47 #include "toonz/txshsoundcolumn.h"
48 
49 // TnzCore includes
50 #include "tbigmemorymanager.h"
51 #include "ttoonzimage.h"
52 #include "trasterimage.h"
53 #include "tunit.h"
54 #include "tsystem.h"
55 
56 // Qt includes
57 #include <QTimer>
58 #include <QDebug>
59 #include <QEvent>
60 #include <QCoreApplication>
61 #include <QApplication>
62 #include <QDesktopWidget>
63 
64 //===================================================================
65 
66 namespace {
67 
getCurrentCameraSize()68 double getCurrentCameraSize() {
69   return TApp::instance()
70       ->getCurrentScene()
71       ->getScene()
72       ->getCurrentCamera()
73       ->getSize()
74       .lx;
75 }
76 
getCurrentDpi()77 std::pair<double, double> getCurrentDpi() {
78   TPointD dpi = TApp::instance()
79                     ->getCurrentScene()
80                     ->getScene()
81                     ->getCurrentCamera()
82                     ->getDpi();
83   return std::make_pair(dpi.x, dpi.y);
84 }
85 
86 }  // namespace
87 
88 //=============================================================================
89 // TApp
90 //-----------------------------------------------------------------------------
91 
TApp()92 TApp::TApp()
93     : m_currentScene(0)
94     , m_currentXsheet(0)
95     , m_currentFrame(0)
96     , m_currentColumn(0)
97     , m_currentLevel(0)
98     , m_currentTool(0)
99     , m_currentObject(0)
100     , m_currentSelection(0)
101     , m_currentOnionSkinMask(0)
102     , m_currentFx(0)
103     , m_mainWindow(0)
104     , m_autosaveTimer(0)
105     , m_autosaveSuspended(false)
106     , m_isStarting(false)
107     , m_isPenCloseToTablet(false) {
108   m_currentScene         = new TSceneHandle();
109   m_currentXsheet        = new TXsheetHandle();
110   m_currentFrame         = new TFrameHandle();
111   m_currentColumn        = new TColumnHandle();
112   m_currentLevel         = new TXshLevelHandle();
113   m_currentTool          = new ToolHandle();
114   m_currentObject        = new TObjectHandle();
115   m_currentOnionSkinMask = new TOnionSkinMaskHandle();
116   m_currentFx            = new TFxHandle();
117   m_currentSelection     = TSelectionHandle::getCurrent();
118 
119   m_paletteController = new PaletteController();
120 
121   bool ret = true;
122 
123   ret = ret && QObject::connect(m_currentXsheet, SIGNAL(xsheetChanged()), this,
124                                 SLOT(onXsheetChanged()));
125 
126   ret = ret && QObject::connect(m_currentXsheet, SIGNAL(xsheetSoundChanged()),
127                                 this, SLOT(onXsheetSoundChanged()));
128 
129   ret = ret && QObject::connect(m_currentScene, SIGNAL(sceneSwitched()), this,
130                                 SLOT(onSceneSwitched()));
131 
132   ret = ret && QObject::connect(m_currentScene, SIGNAL(sceneChanged()), this,
133                                 SLOT(onSceneChanged()));
134 
135   ret = ret && QObject::connect(m_currentXsheet, SIGNAL(xsheetSwitched()), this,
136                                 SLOT(onXsheetSwitched()));
137 
138   ret = ret && QObject::connect(m_currentFrame, SIGNAL(frameSwitched()), this,
139                                 SLOT(onFrameSwitched()));
140 
141   ret = ret && QObject::connect(m_currentFrame, SIGNAL(frameSwitched()), this,
142                                 SLOT(onImageChanged()));
143 
144   ret = ret && QObject::connect(m_currentFx, SIGNAL(fxSwitched()), this,
145                                 SLOT(onFxSwitched()));
146 
147   ret = ret && QObject::connect(m_currentColumn, SIGNAL(columnIndexSwitched()),
148                                 this, SLOT(onColumnIndexSwitched()));
149 
150   ret = ret && QObject::connect(m_currentColumn, SIGNAL(columnIndexSwitched()),
151                                 this, SLOT(onImageChanged()));
152 
153   ret = ret &&
154         QObject::connect(m_currentLevel, SIGNAL(xshLevelSwitched(TXshLevel *)),
155                          this, SLOT(onImageChanged()));
156 
157   ret = ret &&
158         QObject::connect(m_currentLevel, SIGNAL(xshLevelSwitched(TXshLevel *)),
159                          this, SLOT(onXshLevelSwitched(TXshLevel *)));
160 
161   ret = ret && QObject::connect(m_currentLevel, SIGNAL(xshLevelChanged()), this,
162                                 SLOT(onXshLevelChanged()));
163 
164   ret = ret && QObject::connect(m_currentObject, SIGNAL(objectSwitched()), this,
165                                 SLOT(onObjectSwitched()));
166 
167   ret = ret && QObject::connect(m_currentObject, SIGNAL(splineChanged()), this,
168                                 SLOT(onSplineChanged()));
169 
170   ret = ret && QObject::connect(m_paletteController->getCurrentLevelPalette(),
171                                 SIGNAL(paletteChanged()), this,
172                                 SLOT(onPaletteChanged()));
173 
174   ret = ret && QObject::connect(m_paletteController->getCurrentLevelPalette(),
175                                 SIGNAL(colorStyleSwitched()), this,
176                                 SLOT(onLevelColorStyleSwitched()));
177 
178   ret = ret && QObject::connect(m_paletteController->getCurrentLevelPalette(),
179                                 SIGNAL(colorStyleChangedOnMouseRelease()), this,
180                                 SLOT(onLevelColorStyleChanged()));
181 
182   ret = ret && QObject::connect(m_paletteController->getCurrentCleanupPalette(),
183                                 SIGNAL(paletteChanged()), m_currentScene,
184                                 SIGNAL(sceneChanged()));
185 
186   TMeasureManager::instance()->addCameraMeasures(getCurrentCameraSize);
187 
188   m_autosaveTimer = new QTimer(this);
189   ret             = ret &&
190         connect(m_autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
191 
192   Preferences *preferences = Preferences::instance();
193 
194   if (preferences->isRasterOptimizedMemory()) {
195     if (!TBigMemoryManager::instance()->init(
196             (int)(/*15*1024*/ TSystem::getFreeMemorySize(true) * .8)))
197       DVGui::warning(tr("Error allocating memory: not enough memory."));
198   }
199   ret = ret &&
200         connect(preferences, SIGNAL(stopAutoSave()), SLOT(onStopAutoSave()));
201   ret = ret &&
202         connect(preferences, SIGNAL(startAutoSave()), SLOT(onStartAutoSave()));
203   ret = ret && connect(m_currentTool, SIGNAL(toolEditingFinished()),
204                        SLOT(onToolEditingFinished()));
205 
206   if (preferences->isAutosaveEnabled())
207     m_autosaveTimer->start(preferences->getAutosavePeriod() * 1000 * 60);
208 
209   UnitParameters::setCurrentDpiGetter(getCurrentDpi);
210   assert(ret);
211 }
212 
213 //-----------------------------------------------------------------------------
214 
instance()215 TApp *TApp::instance() {
216   static TApp _instance;
217   return &_instance;
218 }
219 
220 //-----------------------------------------------------------------------------
221 
~TApp()222 TApp::~TApp() {}
223 
224 //-----------------------------------------------------------------------------
225 
init()226 void TApp::init() {
227   m_isStarting = true;
228   IoCmd::newScene();
229   m_currentColumn->setColumnIndex(0);
230   m_currentFrame->setFrame(0);
231   m_isStarting = false;
232 }
233 
234 //-----------------------------------------------------------------------------
235 
getCurrentRoom() const236 TMainWindow *TApp::getCurrentRoom() const {
237   MainWindow *mainWindow = dynamic_cast<MainWindow *>(getMainWindow());
238   if (mainWindow)
239     return mainWindow->getCurrentRoom();
240   else
241     return 0;
242 }
243 
244 //-----------------------------------------------------------------------------
245 
writeSettings()246 void TApp::writeSettings() {
247   MainWindow *mainWindow = dynamic_cast<MainWindow *>(getMainWindow());
248   if (mainWindow) mainWindow->refreshWriteSettings();
249 }
250 
251 //-----------------------------------------------------------------------------
252 
getCurrentPalette() const253 TPaletteHandle *TApp::getCurrentPalette() const {
254   return m_paletteController->getCurrentPalette();
255 }
256 
257 //-----------------------------------------------------------------------------
258 
getCurrentLevelStyle() const259 TColorStyle *TApp::getCurrentLevelStyle() const {
260   return m_paletteController->getCurrentLevelPalette()->getStyle();
261 }
262 
263 //-----------------------------------------------------------------------------
264 
getCurrentLevelStyleIndex() const265 int TApp::getCurrentLevelStyleIndex() const {
266   return m_paletteController->getCurrentLevelPalette()->getStyleIndex();
267 }
268 
269 //-----------------------------------------------------------------------------
270 
setCurrentLevelStyleIndex(int index,bool forceUpdate)271 void TApp::setCurrentLevelStyleIndex(int index, bool forceUpdate) {
272   m_paletteController->getCurrentLevelPalette()->setStyleIndex(index,
273                                                                forceUpdate);
274 }
275 
276 //-----------------------------------------------------------------------------
277 
getCurrentImageType()278 int TApp::getCurrentImageType() {
279   /*-- 現在のセルの種類に関係無く、Splineを選択中はベクタを編集できるようにする
280    * --*/
281   if (getCurrentObject()->isSpline()) return TImage::VECTOR;
282 
283   TXshSimpleLevel *sl = 0;
284 
285   if (getCurrentFrame()->isEditingScene()) {
286     int row = getCurrentFrame()->getFrame();
287     int col = getCurrentColumn()->getColumnIndex();
288     if (col < 0) {
289       int levelType = Preferences::instance()->getDefLevelType();
290       return (levelType == PLI_XSHLEVEL)
291                  ? TImage::VECTOR
292                  :  // RASTER image type includes both TZI_XSHLEVEL
293                  (levelType == TZP_XSHLEVEL)
294                      ? TImage::TOONZ_RASTER
295                      : TImage::RASTER;  // and OVL_XSHLEVEL level types
296     }
297 
298     TXsheet *xsh = getCurrentXsheet()->getXsheet();
299     if (xsh->getColumn(col) && xsh->getColumn(col)->getSoundColumn())
300       return TImage::VECTOR;
301     TXshCell cell = xsh->getCell(row, col);
302     if (cell.isEmpty()) {
303       int r0, r1;
304       xsh->getCellRange(col, r0, r1);
305       if (0 <= r0 && r0 <= r1) {
306         /*-- Columnに格納されている一番上のLevelのTypeに合わせる--*/
307         cell = xsh->getCell(r0, col);
308       } else /*-- Columnが空の場合 --*/
309       {
310         int levelType = Preferences::instance()->getDefLevelType();
311         return (levelType == PLI_XSHLEVEL)
312                    ? TImage::VECTOR
313                    : (levelType == TZP_XSHLEVEL) ? TImage::TOONZ_RASTER
314                                                  : TImage::RASTER;
315       }
316     }
317 
318     sl = cell.getSimpleLevel();
319   } else if (getCurrentFrame()->isEditingLevel())
320     sl = getCurrentLevel()->getSimpleLevel();
321 
322   if (sl) {
323     switch (sl->getType()) {
324     case TZP_XSHLEVEL:
325       return TImage::TOONZ_RASTER;
326     case OVL_XSHLEVEL:
327       return TImage::RASTER;
328     case PLI_XSHLEVEL:
329     default:
330       return TImage::VECTOR;
331     case MESH_XSHLEVEL:
332       return TImage::MESH;
333     }
334   }
335 
336   return TImage::VECTOR;
337 }
338 
339 //-----------------------------------------------------------------------------
340 
updateXshLevel()341 void TApp::updateXshLevel() {
342   TXshLevel *xl = 0;
343   if (m_currentFrame->isEditingScene()) {
344     int frame       = m_currentFrame->getFrame();
345     int column      = m_currentColumn->getColumnIndex();
346     TXsheet *xsheet = m_currentXsheet->getXsheet();
347 
348     // sound column case
349     if (xsheet->getColumn(column) &&
350         xsheet->getColumn(column)->getSoundColumn()) {
351       if (xsheet->getColumn(column)->getSoundColumn()->m_levels.size() > 0) {
352         xl = static_cast<TXshLevel *>(xsheet->getColumn(column)
353                                           ->getSoundColumn()
354                                           ->m_levels.at(0)
355                                           ->getSoundLevel());
356       }
357     } else if (xsheet && column >= 0 && frame >= 0 &&
358                !xsheet->isColumnEmpty(column)) {
359       TXshCell cell = xsheet->getCell(frame, column);
360       xl            = cell.m_level.getPointer();
361 
362       // Se sono su una cella vuota successiva a celle di un certo livello
363       // prendo questo come livello corrente.
364       if (!xl && frame > 0) {
365         TXshCell cell = xsheet->getCell(frame - 1, column);
366         xl            = cell.m_level.getPointer();
367       }
368     }
369 
370     m_currentLevel->setLevel(xl);
371 
372     // level could be the same, but palette could have changed
373     if (xl && xl->getSimpleLevel()) {
374       TPalette *currentPalette =
375           m_paletteController->getCurrentPalette()->getPalette();
376       int styleIndex =
377           m_paletteController->getCurrentLevelPalette()->getStyleIndex();
378 
379       m_paletteController->getCurrentLevelPalette()->setPalette(
380           xl->getSimpleLevel()->getPalette(), styleIndex);
381 
382       // Se il nuovo livello selezionato e' un ovl,
383       // la paletta corrente e' una cleanup palette
384       //  => setto come handle corrente quello della paletta di cleanup.
385 
386       if (xl->getType() == OVL_XSHLEVEL && currentPalette &&
387           currentPalette->isCleanupPalette())
388 
389         m_paletteController->editCleanupPalette();
390     } else if (xl && xl->getPaletteLevel()) {
391       int styleIndex =
392           m_paletteController->getCurrentLevelPalette()->getStyleIndex();
393       m_paletteController->getCurrentLevelPalette()->setPalette(
394           xl->getPaletteLevel()->getPalette(), styleIndex);
395     } else
396       m_paletteController->getCurrentLevelPalette()->setPalette(0);
397   }
398 }
399 
400 //-----------------------------------------------------------------------------
401 
updateCurrentFrame()402 void TApp::updateCurrentFrame() {
403   ToonzScene *scene = m_currentScene->getScene();
404   m_currentFrame->setSceneFrameSize(scene->getFrameCount());
405   int f0, f1, step;
406   scene->getProperties()->getPreviewProperties()->getRange(f0, f1, step);
407   if (f0 > f1) {
408     f0 = 0;
409     f1 = scene->getFrameCount() - 1;
410   }
411   if (f0 != m_currentFrame->getStartFrame() ||
412       f1 != m_currentFrame->getEndFrame()) {
413     m_currentFrame->setFrameRange(f0, f1);
414     std::vector<TFrameId> fids;
415     TXshSimpleLevel *sl = m_currentLevel->getSimpleLevel();
416     if (sl) {
417       sl->getFids(fids);
418       m_currentFrame->setFrameIds(fids);
419     }
420   }
421 }
422 
423 //-----------------------------------------------------------------------------
424 
onSceneSwitched()425 void TApp::onSceneSwitched() {
426   // update XSheet
427   m_currentXsheet->setXsheet(m_currentScene->getScene()->getXsheet());
428 
429   TPalette *palette = m_currentScene->getScene()
430                           ->getProperties()
431                           ->getCleanupParameters()
432                           ->m_cleanupPalette.getPointer();
433   m_paletteController->getCurrentCleanupPalette()->setPalette(palette, -1);
434   m_paletteController->editLevelPalette();
435 
436   // reset current frame
437   m_currentFrame->setFrame(0);
438 
439   // clear current onionSkinMask
440   m_currentOnionSkinMask->clear();
441 
442   // update currentFrames
443   updateCurrentFrame();
444 
445   // update current tool
446   m_currentTool->onImageChanged((TImage::Type)getCurrentImageType());
447 }
448 
449 //-----------------------------------------------------------------------------
450 
onImageChanged()451 void TApp::onImageChanged() {
452   m_currentTool->onImageChanged((TImage::Type)getCurrentImageType());
453 }
454 
455 //-----------------------------------------------------------------------------
456 
onXsheetSwitched()457 void TApp::onXsheetSwitched() {
458   // update current object
459   int columnIndex = m_currentColumn->getColumnIndex();
460   if (columnIndex >= 0)
461     m_currentObject->setObjectId(TStageObjectId::ColumnId(columnIndex));
462 
463   // update xsheetlevel
464   updateXshLevel();
465 
466   // no Fx is setted to current.
467   m_currentFx->setFx(0);
468 }
469 
470 //-----------------------------------------------------------------------------
471 
onXsheetChanged()472 void TApp::onXsheetChanged() {
473   updateXshLevel();
474   updateCurrentFrame();
475   // update current tool
476   m_currentTool->onImageChanged((TImage::Type)getCurrentImageType());
477 }
478 
479 //-----------------------------------------------------------------------------
480 
onXsheetSoundChanged()481 void TApp::onXsheetSoundChanged() {
482   m_currentXsheet->getXsheet()->invalidateSound();
483 }
484 
485 //-----------------------------------------------------------------------------
486 
onFrameSwitched()487 void TApp::onFrameSwitched() {
488   updateXshLevel();
489   int row = m_currentFrame->getFrameIndex();
490   TCellSelection *sel =
491       dynamic_cast<TCellSelection *>(TSelection::getCurrent());
492 
493   if (sel && !sel->isRowSelected(row) &&
494       !Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled()) {
495     sel->selectNone();
496   }
497 }
498 
499 //-----------------------------------------------------------------------------
500 
onFxSwitched()501 void TApp::onFxSwitched() {
502   //  if(m_currentFx->getFx() != 0)
503   //    m_currentTool->setTool(T_Edit);
504 }
505 
506 //-----------------------------------------------------------------------------
507 
onColumnIndexSwitched()508 void TApp::onColumnIndexSwitched() {
509   // update xsheetlevel
510   updateXshLevel();
511 
512   // update current object
513   int columnIndex = m_currentColumn->getColumnIndex();
514   if (columnIndex >= 0)
515     m_currentObject->setObjectId(TStageObjectId::ColumnId(columnIndex));
516   else {
517     TXsheet *xsh = getCurrentXsheet()->getXsheet();
518     m_currentObject->setObjectId(
519         TStageObjectId::CameraId(xsh->getCameraColumnIndex()));
520   }
521 }
522 
523 //-----------------------------------------------------------------------------
524 
onXshLevelSwitched(TXshLevel *)525 void TApp::onXshLevelSwitched(TXshLevel *) {
526   TXshLevel *level = m_currentLevel->getLevel();
527   if (level) {
528     TXshSimpleLevel *simpleLevel = level->getSimpleLevel();
529 
530     // Devo aggiornare la paletta corrente
531     if (simpleLevel) {
532       m_paletteController->getCurrentLevelPalette()->setPalette(
533           simpleLevel->getPalette());
534 
535       // Se il nuovo livello selezionato e' un ovl,
536       // la paletta corrente e' una cleanup palette
537       //  => setto come handle corrente quello della paletta di cleanup.
538       TPalette *currentPalette =
539           m_paletteController->getCurrentPalette()->getPalette();
540 
541       if (simpleLevel->getType() == OVL_XSHLEVEL && currentPalette &&
542           currentPalette->isCleanupPalette())
543         m_paletteController->editCleanupPalette();
544 
545       return;
546     }
547 
548     TXshPaletteLevel *paletteLevel = level->getPaletteLevel();
549     if (paletteLevel) {
550       m_paletteController->getCurrentLevelPalette()->setPalette(
551           paletteLevel->getPalette());
552       return;
553     }
554   }
555 
556   m_paletteController->getCurrentLevelPalette()->setPalette(0);
557 }
558 
559 //-----------------------------------------------------------------------------
560 
onXshLevelChanged()561 void TApp::onXshLevelChanged() {
562   TXshLevel *level = m_currentLevel->getLevel();
563   std::vector<TFrameId> fids;
564   if (level != 0) level->getFids(fids);
565   m_currentFrame->setFrameIds(fids);
566   // update current tool
567   m_currentTool->onImageChanged((TImage::Type)getCurrentImageType());
568 }
569 //-----------------------------------------------------------------------------
570 
onObjectSwitched()571 void TApp::onObjectSwitched() {
572   if (m_currentObject->isSpline()) {
573     TXsheet *xsh = m_currentXsheet->getXsheet();
574     TStageObject *currentObject =
575         xsh->getStageObject(m_currentObject->getObjectId());
576     TStageObjectSpline *ps = currentObject->getSpline();
577     m_currentObject->setSplineObject(ps);
578   } else
579     m_currentObject->setSplineObject(0);
580   onImageChanged();
581 }
582 
583 //-----------------------------------------------------------------------------
584 
onSplineChanged()585 void TApp::onSplineChanged() {
586   if (m_currentObject->isSpline()) {
587     TXsheet *xsh = m_currentXsheet->getXsheet();
588     TStageObject *currentObject =
589         xsh->getStageObject(m_currentObject->getObjectId());
590     currentObject->setOffset(
591         currentObject->getOffset());  // invalidate currentObject
592   }
593 }
594 
595 //-----------------------------------------------------------------------------
596 
onSceneChanged()597 void TApp::onSceneChanged() {
598   updateCurrentFrame();
599   m_currentTool->updateMatrix();
600 }
601 
602 //-----------------------------------------------------------------------------
603 
onPaletteChanged()604 void TApp::onPaletteChanged() { m_currentScene->setDirtyFlag(true); }
605 
606 //-----------------------------------------------------------------------------
607 
onLevelColorStyleSwitched()608 void TApp::onLevelColorStyleSwitched() {
609   TXshLevel *sl = m_currentLevel->getLevel();
610   if (!sl || (sl->getType() != TZP_XSHLEVEL && sl->getType() != PLI_XSHLEVEL))
611     return;
612 
613   TPaletteHandle *ph = m_paletteController->getCurrentLevelPalette();
614   assert(ph);
615 
616   if (ToonzCheck::instance()->setColorIndex(ph->getStyleIndex())) {
617     ToonzCheck *tc = ToonzCheck::instance();
618     int mask       = tc->getChecks();
619 
620     if (mask & ToonzCheck::eInk || mask & ToonzCheck::ePaint) {
621       IconGenerator::Settings s;
622       s.m_blackBgCheck      = mask & ToonzCheck::eBlackBg;
623       s.m_transparencyCheck = mask & ToonzCheck::eTransparency;
624       s.m_inksOnly          = mask & ToonzCheck::eInksOnly;
625       s.m_inkIndex   = mask & ToonzCheck::eInk ? tc->getColorIndex() : -1;
626       s.m_paintIndex = mask & ToonzCheck::ePaint ? tc->getColorIndex() : -1;
627 
628       IconGenerator::instance()->setSettings(s);
629 
630       if (sl->getType() == PLI_XSHLEVEL) {
631         std::vector<TFrameId> fids;
632         sl->getFids(fids);
633         for (int i = 0; i < (int)fids.size(); i++)
634           IconGenerator::instance()->invalidate(sl, fids[i]);
635       }
636 
637       m_currentLevel->notifyLevelViewChange();
638     }
639 
640     /*-- 表示オプションが切り替わっただけなので、DirtyFlagを立てない --*/
641     m_currentScene->notifySceneChanged(false);
642   }
643 }
644 
645 //-----------------------------------------------------------------------------
646 
notifyPaletteChanged(TXshSimpleLevel * simpleLevel)647 static void notifyPaletteChanged(TXshSimpleLevel *simpleLevel) {
648   simpleLevel->onPaletteChanged();
649   // palette change can update icons only for ToonzVector / ToonzRaster types
650   if (simpleLevel->getType() != TZP_XSHLEVEL &&
651       simpleLevel->getType() != PLI_XSHLEVEL)
652     return;
653   std::vector<TFrameId> fids;
654   simpleLevel->getFids(fids);
655   // ToonzRaster level does not need to re-generate icons along with palette
656   // changes since the icons are cached as color mapped images and the current
657   // palette is applied just before using it. So here we just emit the signal to
658   // update related panels.
659   if (simpleLevel->getType() == TZP_XSHLEVEL)
660     IconGenerator::instance()->notifyIconGenerated();
661   else {  // ToonzVecor needs to re-generate icons since it includes colors in
662           // the cache.
663     for (int i = 0; i < (int)fids.size(); i++)
664       IconGenerator::instance()->invalidate(simpleLevel, fids[i]);
665   }
666 }
667 
668 //-----------------------------------------------------------------------------
669 
onLevelColorStyleChanged()670 void TApp::onLevelColorStyleChanged() {
671   onPaletteChanged();
672   TXshLevel *level = m_currentLevel->getLevel();
673   if (!level) return;
674   TPalette *palette            = getCurrentPalette()->getPalette();
675   TXshSimpleLevel *simpleLevel = level->getSimpleLevel();
676   if (simpleLevel && simpleLevel->getPalette() == palette) {
677     notifyPaletteChanged(simpleLevel);
678   } else {
679     TLevelSet *levelSet = getCurrentScene()->getScene()->getLevelSet();
680     for (int i = 0; i < levelSet->getLevelCount(); i++) {
681       if (levelSet->getLevel(i)) {
682         simpleLevel = levelSet->getLevel(i)->getSimpleLevel();
683         if (simpleLevel && simpleLevel->getPalette() == palette) {
684           notifyPaletteChanged(simpleLevel);
685         }
686       }
687     }
688   }
689 }
690 
691 //-----------------------------------------------------------------------------
692 
autosave()693 void TApp::autosave() {
694   ToonzScene *scene = getCurrentScene()->getScene();
695 
696   if (!getCurrentScene()->getDirtyFlag()) return;
697 
698   if (getCurrentTool()->isToolBusy()) {
699     m_autosaveSuspended = true;
700     return;
701   } else
702     m_autosaveSuspended = false;
703 
704   DVGui::ProgressDialog pb(
705       "Autosaving scene..." + toQString(scene->getScenePath()), 0, 0, 1);
706   pb.show();
707   Preferences *pref = Preferences::instance();
708   if (pref->isAutosaveSceneEnabled() && pref->isAutosaveOtherFilesEnabled()) {
709     IoCmd::saveAll();
710   } else if (pref->isAutosaveSceneEnabled()) {
711     IoCmd::saveScene();
712   } else if (pref->isAutosaveOtherFilesEnabled()) {
713     IoCmd::saveNonSceneFiles();
714   }
715 
716   pb.setValue(1);
717 }
718 
719 //-----------------------------------------------------------------------------
720 
onToolEditingFinished()721 void TApp::onToolEditingFinished() {
722   if (!Preferences::instance()->isAutosaveEnabled() || !m_autosaveSuspended)
723     return;
724   autosave();
725 }
726 
727 //-----------------------------------------------------------------------------
728 
onStartAutoSave()729 void TApp::onStartAutoSave() {
730   assert(Preferences::instance()->isAutosaveEnabled());
731   m_autosaveTimer->start(Preferences::instance()->getAutosavePeriod() * 1000 *
732                          60);
733 }
734 
735 //-----------------------------------------------------------------------------
736 
onStopAutoSave()737 void TApp::onStopAutoSave() {
738   // assert(!Preferences::instance()->isAutosaveEnabled());
739   m_autosaveTimer->stop();
740 }
741 
742 //-----------------------------------------------------------------------------
743 
eventFilter(QObject * watched,QEvent * e)744 bool TApp::eventFilter(QObject *watched, QEvent *e) {
745   if (e->type() == QEvent::TabletEnterProximity) {
746     m_isPenCloseToTablet = true;
747   } else if (e->type() == QEvent::TabletLeaveProximity) {
748     // if the user is painting very quickly with the pen, a number of events
749     // could be still in the queue
750     // the must be processed as tabled events (not mouse events)
751     qApp->processEvents();
752 
753     m_isPenCloseToTablet = false;
754     emit tabletLeft();
755   }
756 
757   return false;  // I want just peek at the event. It must be processed anyway.
758 }
759 
760 //-----------------------------------------------------------------------------
761 
getCurrentRoomName() const762 QString TApp::getCurrentRoomName() const {
763   Room *currentRoom = dynamic_cast<Room *>(getCurrentRoom());
764   if (!currentRoom) return QString();
765 
766   return currentRoom->getName();
767 }
768