Merge pull request #10466 from cbjeukendrup/save_online/save_location_preparation

Prepared the possibility to have non-local scores
This commit is contained in:
RomanPudashkin 2022-02-09 18:24:42 +02:00 committed by GitHub
commit fab7bbab36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 580 additions and 208 deletions

View file

@ -144,7 +144,7 @@ Ret BackendApi::exportScorePartsPdfs(const io::path& in, const io::path& out, co
QFile outputFile;
openOutputFile(outputFile, out);
std::string scoreFileName = io::dirpath(in).toStdString() + "/" + io::completebasename(in).toStdString() + ".pdf";
std::string scoreFileName = io::dirpath(in).toStdString() + "/" + io::completeBasename(in).toStdString() + ".pdf";
Ret ret = doExportScorePartsPdfs(openScoreRetVal.val, outputFile, scoreFileName);

View file

@ -26,6 +26,8 @@
#include "../rw/scorereader.h"
#include "infrastructure/io/localfileinfoprovider.h"
#include "log.h"
Ms::Score::FileError mu::engraving::compat::mscxToMscz(const QString& mscxFilePath, QByteArray* msczData)
@ -53,7 +55,6 @@ Ms::Score::FileError mu::engraving::compat::mscxToMscz(const QString& mscxFilePa
Ms::Score::FileError mu::engraving::compat::loadMsczOrMscx(Ms::MasterScore* score, const QString& path, bool ignoreVersionError)
{
QByteArray msczData;
QString filePath = path;
if (path.endsWith(".mscx", Qt::CaseInsensitive)) {
//! NOTE Convert mscx -> mscz
@ -74,10 +75,12 @@ Ms::Score::FileError mu::engraving::compat::loadMsczOrMscx(Ms::MasterScore* scor
return Ms::Score::FileError::FILE_UNKNOWN_TYPE;
}
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
QBuffer msczBuf(&msczData);
MscReader::Params params;
params.device = &msczBuf;
params.filePath = filePath;
params.filePath = path;
params.mode = MscIoMode::Zip;
MscReader reader(params);
@ -112,6 +115,8 @@ mu::engraving::Err mu::engraving::compat::loadMsczOrMscx(EngravingProjectPtr pro
return scoreFileErrorToErr(Ms::Score::FileError::FILE_UNKNOWN_TYPE);
}
project->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
QBuffer msczBuf(&msczData);
MscReader::Params params;
params.device = &msczBuf;

View file

@ -57,19 +57,14 @@ void EngravingProject::init(const Ms::MStyle& style)
m_masterScore = new Ms::MasterScore(style, weak_from_this());
}
void EngravingProject::setPath(const QString& path)
IFileInfoProviderPtr EngravingProject::fileInfoProvider() const
{
QFileInfo fi(path);
m_masterScore->setName(fi.completeBaseName());
m_masterScore->setImportedFilePath(fi.filePath());
m_masterScore->setMetaTag("originalFormat", fi.suffix().toLower());
m_path = path;
return m_masterScore->fileInfo();
}
QString EngravingProject::path() const
void EngravingProject::setFileInfoProvider(IFileInfoProviderPtr fileInfoProvider)
{
return m_path;
m_masterScore->setFileInfoProvider(fileInfoProvider);
}
std::string EngravingProject::title() const

View file

@ -27,6 +27,7 @@
#include "engravingerrors.h"
#include "infrastructure/io/mscreader.h"
#include "infrastructure/io/mscwriter.h"
#include "infrastructure/io/ifileinfoprovider.h"
#include "modularity/ioc.h"
#include "diagnostics/iengravingelementsprovider.h"
@ -57,8 +58,8 @@ public:
static std::shared_ptr<EngravingProject> create();
static std::shared_ptr<EngravingProject> create(const Ms::MStyle& style);
void setPath(const QString& path);
QString path() const;
IFileInfoProviderPtr fileInfoProvider() const;
void setFileInfoProvider(IFileInfoProviderPtr fileInfoProvider);
std::string title() const;
@ -73,14 +74,7 @@ public:
Err loadMscz(const mu::engraving::MscReader& msc, bool ignoreVersionError);
bool writeMscz(mu::engraving::MscWriter& writer, bool onlySelection, bool createThumbnail);
void checkTree();
private:
void dumpTree(const Ms::EngravingItem* item, int& level);
void dumpTreeTree(const Ms::EngravingObject* obj, int& level);
void checkTree(const Ms::EngravingObject* obj);
friend class Ms::MasterScore;
EngravingProject() = default;
@ -89,7 +83,6 @@ private:
Err doSetupMasterScore(Ms::MasterScore* score);
QString m_path;
Ms::MasterScore* m_masterScore = nullptr;
};

View file

@ -48,6 +48,9 @@ set (ENGRAVING_INFRASTRUCTURE_SRC
${CMAKE_CURRENT_LIST_DIR}/io/mscwriter.h
${CMAKE_CURRENT_LIST_DIR}/io/htmlparser.cpp
${CMAKE_CURRENT_LIST_DIR}/io/htmlparser.h
${CMAKE_CURRENT_LIST_DIR}/io/ifileinfoprovider.h
${CMAKE_CURRENT_LIST_DIR}/io/localfileinfoprovider.cpp
${CMAKE_CURRENT_LIST_DIR}/io/localfileinfoprovider.h
)
set(ENGRAVING_INFRASTRUCTURE_DEF )

View file

@ -0,0 +1,54 @@
/*
* 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_ENGRAVING_IFILEINFOPROVIDER_H
#define MU_ENGRAVING_IFILEINFOPROVIDER_H
#include <memory>
#include <QDateTime>
#include "io/path.h"
namespace mu::engraving {
class IFileInfoProvider
{
public:
virtual ~IFileInfoProvider() = default;
virtual io::path path() const = 0; //! Absolute path
virtual io::path fileName() const = 0; //! Filename, including extension
virtual io::path completeBaseName() const = 0; //! Filename, excluding extension
virtual io::path absoluteDirPath() const = 0; //! Absolute path to containing folder
virtual QDateTime birthTime() const = 0;
virtual QDateTime lastModified() const = 0;
};
using IFileInfoProviderPtr = std::shared_ptr<IFileInfoProvider>;
}
//! NOTE compat
namespace Ms {
using IFileInfoProviderPtr = mu::engraving::IFileInfoProviderPtr;
}
#endif // MU_ENGRAVING_IFILEINFOPROVIDER_H

View file

@ -0,0 +1,62 @@
/*
* 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 "localfileinfoprovider.h"
#include <QFileInfo>
using namespace mu;
using namespace mu::engraving;
LocalFileInfoProvider::LocalFileInfoProvider(const io::path& path)
: m_path(path)
{
}
io::path LocalFileInfoProvider::path() const
{
return io::absolutePath(m_path);
}
io::path LocalFileInfoProvider::fileName() const
{
return io::filename(m_path);
}
io::path LocalFileInfoProvider::completeBaseName() const
{
return io::completeBasename(m_path);
}
io::path LocalFileInfoProvider::absoluteDirPath() const
{
return io::absoluteDirpath(m_path);
}
QDateTime LocalFileInfoProvider::birthTime() const
{
return QFileInfo(m_path.toQString()).birthTime();
}
QDateTime LocalFileInfoProvider::lastModified() const
{
return QFileInfo(m_path.toQString()).lastModified();
}

View file

@ -0,0 +1,46 @@
/*
* 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_ENGRAVING_LocalFILEINFOPROVIDER_H
#define MU_ENGRAVING_LocalFILEINFOPROVIDER_H
#include "ifileinfoprovider.h"
namespace mu::engraving {
class LocalFileInfoProvider : public IFileInfoProvider
{
public:
explicit LocalFileInfoProvider(const io::path& filePath);
io::path path() const override;
io::path fileName() const override;
io::path completeBaseName() const override;
io::path absoluteDirPath() const override;
QDateTime birthTime() const override;
QDateTime lastModified() const override;
private:
io::path m_path;
};
}
#endif // MU_ENGRAVING_LocalFILEINFOPROVIDER_H

View file

@ -284,7 +284,7 @@ void Image::write(XmlWriter& xml) const
// but we are saving under a temp file name and the 'final' file
// might not exist yet, so canonicalFilePath() may return only "/"
// OTOH, the score 'final' file name is practically always canonical, at this point
QString scorePath = score()->masterScore()->fileInfo()->absolutePath();
QString scorePath = score()->masterScore()->fileInfo()->absoluteDirPath().toQString();
QString imgFPath = fi.canonicalFilePath();
// if imgFPath is in (or below) the directory of scorePath
if (imgFPath.startsWith(scorePath, Qt::CaseSensitive)) {
@ -412,7 +412,7 @@ bool Image::load(const QString& ss)
// if file path is relative, prepend score path
QFileInfo fi(path);
if (fi.isRelative()) {
path.prepend(score()->masterScore()->fileInfo()->absolutePath() + "/");
path.prepend(masterScore()->fileInfo()->absoluteDirPath().toQString() + "/");
fi.setFile(path);
}

View file

@ -114,16 +114,6 @@ MasterScore::~MasterScore()
qDeleteAll(_excerpts);
}
//---------------------------------------------------------
// isSavable
//---------------------------------------------------------
bool MasterScore::isSavable() const
{
// TODO: check if file can be created if it does not exist
return fileInfo()->isWritable() || !fileInfo()->exists();
}
//---------------------------------------------------------
// setTempomap
//---------------------------------------------------------
@ -135,26 +125,22 @@ void MasterScore::setTempomap(TempoMap* tm)
}
//---------------------------------------------------------
// setName
// fileInfo
//---------------------------------------------------------
void MasterScore::setName(const QString& ss)
IFileInfoProviderPtr MasterScore::fileInfo() const
{
QString s(ss);
s.replace('/', '_'); // for sanity
if (!(s.endsWith(".mscz", Qt::CaseInsensitive) || s.endsWith(".mscx", Qt::CaseInsensitive))) {
s += ".mscz";
}
info.setFile(s);
return m_fileInfoProvider;
}
//---------------------------------------------------------
// title
//---------------------------------------------------------
void MasterScore::setFileInfoProvider(IFileInfoProviderPtr fileInfoProvider)
{
m_fileInfoProvider = fileInfoProvider;
}
QString MasterScore::title() const
{
return fileInfo()->completeBaseName();
return fileInfo()->completeBaseName().toQString();
}
//---------------------------------------------------------

View file

@ -22,7 +22,7 @@
#ifndef MU_ENGRAVING_MASTERSCORE_H
#define MU_ENGRAVING_MASTERSCORE_H
#include <QFileInfo>
#include "infrastructure/io/ifileinfoprovider.h"
#include "score.h"
#include "instrument.h"
@ -108,14 +108,15 @@ class MasterScore : public Score
std::weak_ptr<mu::engraving::EngravingProject> m_project;
// FIXME: Move to EngravingProject
// We can't yet, because m_project is not set on every MasterScore
IFileInfoProviderPtr m_fileInfoProvider;
void reorderMidiMapping();
void rebuildExcerptsMidiMapping();
void removeDeletedMidiMapping();
int updateMidiMapping();
QFileInfo _sessionStartBackupInfo;
QFileInfo info;
friend class mu::engraving::EngravingProject;
friend class mu::engraving::compat::ScoreAccess;
friend class mu::engraving::compat::Read114;
@ -178,7 +179,6 @@ public:
Revisions* revisions() { return _revisions; }
bool isSavable() const;
void setTempomap(TempoMap* tm);
int midiPortCount() const { return _midiPortCount; }
@ -219,11 +219,8 @@ public:
MasterScore* unrollRepeats();
QFileInfo* fileInfo() { return &info; }
const QFileInfo* fileInfo() const { return &info; }
void setName(const QString&);
const QFileInfo& sessionStartBackupInfo() const { return _sessionStartBackupInfo; }
IFileInfoProviderPtr fileInfo() const;
void setFileInfoProvider(IFileInfoProviderPtr fileInfoProvider);
QString title() const override;

View file

@ -38,6 +38,8 @@
#include "timesig.h"
#include "masterscore.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
@ -145,11 +147,12 @@ TimeSig* MCursor::addTimeSig(const Fraction& f)
// createScore
//---------------------------------------------------------
void MCursor::createScore(const QString& name)
void MCursor::createScore(const QString& /*name*/)
{
delete _score;
_score = mu::engraving::compat::ScoreAccess::createMasterScoreWithBaseStyle();
_score->setName(name);
// TODO: set path/filename
NOT_IMPLEMENTED;
move(0, Fraction(0, 1));
}

View file

@ -446,10 +446,10 @@ QString Page::replaceTextMacros(const QString& s) const
d += score()->metaTag("partName").toHtmlEscaped();
break;
case 'f':
d += masterScore()->fileInfo()->completeBaseName().toHtmlEscaped();
d += masterScore()->fileInfo()->completeBaseName().toQString().toHtmlEscaped();
break;
case 'F':
d += masterScore()->fileInfo()->absoluteFilePath().toHtmlEscaped();
d += masterScore()->fileInfo()->path().toQString().toHtmlEscaped();
break;
case 'd':
d += QLocale().toString(QDate::currentDate(), QLocale::ShortFormat);

View file

@ -436,8 +436,6 @@ private:
ChordList _chordList;
bool _created { false }; ///< file is never saved, has generated name
bool _startedEmpty { false }; ///< The score was created from an empty template (typically ":/data/My_First_Score.mscx")
/// during this session, so it doesn't need to be saved if it hasn't been modified.
QString _tmpName; ///< auto saved with this name if not empty
QString _importedFilePath; // file from which the score was imported, or empty
@ -860,8 +858,6 @@ public:
ScoreContentState state() const;
void setCreated(bool val) { _created = val; }
bool created() const { return _created; }
void setStartedEmpty(bool val) { _startedEmpty = val; }
bool startedEmpty() const { return _startedEmpty; }
bool savedCapture() const { return _savedCapture; }
bool saved() const { return _saved; }
void setSaved(bool v) { _saved = v; }

View file

@ -74,6 +74,8 @@
#include "masterscore.h"
#include "log.h"
using namespace mu;
namespace Ms {
@ -162,8 +164,8 @@ MasterScore* MasterScore::unrollRepeats()
// create a copy of the original score to play with
MasterScore* score = original->clone();
// Give it an appropriate name
score->setName(original->title() + "_unrolled");
// TODO: Give it an appropriate path/filename
NOT_IMPLEMENTED;
// figure out repeat structure
original->setExpandRepeats(true);

View file

@ -2883,8 +2883,6 @@ Score::FileError Read114::read114(MasterScore* masterScore, XmlReader& e, ReadCo
beam->resetExplicitParent();
// _beams.append(beam);
delete beam;
} else if (tag == "name") {
masterScore->setName(e.readElementText());
} else {
e.unknown();
}

View file

@ -48,7 +48,6 @@ Err ScoreReader::loadMscz(Ms::MasterScore* masterScore, const mu::engraving::Msc
}
ScoreLoad sl;
masterScore->fileInfo()->setFile(mscReader.params().filePath);
// Read style
{
@ -84,7 +83,7 @@ Err ScoreReader::loadMscz(Ms::MasterScore* masterScore, const mu::engraving::Msc
// Read score
{
QByteArray scoreData = mscReader.readScoreFile();
QString completeBaseName = masterScore->fileInfo()->completeBaseName();
QString completeBaseName = masterScore->fileInfo()->completeBaseName().toQString();
compat::ReadStyleHook styleHook(masterScore, scoreData, completeBaseName);

View file

@ -22,30 +22,24 @@
#include "testbase.h"
#include <QtTest/QtTest>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include "config.h"
#include "libmscore/masterscore.h"
#include "libmscore/note.h"
#include "libmscore/chord.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/page.h"
#include "libmscore/musescoreCore.h"
#include "libmscore/excerpt.h"
#include "libmscore/factory.h"
#include "thirdparty/qzip/qzipreader_p.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/scoreaccess.h"
#include "engraving/compat/writescorehook.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "engraving/rw/xml.h"
#include "framework/global/globalmodule.h"
#include "framework/fonts/fontsmodule.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
static void initMyResources()
@ -109,27 +103,28 @@ MasterScore* MTest::readScore(const QString& name)
MasterScore* MTest::readCreatedScore(const QString& name)
{
MasterScore* score_ = mu::engraving::compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(name);
score_->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
io::path path = name;
score_->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
std::string suffix = io::suffix(path);
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score_, name, false);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << QString("readScore: cannot load <%1> type <%2>").arg(name).arg(csl);
LOGE() << "cannot load file at " << path;
delete score_;
score_ = 0;
score_ = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score_;
}
@ -165,8 +160,7 @@ bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
args.append(f2);
args.append(f1);
QProcess p;
qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
<< QFileInfo(f1).fileName();
qDebug() << "Running " << cmd << " with arg1: " << f2 << " and arg2: " << f1;
p.start(cmd, args);
if (!p.waitForFinished() || p.exitCode()) {
QByteArray ba = p.readAll();

View file

@ -27,6 +27,7 @@
#include "engraving/compat/scoreaccess.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/writescorehook.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "engraving/rw/xml.h"
#include "engraving/libmscore/factory.h"
@ -42,16 +43,15 @@ QString ScoreRW::rootPath()
MasterScore* ScoreRW::readScore(const QString& name, bool isAbsolutePath)
{
QString path = isAbsolutePath ? name : (rootPath() + "/" + name);
io::path path = isAbsolutePath ? name : (rootPath() + "/" + name);
MasterScore* score = mu::engraving::compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(path);
score->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
std::string suffix = io::suffix(path);
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
rv = compat::loadMsczOrMscx(score, path, false);
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score, path.toQString(), false);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
@ -59,12 +59,13 @@ MasterScore* ScoreRW::readScore(const QString& name, bool isAbsolutePath)
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << "can't load score, path: " << path;
delete score;
score = 0;
score = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score;
}

View file

@ -100,12 +100,17 @@ mu::io::path mu::io::basename(const mu::io::path& path)
return fi.baseName();
}
mu::io::path mu::io::completebasename(const mu::io::path& path)
mu::io::path mu::io::completeBasename(const mu::io::path& path)
{
QFileInfo fi(path.toQString());
return fi.completeBaseName();
}
mu::io::path mu::io::absolutePath(const path& path)
{
return QFileInfo(path.toQString()).absolutePath();
}
mu::io::path mu::io::dirname(const mu::io::path& path)
{
return QFileInfo(path.toQString()).dir().dirName();
@ -116,6 +121,11 @@ mu::io::path mu::io::dirpath(const mu::io::path& path)
return QFileInfo(path.toQString()).dir().path();
}
mu::io::path mu::io::absoluteDirpath(const mu::io::path& path)
{
return QFileInfo(path.toQString()).dir().absolutePath();
}
bool mu::io::isAllowedFileName(const path& fn_)
{
QString fn = basename(fn_).toQString();

View file

@ -75,9 +75,11 @@ inline mu::logger::Stream& operator<<(mu::logger::Stream& s, const mu::io::path&
std::string suffix(const path& path);
path filename(const path& path);
path basename(const path& path);
path completebasename(const path& path);
path completeBasename(const path& path);
path absolutePath(const path& path);
path dirname(const path& path);
path dirpath(const path& path);
path absoluteDirpath(const path& path);
bool isAllowedFileName(const path& fn);
path escapeFileName(const path& fn);

View file

@ -22,20 +22,22 @@
#include "testbase.h"
#include <QtTest/QtTest>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include "config.h"
#include "libmscore/masterscore.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/musescoreCore.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/scoreaccess.h"
#include "engraving/compat/writescorehook.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
namespace Ms {
@ -52,29 +54,29 @@ MasterScore* MTest::readScore(const QString& name)
{
QString path = root + "/" + name;
MasterScore* score = compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(path);
score->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
std::string suffix = io::suffix(path);
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score, path, false);
} else if (csl == "sgu") {
} else if (suffix == "sgu") {
rv = importBB(score, path);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << QString("readScore: cannot load <%1> type <%2>").arg(path).arg(csl);
LOGE() << "cannot load file at " << path;
delete score;
score = 0;
score = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score;
}
@ -101,8 +103,7 @@ bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
args.append(f2);
args.append(f1);
QProcess p;
qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
<< QFileInfo(f1).fileName();
qDebug() << "Running " << cmd << " with arg1: " << f2 << " and arg2: " << f1;
p.start(cmd, args);
if (!p.waitForFinished() || p.exitCode()) {
QByteArray ba = p.readAll();

View file

@ -22,13 +22,14 @@
#include "testbase.h"
#include <QtTest/QtTest>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include "config.h"
#include "libmscore/masterscore.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/musescoreCore.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/scoreaccess.h"
@ -36,6 +37,7 @@
#include "log.h"
using namespace mu;
using namespace mu::engraving;
namespace Ms {
@ -52,27 +54,27 @@ MasterScore* MTest::readScore(const QString& name)
{
QString path = root + "/" + name;
MasterScore* score = mu::engraving::compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(path);
score->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
std::string suffix = io::suffix(path);
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score, path, false);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << QString("readScore: cannot load <%1> type <%2>").arg(path).arg(csl);
LOGE() << "cannot load file at " << path;
delete score;
score = 0;
score = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score;
}
@ -99,8 +101,7 @@ bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
args.append(f2);
args.append(f1);
QProcess p;
qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
<< QFileInfo(f1).fileName();
qDebug() << "Running " << cmd << " with arg1: " << f2 << " and arg2: " << f1;
p.start(cmd, args);
if (!p.waitForFinished() || p.exitCode()) {
QByteArray ba = p.readAll();

View file

@ -22,13 +22,14 @@
#include "testbase.h"
#include <QtTest/QtTest>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include "config.h"
#include "libmscore/masterscore.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/musescoreCore.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/scoreaccess.h"
@ -36,6 +37,7 @@
#include "log.h"
using namespace mu;
using namespace mu::engraving;
namespace Ms {
@ -46,29 +48,29 @@ MTest::MTest()
MasterScore* MTest::readScore(const QString& name)
{
QString path = root + "/" + name;
io::path path = root + "/" + name;
MasterScore* score = mu::engraving::compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(path);
score->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
std::string suffix = io::suffix(path);
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
rv = compat::loadMsczOrMscx(score, path, false);
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score, path.toQString(), false);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << QString("readScore: cannot load <%1> type <%2>").arg(path).arg(csl);
LOGE() << "cannot load file at " << path;
delete score;
score = 0;
score = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score;
}
@ -95,8 +97,7 @@ bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
args.append(f2);
args.append(f1);
QProcess p;
qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
<< QFileInfo(f1).fileName();
qDebug() << "Running " << cmd << " with arg1: " << f2 << " and arg2: " << f1;
p.start(cmd, args);
if (!p.waitForFinished() || p.exitCode()) {
QByteArray ba = p.readAll();

View file

@ -22,20 +22,22 @@
#include "testbase.h"
#include <QtTest/QtTest>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include "config.h"
#include "libmscore/masterscore.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/musescoreCore.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/scoreaccess.h"
#include "engraving/compat/writescorehook.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
namespace Ms {
@ -53,33 +55,33 @@ MasterScore* MTest::readScore(const QString& name)
{
QString path = root + "/" + name;
MasterScore* score = mu::engraving::compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(path);
score->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
QString suffix = QString::fromStdString(io::suffix(path));
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score, path, false);
} else if (csl == "cap") {
} else if (suffix == "cap") {
rv = importCapella(score, path);
score->setMetaTag("originalFormat", csl);
} else if (csl == "capx") {
score->setMetaTag("originalFormat", suffix);
} else if (suffix == "capx") {
rv = importCapXml(score, path);
score->setMetaTag("originalFormat", csl);
score->setMetaTag("originalFormat", suffix);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << QString("readScore: cannot load <%1> type <%2>").arg(path).arg(csl);
LOGE() << "cannot load file at " << path;
delete score;
score = 0;
score = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score;
}
@ -106,8 +108,7 @@ bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
args.append(f2);
args.append(f1);
QProcess p;
qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
<< QFileInfo(f1).fileName();
qDebug() << "Running " << cmd << " with arg1: " << f2 << " and arg2: " << f1;
p.start(cmd, args);
if (!p.waitForFinished() || p.exitCode()) {
QByteArray ba = p.readAll();

View file

@ -22,20 +22,22 @@
#include "testbase.h"
#include <QtTest/QtTest>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include "config.h"
#include "libmscore/masterscore.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/musescoreCore.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/scoreaccess.h"
#include "engraving/compat/writescorehook.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
namespace Ms {
@ -48,27 +50,27 @@ MasterScore* MTest::readScore(const QString& name)
{
QString path = root + "/" + name;
MasterScore* score = compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(path);
score->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
std::string suffix = io::suffix(path);
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score, path, false);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << QString("readScore: cannot load <%1> type <%2>").arg(path).arg(csl);
LOGE() << "cannot load file at " << path;
delete score;
score = 0;
score = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score;
}
@ -95,8 +97,7 @@ bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
args.append(f2);
args.append(f1);
QProcess p;
qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
<< QFileInfo(f1).fileName();
qDebug() << "Running " << cmd << " with arg1: " << f2 << " and arg2: " << f1;
p.start(cmd, args);
if (!p.waitForFinished() || p.exitCode()) {
QByteArray ba = p.readAll();

View file

@ -22,22 +22,24 @@
#include "testbase.h"
#include <QtTest/QtTest>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include "config.h"
#include "libmscore/masterscore.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/musescoreCore.h"
#include "engraving/compat/mscxcompat.h"
#include "engraving/compat/scoreaccess.h"
#include "engraving/compat/writescorehook.h"
#include "engraving/infrastructure/io/localfileinfoprovider.h"
#include "importexport/musicxml/internal/musicxml/exportxml.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
namespace Ms {
@ -59,32 +61,33 @@ MasterScore* MTest::readScore(const QString& name)
MasterScore* MTest::readCreatedScore(const QString& name)
{
io::path path = name;
MasterScore* score = compat::ScoreAccess::createMasterScoreWithBaseStyle();
QFileInfo fi(name);
score->setName(fi.completeBaseName());
QString csl = fi.suffix().toLower();
score->setFileInfoProvider(std::make_shared<LocalFileInfoProvider>(path));
std::string suffix = io::suffix(path);
ScoreLoad sl;
Score::FileError rv;
if (csl == "mscz" || csl == "mscx") {
if (suffix == "mscz" || suffix == "mscx") {
rv = compat::loadMsczOrMscx(score, name, false);
} else if (csl == "xml" || csl == "musicxml") {
} else if (suffix == "xml" || suffix == "musicxml") {
rv = importMusicXml(score, name);
} else if (csl == "mxl") {
} else if (suffix == "mxl") {
rv = importCompressedMusicXml(score, name);
} else {
rv = Score::FileError::FILE_UNKNOWN_TYPE;
}
if (rv != Score::FileError::FILE_NO_ERROR) {
LOGE() << QString("readScore: cannot load <%1> type <%2>").arg(name).arg(csl);
LOGE() << "cannot load file at " << path;
delete score;
score = 0;
score = nullptr;
} else {
for (Score* s : score->scoreList()) {
s->doLayout();
}
}
return score;
}
@ -111,8 +114,7 @@ bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
args.append(f2);
args.append(f1);
QProcess p;
qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
<< QFileInfo(f1).fileName();
qDebug() << "Running " << cmd << " with arg1: " << f2 << " and arg2: " << f1;
p.start(cmd, args);
if (!p.waitForFinished() || p.exitCode()) {
QByteArray ba = p.readAll();

View file

@ -274,7 +274,6 @@ void MasterNotation::applyOptions(Ms::MasterScore* score, const ScoreCreateOptio
score->setSystemObjectStaves(); // use the template to determine where system objects go
}
score->setName(qtrc("notation", "Untitled"));
score->setSaved(true);
score->setCreated(true);

View file

@ -24,6 +24,7 @@
#include "translation.h"
#include "igetscore.h"
#include "notation.h"
#include "libmscore/masterscore.h"
#include "libmscore/spanner.h"

View file

@ -34,9 +34,9 @@ class Score;
class Selection;
}
namespace mu {
namespace notation {
namespace mu::notation {
class IGetScore;
class Notation;
class NotationAccessibility : public INotationAccessibility, public async::Asyncable
{
public:
@ -65,6 +65,5 @@ private:
ValCh<std::string> m_accessibilityInfo;
};
}
}
#endif // MU_NOTATION_NOTATIONACCESSIBILITY_H

View file

@ -30,7 +30,6 @@ using namespace mu::actions;
using namespace mu::context;
using namespace mu::framework;
static constexpr int INVALID_BOX_INDEX = -1;
static constexpr qreal STRETCH_STEP = 0.1;
static constexpr bool NEAR_NOTE_OR_REST = true;

View file

@ -204,7 +204,6 @@ mu::Ret EditStaffType::loadScore(Ms::MasterScore* score, const mu::io::path& pat
mu::Ret EditStaffType::doLoadScore(Ms::MasterScore* score, const mu::io::path& path) const
{
QFileInfo fi(path.toQString());
score->setName(fi.completeBaseName());
score->setImportedFilePath(fi.filePath());
score->setMetaTag("originalFormat", fi.suffix().toLower());

View file

@ -189,13 +189,14 @@ void PluginAPI::removeElement(Ms::PluginAPI::EngravingItem* wrapped)
// newScore
//---------------------------------------------------------
Score* PluginAPI::newScore(const QString& name, const QString& part, int measures)
Score* PluginAPI::newScore(const QString& /*name*/, const QString& part, int measures)
{
if (msc()->currentScore()) {
msc()->currentScore()->endCmd();
}
MasterScore* score = mu::engraving::compat::ScoreAccess::createMasterScoreWithDefaultStyle();
score->setName(name);
// TODO: Set path/filename
NOT_IMPLEMENTED;
score->appendPart(Score::instrTemplateFromName(part));
score->appendMeasures(measures);
score->doLayout();

View file

@ -29,6 +29,8 @@
#include "excerpt.h"
#include "libmscore/masterscore.h"
#include "log.h"
namespace Ms {
class InstrumentTemplate;
@ -192,7 +194,7 @@ public:
Measure* lastMeasureMM();
QString name() const { return score()->masterScore()->title(); }
void setName(const QString& name) { score()->masterScore()->setName(name); }
void setName(const QString& /*name*/) { NOT_IMPLEMENTED; }
/// \endcond
Q_INVOKABLE QString extractLyrics() { return score()->extractLyrics(); }

View file

@ -104,6 +104,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/templatesrepository.h
${CMAKE_CURRENT_LIST_DIR}/internal/projectmigrator.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/projectmigrator.h
${CMAKE_CURRENT_LIST_DIR}/internal/projectfileinfoprovider.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/projectfileinfoprovider.h
${PLATFORM_SRC}

View file

@ -22,7 +22,6 @@
#include "notationproject.h"
#include <QBuffer>
#include <QFileInfo>
#include <QFile>
#include "engraving/engravingproject.h"
@ -34,9 +33,11 @@
#include "notation/notationerrors.h"
#include "projectaudiosettings.h"
#include "projectfileinfoprovider.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
using namespace mu::notation;
using namespace mu::project;
@ -78,29 +79,30 @@ static bool isStandardTag(const QString& tag)
return standardTags.contains(tag);
}
static void setupProjectProperties(Ms::MasterScore* masterScore, const ProjectCreateOptions& projectOptions)
static void setupScoreMetaTags(Ms::MasterScore* masterScore, const ProjectCreateOptions& projectOptions)
{
if (!projectOptions.title.isEmpty()) {
masterScore->fileInfo()->setFile(projectOptions.title);
masterScore->setMetaTag("workTitle", projectOptions.title);
masterScore->setMetaTag(WORK_TITLE_TAG, projectOptions.title);
}
if (!projectOptions.subtitle.isEmpty()) {
masterScore->setMetaTag("subtitle", projectOptions.subtitle);
masterScore->setMetaTag(SUBTITLE_TAG, projectOptions.subtitle);
}
if (!projectOptions.composer.isEmpty()) {
masterScore->setMetaTag("composer", projectOptions.composer);
masterScore->setMetaTag(COMPOSER_TAG, projectOptions.composer);
}
if (!projectOptions.lyricist.isEmpty()) {
masterScore->setMetaTag("lyricist", projectOptions.lyricist);
masterScore->setMetaTag(LYRICIST_TAG, projectOptions.lyricist);
}
if (!projectOptions.copyright.isEmpty()) {
masterScore->setMetaTag("copyright", projectOptions.copyright);
masterScore->setMetaTag(COPYRIGHT_TAG, projectOptions.copyright);
}
}
NotationProject::NotationProject()
{
setSaveLocation(SaveLocation::makeLocal(""));
m_engravingProject = EngravingProject::create();
m_engravingProject->setFileInfoProvider(std::make_shared<ProjectFileInfoProvider>(this));
m_masterNotation = std::shared_ptr<MasterNotation>(new MasterNotation());
m_projectAudioSettings = std::shared_ptr<ProjectAudioSettings>(new ProjectAudioSettings());
m_viewSettings = std::shared_ptr<ProjectViewSettings>(new ProjectViewSettings());
@ -114,17 +116,14 @@ NotationProject::~NotationProject()
m_engravingProject = nullptr;
}
mu::io::path NotationProject::path() const
{
return m_engravingProject->path();
}
mu::Ret NotationProject::load(const io::path& path, const io::path& stylePath, bool forceMode)
{
TRACEFUNC;
LOGD() << "try load: " << path;
setSaveLocation(SaveLocation::makeLocal(path));
std::string suffix = io::suffix(path);
if (!isMuseScoreFile(suffix)) {
return doImport(path, stylePath, forceMode);
@ -155,7 +154,6 @@ mu::Ret NotationProject::load(const io::path& path, const io::path& stylePath, b
}
if (needRestoreUnsavedChanges) {
m_engravingProject->setPath(path.toQString());
m_masterNotation->score()->setSaved(false);
}
@ -168,7 +166,7 @@ mu::Ret NotationProject::doLoad(engraving::MscReader& reader, const io::path& st
// Create new engraving project
EngravingProjectPtr project = EngravingProject::create();
project->setPath(reader.params().filePath);
project->setFileInfoProvider(std::make_shared<ProjectFileInfoProvider>(this));
// Load engraving project
engraving::Err err = project->loadMscz(reader, forceMode);
@ -236,7 +234,7 @@ mu::Ret NotationProject::doImport(const io::path& path, const io::path& stylePat
// Create new engraving project
EngravingProjectPtr project = EngravingProject::create();
project->setPath(path.toQString());
project->setFileInfoProvider(std::make_shared<ProjectFileInfoProvider>(this));
// Setup import reader
INotationReader::Options options;
@ -301,8 +299,13 @@ mu::Ret NotationProject::createNew(const ProjectCreateOptions& projectOptions)
// Create new engraving project
EngravingProjectPtr project = EngravingProject::create();
setSaveLocation(SaveLocation::makeLocal(projectOptions.title.isEmpty()
? qtrc("project", "Untitled")
: projectOptions.title));
project->setFileInfoProvider(std::make_shared<ProjectFileInfoProvider>(this));
Ms::MasterScore* masterScore = project->masterScore();
setupProjectProperties(masterScore, projectOptions);
setupScoreMetaTags(masterScore, projectOptions);
// Make new master score
MasterNotationPtr masterNotation = std::shared_ptr<MasterNotation>(new MasterNotation());
@ -333,6 +336,16 @@ mu::Ret NotationProject::createNew(const ProjectCreateOptions& projectOptions)
return make_ret(Ret::Code::Ok);
}
io::path NotationProject::path() const
{
return m_saveLocation.isLocal() ? m_saveLocation.localPath() : "";
}
void NotationProject::setSaveLocation(const SaveLocation& saveLocation)
{
m_saveLocation = saveLocation;
}
mu::Ret NotationProject::loadTemplate(const ProjectCreateOptions& projectOptions)
{
TRACEFUNC;
@ -340,10 +353,12 @@ mu::Ret NotationProject::loadTemplate(const ProjectCreateOptions& projectOptions
Ret ret = load(projectOptions.templatePath);
if (ret) {
Ms::MasterScore* masterScore = m_masterNotation->masterScore();
setupProjectProperties(masterScore, projectOptions);
setSaveLocation(SaveLocation::makeLocal(projectOptions.title.isEmpty()
? qtrc("project", "Untitled")
: projectOptions.title));
m_engravingProject->setPath("");
Ms::MasterScore* masterScore = m_masterNotation->masterScore();
setupScoreMetaTags(masterScore, projectOptions);
m_masterNotation->undoStack()->lock();
m_masterNotation->applyOptions(masterScore, projectOptions.scoreOptions, true /*createdFromTemplate*/);
@ -362,13 +377,13 @@ mu::Ret NotationProject::save(const io::path& path, SaveMode saveMode)
case SaveMode::Save:
case SaveMode::SaveAs:
case SaveMode::SaveCopy: {
io::path oldFilePath = m_engravingProject->path();
io::path oldFilePath = this->path();
io::path savePath = path;
if (!savePath.empty()) {
m_engravingProject->setPath(savePath.toQString());
setSaveLocation(SaveLocation::makeLocal(savePath));
} else {
savePath = m_engravingProject->path();
savePath = m_saveLocation.localPath();
}
std::string suffix = io::suffix(savePath);
@ -399,13 +414,13 @@ mu::Ret NotationProject::save(const io::path& path, SaveMode saveMode)
mu::Ret NotationProject::writeToDevice(io::Device* device)
{
if (m_engravingProject->path().isEmpty()) {
m_engravingProject->setPath(m_masterNotation->title() + ".mscz");
IF_ASSERT_FAILED(!path().empty()) {
return make_ret(notation::Err::UnknownError);
}
MscWriter::Params params;
params.device = device;
params.filePath = m_engravingProject->path();
params.filePath = path().toQString();
params.mode = MscIoMode::Zip;
MscWriter msczWriter(params);
@ -491,7 +506,7 @@ mu::Ret NotationProject::makeCurrentFileAsBackup()
return make_ret(Ret::Code::Ok);
}
io::path filePath = m_engravingProject->path();
io::path filePath = path();
if (io::suffix(filePath) != engraving::MSCZ) {
LOGW() << "backup allowed only for MSCZ, currently: " << filePath;
return make_ret(Ret::Code::Ok);
@ -549,7 +564,7 @@ mu::Ret NotationProject::writeProject(MscWriter& msczWriter, bool onlySelection)
mu::Ret NotationProject::saveSelectionOnScore(const mu::io::path& path)
{
IF_ASSERT_FAILED(path.toQString() != m_engravingProject->path()) {
IF_ASSERT_FAILED(path != this->path()) {
return make_ret(notation::Err::UnknownError);
}
@ -648,7 +663,7 @@ ProjectMeta NotationProject::metaInfo() const
}
meta.fileName = score->fileInfo()->fileName();
meta.filePath = score->fileInfo()->filePath();
meta.filePath = score->fileInfo()->path();
meta.partsCount = score->excerpts().count();
return meta;

View file

@ -31,6 +31,7 @@
#include "iprojectautosaver.h"
#include "engraving/engravingproject.h"
#include "engraving/infrastructure/io/ifileinfoprovider.h"
#include "notation/internal/masternotation.h"
#include "projectaudiosettings.h"
@ -55,11 +56,11 @@ public:
NotationProject();
~NotationProject() override;
io::path path() const override;
Ret load(const io::path& path, const io::path& stylePath = io::path(), bool forceMode = false) override;
Ret createNew(const ProjectCreateOptions& projectInfo) override;
io::path path() const override;
RetVal<bool> created() const override;
ValNt<bool> needSave() const override;
@ -79,6 +80,8 @@ private:
Ret doLoad(engraving::MscReader& reader, const io::path& stylePath, bool forceMode);
Ret doImport(const io::path& path, const io::path& stylePath, bool forceMode);
void setSaveLocation(const SaveLocation& saveLocation);
Ret saveScore(const io::path& path, const std::string& fileSuffix);
Ret saveSelectionOnScore(const io::path& path = io::path());
Ret exportProject(const io::path& path, const std::string& suffix);
@ -90,6 +93,8 @@ private:
notation::MasterNotationPtr m_masterNotation = nullptr;
ProjectAudioSettingsPtr m_projectAudioSettings = nullptr;
ProjectViewSettingsPtr m_viewSettings = nullptr;
SaveLocation m_saveLocation = SaveLocation::makeInvalid();
};
}

View file

@ -318,7 +318,7 @@ IInteractive::Button ProjectActionsController::askAboutSavingScore(const io::pat
{
QString scoreName = qtrc("project", "Untitled");
if (!filePath.empty()) {
scoreName = io::completebasename(filePath).toQString();
scoreName = io::completeBasename(filePath).toQString();
}
std::string title = qtrc("project", "Do you want to save changes to the score “%1” before closing?")
.arg(scoreName).toStdString();

View file

@ -84,7 +84,7 @@ void ProjectAutoSaver::removeProjectUnsavedChanges(const io::path& projectPath)
mu::io::path ProjectAutoSaver::projectOriginalPath(const mu::io::path& projectAutoSavePath) const
{
return io::completebasename(projectAutoSavePath);
return io::completeBasename(projectAutoSavePath);
}
mu::io::path ProjectAutoSaver::projectAutoSavePath(const io::path& projectPath) const

View file

@ -40,6 +40,7 @@ static const std::string module_name("project");
static const Settings::Key RECENT_PROJECTS_PATHS(module_name, "project/recentList");
static const Settings::Key USER_TEMPLATES_PATH(module_name, "application/paths/myTemplates");
static const Settings::Key USER_PROJECTS_PATH(module_name, "application/paths/myScores");
static const Settings::Key LAST_USED_SAVE_LOCATION_TYPE(module_name, "project/lastUsedSaveLocationType");
static const Settings::Key PREFERRED_SCORE_CREATION_MODE_KEY(module_name, "project/preferredScoreCreationMode");
static const Settings::Key MIGRATION_OPTIONS(module_name, "project/migration");
static const Settings::Key AUTOSAVE_ENABLED_KEY(module_name, "project/autoSaveEnabled");
@ -69,6 +70,8 @@ void ProjectConfiguration::init()
Val preferredScoreCreationMode = Val(PreferredScoreCreationMode::FromInstruments);
settings()->setDefaultValue(PREFERRED_SCORE_CREATION_MODE_KEY, preferredScoreCreationMode);
settings()->setDefaultValue(LAST_USED_SAVE_LOCATION_TYPE, Val(SaveLocationType::Undefined));
settings()->setDefaultValue(AUTOSAVE_ENABLED_KEY, Val(true));
settings()->valueChanged(AUTOSAVE_ENABLED_KEY).onReceive(nullptr, [this](const Val& val) {
m_autoSaveEnabledChanged.send(val.toBool());
@ -201,6 +204,16 @@ io::path ProjectConfiguration::defaultSavingFilePath(const io::path& fileName) c
return userProjectsPath() + "/" + fileName + DEFAULT_FILE_SUFFIX;
}
SaveLocationType ProjectConfiguration::lastUsedSaveLocationType() const
{
return settings()->value(LAST_USED_SAVE_LOCATION_TYPE).toEnum<SaveLocationType>();
}
void ProjectConfiguration::setLastUsedSaveLocationType(SaveLocationType type)
{
settings()->setSharedValue(LAST_USED_SAVE_LOCATION_TYPE, Val(type));
}
QColor ProjectConfiguration::templatePreviewBackgroundColor() const
{
return notationConfiguration()->backgroundColor();

View file

@ -61,6 +61,9 @@ public:
io::path defaultSavingFilePath(const io::path& fileName) const override;
SaveLocationType lastUsedSaveLocationType() const override;
void setLastUsedSaveLocationType(SaveLocationType type) override;
QColor templatePreviewBackgroundColor() const override;
async::Notification templatePreviewBackgroundChanged() const override;

View file

@ -0,0 +1,66 @@
/*
* 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 "projectfileinfoprovider.h"
#include <QFileInfo>
#include "notationproject.h"
using namespace mu;
using namespace mu::project;
ProjectFileInfoProvider::ProjectFileInfoProvider(NotationProject* project)
: m_project(project)
{
}
//! TODO: update this class when SaveLocation gets implemented further
io::path ProjectFileInfoProvider::path() const
{
return m_project->path();
}
io::path ProjectFileInfoProvider::fileName() const
{
return io::filename(path());
}
io::path ProjectFileInfoProvider::completeBaseName() const
{
return io::completeBasename(path());
}
io::path ProjectFileInfoProvider::absoluteDirPath() const
{
return io::absoluteDirpath(path());
}
QDateTime ProjectFileInfoProvider::birthTime() const
{
return QFileInfo(path().toQString()).birthTime();
}
QDateTime ProjectFileInfoProvider::lastModified() const
{
return QFileInfo(path().toQString()).lastModified();
}

View file

@ -0,0 +1,47 @@
/*
* 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_PROJECT_PROJECTFILEINFOPROVIDER_H
#define MU_PROJECT_PROJECTFILEINFOPROVIDER_H
#include "engraving/infrastructure/io/ifileinfoprovider.h"
namespace mu::project {
class NotationProject;
class ProjectFileInfoProvider : public engraving::IFileInfoProvider
{
public:
explicit ProjectFileInfoProvider(NotationProject* project);
io::path path() const override;
io::path fileName() const override;
io::path completeBaseName() const override;
io::path absoluteDirPath() const override;
QDateTime birthTime() const override;
QDateTime lastModified() const override;
private:
NotationProject* m_project = nullptr;
};
}
#endif // MU_PROJECT_PROJECTFILEINFOPROVIDER_H

View file

@ -58,6 +58,9 @@ public:
virtual io::path defaultSavingFilePath(const io::path& fileName) const = 0;
virtual SaveLocationType lastUsedSaveLocationType() const = 0;
virtual void setLastUsedSaveLocationType(SaveLocationType type) = 0;
virtual QColor templatePreviewBackgroundColor() const = 0;
virtual async::Notification templatePreviewBackgroundChanged() const = 0;

View file

@ -25,6 +25,7 @@
#include <QString>
#include "io/path.h"
#include "log.h"
#include "notation/notationtypes.h"
@ -65,6 +66,67 @@ enum class SaveMode
AutoSave
};
enum class SaveLocationType
{
Undefined,
Local,
Cloud
};
struct SaveLocation {
struct LocalInfo {
io::path path;
};
struct CloudInfo {
// TODO
};
SaveLocationType type = SaveLocationType::Undefined;
std::variant<LocalInfo, CloudInfo> info;
bool isLocal() const
{
return type == SaveLocationType::Local
&& std::holds_alternative<LocalInfo>(info);
}
bool isCloud() const
{
return type == SaveLocationType::Cloud
&& std::holds_alternative<CloudInfo>(info);
}
bool isValid() const
{
return isLocal() || isCloud();
}
io::path localPath() const
{
IF_ASSERT_FAILED(isLocal()) {
return {};
}
return std::get<LocalInfo>(info).path;
}
static SaveLocation makeInvalid()
{
return {};
}
static SaveLocation makeLocal(const io::path& path)
{
return { SaveLocationType::Local, LocalInfo { path } };
}
static SaveLocation makeCloud()
{
return { SaveLocationType::Cloud, CloudInfo {} };
}
};
struct ProjectMeta
{
io::path fileName;

View file

@ -49,6 +49,9 @@ public:
MOCK_METHOD(io::path, defaultSavingFilePath, (const io::path&), (const, override));
MOCK_METHOD(SaveLocationType, lastUsedSaveLocationType, (), (const, override));
MOCK_METHOD(void, setLastUsedSaveLocationType, (SaveLocationType), (override));
MOCK_METHOD(QColor, templatePreviewBackgroundColor, (), (const, override));
MOCK_METHOD(async::Notification, templatePreviewBackgroundChanged, (), (const, override));