Skip to content

Commit

Permalink
Display ScoreItemModel in a Tree View
Browse files Browse the repository at this point in the history
Added a ScoreTreeView that displays the score tree in a QTreeView,
and also created a QDockWidget called ScoreTreeWidget which is enabled
in the debug builds to inspect the score tree model.
  • Loading branch information
krkartikay committed Jun 21, 2020
1 parent 71a0da0 commit 48d860c
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 2 deletions.
2 changes: 1 addition & 1 deletion mscore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ add_library(mscoreapp STATIC
recordbutton.h greendotbutton prefsdialog.h prefsdialog.cpp
stringutils.h stringutils.cpp
scoreview.cpp editharmony.cpp editfiguredbass.cpp events.cpp
scoreitemmodel.cpp
scoreitemmodel.cpp scoretreewidget.cpp scoretreeview.cpp
editinstrument.cpp editstyle.cpp
icons.cpp
instrdialog.cpp instrwidget.cpp
Expand Down
22 changes: 22 additions & 0 deletions mscore/musescore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "libmscore/sym.h"
#include "pagesettings.h"
#include "debugger/debugger.h"
#include "scoretreewidget.h"
#include "editstyle.h"
#include "playpanel.h"
#include "libmscore/page.h"
Expand Down Expand Up @@ -1857,6 +1858,9 @@ MuseScore::MuseScore()
a->setCheckable(true);
a->setChecked(true);
menuDebug->addAction(a);
a = getAction("show-tree-debugger");
a->setCheckable(true);
menuDebug->addAction(a);
a = getAction("relayout");
menuDebug->addAction(a);
a = getAction("qml-reload-source");
Expand Down Expand Up @@ -2789,6 +2793,9 @@ void MuseScore::setCurrentScoreView(ScoreView* view)
if (mixer) {
mixer->setScore(cs);
}
if (scoreTreeWidget && scoreTreeWidget->isVisible()) {
scoreTreeWidget->setScore(cs);
}
#ifdef OMR
if (omrPanel) {
if (cv && cv->omrView()) {
Expand Down Expand Up @@ -6861,6 +6868,16 @@ void MuseScore::cmd(QAction* a, const QString& cmd)
const QString urlString = w->source().toString().replace(oldPrefix, newPrefix);
w->setSource(QUrl(urlString));
}
} else if (cmd == "show-tree-debugger") {
if (a->isChecked()) {
if (!scoreTreeWidget) {
scoreTreeWidget = new ScoreTreeWidget(mscore);
}
scoreTreeWidget->setScore(cs);
scoreTreeWidget->show();
} else {
scoreTreeWidget->hide();
}
}
#endif
else {
Expand All @@ -6879,6 +6896,11 @@ void MuseScore::cmd(QAction* a, const QString& cmd)
if (debugger) {
debugger->reloadClicked();
}
// reload score tree debugger after any possible re-layout
// not doing so causes a crash on re-layout
if (scoreTreeWidget && scoreTreeWidget->isVisible()) {
scoreTreeWidget->setScore(cs);
}
}

//---------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions mscore/musescore.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class PlayPanel;
class IPlayPanel;
class Mixer;
class Debugger;
class ScoreTreeWidget;
class MeasureListEditor;
class MasterScore;
class Score;
Expand Down Expand Up @@ -298,6 +299,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore
Mixer* mixer { 0 };
SynthControl* synthControl { 0 };
Debugger* debugger { 0 };
ScoreTreeWidget* scoreTreeWidget { 0 };
MeasureListEditor* measureListEdit { 0 };
PageSettings* pageSettings { 0 };

Expand Down
103 changes: 103 additions & 0 deletions mscore/scoretreeview.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2020 MuseScore BVBA
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================

#include "scoretreeview.h"

namespace Ms {
//---------------------------------------------------------
// selectElementAndChildren
//---------------------------------------------------------

static void selectElementAndChildren(Element* el)
{
el->score()->selection().add(el);
for (ScoreElement* child : (*el)) {
if (child) {
selectElementAndChildren(toElement(child));
}
}
}

//---------------------------------------------------------
// ScoreTreeView
//---------------------------------------------------------

ScoreTreeView::ScoreTreeView(QWidget* parent)
: QTreeView(parent)
{
}

//---------------------------------------------------------
// ~ScoreTreeView
//---------------------------------------------------------

ScoreTreeView::~ScoreTreeView()
{
}

//---------------------------------------------------------
// setModel
//---------------------------------------------------------

void ScoreTreeView::setModel(QAbstractItemModel* model)
{
Q_ASSERT(model); // ensure there is a model
Q_ASSERT(dynamic_cast<ScoreItemModel*>(model)); // ensure model is correct type
QTreeView::setModel(model);
}

//---------------------------------------------------------
// model
//---------------------------------------------------------

ScoreItemModel* ScoreTreeView::model() const
{
return static_cast<ScoreItemModel*>(QTreeView::model());
}

//---------------------------------------------------------
// currentChanged
//---------------------------------------------------------

void ScoreTreeView::currentChanged(const QModelIndex& current, const QModelIndex& previous)
{
selectElementAtIndex(current);
QTreeView::currentChanged(current, previous);
}

//---------------------------------------------------------
// selectElementAtIndex
/// Select the element represented by index and all its children
/// in the score, so they are highlighted in the ScoreView.
//---------------------------------------------------------

void ScoreTreeView::selectElementAtIndex(const QModelIndex& index)
{
ScoreElement* el = static_cast<ScoreElement*>(index.internalPointer());

if (!el || !el->isElement()) {
return;
}

Score* cs = model()->score();
cs->selection().deselectAll();
cs->selection().setState(SelState::LIST);

// This function recursively adds all the children of the selected element
// to the selection in the score. This is necessary because some non leaf node
// elements cannot be selected by themselves (Segments, Measures) etc.
selectElementAndChildren(toElement(el));

cs->setSelectionChanged(true);
cs->update();
}
} // namespace Ms
37 changes: 37 additions & 0 deletions mscore/scoretreeview.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2020 MuseScore BVBA
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================

#ifndef __STREEVIEW_H__
#define __STREEVIEW_H__

#include "scoreitemmodel.h"

namespace Ms {
class ScoreTreeView : public QTreeView
{
Q_OBJECT

public:
ScoreTreeView(QWidget* parent);
~ScoreTreeView();

void setModel(QAbstractItemModel* model);
ScoreItemModel* model() const;

void currentChanged(const QModelIndex& current, const QModelIndex& prev) override;

private:
void selectElementAtIndex(const QModelIndex& index);
};
} // namespace Ms

#endif // __STREEVIEW_H__
53 changes: 53 additions & 0 deletions mscore/scoretreewidget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2020 MuseScore BVBA
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================

#include "scoretreewidget.h"

#include "libmscore/score.h"
#include "scoreitemmodel.h"
#include "scoretreeview.h"

namespace Ms {
//---------------------------------------------------------
// ScoreTreeWidget
//---------------------------------------------------------

ScoreTreeWidget::ScoreTreeWidget(QMainWindow* parent)
: QDockWidget("Score Tree", parent)
{
_treeView = new ScoreTreeView(this);
setWidget(_treeView);
setAllowedAreas(Qt::RightDockWidgetArea);
parent->addDockWidget(Qt::RightDockWidgetArea, this);
}

//---------------------------------------------------------
// ~ScoreTreeWidget
//---------------------------------------------------------

ScoreTreeWidget::~ScoreTreeWidget()
{
}

//---------------------------------------------------------
// setScore
//---------------------------------------------------------

void ScoreTreeWidget::setScore(Score* s)
{
QAbstractItemModel* oldModel = _treeView->model();
if (s) {
_treeView->setModel(new ScoreItemModel(s, _treeView));
}
delete oldModel;
}
} // namespace Ms
33 changes: 33 additions & 0 deletions mscore/scoretreewidget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2020 MuseScore BVBA
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================

#ifndef __STREEWIDGET_H__
#define __STREEWIDGET_H__

namespace Ms {
class Score;
class ScoreTreeView;

class ScoreTreeWidget : public QDockWidget
{
Q_OBJECT

ScoreTreeView * _treeView;

public:
ScoreTreeWidget(QMainWindow* parent);
~ScoreTreeWidget();
void setScore(Score* s);
};
} // namespace Ms

#endif // __STREEWIDGET_H__
9 changes: 8 additions & 1 deletion mscore/shortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3963,7 +3963,14 @@ Shortcut Shortcut::_sc[] = {
0,
Icons::Invalid_ICON,
Qt::ApplicationShortcut
}
},
{
MsWidget::MAIN_WINDOW,
STATE_ALL,
"show-tree-debugger",
QT_TRANSLATE_NOOP("action", "Show Tree Debugger"),
QT_TRANSLATE_NOOP("action", "Show tree debugger"),
},
#endif
};

Expand Down

0 comments on commit 48d860c

Please sign in to comment.