#include "CmEditorPrefs.h" #include "CmFileSystem.h" #include using namespace pugi; namespace CamelotEditor { UINT32 EditorPrefs::getNumRecentlyUsedProjects() const { return (UINT32)mRecentlyUsedProjects.size(); } const QString& EditorPrefs::getRecentlyUsedProjectPath(UINT32 idx) const { return mRecentlyUsedProjects.at(idx); } void EditorPrefs::addRecentlyUsedProjectPath(const QString& path) { QString cleanPath = QDir::cleanPath(QDir::toNativeSeparators(path)); for(auto iter = mRecentlyUsedProjects.begin(); iter != mRecentlyUsedProjects.end(); ++iter) { if(*iter == cleanPath) return; } mRecentlyUsedProjects.push_back(cleanPath); } void EditorPrefs::removeRecentlyUsedProjectPath(UINT32 idx) { mRecentlyUsedProjects.erase(mRecentlyUsedProjects.begin() + idx); } void EditorPrefs::setLastUsedProjectDirectory(const QString& value) { mLastUsedProjectDirectory = QDir::cleanPath(QDir::toNativeSeparators(value)); } const QString& EditorPrefs::getLastUsedProjectDirectory() const { return mLastUsedProjectDirectory; } void EditorPrefs::setMainWindowLayout(const WindowLayoutDesc& desc) { mMainWindowLayout = desc; } const WindowLayoutDesc& EditorPrefs::getMainWindowLayout() const { return mMainWindowLayout; } void EditorPrefs::save(const QString& path, bool overwrite) const { String stdPath = path.toStdString(); if(FileSystem::fileExists(stdPath)) { if(!overwrite) { CM_EXCEPT(FileNotFoundException, "File already exists at this location."); } else FileSystem::remove(stdPath); } xml_document xmldoc; xml_node camelotEditor = xmldoc.append_child("CamelotEditor"); xml_node recentlyUsedProjects = camelotEditor.append_child("RecentlyUsedProjects"); for(auto iter = mRecentlyUsedProjects.begin(); iter != mRecentlyUsedProjects.end(); ++iter) { xml_node recentlyUsedProject = recentlyUsedProjects.append_child("RecentlyUsedProject"); xml_attribute pathAttrib = recentlyUsedProject.append_attribute("path"); pathAttrib.set_value(iter->toStdString().c_str()); } xml_node lastUsedProjectDirectory = camelotEditor.append_child("LastUsedProjectDir"); xml_attribute pathAttrib = lastUsedProjectDirectory.append_attribute("path"); pathAttrib.set_value(mLastUsedProjectDirectory.toStdString().c_str()); xml_node openWindows = camelotEditor.append_child("OpenWindows"); saveWindowLayout(openWindows, mMainWindowLayout); for(auto iter = mWindowLayouts.begin(); iter != mWindowLayouts.end(); ++iter) { saveWindowLayout(openWindows, *iter); } xmldoc.save_file(stdPath.c_str()); } void EditorPrefs::saveWindowLayout(xml_node parentNode, const WindowLayoutDesc& desc) const { xml_node windowLayout = parentNode.append_child("WindowLayout"); parentNode.append_attribute("id").set_value(desc.id); xml_node windowGeometry = windowLayout.append_child("Geometry"); windowGeometry.append_attribute("left").set_value(desc.left); windowGeometry.append_attribute("top").set_value(desc.top); windowGeometry.append_attribute("width").set_value(desc.width); windowGeometry.append_attribute("height").set_value(desc.height); xml_node windowScreen = windowLayout.append_child("Screen"); windowScreen.append_attribute("fullscreen").set_value(desc.maximized); windowScreen.append_attribute("screenIdx").set_value(desc.screenIdx); xml_node dockInfo = windowLayout.append_child("DockInfo"); dockInfo.append_attribute("state").set_value((UINT32)desc.dockState); dockInfo.append_attribute("parentId").set_value(desc.dockParentId); xml_node childWidgets = windowLayout.append_child("ChildWidgets"); childWidgets.append_attribute("activeWidgetIdx").set_value(desc.activeWidget); for(auto iter = desc.childWidgetNames.begin(); iter != desc.childWidgetNames.end(); ++iter) { childWidgets.append_child("ChildWidget").append_attribute("name").set_value(iter->toStdString().c_str()); } } WindowLayoutDesc EditorPrefs::loadWindowLayout(xml_node node) const { WindowLayoutDesc desc; desc.id = node.attribute("id").as_int(); desc.left = node.child("Geometry").attribute("left").as_uint(); desc.top = node.child("Geometry").attribute("top").as_uint(); desc.width = node.child("Geometry").attribute("width").as_uint(); desc.height = node.child("Geometry").attribute("height").as_uint(); desc.maximized = node.child("Screen").attribute("fullscreen").as_bool(); desc.screenIdx = node.child("Screen").attribute("screenIdx").as_uint(); desc.dockState = (WindowDockState)node.child("DockInfo").attribute("state").as_uint(); desc.dockParentId = node.child("DockInfo").attribute("parentId").as_int(); desc.activeWidget = node.child("ChildWidgets").attribute("activeWidgetIdx").as_uint(); xml_node childWidgets = node.child("ChildWidgets"); for (xml_node childWidget = childWidgets.child("ChildWidget"); childWidget; childWidget = childWidget.next_sibling("ChildWidget")) { desc.childWidgetNames.push_back(childWidget.attribute("name").as_string()); } return desc; } void EditorPrefs::setWindowLayouts(const Vector::type& descs) { mWindowLayouts = descs; } const Vector::type& EditorPrefs::getWindowLayouts() const { return mWindowLayouts; } void EditorPrefs::load(const QString& path) { clear(); String stdPath = path.toStdString(); if(!FileSystem::fileExists(stdPath)) CM_EXCEPT(FileNotFoundException, "Specified file: " + stdPath + " does not exist."); xml_document xmldoc; xml_parse_result parseResult = xmldoc.load_file(stdPath.c_str()); if(parseResult.status != status_ok) CM_EXCEPT(InternalErrorException, "XML parsing failed: " + toString(parseResult.description())); xml_node camelotEditor = xmldoc.child("CamelotEditor"); xml_node recentlyUsedProjects = camelotEditor.child("RecentlyUsedProjects"); for(auto iter = recentlyUsedProjects.begin(); iter != recentlyUsedProjects.end(); ++iter) { xml_attribute pathAttrib = iter->attribute("path"); mRecentlyUsedProjects.push_back(pathAttrib.value()); } xml_node lastUsedProjectDirectory = camelotEditor.child("LastUsedProjectDir"); xml_attribute pathAttrib = lastUsedProjectDirectory.attribute("path"); mLastUsedProjectDirectory = pathAttrib.value(); xml_node openWindows = camelotEditor.child("OpenWindows"); bool foundMainWindowLayoutDesc = false; for (xml_node windowLayout = openWindows.child("WindowLayout"); windowLayout; windowLayout = windowLayout.next_sibling("WindowLayout")) { WindowLayoutDesc desc = loadWindowLayout(windowLayout); if(!foundMainWindowLayoutDesc) { mMainWindowLayout = desc; foundMainWindowLayoutDesc = true; } else { mWindowLayouts.push_back(desc); } } } void EditorPrefs::clear() { mRecentlyUsedProjects.clear(); mLastUsedProjectDirectory = ""; mMainWindowLayout = WindowLayoutDesc(); mWindowLayouts.clear(); } EditorPrefs& gEditorPrefs() { return EditorPrefs::instance(); } }