implemented template preview
fix codestyle codereview fixes
This commit is contained in:
parent
d0899506df
commit
1033d4b514
30 changed files with 590 additions and 159 deletions
|
@ -98,7 +98,7 @@ mu::io::path mu::io::basename(const mu::io::path& path)
|
|||
|
||||
mu::io::path mu::io::dirname(const mu::io::path& path)
|
||||
{
|
||||
return QDir(path.toQString()).dirName();
|
||||
return QFileInfo(path.toQString()).dir().dirName();
|
||||
}
|
||||
|
||||
mu::io::path mu::io::escapeFileName(const mu::io::path& fn_)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
set(MODULE_TEST system_test)
|
||||
|
||||
set(MODULE_TEST_SRC
|
||||
${CMAKE_CURRENT_LIST_DIR}/mocks/fsoperationsmock.h)
|
||||
${CMAKE_CURRENT_LIST_DIR}/mocks/filesystemmock.h)
|
||||
|
||||
set(MODULE_TEST_LINK system)
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//=============================================================================
|
||||
#ifndef MU_FRAMEWORK_FSOPERATIONSMOCK_H
|
||||
#define MU_FRAMEWORK_FSOPERATIONSMOCK_H
|
||||
#ifndef MU_FRAMEWORK_FILESYSTEMMOCK_H
|
||||
#define MU_FRAMEWORK_FILESYSTEMMOCK_H
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
|
@ -25,23 +25,19 @@
|
|||
|
||||
namespace mu {
|
||||
namespace framework {
|
||||
class FsOperationsMock : public IFsOperations
|
||||
class FileSystemMock : public IFileSystem
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD(Ret, exists, (const QString&), (const, override));
|
||||
MOCK_METHOD(Ret, remove, (const QString&), (const, override));
|
||||
MOCK_METHOD(Ret, exists, (const io::path&), (const, override));
|
||||
MOCK_METHOD(Ret, remove, (const io::path&), (const, override));
|
||||
|
||||
MOCK_METHOD(QString, fileName, (const QString&), (const, override));
|
||||
MOCK_METHOD(QString, baseName, (const QString&), (const, override));
|
||||
MOCK_METHOD(QString, dirName, (const QString&), (const, override));
|
||||
MOCK_METHOD(RetVal<QByteArray>, readFile, (const io::path&), (const, override));
|
||||
|
||||
MOCK_METHOD(RetVal<QByteArray>, readFile, (const QString&), (const, override));
|
||||
MOCK_METHOD(Ret, makePath, (const io::path&), (const, override));
|
||||
|
||||
MOCK_METHOD(Ret, makePath, (const QString&), (const, override));
|
||||
|
||||
MOCK_METHOD(RetVal<QStringList>, scanFiles, (const QString&, const QStringList&, ScanMode), (const, override));
|
||||
MOCK_METHOD(RetVal<io::paths>, scanFiles, (const io::path&, const QStringList&, ScanMode), (const, override));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MU_FRAMEWORK_FSOPERATIONSMOCK_H
|
||||
#endif // MU_FRAMEWORK_FILESYSTEMMOCK_H
|
|
@ -13,10 +13,10 @@ Rectangle {
|
|||
name: "HORIZONTAL"
|
||||
when: orientation == Qt.Horizontal
|
||||
|
||||
PropertyChanges {
|
||||
target: anchors
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
AnchorChanges {
|
||||
target: root
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
|
@ -29,10 +29,10 @@ Rectangle {
|
|||
name: "VERTICAL"
|
||||
when: orientation == Qt.Vertical
|
||||
|
||||
PropertyChanges {
|
||||
target: anchors
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
AnchorChanges {
|
||||
target: root
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
|
|
|
@ -25,9 +25,8 @@ Rectangle {
|
|||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16
|
||||
|
||||
spacing: 16
|
||||
spacing: 12
|
||||
|
||||
FamilyView {
|
||||
id: familyView
|
||||
|
@ -114,7 +113,7 @@ Rectangle {
|
|||
Layout.preferredWidth: 30
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
spacing: 4
|
||||
spacing: 12
|
||||
|
||||
FlatButton {
|
||||
enabled: selectedInstrumentsView.canLiftInstrument
|
||||
|
|
|
@ -48,7 +48,7 @@ Item {
|
|||
id: familiesBox
|
||||
|
||||
anchors.top: familyLabel.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.topMargin: 16
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ public:
|
|||
virtual Meta metaInfo() const = 0;
|
||||
|
||||
virtual void setViewSize(const QSizeF& vs) = 0;
|
||||
virtual void paint(QPainter* p, const QRect& r) = 0;
|
||||
virtual void paint(QPainter* painter) = 0;
|
||||
virtual QRectF previewRect() const = 0;
|
||||
|
||||
// input (mouse)
|
||||
virtual INotationInteraction* interaction() const = 0;
|
||||
|
|
|
@ -46,6 +46,8 @@ RetVal<Meta> MsczMetaReader::readMeta(const io::path& filePath) const
|
|||
meta.val.fileName = fileInfo.baseName();
|
||||
}
|
||||
|
||||
meta.val.filePath = fileInfo.absoluteFilePath();
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,37 +120,48 @@ void Notation::setViewSize(const QSizeF& vs)
|
|||
m_viewSize = vs;
|
||||
}
|
||||
|
||||
void Notation::paint(QPainter* p, const QRect&)
|
||||
QRectF Notation::previewRect() const
|
||||
{
|
||||
const QList<Ms::Page*>& pages = m_score->pages();
|
||||
|
||||
if (pages.isEmpty()) {
|
||||
p->drawText(10, 10, "no pages");
|
||||
return QRect();
|
||||
}
|
||||
|
||||
return pages.first()->bbox();
|
||||
}
|
||||
|
||||
void Notation::paint(QPainter* painter)
|
||||
{
|
||||
const QList<Ms::Page*>& mspages = m_score->pages();
|
||||
|
||||
if (mspages.isEmpty()) {
|
||||
painter->drawText(10, 10, "no pages");
|
||||
return;
|
||||
}
|
||||
|
||||
Ms::Page* page = pages.first();
|
||||
page->draw(p);
|
||||
Ms::Page* page = mspages.first();
|
||||
|
||||
p->fillRect(page->bbox(), QColor("#ffffff"));
|
||||
page->draw(painter);
|
||||
|
||||
QList<Ms::Element*> ell = page->elements();
|
||||
for (const Ms::Element* e : ell) {
|
||||
if (!e->visible()) {
|
||||
painter->fillRect(page->bbox(), QColor("#ffffff"));
|
||||
|
||||
for (Ms::Element* element : page->elements()) {
|
||||
if (!element->visible()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
e->itemDiscovered = false;
|
||||
QPointF pos(e->pagePos());
|
||||
element->itemDiscovered = false;
|
||||
QPointF pos(element->pagePos());
|
||||
|
||||
p->translate(pos);
|
||||
painter->translate(pos);
|
||||
|
||||
e->draw(p);
|
||||
element->draw(painter);
|
||||
|
||||
p->translate(-pos);
|
||||
painter->translate(-pos);
|
||||
}
|
||||
|
||||
m_interaction->paint(p);
|
||||
m_interaction->paint(painter);
|
||||
}
|
||||
|
||||
void Notation::notifyAboutNotationChanged()
|
||||
|
|
|
@ -44,7 +44,8 @@ public:
|
|||
Meta metaInfo() const override;
|
||||
|
||||
void setViewSize(const QSizeF& vs) override;
|
||||
void paint(QPainter* p, const QRect& r) override;
|
||||
void paint(QPainter* painter) override;
|
||||
QRectF previewRect() const override;
|
||||
|
||||
INotationInteraction* interaction() const override;
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ enum class MoveSelectionType {
|
|||
|
||||
struct Meta {
|
||||
QString fileName;
|
||||
QString filePath;
|
||||
QString title;
|
||||
QString subtitle;
|
||||
QString composer;
|
||||
|
|
|
@ -181,7 +181,7 @@ void NotationPaintView::paint(QPainter* p)
|
|||
p->setTransform(m_matrix);
|
||||
|
||||
if (m_notation) {
|
||||
m_notation->paint(p, rect);
|
||||
m_notation->paint(p);
|
||||
|
||||
m_playbackCursor->paint(p);
|
||||
} else {
|
||||
|
|
|
@ -37,6 +37,8 @@ set(MODULE_SRC
|
|||
${CMAKE_CURRENT_LIST_DIR}/view/scorethumbnail.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/templatesmodel.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/templatesmodel.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/templatepaintview.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/view/templatepaintview.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/internal/openscorecontroller.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/internal/openscorecontroller.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/internal/userscoresconfiguration.cpp
|
||||
|
|
|
@ -38,6 +38,7 @@ RetVal<Templates> TemplatesRepository::templates() const
|
|||
|
||||
if (!files.ret) {
|
||||
LOGE() << files.ret.toString();
|
||||
continue;
|
||||
}
|
||||
|
||||
result << loadTemplates(files.val);
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
RetVal<Templates> templates() const override;
|
||||
|
||||
private:
|
||||
Templates loadTemplates(const io::paths &filePaths) const;
|
||||
Templates loadTemplates(const io::paths& filePaths) const;
|
||||
QString correctedTitle(const QString& title) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
using namespace mu;
|
||||
using namespace mu::framework;
|
||||
using namespace mu::userscores;
|
||||
using namespace mu::notation;
|
||||
|
||||
static std::string module_name("userscores");
|
||||
|
||||
|
@ -76,3 +77,13 @@ io::paths UserScoresConfiguration::templatesDirPaths() const
|
|||
|
||||
return dirs;
|
||||
}
|
||||
|
||||
QColor UserScoresConfiguration::templatePreviewBackgroundColor() const
|
||||
{
|
||||
return notationConfiguration()->backgroundColor();
|
||||
}
|
||||
|
||||
async::Channel<QColor> UserScoresConfiguration::templatePreviewBackgroundColorChanged() const
|
||||
{
|
||||
return notationConfiguration()->backgroundColorChanged();
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "modularity/ioc.h"
|
||||
#include "iglobalconfiguration.h"
|
||||
#include "extensions/iextensionsconfiguration.h"
|
||||
#include "notation/inotationconfiguration.h"
|
||||
|
||||
namespace mu {
|
||||
namespace userscores {
|
||||
|
@ -30,6 +31,7 @@ class UserScoresConfiguration : public IUserScoresConfiguration
|
|||
{
|
||||
INJECT(usescores, framework::IGlobalConfiguration, globalConfiguration)
|
||||
INJECT(userscores, extensions::IExtensionsConfiguration, extensionsConfiguration)
|
||||
INJECT(userscores, notation::INotationConfiguration, notationConfiguration)
|
||||
|
||||
public:
|
||||
void init();
|
||||
|
@ -39,6 +41,9 @@ public:
|
|||
|
||||
io::paths templatesDirPaths() const override;
|
||||
|
||||
QColor templatePreviewBackgroundColor() const override;
|
||||
async::Channel<QColor> templatePreviewBackgroundColorChanged() const override;
|
||||
|
||||
private:
|
||||
QStringList parseRecentList(const std::string& recents) const;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define MU_USERSCORES_IUSERSCORESCONFIGURATION_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <QColor>
|
||||
|
||||
#include "modularity/imoduleexport.h"
|
||||
#include "retval.h"
|
||||
|
@ -38,6 +39,9 @@ public:
|
|||
virtual void setRecentScoreList(const QStringList& recentScoreList) = 0;
|
||||
|
||||
virtual io::paths templatesDirPaths() const = 0;
|
||||
|
||||
virtual QColor templatePreviewBackgroundColor() const = 0;
|
||||
virtual async::Channel<QColor> templatePreviewBackgroundColorChanged() const = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,14 @@ import MuseScore.Ui 1.0
|
|||
import MuseScore.UserScores 1.0
|
||||
|
||||
Item {
|
||||
property alias selectedTemplatePath: model.currentTemplatePath
|
||||
|
||||
TemplatesModel {
|
||||
id: model
|
||||
|
||||
onCurrentTemplateChanged: {
|
||||
templatePreview.load(model.currentTemplatePath)
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
|
@ -15,10 +21,11 @@ Item {
|
|||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 16
|
||||
id: row
|
||||
|
||||
spacing: 16
|
||||
anchors.fill: parent
|
||||
|
||||
spacing: 12
|
||||
|
||||
TitleListView {
|
||||
Layout.fillHeight: true
|
||||
|
@ -27,7 +34,7 @@ Item {
|
|||
listTitle: qsTrc("userscores", "Category")
|
||||
model: model.categoriesTitles
|
||||
searchEnabled: false
|
||||
booldFont: true
|
||||
boldFont: true
|
||||
|
||||
onTitleClicked: {
|
||||
model.setCurrentCategory(index)
|
||||
|
@ -52,31 +59,39 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
SeparatorLine { orientation: Qt.Vertical }
|
||||
|
||||
Item { Layout.preferredWidth: 30 }
|
||||
SeparatorLine { orientation: Qt.Vertical; Layout.rightMargin: 30 + row.spacing }
|
||||
|
||||
SeparatorLine { orientation: Qt.Vertical }
|
||||
|
||||
TemplatePreview {
|
||||
id: templatePreview
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: parent.width / 3
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SeparatorLine { orientation: Qt.Vertical }
|
||||
|
||||
Column {
|
||||
Layout.minimumWidth: 30
|
||||
Layout.preferredWidth: 30
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
spacing: 16
|
||||
spacing: 12
|
||||
|
||||
FlatButton {
|
||||
icon: IconCode.ZOOM_IN
|
||||
|
||||
onClicked: {
|
||||
templatePreview.zoomIn()
|
||||
}
|
||||
}
|
||||
|
||||
FlatButton {
|
||||
icon: IconCode.ZOOM_OUT
|
||||
|
||||
onClicked: {
|
||||
templatePreview.zoomOut()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ QmlDialog {
|
|||
anchors.right: parent.right
|
||||
anchors.rightMargin: 16
|
||||
anchors.bottom: buttons.top
|
||||
anchors.bottomMargin: 10
|
||||
anchors.bottomMargin: 39
|
||||
|
||||
ChooseInstrumentsAndTemplatesPage {
|
||||
anchors.fill: parent
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import MuseScore.UiComponents 1.0
|
||||
|
@ -7,6 +8,18 @@ import MuseScore.UserScores 1.0
|
|||
Item {
|
||||
id: root
|
||||
|
||||
function load(templatePath) {
|
||||
paintView.load(templatePath)
|
||||
}
|
||||
|
||||
function zoomIn() {
|
||||
paintView.zoomIn()
|
||||
}
|
||||
|
||||
function zoomOut() {
|
||||
paintView.zoomOut()
|
||||
}
|
||||
|
||||
StyledTextLabel {
|
||||
id: title
|
||||
|
||||
|
@ -16,13 +29,53 @@ Item {
|
|||
font.bold: true
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
anchors.top: title.bottom
|
||||
anchors.topMargin: 16
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
width: parent.width
|
||||
TemplatePaintView {
|
||||
id: paintView
|
||||
|
||||
color: "blue"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
z: 1
|
||||
orientation: Qt.Vertical
|
||||
policy: ScrollBar.AlwaysOn
|
||||
|
||||
position: paintView.startVerticalScrollPosition
|
||||
size: paintView.verticalScrollSize
|
||||
|
||||
onPositionChanged: {
|
||||
if (pressed) {
|
||||
paintView.scrollVertical(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
z: 1
|
||||
orientation: Qt.Horizontal
|
||||
policy: ScrollBar.AlwaysOn
|
||||
|
||||
position: paintView.startHorizontalScrollPosition
|
||||
size: paintView.horizontalScrollSize
|
||||
|
||||
onPositionChanged: {
|
||||
if (pressed) {
|
||||
paintView.scrollHorizontal(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ Item {
|
|||
property alias searchEnabled: searchField.visible
|
||||
property alias searchText: searchField.searchText
|
||||
|
||||
property bool booldFont: false
|
||||
property bool boldFont: false
|
||||
|
||||
signal titleClicked(var index)
|
||||
|
||||
|
@ -44,6 +44,8 @@ Item {
|
|||
boundsBehavior: ListView.StopAtBounds
|
||||
clip: true
|
||||
|
||||
currentIndex: 0
|
||||
|
||||
delegate: Item {
|
||||
width: parent.width
|
||||
height: 30
|
||||
|
@ -64,7 +66,7 @@ Item {
|
|||
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
text: modelData
|
||||
font.bold: root.booldFont
|
||||
font.bold: root.boldFont
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
|
|
|
@ -31,7 +31,10 @@ public:
|
|||
MOCK_METHOD(ValCh<QStringList>, recentScoreList, (), (const, override));
|
||||
MOCK_METHOD(void, setRecentScoreList, (const QStringList&), (override));
|
||||
|
||||
MOCK_METHOD(QStringList, templatesDirPaths, (), (const, override));
|
||||
MOCK_METHOD(io::paths, templatesDirPaths, (), (const, override));
|
||||
|
||||
MOCK_METHOD(QColor, templatePreviewBackgroundColor, (), (const, override));
|
||||
MOCK_METHOD(async::Channel<QColor>, templatePreviewBackgroundColorChanged, (), (const, override));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,15 +21,15 @@
|
|||
|
||||
#include "userscores/internal/templatesrepository.h"
|
||||
|
||||
#include "domain/notation/tests/mocks/msczreadermock.h"
|
||||
#include "notation/tests/mocks/msczreadermock.h"
|
||||
#include "mocks/userscoresconfigurationmock.h"
|
||||
#include "system/tests/mocks/fsoperationsmock.h"
|
||||
#include "system/tests/mocks/filesystemmock.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
|
||||
using namespace mu;
|
||||
using namespace mu::domain::notation;
|
||||
using namespace mu::notation;
|
||||
using namespace mu::userscores;
|
||||
using namespace mu::framework;
|
||||
|
||||
|
@ -40,12 +40,12 @@ protected:
|
|||
{
|
||||
m_repository = std::make_shared<TemplatesRepository>();
|
||||
m_msczReader = std::make_shared<MsczReaderMock>();
|
||||
m_fsOperations = std::make_shared<FsOperationsMock>();
|
||||
m_fileSystem = std::make_shared<FileSystemMock>();
|
||||
m_configuration = std::make_shared<UserScoresConfigurationMock>();
|
||||
|
||||
m_repository->setconfiguration(m_configuration);
|
||||
m_repository->setmsczReader(m_msczReader);
|
||||
m_repository->setfsOperations(m_fsOperations);
|
||||
m_repository->setfileSystem(m_fileSystem);
|
||||
}
|
||||
|
||||
Meta createMeta(const QString& title) const
|
||||
|
@ -61,111 +61,73 @@ protected:
|
|||
std::shared_ptr<TemplatesRepository> m_repository;
|
||||
std::shared_ptr<UserScoresConfigurationMock> m_configuration;
|
||||
std::shared_ptr<MsczReaderMock> m_msczReader;
|
||||
std::shared_ptr<FsOperationsMock> m_fsOperations;
|
||||
std::shared_ptr<FileSystemMock> m_fileSystem;
|
||||
};
|
||||
|
||||
namespace mu {
|
||||
namespace userscores {
|
||||
}
|
||||
|
||||
namespace domain {
|
||||
namespace notation {
|
||||
bool operator==(const Meta& meta1, const Meta& meta2)
|
||||
bool operator==(const Template& templ1, const Template& templ2)
|
||||
{
|
||||
bool equals = true;
|
||||
|
||||
equals &= (meta1.title == meta2.title);
|
||||
equals &= (meta1.creationDate == meta2.creationDate);
|
||||
equals &= (templ1.title == templ2.title);
|
||||
equals &= (templ1.categoryTitle == templ2.categoryTitle);
|
||||
equals &= (templ1.creationDate == templ2.creationDate);
|
||||
|
||||
return equals;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TEST_F(TemplatesRepositoryTest, Categories)
|
||||
TEST_F(TemplatesRepositoryTest, Templates)
|
||||
{
|
||||
// [GIVEN] All paths to mscz files dirs
|
||||
QStringList templatesDirPaths {
|
||||
"/path/to/templates/AAAA",
|
||||
"/path/to/templates/01-some_category_name",
|
||||
"/path/to/templates/99#another_category_name",
|
||||
"/path/to/empty/dir"
|
||||
// [GIVEN] All paths to templates dirs
|
||||
io::paths templatesDirPaths {
|
||||
"/path/to/templates",
|
||||
"/path/to/user/templates"
|
||||
"/extensions/templates"
|
||||
};
|
||||
|
||||
ON_CALL(*m_configuration, templatesDirPaths())
|
||||
.WillByDefault(Return(templatesDirPaths));
|
||||
EXPECT_CALL(*m_configuration, templatesDirPaths())
|
||||
.WillOnce(Return(templatesDirPaths));
|
||||
|
||||
ON_CALL(*m_fsOperations, dirName(templatesDirPaths[0]))
|
||||
.WillByDefault(Return("AAAA"));
|
||||
// [GIVEN] All paths to mscz files
|
||||
io::paths allPathsToMsczFiles;
|
||||
|
||||
ON_CALL(*m_fsOperations, dirName(templatesDirPaths[1]))
|
||||
.WillByDefault(Return("01-some_category_name"));
|
||||
for (size_t i = 0; i < templatesDirPaths.size(); ++i) {
|
||||
io::path dirPath = templatesDirPaths[i];
|
||||
io::path filePath = dirPath + QString("/file%1.mscz").arg(i);
|
||||
allPathsToMsczFiles.push_back(filePath);
|
||||
|
||||
ON_CALL(*m_fsOperations, dirName(templatesDirPaths[2]))
|
||||
.WillByDefault(Return("99#another_category_name"));
|
||||
QStringList filters = { "*.mscz", "*.mscx" };
|
||||
|
||||
// [GIVEN] Some dirs have MSCZ files
|
||||
QStringList filters = { "*.mscz", "*.mscx" };
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
ON_CALL(*m_fsOperations, scanFiles(templatesDirPaths[i], filters, IFsOperations::ScanMode::IncludeSubdirs))
|
||||
.WillByDefault(Return(RetVal<QStringList>::make_ok(QStringList { "/some/path/to/file.mscz" })));
|
||||
RetVal<io::paths> result = RetVal<io::paths>::make_ok(io::paths { filePath });
|
||||
ON_CALL(*m_fileSystem, scanFiles(dirPath, filters, IFileSystem::ScanMode::IncludeSubdirs))
|
||||
.WillByDefault(Return(result));
|
||||
}
|
||||
|
||||
// [WHEN] Get templates categories
|
||||
RetVal<TemplateCategoryList> categories = m_repository->categories();
|
||||
|
||||
// [THEN] Successfully got categories, empty dir was skipped
|
||||
EXPECT_TRUE(categories.ret);
|
||||
|
||||
TemplateCategoryList expectedCategories;
|
||||
expectedCategories << createCategory("AAAA", "/path/to/templates/AAAA")
|
||||
<< createCategory("some category name", "/path/to/templates/01-some_category_name")
|
||||
<< createCategory("another category name", "/path/to/templates/99#another_category_name");
|
||||
|
||||
EXPECT_EQ(categories.val.size(), expectedCategories.size());
|
||||
for (const TemplateCategory& category: categories.val) {
|
||||
EXPECT_TRUE(expectedCategories.contains(category));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TemplatesRepositoryTest, TemplatesMeta)
|
||||
{
|
||||
// [GIVEN] Category codeKey
|
||||
QString codeKey = "/path/to/templates";
|
||||
|
||||
// [GIVEN] Category templates
|
||||
QStringList pathsToMsczFiles;
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
QString filePath = codeKey + QString("/file%1.mscz").arg(i);
|
||||
pathsToMsczFiles << filePath;
|
||||
}
|
||||
|
||||
QStringList filters = { "*.mscz", "*.mscx" };
|
||||
ON_CALL(*m_fsOperations, scanFiles(codeKey, filters, IFsOperations::ScanMode::IncludeSubdirs))
|
||||
.WillByDefault(Return(RetVal<QStringList>::make_ok(pathsToMsczFiles)));
|
||||
|
||||
// [GIVEN] Templates meta
|
||||
MetaList expectedMetaList;
|
||||
Templates expectedTemplates;
|
||||
|
||||
for (const QString& path: pathsToMsczFiles) {
|
||||
Meta meta = createMeta(path);
|
||||
expectedMetaList << meta;
|
||||
for (const io::path& path: allPathsToMsczFiles) {
|
||||
Meta meta = createMeta(path.toQString());
|
||||
|
||||
ON_CALL(*m_msczReader, readMeta(io::pathFromQString(path)))
|
||||
ON_CALL(*m_msczReader, readMeta(path))
|
||||
.WillByDefault(Return(RetVal<Meta>::make_ok(meta)));
|
||||
|
||||
Template templ(meta);
|
||||
templ.categoryTitle = io::dirname(path).toQString();
|
||||
expectedTemplates << templ;
|
||||
}
|
||||
|
||||
// [WHEN] Get templates meta
|
||||
RetVal<MetaList> metaList = m_repository->templatesMeta(codeKey);
|
||||
RetVal<Templates> templates = m_repository->templates();
|
||||
|
||||
// [THEN] Successfully got templates meta
|
||||
EXPECT_TRUE(metaList.ret);
|
||||
EXPECT_TRUE(templates.ret);
|
||||
|
||||
EXPECT_EQ(metaList.val.size(), expectedMetaList.size());
|
||||
for (const Meta& meta: metaList.val) {
|
||||
EXPECT_TRUE(expectedMetaList.contains(meta));
|
||||
EXPECT_EQ(templates.val.size(), expectedTemplates.size());
|
||||
for (const Template& templ: templates.val) {
|
||||
EXPECT_TRUE(expectedTemplates.contains(templ));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "view/newscoremodel.h"
|
||||
#include "view/scorethumbnail.h"
|
||||
#include "view/templatesmodel.h"
|
||||
#include "view/templatepaintview.h"
|
||||
#include "internal/openscorecontroller.h"
|
||||
#include "internal/userscoresconfiguration.h"
|
||||
#include "internal/templatesrepository.h"
|
||||
|
@ -75,6 +76,7 @@ void UserScoresModule::registerUiTypes()
|
|||
qmlRegisterType<NewScoreModel>("MuseScore.UserScores", 1, 0, "NewScoreModel");
|
||||
qmlRegisterType<ScoreThumbnail>("MuseScore.UserScores", 1, 0, "ScoreThumbnail");
|
||||
qmlRegisterType<TemplatesModel>("MuseScore.UserScores", 1, 0, "TemplatesModel");
|
||||
qmlRegisterType<TemplatePaintView>("MuseScore.UserScores", 1, 0, "TemplatePaintView");
|
||||
|
||||
framework::ioc()->resolve<framework::IUiEngine>(moduleName())->addSourceImportPath(userscores_QML_IMPORT);
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ struct Template : public notation::Meta {
|
|||
QString categoryTitle;
|
||||
|
||||
Template() = default;
|
||||
Template(const notation::Meta& meta) : Meta(meta) {}
|
||||
|
||||
Template(const notation::Meta& meta)
|
||||
: Meta(meta) {}
|
||||
};
|
||||
|
||||
using Templates = QList<Template>;
|
||||
|
|
239
mu4/userscores/view/templatepaintview.cpp
Normal file
239
mu4/userscores/view/templatepaintview.cpp
Normal file
|
@ -0,0 +1,239 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2020 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 2.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//=============================================================================
|
||||
|
||||
#include "templatepaintview.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "io/path.h"
|
||||
|
||||
using namespace mu::userscores;
|
||||
using namespace mu::notation;
|
||||
|
||||
//! NOTE: experimental values
|
||||
static constexpr qreal INITIAL_SCALE_FACTOR = 0.05;
|
||||
static constexpr qreal SCALE_FACTOR_STEP = 0.01;
|
||||
|
||||
static constexpr qreal MIN_SCROLL_SIZE = 0.1;
|
||||
static constexpr qreal MAX_SCROLL_SIZE = 1.0;
|
||||
static constexpr qreal MID_SCROLL_POSITION = (MAX_SCROLL_SIZE - MIN_SCROLL_SIZE) / 2.0;
|
||||
|
||||
TemplatePaintView::TemplatePaintView(QQuickItem* parent)
|
||||
: QQuickPaintedItem(parent), m_currentScaleFactor(INITIAL_SCALE_FACTOR)
|
||||
{
|
||||
setAntialiasing(true);
|
||||
|
||||
m_backgroundColor = configuration()->templatePreviewBackgroundColor();
|
||||
configuration()->templatePreviewBackgroundColorChanged().onReceive(this, [this](const QColor& color) {
|
||||
m_backgroundColor = color;
|
||||
update();
|
||||
});
|
||||
|
||||
connect(this, &QQuickPaintedItem::widthChanged, this, &TemplatePaintView::onViewSizeChanged);
|
||||
connect(this, &QQuickPaintedItem::heightChanged, this, &TemplatePaintView::onViewSizeChanged);
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::startHorizontalScrollPosition() const
|
||||
{
|
||||
if (horizontalScrollSize() == MIN_SCROLL_SIZE) {
|
||||
return MID_SCROLL_POSITION;
|
||||
}
|
||||
|
||||
return MAX_SCROLL_SIZE - horizontalScrollableAreaSize();
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::horizontalScrollSize() const
|
||||
{
|
||||
qreal area = horizontalScrollableAreaSize();
|
||||
if (qFuzzyIsNull(area)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
qreal size = area - (MAX_SCROLL_SIZE - area);
|
||||
size = std::max(size, MIN_SCROLL_SIZE);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::horizontalScrollableAreaSize() const
|
||||
{
|
||||
if (canvasWidth() <= width() || !canvasScaled()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return width() / canvasWidth();
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::startVerticalScrollPosition() const
|
||||
{
|
||||
if (verticalScrollSize() == MIN_SCROLL_SIZE) {
|
||||
return MID_SCROLL_POSITION;
|
||||
}
|
||||
|
||||
return MAX_SCROLL_SIZE - verticalScrollableAreaSize();
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::verticalScrollSize() const
|
||||
{
|
||||
qreal area = verticalScrollableAreaSize();
|
||||
if (qFuzzyIsNull(area)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
qreal size = area - (MAX_SCROLL_SIZE - area);
|
||||
size = std::max(size, MIN_SCROLL_SIZE);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::verticalScrollableAreaSize() const
|
||||
{
|
||||
if (canvasHeight() <= height() || !canvasScaled()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return height() / canvasHeight();
|
||||
}
|
||||
|
||||
void TemplatePaintView::load(const QString& templatePath)
|
||||
{
|
||||
if (m_templatePath == templatePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_templatePath = templatePath;
|
||||
m_notation = notationCreator()->newMasterNotation();
|
||||
|
||||
Ret ret = m_notation->load(m_templatePath);
|
||||
if (!ret) {
|
||||
LOGE() << ret.toString();
|
||||
}
|
||||
|
||||
scaleCanvas(INITIAL_SCALE_FACTOR);
|
||||
}
|
||||
|
||||
void TemplatePaintView::moveCanvasToCenter()
|
||||
{
|
||||
m_dx = (width() - canvasWidth()) / 2.;
|
||||
m_dy = (height() - canvasHeight()) / 2.;
|
||||
|
||||
m_previousHorizontalScrollPosition = 0;
|
||||
m_previousVerticalScrollPosition = 0;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void TemplatePaintView::onViewSizeChanged()
|
||||
{
|
||||
moveCanvasToCenter();
|
||||
}
|
||||
|
||||
void TemplatePaintView::zoomIn()
|
||||
{
|
||||
scaleCanvas(m_currentScaleFactor + SCALE_FACTOR_STEP);
|
||||
}
|
||||
|
||||
void TemplatePaintView::zoomOut()
|
||||
{
|
||||
scaleCanvas(m_currentScaleFactor - SCALE_FACTOR_STEP);
|
||||
}
|
||||
|
||||
void TemplatePaintView::scaleCanvas(qreal scaleFactor)
|
||||
{
|
||||
if (scaleFactor < INITIAL_SCALE_FACTOR) {
|
||||
scaleFactor = INITIAL_SCALE_FACTOR;
|
||||
}
|
||||
|
||||
m_currentScaleFactor = scaleFactor;
|
||||
moveCanvasToCenter();
|
||||
|
||||
emit horizontalScrollChanged();
|
||||
emit verticalScrollChanged();
|
||||
}
|
||||
|
||||
bool TemplatePaintView::canvasScaled() const
|
||||
{
|
||||
return !qFuzzyCompare(m_currentScaleFactor, INITIAL_SCALE_FACTOR);
|
||||
}
|
||||
|
||||
void TemplatePaintView::scrollHorizontal(qreal position)
|
||||
{
|
||||
if (position == m_previousHorizontalScrollPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (qFuzzyIsNull(m_previousHorizontalScrollPosition)) {
|
||||
m_previousHorizontalScrollPosition = position;
|
||||
return;
|
||||
}
|
||||
|
||||
qreal scrollStep = position - m_previousHorizontalScrollPosition;
|
||||
m_dx -= canvasWidth() * scrollStep;
|
||||
|
||||
m_previousHorizontalScrollPosition = position;
|
||||
update();
|
||||
}
|
||||
|
||||
void TemplatePaintView::scrollVertical(qreal position)
|
||||
{
|
||||
if (position == m_previousVerticalScrollPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (qFuzzyIsNull(m_previousVerticalScrollPosition)) {
|
||||
m_previousVerticalScrollPosition = position;
|
||||
return;
|
||||
}
|
||||
|
||||
qreal scrollStep = position - m_previousVerticalScrollPosition;
|
||||
m_dy -= canvasHeight() * scrollStep;
|
||||
|
||||
m_previousVerticalScrollPosition = position;
|
||||
update();
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::canvasWidth() const
|
||||
{
|
||||
if (m_notation) {
|
||||
return m_notation->previewRect().width() * m_currentScaleFactor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
qreal TemplatePaintView::canvasHeight() const
|
||||
{
|
||||
if (m_notation) {
|
||||
return m_notation->previewRect().height() * m_currentScaleFactor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TemplatePaintView::paint(QPainter* painter)
|
||||
{
|
||||
QRect rect(0, 0, width(), height());
|
||||
|
||||
painter->fillRect(rect, m_backgroundColor);
|
||||
painter->translate(m_dx, m_dy);
|
||||
painter->scale(m_currentScaleFactor, m_currentScaleFactor);
|
||||
|
||||
if (m_notation) {
|
||||
m_notation->paint(painter);
|
||||
}
|
||||
}
|
96
mu4/userscores/view/templatepaintview.h
Normal file
96
mu4/userscores/view/templatepaintview.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2020 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 2.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//=============================================================================
|
||||
#ifndef MU_USERSCORES_TEMPLATEPAINTVIEW_H
|
||||
#define MU_USERSCORES_TEMPLATEPAINTVIEW_H
|
||||
|
||||
#include <QQuickPaintedItem>
|
||||
|
||||
#include "modularity/ioc.h"
|
||||
#include "notation/inotationcreator.h"
|
||||
#include "notation/imasternotation.h"
|
||||
#include "iuserscoresconfiguration.h"
|
||||
#include "async/asyncable.h"
|
||||
|
||||
namespace mu {
|
||||
namespace userscores {
|
||||
class TemplatePaintView : public QQuickPaintedItem, public async::Asyncable
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
INJECT(userscores, notation::INotationCreator, notationCreator)
|
||||
INJECT(userscores, IUserScoresConfiguration, configuration)
|
||||
|
||||
Q_PROPERTY(qreal startHorizontalScrollPosition READ startHorizontalScrollPosition NOTIFY horizontalScrollChanged)
|
||||
Q_PROPERTY(qreal horizontalScrollSize READ horizontalScrollSize NOTIFY horizontalScrollChanged)
|
||||
Q_PROPERTY(qreal startVerticalScrollPosition READ startVerticalScrollPosition NOTIFY verticalScrollChanged)
|
||||
Q_PROPERTY(qreal verticalScrollSize READ verticalScrollSize NOTIFY verticalScrollChanged)
|
||||
|
||||
public:
|
||||
explicit TemplatePaintView(QQuickItem* parent = nullptr);
|
||||
|
||||
qreal startHorizontalScrollPosition() const;
|
||||
qreal horizontalScrollSize() const;
|
||||
qreal startVerticalScrollPosition() const;
|
||||
qreal verticalScrollSize() const;
|
||||
|
||||
Q_INVOKABLE void load(const QString& templatePath);
|
||||
|
||||
Q_INVOKABLE void zoomIn();
|
||||
Q_INVOKABLE void zoomOut();
|
||||
|
||||
Q_INVOKABLE void scrollHorizontal(qreal position);
|
||||
Q_INVOKABLE void scrollVertical(qreal position);
|
||||
|
||||
signals:
|
||||
void horizontalScrollChanged();
|
||||
void verticalScrollChanged();
|
||||
|
||||
private:
|
||||
qreal horizontalScrollableAreaSize() const;
|
||||
qreal verticalScrollableAreaSize() const;
|
||||
|
||||
void paint(QPainter* painter) override;
|
||||
|
||||
qreal canvasWidth() const;
|
||||
qreal canvasHeight() const;
|
||||
|
||||
void moveCanvasToCenter();
|
||||
|
||||
void scaleCanvas(qreal scaleFactor);
|
||||
bool canvasScaled() const;
|
||||
|
||||
private slots:
|
||||
void onViewSizeChanged();
|
||||
|
||||
private:
|
||||
QString m_templatePath;
|
||||
notation::IMasterNotationPtr m_notation;
|
||||
QColor m_backgroundColor;
|
||||
|
||||
qreal m_previousVerticalScrollPosition = 0;
|
||||
qreal m_previousHorizontalScrollPosition = 0;
|
||||
|
||||
qreal m_currentScaleFactor = 0;
|
||||
qreal m_dx = 0;
|
||||
qreal m_dy = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MU_USERSCORES_TEMPLATEPAINTVIEW_H
|
|
@ -8,7 +8,6 @@ using namespace mu::notation;
|
|||
TemplatesModel::TemplatesModel(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TemplatesModel::load()
|
||||
|
@ -27,11 +26,7 @@ void TemplatesModel::load()
|
|||
|
||||
emit categoriesChanged();
|
||||
emit templatesChanged();
|
||||
}
|
||||
|
||||
void TemplatesModel::apply()
|
||||
{
|
||||
NOT_IMPLEMENTED;
|
||||
emit currentTemplateChanged();
|
||||
}
|
||||
|
||||
QStringList TemplatesModel::categoriesTitles() const
|
||||
|
@ -39,16 +34,21 @@ QStringList TemplatesModel::categoriesTitles() const
|
|||
return m_visibleCategoriesTitles.toList();
|
||||
}
|
||||
|
||||
QString TemplatesModel::currentTemplatePath() const
|
||||
{
|
||||
if (m_visibleTemplates.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return m_visibleTemplates[m_currentTemplateIndex].filePath;
|
||||
}
|
||||
|
||||
QStringList TemplatesModel::templatesTitles() const
|
||||
{
|
||||
QStringList titles;
|
||||
|
||||
for (const Template& templ: m_visibleTemplates) {
|
||||
bool acceptedByCategory = templ.categoryTitle == categoriesTitles()[m_currentCategoryIndex];
|
||||
|
||||
if (acceptedByCategory) {
|
||||
titles << templ.title;
|
||||
}
|
||||
titles << templ.title;
|
||||
}
|
||||
|
||||
return titles;
|
||||
|
@ -61,7 +61,24 @@ void TemplatesModel::setCurrentCategory(int index)
|
|||
}
|
||||
|
||||
m_currentCategoryIndex = index;
|
||||
updateTemplatesByCategory();
|
||||
}
|
||||
|
||||
void TemplatesModel::updateTemplatesByCategory()
|
||||
{
|
||||
m_visibleTemplates.clear();
|
||||
m_currentTemplateIndex = 0;
|
||||
|
||||
QString currentCategoryTitle = categoriesTitles()[m_currentCategoryIndex];
|
||||
|
||||
for (const Template& templ: m_allTemplates) {
|
||||
if (templ.categoryTitle == currentCategoryTitle) {
|
||||
m_visibleTemplates << templ;
|
||||
}
|
||||
}
|
||||
|
||||
emit templatesChanged();
|
||||
emit currentTemplateChanged();
|
||||
}
|
||||
|
||||
void TemplatesModel::setCurrentTemplate(int index)
|
||||
|
@ -71,6 +88,7 @@ void TemplatesModel::setCurrentTemplate(int index)
|
|||
}
|
||||
|
||||
m_currentTemplateIndex = index;
|
||||
emit currentTemplateChanged();
|
||||
}
|
||||
|
||||
void TemplatesModel::setSearchText(const QString& text)
|
||||
|
@ -80,10 +98,10 @@ void TemplatesModel::setSearchText(const QString& text)
|
|||
}
|
||||
|
||||
m_searchText = text;
|
||||
updateBySearch();
|
||||
updateTemplatesAndCategoriesBySearch();
|
||||
}
|
||||
|
||||
void TemplatesModel::updateBySearch()
|
||||
void TemplatesModel::updateTemplatesAndCategoriesBySearch()
|
||||
{
|
||||
m_visibleTemplates.clear();
|
||||
m_visibleCategoriesTitles.clear();
|
||||
|
@ -100,6 +118,7 @@ void TemplatesModel::updateBySearch()
|
|||
|
||||
emit categoriesChanged();
|
||||
emit templatesChanged();
|
||||
emit currentTemplateChanged();
|
||||
}
|
||||
|
||||
bool TemplatesModel::titleAccepted(const QString& title) const
|
||||
|
|
|
@ -33,14 +33,17 @@ class TemplatesModel : public QObject
|
|||
Q_PROPERTY(QStringList categoriesTitles READ categoriesTitles NOTIFY categoriesChanged)
|
||||
Q_PROPERTY(QStringList templatesTitles READ templatesTitles NOTIFY templatesChanged)
|
||||
|
||||
Q_PROPERTY(QString currentTemplatePath READ currentTemplatePath NOTIFY currentTemplateChanged)
|
||||
|
||||
public:
|
||||
TemplatesModel(QObject* parent = nullptr);
|
||||
|
||||
QStringList categoriesTitles() const;
|
||||
QStringList templatesTitles() const;
|
||||
|
||||
QString currentTemplatePath() const;
|
||||
|
||||
Q_INVOKABLE void load();
|
||||
Q_INVOKABLE void apply();
|
||||
|
||||
Q_INVOKABLE void setCurrentCategory(int index);
|
||||
Q_INVOKABLE void setCurrentTemplate(int index);
|
||||
|
@ -49,9 +52,12 @@ public:
|
|||
signals:
|
||||
void categoriesChanged();
|
||||
void templatesChanged();
|
||||
void currentTemplateChanged();
|
||||
|
||||
private:
|
||||
void updateBySearch();
|
||||
void updateTemplatesByCategory();
|
||||
void updateTemplatesAndCategoriesBySearch();
|
||||
|
||||
bool titleAccepted(const QString& title) const;
|
||||
|
||||
Templates m_allTemplates;
|
||||
|
|
Loading…
Reference in a new issue