reimplemented workspace module

This commit is contained in:
Igor Korsukov 2021-06-24 18:50:12 +02:00 committed by pereverzev+v
parent 503e0c7806
commit 0e88cedd27
33 changed files with 292 additions and 348 deletions

View file

@ -27,6 +27,7 @@
#include "io/path.h"
#include "appshelltypes.h"
#include "async/notification.h"
namespace mu::appshell {
class IAppShellConfiguration : MODULE_EXPORT_INTERFACE
@ -62,10 +63,13 @@ public:
virtual ValCh<io::paths> recentScorePaths() const = 0;
virtual ValCh<bool> isNotationStatusBarVisible() const = 0;
virtual bool isNotationStatusBarVisible() const = 0;
virtual void setIsNotationStatusBarVisible(bool visible) const = 0;
virtual ValCh<bool> isNotationNavigatorVisible() const = 0;
virtual async::Notification isNotationStatusBarVisibleChanged() const = 0;
virtual bool isNotationNavigatorVisible() const = 0;
virtual void setIsNotationNavigatorVisible(bool visible) const = 0;
virtual async::Notification isNotationNavigatorVisibleChanged() const = 0;
virtual bool needShowSplashScreen() const = 0;
virtual void setNeedShowSplashScreen(bool show) = 0;

View file

@ -56,14 +56,6 @@ void AppShellConfiguration::init()
settings()->setDefaultValue(STARTUP_SCORE_PATH, Val(userScoresConfiguration()->myFirstScorePath().toStdString()));
settings()->setDefaultValue(CHECK_FOR_UPDATE_KEY, Val(isAppUpdatable()));
uiConfiguration()->isVisibleChanged(NOTATION_STATUSBAR_VISIBLE_KEY).onNotify(this, [this]() {
m_notationStatusBarVisibleChanged.send(isNotationStatusBarVisible().val);
});
uiConfiguration()->isVisibleChanged(NOTATION_NAVIGATOR_VISIBLE_KEY).onNotify(this, [this]() {
m_notationNavigatorVisibleChanged.send(isNotationNavigatorVisible().val);
});
}
StartupSessionType AppShellConfiguration::startupSessionType() const
@ -175,12 +167,9 @@ mu::ValCh<mu::io::paths> AppShellConfiguration::recentScorePaths() const
return userScoresConfiguration()->recentScorePaths();
}
mu::ValCh<bool> AppShellConfiguration::isNotationStatusBarVisible() const
bool AppShellConfiguration::isNotationStatusBarVisible() const
{
ValCh<bool> visible;
visible.ch = m_notationStatusBarVisibleChanged;
visible.val = uiConfiguration()->isVisible(NOTATION_STATUSBAR_VISIBLE_KEY);
return visible;
return uiConfiguration()->isVisible(NOTATION_STATUSBAR_VISIBLE_KEY);
}
void AppShellConfiguration::setIsNotationStatusBarVisible(bool visible) const
@ -188,13 +177,14 @@ void AppShellConfiguration::setIsNotationStatusBarVisible(bool visible) const
uiConfiguration()->setIsVisible(NOTATION_STATUSBAR_VISIBLE_KEY, visible);
}
mu::ValCh<bool> AppShellConfiguration::isNotationNavigatorVisible() const
mu::async::Notification AppShellConfiguration::isNotationStatusBarVisibleChanged() const
{
ValCh<bool> visible;
visible.ch = m_notationNavigatorVisibleChanged;
visible.val = uiConfiguration()->isVisible(NOTATION_NAVIGATOR_VISIBLE_KEY);
return uiConfiguration()->isVisibleChanged(NOTATION_STATUSBAR_VISIBLE_KEY);
}
return visible;
bool AppShellConfiguration::isNotationNavigatorVisible() const
{
return uiConfiguration()->isVisible(NOTATION_NAVIGATOR_VISIBLE_KEY);
}
void AppShellConfiguration::setIsNotationNavigatorVisible(bool visible) const
@ -202,6 +192,11 @@ void AppShellConfiguration::setIsNotationNavigatorVisible(bool visible) const
uiConfiguration()->setIsVisible(NOTATION_NAVIGATOR_VISIBLE_KEY, visible);
}
mu::async::Notification AppShellConfiguration::isNotationNavigatorVisibleChanged() const
{
return uiConfiguration()->isVisibleChanged(NOTATION_NAVIGATOR_VISIBLE_KEY);
}
bool AppShellConfiguration::needShowSplashScreen() const
{
return settings()->value(SPLASH_SCREEN_VISIBLE_KEY).toBool();

View file

@ -69,10 +69,13 @@ public:
ValCh<io::paths> recentScorePaths() const override;
ValCh<bool> isNotationStatusBarVisible() const override;
bool isNotationStatusBarVisible() const override;
void setIsNotationStatusBarVisible(bool visible) const override;
ValCh<bool> isNotationNavigatorVisible() const override;
async::Notification isNotationStatusBarVisibleChanged() const override;
bool isNotationNavigatorVisible() const override;
void setIsNotationNavigatorVisible(bool visible) const override;
async::Notification isNotationNavigatorVisibleChanged() const override;
bool needShowSplashScreen() const override;
void setNeedShowSplashScreen(bool show) override;
@ -92,7 +95,6 @@ private:
std::string currentLanguageCode() const;
async::Channel<bool> m_notationStatusBarVisibleChanged;
async::Channel<bool> m_notationNavigatorVisibleChanged;
};
}

