Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 47ab303

Browse files
authored
Merge pull request #3755 from shun-iwasawa/g/clean_assets
Auto Cleaning Assets Feature
2 parents fff79ff + efd2900 commit 47ab303

File tree

12 files changed

+208
-66
lines changed

12 files changed

+208
-66
lines changed

toonz/sources/include/toonz/preferences.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ class DVAPI Preferences final : public QObject // singleton
270270
int matchLevelFormat(const TFilePath &fp)
271271
const; //!< Returns the \a nonnegative index of the first level format
272272
//! matching the specified file path, <I>or \p -1 if none</I>.
273+
bool isAutoRemoveUnusedLevelsEnabled() const {
274+
return isAutoExposeEnabled() && getBoolValue(autoRemoveUnusedLevels);
275+
}
273276

274277
// Saving tab
275278
TPixel getRasterBackgroundColor() const {

toonz/sources/include/toonz/preferencesitemids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum PreferencesItemId {
5757
initialLoadTlvCachingBehavior,
5858
columnIconLoadingPolicy,
5959
levelFormats, // need to be handle separately
60+
autoRemoveUnusedLevels,
6061

6162
//----------
6263
// Saving

toonz/sources/include/toonz/toonzscene.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ If \b scene is in +scenes/name.tnz return name,
286286
ToonzScene(const ToonzScene &);
287287
ToonzScene &operator=(const ToonzScene &);
288288

289+
public:
289290
// if the option is set in the preferences,
290291
// remove the scene numbers("c####_") from the file name
291292
std::wstring getLevelNameWithoutSceneNumber(std::wstring orgName);

toonz/sources/toonz/iocommand.cpp

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "cachefxcommand.h"
2222
#include "xdtsio.h"
2323
#include "expressionreferencemanager.h"
24+
#include "levelcommand.h"
2425

2526
// TnzTools includes
2627
#include "tools/toolhandle.h"
@@ -355,6 +356,37 @@ int getLevelType(const TFilePath &actualPath) {
355356
return UNKNOWN_XSHLEVEL;
356357
}
357358

359+
//===========================================================================
360+
// removeSameNamedUnusedLevel(scene, actualPath, levelName);
361+
//---------------------------------------------------------------------------
362+
363+
void removeSameNamedUnusedLevel(ToonzScene *scene, const TFilePath actualPath,
364+
std::wstring levelName) {
365+
if (QString::fromStdWString(levelName).isEmpty()) {
366+
// if the option is set in the preferences,
367+
// remove the scene numbers("c####_") from the file name
368+
levelName = scene->getLevelNameWithoutSceneNumber(actualPath.getWideName());
369+
}
370+
371+
TLevelSet *levelSet = scene->getLevelSet();
372+
NameModifier nm(levelName);
373+
levelName = nm.getNext();
374+
while (1) {
375+
TXshLevel *existingLevel = levelSet->getLevel(levelName);
376+
// if the level name is not used in the cast, nothing to do
377+
if (!existingLevel) return;
378+
// try if the existing level is unused in the xsheet and remove from the
379+
// cast
380+
else if (LevelCmd::removeLevelFromCast(existingLevel, scene, false)) {
381+
DVGui::info(QObject::tr("Removed unused level %1 from the scene cast. "
382+
"(This behavior can be disabled in Preferences.)")
383+
.arg(QString::fromStdWString(levelName)));
384+
return;
385+
}
386+
levelName = nm.getNext();
387+
}
388+
}
389+
358390
//===========================================================================
359391
// class LoadLevelUndo
360392
//---------------------------------------------------------------------------
@@ -875,6 +907,11 @@ TXshLevel *loadLevel(ToonzScene *scene,
875907
bool isFirstTime = !xl;
876908
std::wstring name = actualPath.getWideName();
877909

910+
if (isFirstTime && expose &&
911+
Preferences::instance()->isAutoRemoveUnusedLevelsEnabled()) {
912+
removeSameNamedUnusedLevel(scene, actualPath, levelName);
913+
}
914+
878915
IoCmd::ConvertingPopup *convertingPopup = new IoCmd::ConvertingPopup(
879916
TApp::instance()->getMainWindow(),
880917
QString::fromStdWString(name) +
@@ -1365,6 +1402,7 @@ void IoCmd::newScene() {
13651402
bool IoCmd::saveScene(const TFilePath &path, int flags) {
13661403
bool overwrite = (flags & SILENTLY_OVERWRITE) != 0;
13671404
bool saveSubxsheet = (flags & SAVE_SUBXSHEET) != 0;
1405+
bool isAutosave = (flags & AUTO_SAVE) != 0;
13681406
TApp *app = TApp::instance();
13691407

13701408
assert(!path.isEmpty());
@@ -1404,6 +1442,15 @@ bool IoCmd::saveScene(const TFilePath &path, int flags) {
14041442
TXsheet *xsheet = 0;
14051443
if (saveSubxsheet) xsheet = TApp::instance()->getCurrentXsheet()->getXsheet();
14061444

1445+
// Automatically remove unused levels
1446+
if (!saveSubxsheet && !isAutosave &&
1447+
Preferences::instance()->isAutoRemoveUnusedLevelsEnabled()) {
1448+
if (LevelCmd::removeUnusedLevelsFromCast(false))
1449+
DVGui::info(
1450+
QObject::tr("Removed unused levels from the scene cast. (This "
1451+
"behavior can be disabled in Preferences.)"));
1452+
}
1453+
14071454
// If the scene will be saved in the different folder, check out the scene
14081455
// cast.
14091456
// if the cast contains the level specified with $scenefolder alias,
@@ -1510,7 +1557,7 @@ bool IoCmd::saveScene(const TFilePath &path, int flags) {
15101557
// IoCmd::saveScene()
15111558
//---------------------------------------------------------------------------
15121559

1513-
bool IoCmd::saveScene() {
1560+
bool IoCmd::saveScene(int flags) {
15141561
TSelection *oldSelection =
15151562
TApp::instance()->getCurrentSelection()->getSelection();
15161563
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
@@ -1528,7 +1575,7 @@ bool IoCmd::saveScene() {
15281575
} else {
15291576
TFilePath fp = scene->getScenePath();
15301577
// salva la scena con il nome fp. se fp esiste gia' lo sovrascrive
1531-
return saveScene(fp, SILENTLY_OVERWRITE);
1578+
return saveScene(fp, SILENTLY_OVERWRITE | flags);
15321579
}
15331580
}
15341581

@@ -1673,10 +1720,10 @@ bool IoCmd::saveLevel(TXshSimpleLevel *sl) {
16731720
// IoCmd::saveAll()
16741721
//---------------------------------------------------------------------------
16751722

1676-
bool IoCmd::saveAll() {
1723+
bool IoCmd::saveAll(int flags) {
16771724
// try to save as much as possible
16781725
// if anything is wrong, return false
1679-
bool result = saveScene();
1726+
bool result = saveScene(flags);
16801727

16811728
TApp *app = TApp::instance();
16821729
ToonzScene *scene = app->getCurrentScene()->getScene();

toonz/sources/toonz/iocommand.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ bool loadSubScene(const TFilePath &scenePath);
186186
enum SaveSceneFlags {
187187
SILENTLY_OVERWRITE = 0x1,
188188
SAVE_SUBXSHEET = 0x2,
189+
AUTO_SAVE = 0x4
189190
};
190191

191192
// ritorna true sse la scena e' stata salvata
@@ -196,15 +197,15 @@ enum SaveSceneFlags {
196197
// 0 salva comunque
197198
// tutta la scena, altrimenti solo il sottoxsheet
198199
bool saveScene(const TFilePath &fp, int flags);
199-
bool saveScene();
200+
bool saveScene(int flags = 0);
200201

201202
bool saveLevel(const TFilePath &fp);
202203
bool saveLevel();
203204

204205
bool saveLevel(const TFilePath &fp, TXshSimpleLevel *sl, bool overwrite);
205206
bool saveLevel(TXshSimpleLevel *sl);
206207

207-
bool saveAll();
208+
bool saveAll(int flags = 0);
208209

209210
void saveNonSceneFiles();
210211

toonz/sources/toonz/levelcommand.cpp

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -62,46 +62,70 @@ class DeleteLevelUndo final : public TUndo {
6262

6363
} // namespace
6464

65-
//=============================================================================
66-
// RemoveUnusedLevelCommand
6765
//-----------------------------------------------------------------------------
6866

69-
class RemoveUnusedLevelsCommand final : public MenuItemHandler {
70-
public:
71-
RemoveUnusedLevelsCommand() : MenuItemHandler(MI_RemoveUnused) {}
67+
bool LevelCmd::removeUnusedLevelsFromCast(bool showMessage) {
68+
TApp *app = TApp::instance();
69+
ToonzScene *scene = app->getCurrentScene()->getScene();
7270

73-
void execute() override {
74-
TApp *app = TApp::instance();
75-
ToonzScene *scene = app->getCurrentScene()->getScene();
71+
TLevelSet *levelSet = scene->getLevelSet();
7672

77-
TLevelSet *levelSet = scene->getLevelSet();
73+
std::set<TXshLevel *> usedLevels;
74+
scene->getTopXsheet()->getUsedLevels(usedLevels);
7875

79-
std::set<TXshLevel *> usedLevels;
80-
scene->getTopXsheet()->getUsedLevels(usedLevels);
76+
std::vector<TXshLevel *> unused;
8177

82-
std::vector<TXshLevel *> unused;
83-
84-
for (int i = 0; i < levelSet->getLevelCount(); i++) {
85-
TXshLevel *xl = levelSet->getLevel(i);
86-
if (usedLevels.count(xl) == 0) unused.push_back(xl);
78+
for (int i = 0; i < levelSet->getLevelCount(); i++) {
79+
TXshLevel *xl = levelSet->getLevel(i);
80+
if (usedLevels.count(xl) == 0) unused.push_back(xl);
81+
}
82+
if (unused.empty()) {
83+
if (showMessage) DVGui::error(QObject::tr("No unused levels"));
84+
return false;
85+
} else {
86+
TUndoManager *um = TUndoManager::manager();
87+
um->beginBlock();
88+
for (int i = 0; i < (int)unused.size(); i++) {
89+
TXshLevel *xl = unused[i];
90+
um->add(new DeleteLevelUndo(xl));
91+
scene->getLevelSet()->removeLevel(xl);
8792
}
88-
if (unused.empty()) {
89-
DVGui::error(QObject::tr("No unused levels"));
90-
return;
91-
} else {
92-
TUndoManager *um = TUndoManager::manager();
93-
um->beginBlock();
94-
for (int i = 0; i < (int)unused.size(); i++) {
95-
TXshLevel *xl = unused[i];
96-
um->add(new DeleteLevelUndo(xl));
97-
scene->getLevelSet()->removeLevel(xl);
98-
}
99-
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
100-
TApp::instance()->getCurrentScene()->notifyCastChange();
93+
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
94+
TApp::instance()->getCurrentScene()->notifyCastChange();
95+
96+
um->endBlock();
97+
}
98+
return true;
99+
}
101100

102-
um->endBlock();
101+
bool LevelCmd::removeLevelFromCast(TXshLevel *level, ToonzScene *scene,
102+
bool showMessage) {
103+
if (!scene) scene = TApp::instance()->getCurrentScene()->getScene();
104+
if (scene->getChildStack()->getTopXsheet()->isLevelUsed(level)) {
105+
if (showMessage) {
106+
DVGui::error(
107+
QObject::tr("It is not possible to delete the used level %1.")
108+
.arg(QString::fromStdWString(
109+
level->getName()))); //"E_CantDeleteUsedLevel_%1"
103110
}
111+
return false;
112+
} else {
113+
TUndoManager *um = TUndoManager::manager();
114+
um->add(new DeleteLevelUndo(level));
115+
scene->getLevelSet()->removeLevel(level);
104116
}
117+
return true;
118+
}
119+
120+
//=============================================================================
121+
// RemoveUnusedLevelCommand
122+
//-----------------------------------------------------------------------------
123+
124+
class RemoveUnusedLevelsCommand final : public MenuItemHandler {
125+
public:
126+
RemoveUnusedLevelsCommand() : MenuItemHandler(MI_RemoveUnused) {}
127+
128+
void execute() override { LevelCmd::removeUnusedLevelsFromCast(); }
105129
} removeUnusedLevelsCommand;
106130

107131
//=============================================================================
@@ -112,22 +136,6 @@ class RemoveLevelCommand final : public MenuItemHandler {
112136
public:
113137
RemoveLevelCommand() : MenuItemHandler(MI_RemoveLevel) {}
114138

115-
bool removeLevel(TXshLevel *level) {
116-
TApp *app = TApp::instance();
117-
ToonzScene *scene = app->getCurrentScene()->getScene();
118-
if (scene->getChildStack()->getTopXsheet()->isLevelUsed(level))
119-
DVGui::error(
120-
QObject::tr("It is not possible to delete the used level %1.")
121-
.arg(QString::fromStdWString(
122-
level->getName()))); //"E_CantDeleteUsedLevel_%1"
123-
else {
124-
TUndoManager *um = TUndoManager::manager();
125-
um->add(new DeleteLevelUndo(level));
126-
scene->getLevelSet()->removeLevel(level);
127-
}
128-
return true;
129-
}
130-
131139
void execute() override {
132140
TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet();
133141
CastSelection *castSelection =
@@ -142,7 +150,7 @@ class RemoveLevelCommand final : public MenuItemHandler {
142150
}
143151
int count = 0;
144152
for (int i = 0; i < (int)levels.size(); i++)
145-
if (removeLevel(levels[i])) count++;
153+
if (LevelCmd::removeLevelFromCast(levels[i])) count++;
146154
if (count == 0) return;
147155
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
148156
TApp::instance()->getCurrentScene()->notifyCastChange();
@@ -522,7 +530,24 @@ void LevelCmd::addMissingLevelsToCast(std::set<TXshLevel *> &levels) {
522530
std::wstring oldName = levelName;
523531
NameModifier nm(levelName);
524532
levelName = nm.getNext();
525-
while (levelSet->hasLevel(levelName)) levelName = nm.getNext();
533+
while (1) {
534+
TXshLevel *existingLevel = levelSet->getLevel(levelName);
535+
// if the level name is not used in the cast, nothing to do
536+
if (!existingLevel) break;
537+
// try if the existing level is unused in the xsheet and remove from the
538+
// cast
539+
else if (Preferences::instance()->isAutoRemoveUnusedLevelsEnabled() &&
540+
LevelCmd::removeLevelFromCast(
541+
existingLevel,
542+
TApp::instance()->getCurrentScene()->getScene(), false)) {
543+
DVGui::info(
544+
QObject::tr("Removed unused level %1 from the scene cast. (This "
545+
"behavior can be disabled in Preferences.)")
546+
.arg(QString::fromStdWString(levelName)));
547+
break;
548+
}
549+
levelName = nm.getNext();
550+
}
526551
addLevelToCastUndo *undo =
527552
new addLevelToCastUndo(level, levelName, oldName);
528553
undo->m_isLastInRedoBlock = false; // prevent to emit signal

toonz/sources/toonz/levelcommand.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,23 @@
99
#include <QList>
1010

1111
class TXshLevel;
12+
class ToonzScene;
1213

1314
namespace LevelCmd {
1415
void addMissingLevelsToCast(const QList<TXshColumnP>& columns);
1516
void addMissingLevelsToCast(std::set<TXshLevel*>& levels);
17+
18+
// Remove all unused level from the scene cast.
19+
// When there is no unused level, show an error message if showmessage==true.
20+
// Return true if something is removed.
21+
bool removeUnusedLevelsFromCast(bool showMessage = true);
22+
23+
// Remove the level from the scene cast if it is not used in the xsheet.
24+
// Return true if the level is unused and removed.
25+
// When the level is used, an show error message if showMessage==true and
26+
// returns false.
27+
bool removeLevelFromCast(TXshLevel* level, ToonzScene* scene = nullptr,
28+
bool showMessage = true);
1629
} // namespace LevelCmd
1730

18-
#endif
31+
#endif

0 commit comments

Comments
 (0)