added open new project in a new window
This commit is contained in:
parent
879efc8859
commit
f8f50f2895
11 changed files with 119 additions and 78 deletions
|
@ -197,7 +197,7 @@ RetVal<project::INotationProjectPtr> BackendApi::openProject(const io::path& pat
|
|||
{
|
||||
TRACEFUNC
|
||||
|
||||
auto notationProject = notationCreator()->newNotationProject();
|
||||
auto notationProject = notationCreator()->newProject();
|
||||
IF_ASSERT_FAILED(notationProject) {
|
||||
return make_ret(Ret::Code::InternalError);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ mu::Ret ConverterController::fileConvert(const io::path& in, const io::path& out
|
|||
TRACEFUNC;
|
||||
|
||||
LOGI() << "in: " << in << ", out: " << out;
|
||||
auto notationProject = notationCreator()->newNotationProject();
|
||||
auto notationProject = notationCreator()->newProject();
|
||||
IF_ASSERT_FAILED(notationProject) {
|
||||
return make_ret(Err::UnknownError);
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ mu::Ret ConverterController::convertScoreParts(const mu::io::path& in, const mu:
|
|||
{
|
||||
TRACEFUNC;
|
||||
|
||||
auto notationProject = notationCreator()->newNotationProject();
|
||||
auto notationProject = notationCreator()->newProject();
|
||||
IF_ASSERT_FAILED(notationProject) {
|
||||
return make_ret(Err::UnknownError);
|
||||
}
|
||||
|
|
|
@ -38,9 +38,10 @@ class IMultiInstancesProvider : MODULE_EXPORT_INTERFACE
|
|||
public:
|
||||
virtual ~IMultiInstancesProvider() = default;
|
||||
|
||||
// Score opening
|
||||
virtual bool isScoreAlreadyOpened(const io::path& scorePath) const = 0;
|
||||
virtual void activateWindowWithScore(const io::path& scorePath) = 0;
|
||||
// Project opening
|
||||
virtual bool isProjectAlreadyOpened(const io::path& projectPath) const = 0;
|
||||
virtual void activateWindowWithProject(const io::path& projectPath) = 0;
|
||||
virtual bool openNewAppInstance(const io::path& projectPath) = 0;
|
||||
|
||||
// Settings
|
||||
virtual bool isPreferencesAlreadyOpened() const = 0;
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
*/
|
||||
#include "multiinstancesprovider.h"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "uri.h"
|
||||
#include "settings.h"
|
||||
#include "log.h"
|
||||
|
@ -30,8 +33,8 @@ using namespace mu::ipc;
|
|||
using namespace mu::framework;
|
||||
|
||||
static const mu::UriQuery DEV_SHOW_INFO_URI("musescore://devtools/multiinstances/info?sync=false&modal=false");
|
||||
static const QString METHOD_SCORE_IS_OPENED("SCORE_IS_OPENED");
|
||||
static const QString METHOD_ACTIVATE_WINDOW_WITH_SCORE("ACTIVATE_WINDOW_WITH_SCORE");
|
||||
static const QString METHOD_PROJECT_IS_OPENED("PROJECT_IS_OPENED");
|
||||
static const QString METHOD_ACTIVATE_WINDOW_WITH_PROJECT("ACTIVATE_WINDOW_WITH_PROJECT");
|
||||
|
||||
static const mu::Uri PREFERENCES_URI("musescore://preferences");
|
||||
static const QString METHOD_PREFERENCES_IS_OPENED("PREFERENCES_IS_OPENED");
|
||||
|
@ -75,12 +78,12 @@ void MultiInstancesProvider::onMsg(const Msg& msg)
|
|||
#define CHECK_ARGS_COUNT(c) IF_ASSERT_FAILED(msg.args.count() >= c) { return; }
|
||||
|
||||
// Score opening
|
||||
if (msg.type == MsgType::Request && msg.method == METHOD_SCORE_IS_OPENED) {
|
||||
if (msg.type == MsgType::Request && msg.method == METHOD_PROJECT_IS_OPENED) {
|
||||
CHECK_ARGS_COUNT(1);
|
||||
io::path scorePath = io::path(msg.args.at(0));
|
||||
bool isOpened = projectFilesController()->isProjectOpened(scorePath);
|
||||
m_ipcChannel->response(METHOD_SCORE_IS_OPENED, { QString::number(isOpened) }, msg.srcID);
|
||||
} else if (msg.method == METHOD_ACTIVATE_WINDOW_WITH_SCORE) {
|
||||
m_ipcChannel->response(METHOD_PROJECT_IS_OPENED, { QString::number(isOpened) }, msg.srcID);
|
||||
} else if (msg.method == METHOD_ACTIVATE_WINDOW_WITH_PROJECT) {
|
||||
CHECK_ARGS_COUNT(1);
|
||||
io::path scorePath = io::path(msg.args.at(0));
|
||||
bool isOpened = projectFilesController()->isProjectOpened(scorePath);
|
||||
|
@ -112,14 +115,14 @@ void MultiInstancesProvider::onMsg(const Msg& msg)
|
|||
}
|
||||
}
|
||||
|
||||
bool MultiInstancesProvider::isScoreAlreadyOpened(const io::path& scorePath) const
|
||||
bool MultiInstancesProvider::isProjectAlreadyOpened(const io::path& projectPath) const
|
||||
{
|
||||
if (!isInited()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
m_ipcChannel->syncRequestToAll(METHOD_SCORE_IS_OPENED, { scorePath.toQString() }, [&ret](const QStringList& args) {
|
||||
m_ipcChannel->syncRequestToAll(METHOD_PROJECT_IS_OPENED, { projectPath.toQString() }, [&ret](const QStringList& args) {
|
||||
IF_ASSERT_FAILED(args.count() > 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -133,14 +136,32 @@ bool MultiInstancesProvider::isScoreAlreadyOpened(const io::path& scorePath) con
|
|||
return ret;
|
||||
}
|
||||
|
||||
void MultiInstancesProvider::activateWindowWithScore(const io::path& scorePath)
|
||||
void MultiInstancesProvider::activateWindowWithProject(const io::path& projectPath)
|
||||
{
|
||||
if (!isInited()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mainWindow()->requestShowOnBack();
|
||||
m_ipcChannel->broadcast(METHOD_ACTIVATE_WINDOW_WITH_SCORE, { scorePath.toQString() });
|
||||
m_ipcChannel->broadcast(METHOD_ACTIVATE_WINDOW_WITH_PROJECT, { projectPath.toQString() });
|
||||
}
|
||||
|
||||
bool MultiInstancesProvider::openNewAppInstance(const io::path& projectPath)
|
||||
{
|
||||
if (!isInited()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString appPath = QCoreApplication::applicationFilePath();
|
||||
QStringList args;
|
||||
args << projectPath.toQString();
|
||||
bool ok = QProcess::startDetached(appPath, args);
|
||||
if (ok) {
|
||||
LOGI() << "success start: " << appPath << ", args: " << args;
|
||||
} else {
|
||||
LOGE() << "failed start: " << appPath << ", args: " << args;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool MultiInstancesProvider::isPreferencesAlreadyOpened() const
|
||||
|
|
|
@ -51,9 +51,10 @@ public:
|
|||
|
||||
void init();
|
||||
|
||||
// Score opening
|
||||
bool isScoreAlreadyOpened(const io::path& scorePath) const override;
|
||||
void activateWindowWithScore(const io::path& scorePath) override;
|
||||
// Project opening
|
||||
bool isProjectAlreadyOpened(const io::path& projectPath) const override;
|
||||
void activateWindowWithProject(const io::path& projectPath) override;
|
||||
bool openNewAppInstance(const io::path& projectPath) override;
|
||||
|
||||
// Settings
|
||||
bool isPreferencesAlreadyOpened() const override;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
using namespace mu::project;
|
||||
|
||||
INotationProjectPtr ProjectCreator::newNotationProject() const
|
||||
INotationProjectPtr ProjectCreator::newProject() const
|
||||
{
|
||||
return std::make_shared<NotationProject>();
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace mu::project {
|
|||
class ProjectCreator : public IProjectCreator
|
||||
{
|
||||
public:
|
||||
INotationProjectPtr newNotationProject() const override;
|
||||
INotationProjectPtr newProject() const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -81,11 +81,83 @@ INotationSelectionPtr ProjectFilesController::currentNotationSelection() const
|
|||
return currentNotation() ? currentInteraction()->selection() : nullptr;
|
||||
}
|
||||
|
||||
Ret ProjectFilesController::openProject(const io::path& projectPath)
|
||||
void ProjectFilesController::openProject(const actions::ActionData& args)
|
||||
{
|
||||
io::path projectPath = args.count() > 0 ? args.arg<io::path>(0) : "";
|
||||
openProject(projectPath);
|
||||
}
|
||||
|
||||
Ret ProjectFilesController::openProject(const io::path& projectPath_)
|
||||
{
|
||||
//! Step 1. If no path is specified, ask the user to select a project
|
||||
io::path projectPath = projectPath_;
|
||||
if (projectPath.empty()) {
|
||||
projectPath = selectScoreOpeningFile();
|
||||
|
||||
if (projectPath.empty()) {
|
||||
return make_ret(Ret::Code::Cancel);
|
||||
}
|
||||
}
|
||||
|
||||
//! Sеep 2. If the project is already open in the current window, then just switch to showing the notation
|
||||
if (isProjectOpened(projectPath)) {
|
||||
if (!interactive()->isOpened("musescore://notation").val) {
|
||||
interactive()->open("musescore://notation");
|
||||
}
|
||||
return make_ret(Ret::Code::Ok);
|
||||
}
|
||||
|
||||
//! Step 3. Check, if the project already opened in another window, then activate the window with the project
|
||||
if (multiInstancesProvider()->isProjectAlreadyOpened(projectPath)) {
|
||||
multiInstancesProvider()->activateWindowWithProject(projectPath);
|
||||
return make_ret(Ret::Code::Ok);
|
||||
}
|
||||
|
||||
//! Step 4. Check, if a any project already opened in the current window,
|
||||
//! then we open new window
|
||||
if (globalContext()->currentNotationProject()) {
|
||||
multiInstancesProvider()->openNewAppInstance(projectPath);
|
||||
return make_ret(Ret::Code::Ok);
|
||||
}
|
||||
|
||||
//! Step 5. Open project in the current window
|
||||
return doOpenProject(projectPath);
|
||||
}
|
||||
|
||||
Ret ProjectFilesController::doOpenProject(const io::path& filePath)
|
||||
{
|
||||
TRACEFUNC;
|
||||
|
||||
auto project = projectCreator()->newProject();
|
||||
IF_ASSERT_FAILED(project) {
|
||||
return make_ret(Ret::Code::InternalError);
|
||||
}
|
||||
|
||||
Ret ret = project->load(filePath);
|
||||
|
||||
if (!ret && checkCanIgnoreError(ret, filePath)) {
|
||||
constexpr auto NO_STYLE = "";
|
||||
constexpr bool FORCE_MODE = true;
|
||||
ret = project->load(filePath, NO_STYLE, FORCE_MODE);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!globalContext()->containsNotationProject(filePath)) {
|
||||
globalContext()->addNotationProject(project);
|
||||
}
|
||||
|
||||
globalContext()->setCurrentNotationProject(project);
|
||||
|
||||
prependToRecentScoreList(filePath);
|
||||
|
||||
interactive()->open("musescore://notation");
|
||||
|
||||
return make_ret(Ret::Code::Ok);
|
||||
}
|
||||
|
||||
bool ProjectFilesController::isProjectOpened(const io::path& scorePath) const
|
||||
{
|
||||
auto project = globalContext()->currentNotationProject();
|
||||
|
@ -101,21 +173,6 @@ bool ProjectFilesController::isProjectOpened(const io::path& scorePath) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void ProjectFilesController::openProject(const actions::ActionData& args)
|
||||
{
|
||||
io::path scorePath = args.count() > 0 ? args.arg<io::path>(0) : "";
|
||||
|
||||
if (scorePath.empty()) {
|
||||
scorePath = selectScoreOpeningFile();
|
||||
|
||||
if (scorePath.empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
doOpenProject(scorePath);
|
||||
}
|
||||
|
||||
void ProjectFilesController::newProject()
|
||||
{
|
||||
Ret ret = interactive()->open("musescore://userscores/newscore").ret;
|
||||
|
@ -378,45 +435,6 @@ io::path ProjectFilesController::selectScoreSavingFile(const io::path& defaultFi
|
|||
return filePath;
|
||||
}
|
||||
|
||||
Ret ProjectFilesController::doOpenProject(const io::path& filePath)
|
||||
{
|
||||
TRACEFUNC;
|
||||
|
||||
if (multiInstancesProvider()->isScoreAlreadyOpened(filePath)) {
|
||||
multiInstancesProvider()->activateWindowWithScore(filePath);
|
||||
return make_ret(Ret::Code::Ok);
|
||||
}
|
||||
|
||||
auto project = projectCreator()->newNotationProject();
|
||||
IF_ASSERT_FAILED(project) {
|
||||
return make_ret(Ret::Code::InternalError);
|
||||
}
|
||||
|
||||
Ret ret = project->load(filePath);
|
||||
|
||||
if (!ret && checkCanIgnoreError(ret, filePath)) {
|
||||
constexpr auto NO_STYLE = "";
|
||||
constexpr bool FORCE_MODE = true;
|
||||
ret = project->load(filePath, NO_STYLE, FORCE_MODE);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!globalContext()->containsNotationProject(filePath)) {
|
||||
globalContext()->addNotationProject(project);
|
||||
}
|
||||
|
||||
globalContext()->setCurrentNotationProject(project);
|
||||
|
||||
prependToRecentScoreList(filePath);
|
||||
|
||||
interactive()->open("musescore://notation");
|
||||
|
||||
return make_ret(Ret::Code::Ok);
|
||||
}
|
||||
|
||||
void ProjectFilesController::doSaveScore(const io::path& filePath, project::SaveMode saveMode)
|
||||
{
|
||||
io::path oldPath = currentNotationProject()->metaInfo().filePath;
|
||||
|
|
|
@ -34,7 +34,7 @@ class IProjectCreator : MODULE_EXPORT_INTERFACE
|
|||
public:
|
||||
virtual ~IProjectCreator() = default;
|
||||
|
||||
virtual INotationProjectPtr newNotationProject() const = 0;
|
||||
virtual INotationProjectPtr newProject() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ bool NewScoreModel::createScore(const QVariant& info)
|
|||
{
|
||||
ProjectCreateOptions options = parseOptions(info.toMap());
|
||||
|
||||
auto project = notationCreator()->newNotationProject();
|
||||
auto project = notationCreator()->newProject();
|
||||
Ret ret = project->createNew(options);
|
||||
|
||||
if (!ret) {
|
||||
|
|
|
@ -94,7 +94,7 @@ void TemplatePaintView::onViewSizeChanged()
|
|||
|
||||
void TemplatePaintView::onNotationSetup()
|
||||
{
|
||||
INotationProjectPtr notationProject = notationCreator()->newNotationProject();
|
||||
INotationProjectPtr notationProject = notationCreator()->newProject();
|
||||
Ret ret = notationProject->load(m_templatePath);
|
||||
|
||||
if (!ret) {
|
||||
|
|
Loading…
Reference in a new issue