View file

@ -25,11 +25,11 @@ using namespace mu::appshell;
void NotationPageState::init()
{
configuration()->isNotationNavigatorVisible().ch.onReceive(this, [this](bool) {
configuration()->isNotationNavigatorVisibleChanged().onNotify(this, [this]() {
m_panelsVisibleChanged.send({ PanelType::NotationNavigator });
});
configuration()->isNotationStatusBarVisible().ch.onReceive(this, [this](bool) {
configuration()->isNotationStatusBarVisibleChanged().onNotify(this, [this]() {
m_panelsVisibleChanged.send({ PanelType::NotationStatusBar });
});
}
@ -46,9 +46,9 @@ bool NotationPageState::isPanelVisible(PanelType type) const
case PanelType::PlaybackToolBar:
return m_panelVisibleMap[type];
case PanelType::NotationNavigator:
return configuration()->isNotationNavigatorVisible().val;
return configuration()->isNotationNavigatorVisible();
case PanelType::NotationStatusBar:
return configuration()->isNotationStatusBarVisible().val;
return configuration()->isNotationStatusBarVisible();
case PanelType::Mixer:
case PanelType::TimeLine:
case PanelType::Synthesizer:

View file

@ -84,7 +84,13 @@ void AppMenuModel::setupConnections()
emit itemsChanged();
});
workspacesManager()->currentWorkspace().ch.onReceive(this, [this](const IWorkspacePtr&) {
workspacesManager()->currentWorkspaceChanged().onNotify(this, [this]() {
MenuItem& workspacesItem = findMenu("select-workspace");
workspacesItem.subitems = workspacesItems();
emit itemsChanged();
});
workspacesManager()->workspacesListChanged().onNotify(this, [this]() {
MenuItem& workspacesItem = findMenu("select-workspace");
workspacesItem.subitems = workspacesItems();
emit itemsChanged();
@ -470,25 +476,20 @@ MenuItemList AppMenuModel::workspacesItems() const
{
MenuItemList items;
RetVal<IWorkspacePtrList> workspaces = workspacesManager()->workspaces();
if (!workspaces.ret) {
return items;
}
IWorkspacePtrList workspaces = workspacesManager()->workspaces();
IWorkspacePtr currentWorkspace = workspacesManager()->currentWorkspace();
IWorkspacePtr currentWorkspace = workspacesManager()->currentWorkspace().val;
std::sort(workspaces.val.begin(), workspaces.val.end(), [](const IWorkspacePtr& workspace1, const IWorkspacePtr& workspace2) {
std::sort(workspaces.begin(), workspaces.end(), [](const IWorkspacePtr& workspace1, const IWorkspacePtr& workspace2) {
return workspace1->name() < workspace2->name();
});
for (const IWorkspacePtr& workspace : workspaces.val) {
for (const IWorkspacePtr& workspace : workspaces) {
MenuItem item = uiactionsRegister()->action("select-workspace");
item.title = QString::fromStdString(workspace->title());
item.args = ActionData::make_arg1<std::string>(workspace->name());
bool isCurrentWorkspace = workspace == currentWorkspace;
item.selectable = true;
item.selected = isCurrentWorkspace;
item.selected = (workspace == currentWorkspace);
item.state.enabled = true;
items << item;

View file

@ -95,7 +95,7 @@ ProgrammeStartPreferencesModel::PanelList ProgrammeStartPreferencesModel::allPan
{
PanelList panels {
Panel { SplashScreen, qtrc("appshell", "Show splash screen"), configuration()->needShowSplashScreen() },
Panel { Navigator, qtrc("appshell", "Show navigator"), configuration()->isNotationNavigatorVisible().val },
Panel { Navigator, qtrc("appshell", "Show navigator"), configuration()->isNotationNavigatorVisible() },
Panel { Tours, qtrc("appshell", "Show tours"), configuration()->needShowTours() }
};

View file

@ -22,6 +22,7 @@
#include "uiarrangement.h"
#include <QJsonDocument>
#include <QJsonValue>
#include <QJsonArray>
@ -43,30 +44,32 @@ void UiArrangement::init()
workspacesDataProvider()->dataChanged(DataKey::UiSettings).onNotify(this, [this]() {
updateData(DataKey::UiToolConfigs, m_toolconfigs);
});
updateData(DataKey::UiSettings, m_settings);
updateData(DataKey::UiStates, m_states);
updateData(DataKey::UiToolConfigs, m_toolconfigs);
}
void UiArrangement::updateData(DataKey key, QJsonObject& obj)
void UiArrangement::updateData(DataKey key, QJsonObject& obj) const
{
RetVal<Data> data = workspacesDataProvider()->data(key);
RetVal<QByteArray> data = workspacesDataProvider()->rawData(key);
if (!data.ret) {
LOGE() << "failed get data: " << int(key) << ", ret: " << data.ret.toString();
return;
}
obj = data.val.data.toObject();
obj = QJsonDocument::fromJson(data.val).object();
}
void UiArrangement::saveData(workspace::DataKey key, const QJsonObject& obj)
{
workspacesDataProvider()->setData(key, { obj });
QByteArray data = QJsonDocument(obj).toJson();
workspacesDataProvider()->setRawData(key, data);
}
QString UiArrangement::value(const QString& key) const
{
if (m_settings.isEmpty()) {
updateData(DataKey::UiSettings, m_settings);
}
QJsonValue val = m_settings.value(key);
return val.toString();
}
@ -85,6 +88,10 @@ mu::async::Notification UiArrangement::valueChanged(const QString& key) const
QByteArray UiArrangement::state(const QString& key) const
{
if (m_states.isEmpty()) {
updateData(DataKey::UiStates, m_states);
}
QJsonValue val = m_states.value(key);
QString valStr = val.toString();
return valStr.toLocal8Bit();
@ -100,6 +107,10 @@ ToolConfig UiArrangement::toolConfig(const QString& toolName) const
{
TRACEFUNC;
if (m_toolconfigs.isEmpty()) {
updateData(DataKey::UiToolConfigs, m_toolconfigs);
}
//! NOTE Maybe we need to cache?
QJsonObject confObj = m_toolconfigs.value(toolName).toObject();

View file

@ -55,12 +55,12 @@ public:
private:
void updateData(workspace::DataKey key, QJsonObject& obj);
void updateData(workspace::DataKey key, QJsonObject& obj) const;
void saveData(workspace::DataKey key, const QJsonObject& obj);
QJsonObject m_settings;
QJsonObject m_states;
QJsonObject m_toolconfigs;
mutable QJsonObject m_settings;
mutable QJsonObject m_states;
mutable QJsonObject m_toolconfigs;
};
}

View file

@ -150,10 +150,17 @@ void UiModule::registerUiTypes()
void UiModule::onInit(const IApplication::RunMode&)
{
s_configuration->init();
s_uiactionsRegister->init();
s_keyNavigationController->init();
}
void UiModule::onStartApp()
{
//! NOTE UIActions are collected from many modules, and these modules determine the state of their UIActions.
//! All modules need to be initialized in order to get the correct state of UIActions.
//! So, we do init on onStartApp
s_uiactionsRegister->init();
}
void UiModule::onDeinit()
{
s_configuration->deinit();

View file

@ -36,6 +36,7 @@ public:
void registerResources() override;
void registerUiTypes() override;
void onInit(const framework::IApplication::RunMode& mode) override;
void onStartApp() override;
void onDeinit() override;
};
}

View file

@ -117,10 +117,13 @@ void PaletteModule::onInit(const IApplication::RunMode& mode)
return;
}
// load workspace
s_paletteWorkspaceSetup->setup();
s_configuration->init();
s_actionsController->init();
s_paletteUiActions->init();
}
void PaletteModule::onStartApp()
{
// load workspace
s_paletteWorkspaceSetup->setup();
}

View file

@ -37,6 +37,7 @@ public:
void registerUiTypes() override;
void onInit(const framework::IApplication::RunMode& mode) override;
void onStartApp() override;
};
}

View file

@ -40,9 +40,6 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/workspacesdataprovider.h
${CMAKE_CURRENT_LIST_DIR}/internal/workspacefile.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/workspacefile.h
${CMAKE_CURRENT_LIST_DIR}/internal/iworkspacecreator.h
${CMAKE_CURRENT_LIST_DIR}/internal/workspacecreator.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/workspacecreator.h
${CMAKE_CURRENT_LIST_DIR}/internal/workspaceuiactions.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/workspaceuiactions.h
${CMAKE_CURRENT_LIST_DIR}/internal/workspaceactioncontroller.cpp

View file

@ -1,41 +0,0 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_WORKSPACE_IWORKSPACECREATOR_H
#define MU_WORKSPACE_IWORKSPACECREATOR_H
#include "iworkspace.h"
#include "modularity/imoduleexport.h"
namespace mu::workspace {
class IWorkspaceCreator : MODULE_EXPORT_INTERFACE
{
INTERFACE_ID(IWorkspaceCreator)
public:
virtual ~IWorkspaceCreator() = default;
virtual IWorkspacePtr newWorkspace(const std::string& workspaceName) const = 0;
};
}
#endif // MU_WORKSPACE_IWORKSPACECREATOR_H

View file

@ -58,31 +58,19 @@ void Workspace::setIsManaged(const DataKey& key, bool val) const
NOT_IMPLEMENTED;
}
RetVal<QByteArray> Workspace::readRawData(const std::string& name) const
RetVal<QByteArray> Workspace::rawData(const DataKey& key) const
{
NOT_IMPLEMENTED;
return RetVal<QByteArray>();
}
Ret Workspace::writeRawData(const std::string& name, const QByteArray& data)
Ret Workspace::setRawData(const DataKey& key, const QByteArray& data)
{
NOT_IMPLEMENTED;
return Ret();
}
RetVal<Data> Workspace::readData(const std::string& name) const
{
NOT_IMPLEMENTED;
return RetVal<Data>();
}
Ret Workspace::writeData(const std::string& name, const Data& data)
{
NOT_IMPLEMENTED;
return Ret();
}
bool Workspace::isInited() const
bool Workspace::isLoaded() const
{
return m_isInited;
}
@ -92,7 +80,7 @@ io::path Workspace::filePath() const
return m_filePath;
}
Ret Workspace::read()
Ret Workspace::load()
{
clear();
@ -123,7 +111,7 @@ Ret Workspace::readWorkspace(const QByteArray& xmlData)
return make_ret(Ret::Code::Ok);
}
Ret Workspace::write()
Ret Workspace::save()
{
if (!m_hasUnsavedChanges) {
return make_ret(Ret::Code::Ok);

View file

@ -37,18 +37,13 @@ public:
bool isManaged(const DataKey& key) const override;
void setIsManaged(const DataKey& key, bool val) const override;
RetVal<QByteArray> readRawData(const std::string& name) const override;
Ret writeRawData(const std::string& name, const QByteArray& data) override;
RetVal<QByteArray> rawData(const DataKey& key) const override;
Ret setRawData(const DataKey& key, const QByteArray& data) override;
RetVal<Data> readData(const std::string& name) const override;
Ret writeData(const std::string& name, const Data& data) override;
// =======================================
bool isInited() const;
io::path filePath() const;
Ret read();
Ret write();
bool isLoaded() const;
Ret load();
Ret save();
private:
Ret readWorkspace(const QByteArray& data);

View file

@ -29,7 +29,7 @@ using namespace mu;
using namespace mu::workspace;
using namespace mu::framework;
static const Settings::Key CURRENT_WORKSPACE("workspace", "application/workspace");
static const Settings::Key CURRENT_WORKSPACE("workspace", "workspace");
void WorkspaceConfiguration::init()
{
@ -42,10 +42,7 @@ void WorkspaceConfiguration::init()
io::paths WorkspaceConfiguration::workspacePaths() const
{
io::paths paths;
io::path sharePath = globalConfiguration()->appDataPath() + "/workspaces";
paths.push_back(sharePath);
paths.push_back(userWorkspacesDirPath());
paths.push_back(userWorkspacesPath());
std::vector<io::path> extensionsPath = this->extensionsPaths();
paths.insert(paths.end(), extensionsPath.begin(), extensionsPath.end());
@ -53,14 +50,14 @@ io::paths WorkspaceConfiguration::workspacePaths() const
return paths;
}
io::path WorkspaceConfiguration::userWorkspacesDirPath() const
io::path WorkspaceConfiguration::templateWorkspacePath() const
{
return globalConfiguration()->userAppDataPath() + "/workspaces";
return ":/workspace/template";
}
io::path WorkspaceConfiguration::userWorkspacePath(const std::string& workspaceName) const
io::path WorkspaceConfiguration::userWorkspacesPath() const
{
return userWorkspacesDirPath() + "/" + workspaceName + ".workspace";
return globalConfiguration()->userAppDataPath() + "/workspaces";
}
ValCh<std::string> WorkspaceConfiguration::currentWorkspaceName() const

View file

@ -39,8 +39,9 @@ public:
io::paths workspacePaths() const override;
io::path userWorkspacesDirPath() const override;
io::path userWorkspacePath(const std::string& workspaceName) const override;
io::path templateWorkspacePath() const override;
io::path userWorkspacesPath() const override;
ValCh<std::string> currentWorkspaceName() const override;
void setCurrentWorkspaceName(const std::string& workspaceName) override;

View file

@ -1,34 +0,0 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "workspacecreator.h"
#include "workspace.h"
using namespace mu::workspace;
IWorkspacePtr WorkspaceCreator::newWorkspace(const std::string& workspaceName) const
{
io::path filePath = configuration()->userWorkspacePath(workspaceName);
return std::make_shared<Workspace>(filePath);
}

View file

@ -1,40 +0,0 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_WORKSPACE_WORKSPACECREATOR_H
#define MU_WORKSPACE_WORKSPACECREATOR_H
#include "iworkspacecreator.h"
#include "iworkspaceconfiguration.h"
#include "modularity/ioc.h"
namespace mu::workspace {
class WorkspaceCreator : public IWorkspaceCreator
{
INJECT(workspace, IWorkspaceConfiguration, configuration)
public:
IWorkspacePtr newWorkspace(const std::string& workspaceName) const override;
};
}
#endif // MU_WORKSPACE_WORKSPACECREATOR_H

View file

@ -25,40 +25,61 @@
using namespace mu;
using namespace mu::workspace;
using namespace mu::extensions;
static const std::string WORKSPACE_EXT(".workspace");
static bool containsWorkspace(const IWorkspacePtrList& list, const IWorkspacePtr& workspace)
{
return std::find(list.cbegin(), list.cend(), workspace) != list.cend();
}
RetValCh<IWorkspacePtr> WorkspaceManager::currentWorkspace() const
void WorkspaceManager::init()
{
RetValCh<IWorkspacePtr> rv;
configuration()->currentWorkspaceName().ch.onReceive(this, [this](const std::string&) {
setupCurrentWorkspace();
});
if (!m_currentWorkspace) {
rv.ret = make_ret(Ret::Code::UnknownError);
rv.val = nullptr;
} else {
rv.ret = make_ret(Ret::Code::Ok);
rv.val = m_currentWorkspace;
}
rv.ch = m_currentWorkspaceChanged;
return rv;
load();
}
RetVal<IWorkspacePtrList> WorkspaceManager::workspaces() const
void WorkspaceManager::deinit()
{
RetVal<IWorkspacePtrList> result;
result.ret = make_ret(Ret::Code::Ok);
saveCurrentWorkspace();
for (auto workspace : m_workspaces) {
result.val.push_back(workspace);
m_currentWorkspace = nullptr;
m_defaultWorkspace = nullptr;
m_workspaces.clear();
}
bool WorkspaceManager::isInited() const
{
return m_defaultWorkspace != nullptr;
}
IWorkspacePtr WorkspaceManager::defaultWorkspace() const
{
return m_defaultWorkspace;
}
IWorkspacePtr WorkspaceManager::currentWorkspace() const
{
return m_currentWorkspace;
}
async::Notification WorkspaceManager::currentWorkspaceChanged() const
{
NOT_IMPLEMENTED;
return async::Notification();
}
IWorkspacePtrList WorkspaceManager::workspaces() const
{
IWorkspacePtrList iworkspaces;
iworkspaces.reserve(m_workspaces.size());
for (WorkspacePtr w : m_workspaces) {
iworkspaces.push_back(w);
}
return result;
return iworkspaces;
}
Ret WorkspaceManager::setWorkspaces(const IWorkspacePtrList& workspaces)
@ -72,14 +93,27 @@ Ret WorkspaceManager::setWorkspaces(const IWorkspacePtrList& workspaces)
return ret;
}
async::Notification WorkspaceManager::workspacesListChanged() const
{
NOT_IMPLEMENTED;
return async::Notification();
}
IWorkspacePtr WorkspaceManager::newWorkspace(const std::string& workspaceName) const
{
return doNewWorkspace(workspaceName);
}
WorkspacePtr WorkspaceManager::doNewWorkspace(const std::string& workspaceName) const
{
io::path filePath = configuration()->userWorkspacesPath() + "/" + workspaceName + WORKSPACE_EXT;
return std::make_shared<Workspace>(filePath);
}
Ret WorkspaceManager::removeMissingWorkspaces(const IWorkspacePtrList& newWorkspaceList)
{
RetVal<IWorkspacePtrList> oldWorkspaceList = workspaces();
if (!oldWorkspaceList.ret) {
return oldWorkspaceList.ret;
}
for (const IWorkspacePtr& oldWorkspace : oldWorkspaceList.val) {
IWorkspacePtrList oldWorkspaceList = workspaces();
for (const IWorkspacePtr& oldWorkspace : oldWorkspaceList) {
if (containsWorkspace(newWorkspaceList, oldWorkspace)) {
continue;
}
@ -117,13 +151,9 @@ bool WorkspaceManager::canRemoveWorkspace(const std::string& workspaceName) cons
Ret WorkspaceManager::createInexistentWorkspaces(const IWorkspacePtrList& newWorkspaceList)
{
RetVal<IWorkspacePtrList> existentWorkspaces = workspaces();
if (!existentWorkspaces.ret) {
return existentWorkspaces.ret;
}
IWorkspacePtrList existentWorkspaces = workspaces();
for (const IWorkspacePtr& workspace : newWorkspaceList) {
if (containsWorkspace(existentWorkspaces.val, workspace)) {
if (containsWorkspace(existentWorkspaces, workspace)) {
continue;
}
@ -143,7 +173,7 @@ Ret WorkspaceManager::createWorkspace(IWorkspacePtr workspace)
return make_ret(Ret::Code::Ok);
}
Ret ret = writable->write();
Ret ret = writable->save();
if (ret) {
m_workspaces.push_back(writable);
@ -152,40 +182,17 @@ Ret WorkspaceManager::createWorkspace(IWorkspacePtr workspace)
return ret;
}
void WorkspaceManager::init()
{
Ret ret = fileSystem()->makePath(configuration()->userWorkspacesDirPath());
if (!ret) {
LOGE() << ret.toString();
}
RetCh<Extension> extensionChanged = extensionsService()->extensionChanged();
if (extensionChanged.ret) {
extensionChanged.ch.onReceive(this, [this](const Extension& newExtension) {
if (newExtension.types.testFlag(Extension::Workspaces)) {
load();
}
});
}
configuration()->currentWorkspaceName().ch.onReceive(this, [this](const std::string&) {
setupCurrentWorkspace();
});
load();
}
void WorkspaceManager::load()
{
m_workspaces.clear();
io::paths files = findWorkspaceFiles();
for (const io::path& file : files) {
auto workspace = std::make_shared<Workspace>(file);
m_workspaces.push_back(workspace);
}
setupDefaultWorkspace();
setupCurrentWorkspace();
}
@ -207,27 +214,61 @@ io::paths WorkspaceManager::findWorkspaceFiles() const
return result;
}
void WorkspaceManager::setupDefaultWorkspace()
{
WorkspacePtr workspace = findAndInit(DEFAULT_WORKSPACE_NAME);
if (workspace) {
m_defaultWorkspace = workspace;
return;
}
LOGW() << "not found default workspace, will be created new from template";
m_defaultWorkspace = doNewWorkspace(DEFAULT_WORKSPACE_NAME);
m_workspaces.push_back(m_defaultWorkspace);
//! TODO Needs add data from the template
Ret ret = fileSystem()->makePath(configuration()->userWorkspacesPath());
if (!ret) {
LOGE() << ret.toString();
return;
}
ret = m_defaultWorkspace->save();
if (ret) {
LOGE() << "failed save default workspace";
}
}
void WorkspaceManager::setupCurrentWorkspace()
{
saveCurrentWorkspace();
std::string workspaceName = configuration()->currentWorkspaceName().val;
WorkspacePtr workspace = findAndInit(workspaceName);
if (!workspace) {
std::string defaultWorkspaceName(DEFAULT_WORKSPACE_NAME);
LOGW() << "failed get workspace: " << workspaceName << ", will use " << defaultWorkspaceName;
workspace = findAndInit(defaultWorkspaceName);
if (workspace) {
configuration()->setCurrentWorkspaceName(defaultWorkspaceName);
if (m_currentWorkspace && m_currentWorkspace->isLoaded()) {
if (m_currentWorkspace->name() == workspaceName) {
return;
}
saveCurrentWorkspace();
//! NOTE Perhaps we need to unload the current workspace (clear memory)
}
if (workspace && workspace != m_currentWorkspace) {
m_currentWorkspace = workspace;
m_currentWorkspaceChanged.send(workspace);
WorkspacePtr workspace = findAndInit(workspaceName);
if (!workspace) {
LOGW() << "failed get workspace: " << workspaceName << ", will use " << DEFAULT_WORKSPACE_NAME;
//! NOTE Already should be inited
IF_ASSERT_FAILED(m_defaultWorkspace) {
setupDefaultWorkspace();
}
workspace = m_defaultWorkspace;
configuration()->setCurrentWorkspaceName(DEFAULT_WORKSPACE_NAME);
}
m_currentWorkspace = workspace;
m_currentWorkspaceChanged.send(workspace);
}
WorkspacePtr WorkspaceManager::findByName(const std::string& name) const
@ -248,10 +289,10 @@ WorkspacePtr WorkspaceManager::findAndInit(const std::string& name) const
return nullptr;
}
if (!workspace->isInited()) {
Ret ret = workspace->read();
if (!workspace->isLoaded()) {
Ret ret = workspace->load();
if (!ret) {
LOGE() << "failed read workspace: " << name;
LOGE() << "failed load workspace: " << name;
return nullptr;
}
}
@ -259,19 +300,14 @@ WorkspacePtr WorkspaceManager::findAndInit(const std::string& name) const
return workspace;
}
void WorkspaceManager::deinit()
{
saveCurrentWorkspace();
}
void WorkspaceManager::saveCurrentWorkspace()
{
if (!m_currentWorkspace) {
return;
}
Ret ret = m_currentWorkspace->write();
Ret ret = m_currentWorkspace->save();
if (!ret) {
LOGE() << ret.toString();
LOGE() << "failed save current workspace, err: " << ret.toString();
}
}

View file

@ -29,26 +29,41 @@
#include "../iworkspaceconfiguration.h"
#include "../system/ifilesystem.h"
#include "workspace.h"
#include "extensions/iextensionsservice.h"
namespace mu::workspace {
class WorkspaceManager : public IWorkspaceManager, async::Asyncable
class WorkspaceManager : public IWorkspaceManager, public async::Asyncable
{
INJECT(workspace, IWorkspaceConfiguration, configuration)
INJECT(workspace, extensions::IExtensionsService, extensionsService)
INJECT(workspace, system::IFileSystem, fileSystem)
public:
WorkspaceManager() = default;
void init();
void deinit();
bool isInited() const;
RetValCh<IWorkspacePtr> currentWorkspace() const override;
IWorkspacePtr defaultWorkspace() const override;
RetVal<IWorkspacePtrList> workspaces() const override;
IWorkspacePtr currentWorkspace() const override;
async::Notification currentWorkspaceChanged() const override;
IWorkspacePtrList workspaces() const override;
Ret setWorkspaces(const IWorkspacePtrList& workspaces) override;
async::Notification workspacesListChanged() const override;
IWorkspacePtr newWorkspace(const std::string& workspaceName) const override;
private:
void load();
io::paths findWorkspaceFiles() const;
WorkspacePtr doNewWorkspace(const std::string& workspaceName) const;
void setupDefaultWorkspace();
void setupCurrentWorkspace();
void saveCurrentWorkspace();
Ret removeMissingWorkspaces(const IWorkspacePtrList& newWorkspaceList);
@ -58,12 +73,10 @@ private:
Ret createInexistentWorkspaces(const IWorkspacePtrList& newWorkspaceList);
Ret createWorkspace(IWorkspacePtr workspace);
io::paths findWorkspaceFiles() const;
void setupCurrentWorkspace();
WorkspacePtr findByName(const std::string& name) const;
WorkspacePtr findAndInit(const std::string& name) const;
WorkspacePtr m_defaultWorkspace;
WorkspacePtr m_currentWorkspace;
std::vector<WorkspacePtr> m_workspaces;

View file

@ -27,26 +27,40 @@ using namespace mu::workspace;
mu::RetVal<QByteArray> WorkspacesDataProvider::rawData(DataKey key) const
{
NOT_IMPLEMENTED;
return RetVal<QByteArray>();
IWorkspacePtr current = manager()->currentWorkspace();
IF_ASSERT_FAILED(current) {
return RetVal<QByteArray>(make_ret(Ret::Code::InternalError));
}
if (current->isManaged(key)) {
return current->rawData(key);
}
IWorkspacePtr def = manager()->defaultWorkspace();
IF_ASSERT_FAILED(def) {
return RetVal<QByteArray>(make_ret(Ret::Code::InternalError));
}
return def->rawData(key);
}
mu::Ret WorkspacesDataProvider::setRawData(DataKey key, const QByteArray& data)
{
NOT_IMPLEMENTED;
return Ret();
}
IWorkspacePtr current = manager()->currentWorkspace();
IF_ASSERT_FAILED(current) {
return make_ret(Ret::Code::InternalError);
}
mu::RetVal<Data> WorkspacesDataProvider::data(DataKey key) const
{
NOT_IMPLEMENTED;
return RetVal<Data>();
}
if (current->isManaged(key)) {
return current->setRawData(key, data);
}
mu::Ret WorkspacesDataProvider::setData(DataKey key, const Data& data)
{
NOT_IMPLEMENTED;
return Ret();
IWorkspacePtr def = manager()->defaultWorkspace();
IF_ASSERT_FAILED(def) {
return make_ret(Ret::Code::InternalError);
}
return def->setRawData(key, data);
}
mu::async::Notification WorkspacesDataProvider::dataChanged(DataKey key)

View file

@ -24,18 +24,20 @@
#include "../iworkspacesdataprovider.h"
#include "modularity/ioc.h"
#include "iworkspacemanager.h"
namespace mu::workspace {
class WorkspacesDataProvider : public IWorkspacesDataProvider
{
INJECT(workspace, IWorkspaceManager, manager)
public:
WorkspacesDataProvider() = default;
RetVal<QByteArray> rawData(DataKey key) const override;
Ret setRawData(DataKey key, const QByteArray& data) override;
RetVal<Data> data(DataKey key) const override;
Ret setData(DataKey key, const Data& data) override;
async::Notification dataChanged(DataKey key) override;
};
}

View file

@ -41,11 +41,8 @@ public:
virtual bool isManaged(const DataKey& key) const = 0;
virtual void setIsManaged(const DataKey& key, bool val) const = 0;
virtual RetVal<QByteArray> readRawData(const std::string& name) const = 0;
virtual Ret writeRawData(const std::string& name, const QByteArray& data) = 0;
virtual RetVal<Data> readData(const std::string& name) const = 0;
virtual Ret writeData(const std::string& name, const Data& data) = 0;
virtual RetVal<QByteArray> rawData(const DataKey& key) const = 0;
virtual Ret setRawData(const DataKey& key, const QByteArray& data) = 0;
};
using IWorkspacePtr = std::shared_ptr<IWorkspace>;

View file

@ -38,8 +38,10 @@ public:
virtual io::paths workspacePaths() const = 0;
virtual io::path userWorkspacesDirPath() const = 0;
virtual io::path userWorkspacePath(const std::string& workspaceName) const = 0;
//! NOTE The path to the read-only template for the default workspace
virtual io::path templateWorkspacePath() const = 0;
virtual io::path userWorkspacesPath() const = 0;
virtual ValCh<std::string> currentWorkspaceName() const = 0;
virtual void setCurrentWorkspaceName(const std::string& workspaceName) = 0;

View file

@ -26,6 +26,7 @@
#include "iworkspace.h"
#include "retval.h"
#include "async/notification.h"
namespace mu::workspace {
class IWorkspaceManager : MODULE_EXPORT_INTERFACE
@ -35,10 +36,18 @@ class IWorkspaceManager : MODULE_EXPORT_INTERFACE
public:
virtual ~IWorkspaceManager() = default;
virtual RetValCh<IWorkspacePtr> currentWorkspace() const = 0;
//! NOTE Default from user app data, writable, full managed
virtual IWorkspacePtr defaultWorkspace() const = 0;
virtual RetVal<IWorkspacePtrList> workspaces() const = 0;
//! NOTE Current selected by a user, writable, optionally managed
virtual IWorkspacePtr currentWorkspace() const = 0;
virtual async::Notification currentWorkspaceChanged() const = 0;
virtual IWorkspacePtrList workspaces() const = 0;
virtual Ret setWorkspaces(const IWorkspacePtrList& workspaces) = 0;
virtual async::Notification workspacesListChanged() const = 0;
virtual IWorkspacePtr newWorkspace(const std::string& workspaceName) const = 0;
};
}

View file

@ -39,9 +39,6 @@ public:
virtual RetVal<QByteArray> rawData(DataKey key) const = 0;
virtual Ret setRawData(DataKey key, const QByteArray& data) = 0;
virtual RetVal<Data> data(DataKey key) const = 0;
virtual Ret setData(DataKey key, const Data& data) = 0;
virtual async::Notification dataChanged(DataKey key) = 0;
};
}

View file

@ -124,7 +124,7 @@ void NewWorkspaceModel::setUseToolbarCustomization(bool needUse)
QVariant NewWorkspaceModel::createWorkspace()
{
IWorkspacePtr newWorkspace = workspaceCreator()->newWorkspace(m_workspaceName.toStdString());
IWorkspacePtr newWorkspace = workspaceManager()->newWorkspace(m_workspaceName.toStdString());
newWorkspace->setIsManaged(DataKey::UiSettings, useUiPreferences());
newWorkspace->setIsManaged(DataKey::UiStates, useUiArrangement());

View file

@ -26,7 +26,6 @@
#include <QObject>
#include "modularity/ioc.h"
#include "internal/iworkspacecreator.h"
#include "iworkspacemanager.h"
namespace mu::workspace {
@ -34,7 +33,6 @@ class NewWorkspaceModel : public QObject
{
Q_OBJECT
INJECT(workspace, IWorkspaceCreator, workspaceCreator)
INJECT(workspace, IWorkspaceManager, workspaceManager)
Q_PROPERTY(QString workspaceName READ workspaceName WRITE setWorkspaceName NOTIFY dataChanged)

View file

@ -41,15 +41,12 @@ void WorkspaceListModel::load()
beginResetModel();
m_workspaces.clear();
RetVal<IWorkspacePtrList> workspaces = workspacesManager()->workspaces();
if (!workspaces.ret) {
LOGE() << workspaces.ret.toString();
}
IWorkspacePtrList workspaces = workspacesManager()->workspaces();
IWorkspacePtr currentWorkspace = workspacesManager()->currentWorkspace().val;
IWorkspacePtr currentWorkspace = workspacesManager()->currentWorkspace();
IWorkspacePtr selectedWorkspace;
for (const IWorkspacePtr& workspace : workspaces.val) {
for (const IWorkspacePtr& workspace : workspaces) {
if (workspace == currentWorkspace) {
selectedWorkspace = workspace;
}

View file

@ -31,7 +31,6 @@
#include "internal/workspaceconfiguration.h"
#include "internal/workspacemanager.h"
#include "internal/workspacecreator.h"
#include "internal/workspaceactioncontroller.h"
#include "internal/workspaceuiactions.h"
#include "internal/workspacesdataprovider.h"
@ -64,7 +63,6 @@ void WorkspaceModule::registerExports()
{
ioc()->registerExport<IWorkspaceConfiguration>(moduleName(), s_configuration);
ioc()->registerExport<IWorkspaceManager>(moduleName(), s_manager);
ioc()->registerExport<IWorkspaceCreator>(moduleName(), std::make_shared<WorkspaceCreator>());
ioc()->registerExport<IWorkspacesDataProvider>(moduleName(), s_provider);
}

View file

@ -22,8 +22,6 @@
#ifndef MU_WORKSPACE_WORKSPACETYPES_H
#define MU_WORKSPACE_WORKSPACETYPES_H
#include <QJsonValue>
namespace mu::workspace {
static const std::string DEFAULT_WORKSPACE_NAME("Default");
@ -34,11 +32,6 @@ enum class DataKey {
UiToolConfigs,
Palettes,
};
struct Data
{
QJsonValue data;
};
}
#endif // MU_WORKSPACE_WORKSPACETYPES_H