added open new project in a new window

This commit is contained in:
Igor Korsukov 2021-08-02 14:03:26 +02:00
parent 879efc8859
commit f8f50f2895
11 changed files with 119 additions and 78 deletions

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -25,7 +25,7 @@
using namespace mu::project;
INotationProjectPtr ProjectCreator::newNotationProject() const
INotationProjectPtr ProjectCreator::newProject() const
{
return std::make_shared<NotationProject>();
}

View file

@ -28,7 +28,7 @@ namespace mu::project {
class ProjectCreator : public IProjectCreator
{
public:
INotationProjectPtr newNotationProject() const override;
INotationProjectPtr newProject() const override;
};
}

View file

@ -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;

View file

@ -34,7 +34,7 @@ class IProjectCreator : MODULE_EXPORT_INTERFACE
public:
virtual ~IProjectCreator() = default;
virtual INotationProjectPtr newNotationProject() const = 0;
virtual INotationProjectPtr newProject() const = 0;
};
}

View file

@ -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) {

View file

@ -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) {