From e3b1897540b8727980076d366b63e5cb261bd7b7 Mon Sep 17 00:00:00 2001 From: shun-iwasawa Date: Jul 10 2018 05:42:57 +0000 Subject: set system path with command line qualifiers (#2143) --- diff --git a/toonz/sources/common/tapptools/tenv.cpp b/toonz/sources/common/tapptools/tenv.cpp index 9151016..47bb8af 100644 --- a/toonz/sources/common/tapptools/tenv.cpp +++ b/toonz/sources/common/tapptools/tenv.cpp @@ -32,6 +32,11 @@ using namespace TEnv; //========================================================= namespace { +const std::map systemPathMap{ + {"LIBRARY", "library"}, {"STUDIOPALETTE", "studiopalette"}, + {"FXPRESETS", "fxs"}, {"CACHEROOT", "cache"}, + {"PROFILES", "profiles"}, {"CONFIG", "config"}, + {"PROJECTS", "projects"}}; class EnvGlobals { // singleton @@ -49,6 +54,9 @@ class EnvGlobals { // singleton TFilePath *m_dllRelativeDir; bool m_isPortable = false; + // path values specified with command line arguments + std::map m_argPathValues; + EnvGlobals() : m_stuffDir(0) { setWorkingDirectory(); } public: @@ -91,6 +99,7 @@ public: TFilePath getRootVarPath() { return getSystemVarPath(m_rootVarName); } std::string getSystemVarValue(std::string varName) { + if (getIsPortable()) return ""; #ifdef _WIN32 return TSystem::getSystemValue(getSystemVarPath(varName)).toStdString(); #else @@ -138,7 +147,8 @@ public: void updateEnvFile() { TFilePath profilesDir = getSystemVarPathValue(getSystemVarPrefix() + "PROFILES"); - if (profilesDir == TFilePath()) profilesDir = getStuffDir() + "profiles"; + if (profilesDir == TFilePath()) + profilesDir = getStuffDir() + systemPathMap.at("PROFILES"); m_envFile = profilesDir + "env" + (TSystem::getUserName().toStdString() + ".env"); } @@ -193,10 +203,7 @@ public: m_systemVarPrefix = prefix; updateEnvFile(); } - std::string getSystemVarPrefix() { - if (getIsPortable()) return ""; - return m_systemVarPrefix; - } + std::string getSystemVarPrefix() { return m_systemVarPrefix; } void setWorkingDirectory() { QString workingDirectoryTmp = QDir::currentPath(); @@ -223,6 +230,19 @@ public: if (m_dllRelativeDir) return *m_dllRelativeDir; return TFilePath("."); } + + void setArgPathValue(std::string key, std::string value) { + m_argPathValues.emplace(key, value); + if (key == m_systemVarPrefix + "PROFILES") updateEnvFile(); + } + + std::string getArgPathValue(std::string key) { + decltype(m_argPathValues)::iterator it = m_argPathValues.find(key); + if (it != m_argPathValues.end()) + return it->second; + else + return ""; + } }; /* @@ -502,15 +522,21 @@ std::string TEnv::getSystemVarStringValue(std::string varName) { TFilePath TEnv::getSystemVarPathValue(std::string varName) { EnvGlobals *eg = EnvGlobals::instance(); + // return if the path is registered by command line argument + std::string argVar = eg->getArgPathValue(varName); + if (argVar != "") return TFilePath(argVar); return TFilePath(eg->getSystemVarValue(varName)); } TFilePathSet TEnv::getSystemVarPathSetValue(std::string varName) { TFilePathSet lst; - std::string value = EnvGlobals::instance()->getSystemVarValue(varName); - int len = (int)value.size(); - int i = 0; - int j = value.find(';'); + EnvGlobals *eg = EnvGlobals::instance(); + // if the path is registered by command line argument, then use it + std::string value = eg->getArgPathValue(varName); + if (value == "") value = eg->getSystemVarValue(varName); + int len = (int)value.size(); + int i = 0; + int j = value.find(';'); while (j != std::string::npos) { std::string s = value.substr(i, j - i); lst.push_back(TFilePath(s)); @@ -542,7 +568,8 @@ bool TEnv::getIsPortable() { return EnvGlobals::instance()->getIsPortable(); } TFilePath TEnv::getConfigDir() { TFilePath configDir = getSystemVarPathValue(getSystemVarPrefix() + "CONFIG"); - if (configDir == TFilePath()) configDir = getStuffDir() + "config"; + if (configDir == TFilePath()) + configDir = getStuffDir() + systemPathMap.at("CONFIG"); return configDir; } @@ -566,6 +593,36 @@ void TEnv::setDllRelativeDir(const TFilePath &dllRelativeDir) { void TEnv::saveAllEnvVariables() { VariableSet::instance()->save(); } +bool TEnv::setArgPathValue(std::string key, std::string value) { + EnvGlobals *eg = EnvGlobals::instance(); + // in case of "-TOONZROOT" , set the all unregistered paths + if (key == getRootVarName()) { + TFilePath rootPath(value); + eg->setStuffDir(rootPath); + for (auto itr = systemPathMap.begin(); itr != systemPathMap.end(); ++itr) { + std::string k = getSystemVarPrefix() + (*itr).first; + std::string val = value + "\\" + (*itr).second; + // set all unregistered values + if (eg->getArgPathValue(k) == "") eg->setArgPathValue(k, val); + } + return true; + } else { + for (auto itr = systemPathMap.begin(); itr != systemPathMap.end(); ++itr) { + // found the corresponding registry key + if (key == getSystemVarPrefix() + (*itr).first) { + eg->setArgPathValue(key, value); + return true; + } + } + // registry key not found. failed to register + return false; + } +} + +const std::map &TEnv::getSystemPathMap() { + return systemPathMap; +} + /* void TEnv::defineSystemPath(SystemFileId id, const TFilePath ®istryName) { diff --git a/toonz/sources/include/tcli.h b/toonz/sources/include/tcli.h index 02f1796..f65b376 100644 --- a/toonz/sources/include/tcli.h +++ b/toonz/sources/include/tcli.h @@ -45,11 +45,11 @@ inline bool fromStr(double &value, std::string s) { return false; } inline bool fromStr(std::string &value, std::string s) { - value = s; + value = QString::fromLocal8Bit(s.c_str()).toStdString(); return true; } inline bool fromStr(TFilePath &value, std::string s) { - value = TFilePath(s); + value = TFilePath(QString::fromLocal8Bit(s.c_str())); return true; } diff --git a/toonz/sources/include/tenv.h b/toonz/sources/include/tenv.h index 5c97cf3..155044c 100644 --- a/toonz/sources/include/tenv.h +++ b/toonz/sources/include/tenv.h @@ -142,6 +142,12 @@ DVAPI void setDllRelativeDir(const TFilePath &dllRelativeDir); DVAPI void saveAllEnvVariables(); +// register command line argument paths. +// returns true on success +DVAPI bool setArgPathValue(std::string key, std::string value); + +DVAPI const std::map &getSystemPathMap(); + /* enum SystemFileId { diff --git a/toonz/sources/toonz/main.cpp b/toonz/sources/toonz/main.cpp index 9561e51..c839c9b 100644 --- a/toonz/sources/toonz/main.cpp +++ b/toonz/sources/toonz/main.cpp @@ -77,6 +77,7 @@ #include #include #include +#include using namespace DVGui; #if defined LINETEST @@ -97,9 +98,10 @@ const char *dllRelativePath = "./toonz6.app/Contents/Frameworks"; TEnv::IntVar EnvSoftwareCurrentFontSize("SoftwareCurrentFontSize", 12); -const char *applicationFullName = "OpenToonz 1.2.1"; // next will be 1.3 (not 1.3.0) -const char *rootVarName = "TOONZROOT"; -const char *systemVarPrefix = "TOONZ"; +const char *applicationFullName = + "OpenToonz 1.2.1"; // next will be 1.3 (not 1.3.0) +const char *rootVarName = "TOONZROOT"; +const char *systemVarPrefix = "TOONZ"; #ifdef MACOSX #include "tthread.h" @@ -150,7 +152,7 @@ DV_IMPORT_API void initColorFx(); la stuffDir, controlla se la directory di outputs esiste (e provvede a crearla in caso contrario) verifica inoltre che stuffDir esista. */ -static void initToonzEnv() { +static void initToonzEnv(QHash &argPathValues) { StudioPalette::enable(true); TEnv::setApplication(applicationName, applicationVersion, @@ -159,6 +161,15 @@ static void initToonzEnv() { TEnv::setSystemVarPrefix(systemVarPrefix); TEnv::setDllRelativeDir(TFilePath(dllRelativePath)); + QHash::const_iterator i = argPathValues.constBegin(); + while (i != argPathValues.constEnd()) { + if (!TEnv::setArgPathValue(i.key().toStdString(), i.value().toStdString())) + DVGui::error( + QObject::tr("The qualifier %1 is not a valid key name. Skipping.") + .arg(i.key())); + ++i; + } + QCoreApplication::setOrganizationName("OpenToonz"); QCoreApplication::setOrganizationDomain(""); QString fullApplicationNameQStr = @@ -244,17 +255,60 @@ int main(int argc, char *argv[]) { } #endif - /*-- "-layout [レイアウト設定ファイル名]" - * で、必要なモジュールのPageだけのレイアウトで起動することを可能にする --*/ - QString argumentLayoutFileName = ""; + // parsing arguments and qualifiers TFilePath loadScenePath; + QString argumentLayoutFileName = ""; + QHash argumentPathValues; if (argc > 1) { - for (int a = 1; a < argc; a++) { - if (QString(argv[a]) == "-layout") { - argumentLayoutFileName = QString(argv[a + 1]); - a++; - } else - loadScenePath = TFilePath(argv[a]); + TCli::Usage usage(argv[0]); + TCli::UsageLine usageLine; + TCli::FilePathArgument loadSceneArg("scenePath", "Source scene file"); + TCli::StringQualifier layoutFileQual( + "-layout filename", + "Custom layout file to be used, it should be saved in " + "$TOONZPROFILES\\layouts\\personal\\[CurrentLayoutName].[UserName]\\. " + "layouts.txt is used by default."); + usageLine = usageLine + layoutFileQual; + + // system path qualifiers + std::map>> + systemPathQualMap; + QString qualKey = QString("%1ROOT").arg(systemVarPrefix); + QString qualName = QString("-%1 folderpath").arg(qualKey); + QString qualHelp = + QString( + "%1 path. It will automatically set other system paths to %1 " + "unless individually specified with other qualifiers.") + .arg(qualKey); + systemPathQualMap[qualKey].reset(new TCli::QualifierT( + qualName.toStdString(), qualHelp.toStdString())); + usageLine = usageLine + *systemPathQualMap[qualKey]; + + const std::map &spm = TEnv::getSystemPathMap(); + for (auto itr = spm.begin(); itr != spm.end(); ++itr) { + qualKey = QString("%1%2") + .arg(systemVarPrefix) + .arg(QString::fromStdString((*itr).first)); + qualName = QString("-%1 folderpath").arg(qualKey); + qualHelp = QString("%1 path.").arg(qualKey); + systemPathQualMap[qualKey].reset(new TCli::QualifierT( + qualName.toStdString(), qualHelp.toStdString())); + usageLine = usageLine + *systemPathQualMap[qualKey]; + } + usage.add(usageLine); + usage.add(usageLine + loadSceneArg); + + if (!usage.parse(argc, argv)) exit(1); + + loadScenePath = loadSceneArg.getValue(); + if (layoutFileQual.isSelected()) + argumentLayoutFileName = + QString::fromStdString(layoutFileQual.getValue()); + for (auto q_itr = systemPathQualMap.begin(); + q_itr != systemPathQualMap.end(); ++q_itr) { + if (q_itr->second->isSelected()) + argumentPathValues.insert(q_itr->first, + q_itr->second->getValue().getQString()); } } @@ -409,7 +463,7 @@ int main(int argc, char *argv[]) { &toonzRunOutOfContMemHandler); // Toonz environment - initToonzEnv(); + initToonzEnv(argumentPathValues); // Initialize thread components TThread::init(); diff --git a/toonz/sources/toonzlib/toonzfolders.cpp b/toonz/sources/toonzlib/toonzfolders.cpp index f699f87..a9bc0cf 100644 --- a/toonz/sources/toonzlib/toonzfolders.cpp +++ b/toonz/sources/toonzlib/toonzfolders.cpp @@ -50,7 +50,9 @@ TFilePathSet ToonzFolder::getProjectsFolders() { fps.push_back(TFilePath(tempPath)); } } - if (tempFps.size() == 0) fps.push_back(TEnv::getStuffDir() + "Projects"); + if (tempFps.size() == 0) + fps.push_back(TEnv::getStuffDir() + + TEnv::getSystemPathMap().at("PROJECTS")); } if (documents) { fps.push_back(getMyDocumentsPath() + "OpenToonz"); @@ -85,31 +87,36 @@ TFilePath ToonzFolder::getFirstProjectsFolder() { TFilePath ToonzFolder::getLibraryFolder() { TFilePath fp = getSystemVarPathValue(getSystemVarPrefix() + "LIBRARY"); - if (fp == TFilePath()) fp = getStuffDir() + "library"; + if (fp == TFilePath()) + fp = getStuffDir() + TEnv::getSystemPathMap().at("LIBRARY"); return fp; } TFilePath ToonzFolder::getStudioPaletteFolder() { TFilePath fp = getSystemVarPathValue(getSystemVarPrefix() + "STUDIOPALETTE"); - if (fp == TFilePath()) fp = getStuffDir() + "studiopalette"; + if (fp == TFilePath()) + fp = getStuffDir() + TEnv::getSystemPathMap().at("STUDIOPALETTE"); return fp; } TFilePath ToonzFolder::getFxPresetFolder() { TFilePath fp = getSystemVarPathValue(getSystemVarPrefix() + "FXPRESETS"); - if (fp == TFilePath()) fp = getStuffDir() + "fxs"; + if (fp == TFilePath()) + fp = getStuffDir() + TEnv::getSystemPathMap().at("FXPRESETS"); return fp; } TFilePath ToonzFolder::getCacheRootFolder() { TFilePath fp = getSystemVarPathValue(getSystemVarPrefix() + "CACHEROOT"); - if (fp == TFilePath()) fp = getStuffDir() + "cache"; + if (fp == TFilePath()) + fp = getStuffDir() + TEnv::getSystemPathMap().at("CACHEROOT"); return fp; } TFilePath ToonzFolder::getProfileFolder() { TFilePath fp = getSystemVarPathValue(getSystemVarPrefix() + "PROFILES"); - if (fp == TFilePath()) fp = getStuffDir() + "profiles"; + if (fp == TFilePath()) + fp = getStuffDir() + TEnv::getSystemPathMap().at("PROFILES"); return fp; }