clean assets feature

This commit is contained in:
shun-iwasawa 2021-02-18 17:24:29 +09:00 committed by manongjohn
parent 53900472aa
commit f41dfc8dba
10 changed files with 200 additions and 60 deletions

View file

@ -269,6 +269,9 @@ public:
int matchLevelFormat(const TFilePath &fp) int matchLevelFormat(const TFilePath &fp)
const; //!< Returns the \a nonnegative index of the first level format const; //!< Returns the \a nonnegative index of the first level format
//! matching the specified file path, <I>or \p -1 if none</I>. //! matching the specified file path, <I>or \p -1 if none</I>.
bool isAutoRemoveUnusedLevelsEnabled() const {
return isAutoExposeEnabled() && getBoolValue(autoRemoveUnusedLevels);
}
// Saving tab // Saving tab
TPixel getRasterBackgroundColor() const { TPixel getRasterBackgroundColor() const {

View file

@ -62,6 +62,7 @@ enum PreferencesItemId {
initialLoadTlvCachingBehavior, initialLoadTlvCachingBehavior,
columnIconLoadingPolicy, columnIconLoadingPolicy,
levelFormats, // need to be handle separately levelFormats, // need to be handle separately
autoRemoveUnusedLevels,
//---------- //----------
// Saving // Saving

View file

@ -286,6 +286,7 @@ private:
ToonzScene(const ToonzScene &); ToonzScene(const ToonzScene &);
ToonzScene &operator=(const ToonzScene &); ToonzScene &operator=(const ToonzScene &);
public:
// if the option is set in the preferences, // if the option is set in the preferences,
// remove the scene numbers("c####_") from the file name // remove the scene numbers("c####_") from the file name
std::wstring getLevelNameWithoutSceneNumber(std::wstring orgName); std::wstring getLevelNameWithoutSceneNumber(std::wstring orgName);

View file

@ -21,6 +21,7 @@
#include "cachefxcommand.h" #include "cachefxcommand.h"
#include "xdtsio.h" #include "xdtsio.h"
#include "expressionreferencemanager.h" #include "expressionreferencemanager.h"
#include "levelcommand.h"
// TnzTools includes // TnzTools includes
#include "tools/toolhandle.h" #include "tools/toolhandle.h"
@ -356,6 +357,37 @@ int getLevelType(const TFilePath &actualPath) {
return UNKNOWN_XSHLEVEL; return UNKNOWN_XSHLEVEL;
} }
//===========================================================================
// removeSameNamedUnusedLevel(scene, actualPath, levelName);
//---------------------------------------------------------------------------
void removeSameNamedUnusedLevel(ToonzScene *scene, const TFilePath actualPath,
std::wstring levelName) {
if (QString::fromStdWString(levelName).isEmpty()) {
// if the option is set in the preferences,
// remove the scene numbers("c####_") from the file name
levelName = scene->getLevelNameWithoutSceneNumber(actualPath.getWideName());
}
TLevelSet *levelSet = scene->getLevelSet();
NameModifier nm(levelName);
levelName = nm.getNext();
while (1) {
TXshLevel *existingLevel = levelSet->getLevel(levelName);
// if the level name is not used in the cast, nothing to do
if (!existingLevel) return;
// try if the existing level is unused in the xsheet and remove from the
// cast
else if (LevelCmd::removeLevelFromCast(existingLevel, scene, false)) {
DVGui::info(QObject::tr("Removed unused level %1 from the scene cast. "
"(This behavior can be disabled in Preferences.)")
.arg(QString::fromStdWString(levelName)));
return;
}
levelName = nm.getNext();
}
}
//=========================================================================== //===========================================================================
// class LoadLevelUndo // class LoadLevelUndo
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -876,6 +908,11 @@ TXshLevel *loadLevel(ToonzScene *scene,
bool isFirstTime = !xl; bool isFirstTime = !xl;
std::wstring name = actualPath.getWideName(); std::wstring name = actualPath.getWideName();
if (isFirstTime && expose &&
Preferences::instance()->isAutoRemoveUnusedLevelsEnabled()) {
removeSameNamedUnusedLevel(scene, actualPath, levelName);
}
IoCmd::ConvertingPopup *convertingPopup = new IoCmd::ConvertingPopup( IoCmd::ConvertingPopup *convertingPopup = new IoCmd::ConvertingPopup(
TApp::instance()->getMainWindow(), TApp::instance()->getMainWindow(),
QString::fromStdWString(name) + QString::fromStdWString(name) +
@ -1404,6 +1441,15 @@ bool IoCmd::saveScene(const TFilePath &path, int flags) {
TXsheet *xsheet = 0; TXsheet *xsheet = 0;
if (saveSubxsheet) xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); if (saveSubxsheet) xsheet = TApp::instance()->getCurrentXsheet()->getXsheet();
// Automatically remove unused levels
if (!saveSubxsheet &&
Preferences::instance()->isAutoRemoveUnusedLevelsEnabled()) {
if (LevelCmd::removeUnusedLevelsFromCast(false))
DVGui::info(
QObject::tr("Removed unused levels from the scene cast. (This "
"behavior can be disabled in Preferences.)"));
}
// If the scene will be saved in the different folder, check out the scene // If the scene will be saved in the different folder, check out the scene
// cast. // cast.
// if the cast contains the level specified with $scenefolder alias, // if the cast contains the level specified with $scenefolder alias,

View file

@ -63,15 +63,9 @@ public:
} // namespace } // namespace
//=============================================================================
// RemoveUnusedLevelCommand
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class RemoveUnusedLevelsCommand final : public MenuItemHandler { bool LevelCmd::removeUnusedLevelsFromCast(bool showMessage) {
public:
RemoveUnusedLevelsCommand() : MenuItemHandler(MI_RemoveUnused) {}
void execute() override {
TApp *app = TApp::instance(); TApp *app = TApp::instance();
ToonzScene *scene = app->getCurrentScene()->getScene(); ToonzScene *scene = app->getCurrentScene()->getScene();
@ -87,8 +81,8 @@ public:
if (usedLevels.count(xl) == 0) unused.push_back(xl); if (usedLevels.count(xl) == 0) unused.push_back(xl);
} }
if (unused.empty()) { if (unused.empty()) {
DVGui::error(QObject::tr("No unused levels")); if (showMessage) DVGui::error(QObject::tr("No unused levels"));
return; return false;
} else { } else {
TUndoManager *um = TUndoManager::manager(); TUndoManager *um = TUndoManager::manager();
um->beginBlock(); um->beginBlock();
@ -102,7 +96,37 @@ public:
um->endBlock(); um->endBlock();
} }
return true;
} }
bool LevelCmd::removeLevelFromCast(TXshLevel *level, ToonzScene *scene,
bool showMessage) {
if (!scene) scene = TApp::instance()->getCurrentScene()->getScene();
if (scene->getChildStack()->getTopXsheet()->isLevelUsed(level)) {
if (showMessage) {
DVGui::error(
QObject::tr("It is not possible to delete the used level %1.")
.arg(QString::fromStdWString(
level->getName()))); //"E_CantDeleteUsedLevel_%1"
}
return false;
} else {
TUndoManager *um = TUndoManager::manager();
um->add(new DeleteLevelUndo(level));
scene->getLevelSet()->removeLevel(level);
}
return true;
}
//=============================================================================
// RemoveUnusedLevelCommand
//-----------------------------------------------------------------------------
class RemoveUnusedLevelsCommand final : public MenuItemHandler {
public:
RemoveUnusedLevelsCommand() : MenuItemHandler(MI_RemoveUnused) {}
void execute() override { LevelCmd::removeUnusedLevelsFromCast(); }
} removeUnusedLevelsCommand; } removeUnusedLevelsCommand;
//============================================================================= //=============================================================================
@ -113,22 +137,6 @@ class RemoveLevelCommand final : public MenuItemHandler {
public: public:
RemoveLevelCommand() : MenuItemHandler(MI_RemoveLevel) {} RemoveLevelCommand() : MenuItemHandler(MI_RemoveLevel) {}
bool removeLevel(TXshLevel *level) {
TApp *app = TApp::instance();
ToonzScene *scene = app->getCurrentScene()->getScene();
if (scene->getChildStack()->getTopXsheet()->isLevelUsed(level))
DVGui::error(
QObject::tr("It is not possible to delete the used level %1.")
.arg(QString::fromStdWString(
level->getName()))); //"E_CantDeleteUsedLevel_%1"
else {
TUndoManager *um = TUndoManager::manager();
um->add(new DeleteLevelUndo(level));
scene->getLevelSet()->removeLevel(level);
}
return true;
}
void execute() override { void execute() override {
TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet(); TXsheet *xsheet = TApp::instance()->getCurrentXsheet()->getXsheet();
CastSelection *castSelection = CastSelection *castSelection =
@ -143,7 +151,7 @@ public:
} }
int count = 0; int count = 0;
for (int i = 0; i < (int)levels.size(); i++) for (int i = 0; i < (int)levels.size(); i++)
if (removeLevel(levels[i])) count++; if (LevelCmd::removeLevelFromCast(levels[i])) count++;
if (count == 0) return; if (count == 0) return;
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
TApp::instance()->getCurrentScene()->notifyCastChange(); TApp::instance()->getCurrentScene()->notifyCastChange();
@ -523,7 +531,24 @@ void LevelCmd::addMissingLevelsToCast(std::set<TXshLevel *> &levels) {
std::wstring oldName = levelName; std::wstring oldName = levelName;
NameModifier nm(levelName); NameModifier nm(levelName);
levelName = nm.getNext(); levelName = nm.getNext();
while (levelSet->hasLevel(levelName)) levelName = nm.getNext(); while (1) {
TXshLevel *existingLevel = levelSet->getLevel(levelName);
// if the level name is not used in the cast, nothing to do
if (!existingLevel) break;
// try if the existing level is unused in the xsheet and remove from the
// cast
else if (Preferences::instance()->isAutoRemoveUnusedLevelsEnabled() &&
LevelCmd::removeLevelFromCast(
existingLevel,
TApp::instance()->getCurrentScene()->getScene(), false)) {
DVGui::info(
QObject::tr("Removed unused level %1 from the scene cast. (This "
"behavior can be disabled in Preferences.)")
.arg(QString::fromStdWString(levelName)));
break;
}
levelName = nm.getNext();
}
addLevelToCastUndo *undo = addLevelToCastUndo *undo =
new addLevelToCastUndo(level, levelName, oldName); new addLevelToCastUndo(level, levelName, oldName);
undo->m_isLastInRedoBlock = false; // prevent to emit signal undo->m_isLastInRedoBlock = false; // prevent to emit signal

View file

@ -9,10 +9,23 @@
#include <QList> #include <QList>
class TXshLevel; class TXshLevel;
class ToonzScene;
namespace LevelCmd { namespace LevelCmd {
void addMissingLevelsToCast(const QList<TXshColumnP>& columns); void addMissingLevelsToCast(const QList<TXshColumnP>& columns);
void addMissingLevelsToCast(std::set<TXshLevel*>& levels); void addMissingLevelsToCast(std::set<TXshLevel*>& levels);
// Remove all unused level from the scene cast.
// When there is no unused level, show an error message if showmessage==true.
// Return true if something is removed.
bool removeUnusedLevelsFromCast(bool showMessage = true);
// Remove the level from the scene cast if it is not used in the xsheet.
// Return true if the level is unused and removed.
// When the level is used, an show error message if showMessage==true and
// returns false.
bool removeLevelFromCast(TXshLevel* level, ToonzScene* scene = nullptr,
bool showMessage = true);
} // namespace LevelCmd } // namespace LevelCmd
#endif #endif

View file

@ -5,6 +5,7 @@
// Tnz6 includes // Tnz6 includes
#include "menubarcommandids.h" #include "menubarcommandids.h"
#include "tapp.h" #include "tapp.h"
#include "levelcommand.h"
// TnzTools includes // TnzTools includes
#include "tools/toolhandle.h" #include "tools/toolhandle.h"
@ -34,6 +35,7 @@
#include "toonz/palettecontroller.h" #include "toonz/palettecontroller.h"
#include "toonz/tproject.h" #include "toonz/tproject.h"
#include "toonz/namebuilder.h" #include "toonz/namebuilder.h"
#include "toonz/childstack.h"
// TnzCore includes // TnzCore includes
#include "tsystem.h" #include "tsystem.h"
@ -327,8 +329,15 @@ bool LevelCreatePopup::levelExists(std::wstring levelName) {
.withParentDir(parentDir); .withParentDir(parentDir);
actualFp = scene->decodeFilePath(fp); actualFp = scene->decodeFilePath(fp);
if (levelSet->getLevel(levelName) != 0 || if (TSystem::doesExistFileOrLevel(actualFp))
TSystem::doesExistFileOrLevel(actualFp)) { return true;
else if (TXshLevel *level = levelSet->getLevel(levelName)) {
// even if the level exists in the scene cast, it can be replaced if it is
// unused
if (Preferences::instance()->isAutoRemoveUnusedLevelsEnabled() &&
!scene->getChildStack()->getTopXsheet()->isLevelUsed(level))
return false;
else
return true; return true;
} else } else
return false; return false;
@ -469,13 +478,19 @@ bool LevelCreatePopup::apply() {
int numFrames = step * (((to - from) / inc) + 1); int numFrames = step * (((to - from) / inc) + 1);
if (scene->getLevelSet()->getLevel(levelName)) { TXshLevel *existingLevel = scene->getLevelSet()->getLevel(levelName);
if (existingLevel) {
// check if the existing level can be removed
if (!Preferences::instance()->isAutoRemoveUnusedLevelsEnabled() ||
scene->getChildStack()->getTopXsheet()->isLevelUsed(existingLevel)) {
error( error(
tr("The level name specified is already used: please choose a " tr("The level name specified is already used: please choose a "
"different level name")); "different level name"));
m_nameFld->selectAll(); m_nameFld->selectAll();
return false; return false;
} }
// if the exitingLevel is not null, it will be removed afterwards
}
TFilePath parentDir(m_pathFld->getPath().toStdWString()); TFilePath parentDir(m_pathFld->getPath().toStdWString());
TFilePath fp = TFilePath fp =
@ -525,6 +540,18 @@ bool LevelCreatePopup::apply() {
} }
} }
TUndoManager::manager()->beginBlock();
// existingLevel is not nullptr only if the level is unused AND
// the preference option AutoRemoveUnusedLevels is ON
if (existingLevel) {
bool ok = LevelCmd::removeLevelFromCast(existingLevel, scene, false);
assert(ok);
DVGui::info(QObject::tr("Removed unused level %1 from the scene cast. "
"(This behavior can be disabled in Preferences.)")
.arg(QString::fromStdWString(levelName)));
}
/*-- これからLevelを配置しようとしているセルが空いているかどうかのチェック /*-- これからLevelを配置しようとしているセルが空いているかどうかのチェック
* --*/ * --*/
bool areColumnsShifted = false; bool areColumnsShifted = false;
@ -560,6 +587,7 @@ bool LevelCreatePopup::apply() {
TXshLevel *level = TXshLevel *level =
scene->createNewLevel(lType, levelName, TDimension(), 0, fp); scene->createNewLevel(lType, levelName, TDimension(), 0, fp);
TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(level); TXshSimpleLevel *sl = dynamic_cast<TXshSimpleLevel *>(level);
assert(sl); assert(sl);
// sl->setPath(fp, true); // sl->setPath(fp, true);
if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) { if (lType == TZP_XSHLEVEL || lType == OVL_XSHLEVEL) {
@ -603,6 +631,8 @@ bool LevelCreatePopup::apply() {
undo->onAdd(sl); undo->onAdd(sl);
TUndoManager::manager()->endBlock();
app->getCurrentScene()->notifySceneChanged(); app->getCurrentScene()->notifySceneChanged();
app->getCurrentScene()->notifyCastChange(); app->getCurrentScene()->notifyCastChange();
app->getCurrentXsheet()->notifyXsheetChanged(); app->getCurrentXsheet()->notifyXsheetChanged();

View file

@ -10,6 +10,7 @@
#include "castselection.h" #include "castselection.h"
#include "fileselection.h" #include "fileselection.h"
#include "columnselection.h" #include "columnselection.h"
#include "levelcommand.h"
// TnzQt includes // TnzQt includes
#include "toonzqt/menubarcommand.h" #include "toonzqt/menubarcommand.h"
@ -964,6 +965,18 @@ void LevelSettingsPopup::onNameChanged() {
TLevelSet *levelSet = TLevelSet *levelSet =
TApp::instance()->getCurrentScene()->getScene()->getLevelSet(); TApp::instance()->getCurrentScene()->getScene()->getLevelSet();
TUndoManager::manager()->beginBlock();
// remove existing & unused level
if (Preferences::instance()->isAutoRemoveUnusedLevelsEnabled()) {
TXshLevel *existingLevel = levelSet->getLevel(text.toStdWString());
if (existingLevel &&
LevelCmd::removeLevelFromCast(existingLevel, nullptr, false))
DVGui::info(QObject::tr("Removed unused level %1 from the scene cast. "
"(This behavior can be disabled in Preferences.)")
.arg(text));
}
if (!levelSet->renameLevel(level, text.toStdWString())) { if (!levelSet->renameLevel(level, text.toStdWString())) {
error("The name " + text + error("The name " + text +
" you entered for the level is already used.\nPlease enter a " " you entered for the level is already used.\nPlease enter a "
@ -975,6 +988,8 @@ void LevelSettingsPopup::onNameChanged() {
TUndoManager::manager()->add( TUndoManager::manager()->add(
new LevelSettingsUndo(level, LevelSettingsUndo::Name, oldName, text)); new LevelSettingsUndo(level, LevelSettingsUndo::Name, oldName, text));
TUndoManager::manager()->endBlock();
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
TApp::instance()->getCurrentScene()->notifyCastChange(); TApp::instance()->getCurrentScene()->notifyCastChange();
} }

View file

@ -1027,6 +1027,8 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
// Loading // Loading
{importPolicy, tr("Default File Import Behavior:")}, {importPolicy, tr("Default File Import Behavior:")},
{autoExposeEnabled, tr("Expose Loaded Levels in the Scene")}, {autoExposeEnabled, tr("Expose Loaded Levels in the Scene")},
{autoRemoveUnusedLevels,
tr("Automatically Remove Unused Levels From Scene Cast")},
{subsceneFolderEnabled, tr("Create Sub-folder when Importing Sub-Scene")}, {subsceneFolderEnabled, tr("Create Sub-folder when Importing Sub-Scene")},
{removeSceneNumberFromLoadedLevelName, {removeSceneNumberFromLoadedLevelName,
tr("Automatically Remove Scene Number from Loaded Level Name")}, tr("Automatically Remove Scene Number from Loaded Level Name")},
@ -1535,7 +1537,8 @@ QWidget* PreferencesPopup::createLoadingPage() {
setupLayout(lay); setupLayout(lay);
insertUI(importPolicy, lay, getComboItemList(importPolicy)); insertUI(importPolicy, lay, getComboItemList(importPolicy));
insertUI(autoExposeEnabled, lay); QGridLayout* autoExposeLay = insertGroupBoxUI(autoExposeEnabled, lay);
{ insertUI(autoRemoveUnusedLevels, autoExposeLay); }
insertUI(subsceneFolderEnabled, lay); insertUI(subsceneFolderEnabled, lay);
insertUI(removeSceneNumberFromLoadedLevelName, lay); insertUI(removeSceneNumberFromLoadedLevelName, lay);
// insertUI(IgnoreImageDpi, lay); // insertUI(IgnoreImageDpi, lay);

View file

@ -456,6 +456,9 @@ void Preferences::definePreferenceItems() {
QMetaType::Int, 0); // On Demand QMetaType::Int, 0); // On Demand
define(columnIconLoadingPolicy, "columnIconLoadingPolicy", QMetaType::Int, define(columnIconLoadingPolicy, "columnIconLoadingPolicy", QMetaType::Int,
(int)LoadAtOnce); (int)LoadAtOnce);
define(autoRemoveUnusedLevels, "autoRemoveUnusedLevels", QMetaType::Bool,
false);
//"levelFormats" need to be handle separately //"levelFormats" need to be handle separately
// Saving // Saving