Merge pull request #10466 from cbjeukendrup/save_online/save_location_preparation
Prepared the possibility to have non-local scores
This commit is contained in:
commit
fab7bbab36
46 changed files with 580 additions and 208 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
54
src/engraving/infrastructure/io/ifileinfoprovider.h
Normal file
54
src/engraving/infrastructure/io/ifileinfoprovider.h
Normal 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
|
62
src/engraving/infrastructure/io/localfileinfoprovider.cpp
Normal file
62
src/engraving/infrastructure/io/localfileinfoprovider.cpp
Normal 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();
|
||||
}
|
46
src/engraving/infrastructure/io/localfileinfoprovider.h
Normal file
46
src/engraving/infrastructure/io/localfileinfoprovider.h
Normal 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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "translation.h"
|
||||
|
||||
#include "igetscore.h"
|
||||
#include "notation.h"
|
||||
|
||||
#include "libmscore/masterscore.h"
|
||||
#include "libmscore/spanner.h"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
66
src/project/internal/projectfileinfoprovider.cpp
Normal file
66
src/project/internal/projectfileinfoprovider.cpp
Normal 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();
|
||||
}
|
47
src/project/internal/projectfileinfoprovider.h
Normal file
47
src/project/internal/projectfileinfoprovider.h
Normal 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
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in a new issue