tahoma2d/toonz/sources/toonzlib/levelset.cpp

359 lines
11 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
// TnzCore includes
#include "tconvert.h"
#include "tstream.h"
// TnzLib includes
#include "toonz/txshsimplelevel.h"
#include "toonz/toonzscene.h"
#include "toonz/levelset.h"
//=============================================================================
2016-06-15 18:43:10 +12:00
namespace {
2016-03-19 06:57:51 +13:00
const TFilePath defaultRootFolder("Cast");
const TFilePath defaultSoundRootFolder("Audio");
}
//=============================================================================
// TLevelSet
2016-06-15 18:43:10 +12:00
TLevelSet::TLevelSet() : m_defaultFolder(defaultRootFolder) {
m_folders.push_back(defaultRootFolder);
m_folders.push_back(defaultSoundRootFolder);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TLevelSet::~TLevelSet() { clear(); }
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::clear() {
for (std::vector<TXshLevel *>::iterator it = m_levels.begin();
it != m_levels.end(); ++it) {
TXshLevel *level = *it;
if (level->getSimpleLevel()) level->getSimpleLevel()->clearFrames();
(*it)->release();
}
m_levelTable.clear();
m_levels.clear();
m_folderTable.clear();
m_folders.clear();
m_folders.push_back(defaultRootFolder);
m_folders.push_back(defaultSoundRootFolder);
m_defaultFolder = defaultRootFolder;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::removeLevel(TXshLevel *level, bool deleteIt) {
// if(level->getSimpleLevel())
// level->getSimpleLevel()->clearFrames();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
m_levels.erase(std::remove(m_levels.begin(), m_levels.end(), level),
m_levels.end());
m_levelTable.erase(level->getName());
if (deleteIt) level->release();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
m_folderTable.erase(level);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TLevelSet::renameLevel(TXshLevel *level, const std::wstring &newName) {
if (level->getName() == newName) return true;
if (m_levelTable.count(newName) > 0) return false;
m_levelTable.erase(level->getName());
level->setName(newName);
m_levelTable[newName] = level;
return true;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
int TLevelSet::getLevelCount() const { return m_levels.size(); }
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TXshLevel *TLevelSet::getLevel(int index) const {
assert(0 <= index && index < getLevelCount());
return m_levels[index];
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TXshLevel *TLevelSet::getLevel(const std::wstring &levelName) const {
std::map<std::wstring, TXshLevel *>::const_iterator it;
it = m_levelTable.find(levelName);
if (it == m_levelTable.end())
return 0;
else
return it->second;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TXshLevel *TLevelSet::getLevel(const ToonzScene &scene,
const TFilePath &levelPath) const {
const TFilePath &decodedPath = scene.decodeFilePath(levelPath);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int l, lCount = getLevelCount();
for (l = 0; l != lCount; ++l) {
TXshLevel *level = getLevel(l);
if (decodedPath == scene.decodeFilePath(level->getPath())) return level;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return 0;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TLevelSet::hasLevel(const std::wstring &levelName) const {
std::vector<TXshLevel *>::const_iterator it = m_levels.begin();
for (auto const level : m_levels) {
if (levelName == level->getName()) return true;
}
return false;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TLevelSet::hasLevel(const ToonzScene &scene,
const TFilePath &levelPath) const {
return getLevel(scene, levelPath);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::listLevels(std::vector<TXshLevel *> &levels) const {
levels = m_levels;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TLevelSet::insertLevel(TXshLevel *xl) {
std::map<std::wstring, TXshLevel *>::const_iterator it;
it = m_levelTable.find(xl->getName());
if (it != m_levelTable.end() && it->second == xl)
return it->second == xl;
else {
xl->addRef();
m_levelTable[xl->getName()] = xl;
m_levels.push_back(xl);
TFilePath folder =
(xl->getSoundLevel()) ? defaultSoundRootFolder : m_defaultFolder;
m_folderTable[xl] = folder;
assert(std::find(m_folders.begin(), m_folders.end(), folder) !=
m_folders.end());
return true;
}
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::setDefaultFolder(TFilePath folder) {
assert(std::find(m_folders.begin(), m_folders.end(), folder) !=
m_folders.end());
m_defaultFolder = folder;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TFilePath TLevelSet::getFolder(TXshLevel *xl) const {
std::map<TXshLevel *, TFilePath>::const_iterator it;
it = m_folderTable.find(xl);
assert(it != m_folderTable.end());
return it->second;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TFilePath TLevelSet::renameFolder(const TFilePath &folder,
const std::wstring &newName) {
// Impedisco la creazione di folder con nome "" che creano problemi
// (praticamente Ecome se avessero infinite sottocartelle)
if (newName == L"") return folder;
TFilePath folder2 = folder.withName(newName);
for (int i = 0; i < (int)m_folders.size(); i++) {
if (folder == m_folders[i])
m_folders[i] = folder2;
else if (folder.isAncestorOf(m_folders[i]))
m_folders[i] = folder2 + (m_folders[i] - folder);
}
if (m_defaultFolder == folder) m_defaultFolder = folder2;
std::map<TXshLevel *, TFilePath>::iterator it;
for (it = m_folderTable.begin(); it != m_folderTable.end(); ++it) {
if (folder == it->second)
it->second = folder2;
else if (folder.isAncestorOf(it->second))
it->second = folder2 + (it->second - folder);
}
return folder2;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TFilePath TLevelSet::createFolder(const TFilePath &parentFolder,
const std::wstring &newName) {
TFilePath child = parentFolder + newName;
if (std::find(m_folders.begin(), m_folders.end(), child) == m_folders.end())
m_folders.push_back(child);
return child;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::removeFolder(const TFilePath &folder) {
if (folder == m_defaultFolder) return;
std::vector<TFilePath> folders;
for (int i = 0; i < (int)m_folders.size(); i++)
if (!folder.isAncestorOf(m_folders[i])) folders.push_back(m_folders[i]);
folders.swap(m_folders);
std::map<TXshLevel *, TFilePath>::iterator it;
for (it = m_folderTable.begin(); it != m_folderTable.end(); ++it) {
if (folder.isAncestorOf(it->second)) it->second = m_defaultFolder;
}
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::listLevels(std::vector<TXshLevel *> &levels,
const TFilePath &folder) const {
std::map<TXshLevel *, TFilePath>::const_iterator it;
for (it = m_folderTable.begin(); it != m_folderTable.end(); ++it)
if (folder == it->second) levels.push_back(it->first);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::listFolders(std::vector<TFilePath> &folders,
const TFilePath &folder) const {
for (int i = 0; i < (int)m_folders.size(); i++)
if (m_folders[i].getParentDir() == folder) folders.push_back(m_folders[i]);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::moveLevelToFolder(const TFilePath &fp, TXshLevel *level) {
TFilePath folder(fp);
if (folder == TFilePath()) folder = m_defaultFolder;
if (std::find(m_folders.begin(), m_folders.end(), folder) ==
m_folders.end()) {
assert(0);
return;
}
std::map<TXshLevel *, TFilePath>::iterator it;
it = m_folderTable.find(level);
assert(it != m_folderTable.end());
if (it == m_folderTable.end()) return;
it->second = folder;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::saveFolder(TOStream &os, TFilePath folder) {
std::map<std::string, std::string> attr;
attr["name"] = folder.getName();
if (folder == getDefaultFolder()) attr["type"] = "default";
os.openChild("folder", attr);
std::vector<TFilePath> folders;
listFolders(folders, folder);
if (!folders.empty()) {
for (int i = 0; i < (int)folders.size(); i++) saveFolder(os, folders[i]);
}
std::vector<TXshLevel *> levels;
listLevels(levels, folder);
if (!levels.empty()) {
os.openChild("levels");
for (int i = 0; i < (int)levels.size(); i++)
if (m_saveSet.empty() || m_saveSet.count(levels[i]) > 0) os << levels[i];
os.closeChild();
}
os.closeChild();
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::loadFolder(TIStream &is, TFilePath folder) {
std::string s;
is.getTagParam("type", s);
if (s == "default") setDefaultFolder(folder);
while (!is.eos()) {
std::string tagName;
is.matchTag(tagName);
if (tagName == "levels") {
while (!is.eos()) {
TPersist *p = 0;
is >> p;
TXshLevel *xshLevel = dynamic_cast<TXshLevel *>(p);
if (xshLevel && !xshLevel->getChildLevel())
moveLevelToFolder(folder, xshLevel);
}
} else if (tagName == "folder") {
is.getTagParam("name", s);
TFilePath child = createFolder(folder, ::to_wstring(s));
loadFolder(is, child);
} else
throw TException("expected <levels> or <folder>");
is.closeChild();
}
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::loadData(TIStream &is) {
int folderCount = 1;
while (!is.eos()) {
std::string tagName;
if (is.matchTag(tagName)) {
if (tagName == "levels") {
while (!is.eos()) {
TPersist *p = 0;
is >> p;
TXshLevel *xshLevel = dynamic_cast<TXshLevel *>(p);
if (xshLevel) {
insertLevel(xshLevel);
}
}
} else if (tagName == "folder") {
std::string name = ::to_string(defaultRootFolder.getWideString());
is.getTagParam("name", name);
TFilePath folder(name);
if (folderCount == 1)
m_defaultFolder = m_folders[0] = folder;
else if (name != defaultSoundRootFolder.getName())
m_folders.push_back(folder);
folderCount++;
loadFolder(is, folder);
} else
throw TException("expected <levels> or <folder>");
is.closeChild();
} else
throw TException("expected tag");
}
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelSet::saveData(TOStream &os) {
os.openChild("levels");
int i;
for (i = 0; i < getLevelCount(); i++) {
TXshLevel *level = getLevel(i);
if (m_saveSet.empty() || m_saveSet.count(level) > 0) os << level;
}
os.closeChild();
std::vector<TFilePath> folders;
listFolders(folders, TFilePath());
assert(!folders.empty());
for (i = 0; i < (int)folders.size(); i++) saveFolder(os, folders[i]);
2016-03-19 06:57:51 +13:00
}