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