MuseScore/mscore/scoretab.cpp
2015-01-23 14:41:08 +01:00

419 lines
13 KiB
C++

//=============================================================================
// MuseScore
// Linux Music Score Editor
// $Id:$
//
// Copyright (C) 2009-2010 Werner Schweer 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 "shortcut.h"
#include "musescore.h"
#include "config.h"
#include "scoretab.h"
#include "scoreview.h"
#include "scoreview.h"
#include "libmscore/score.h"
#include "magbox.h"
#ifdef OMR
#include "omr/omr.h"
#include "omr/omrview.h"
#endif
#include "libmscore/excerpt.h"
namespace Ms {
//---------------------------------------------------------
// ScoreTab
//---------------------------------------------------------
ScoreTab::ScoreTab(QList<Score*>* sl, QWidget* parent)
: QWidget(parent)
{
mainWindow = static_cast<MuseScore*>(parent);
scoreList = sl;
QVBoxLayout* layout = new QVBoxLayout;
setLayout(layout);
layout->setSpacing(0);
layout->setMargin(2);
QActionGroup* ag = Shortcut::getActionGroupForWidget(MsWidget::SCORE_TAB, Qt::WidgetWithChildrenShortcut);
ag->setParent(this);
this->addActions(ag->actions());
connect(ag, SIGNAL(triggered(QAction*)), this, SIGNAL(actionTriggered(QAction*)));
tab = new QTabBar(this);
tab->setExpanding(false);
tab->setSelectionBehaviorOnRemove(QTabBar::SelectRightTab);
tab->setFocusPolicy(Qt::ClickFocus);
tab->setTabsClosable(true);
tab2 = new QTabBar(this);
tab2->setExpanding(false);
tab2->setSelectionBehaviorOnRemove(QTabBar::SelectRightTab);
tab2->setFocusPolicy(Qt::ClickFocus);
tab2->setVisible(false);
tab2->setTabsClosable(false);
stack = new QStackedLayout;
layout->addWidget(tab);
layout->addWidget(tab2);
layout->addLayout(stack);
foreach(Score* s, *sl)
insertTab(s);
connect(tab, SIGNAL(currentChanged(int)), this, SLOT(setCurrent(int)));
connect(tab2, SIGNAL(currentChanged(int)), this, SLOT(setExcerpt(int)));
connect(tab, SIGNAL(tabCloseRequested(int)), this, SIGNAL(tabCloseRequested(int)));
}
ScoreTab::~ScoreTab()
{
// while (tab->count() > 0)
// tab->removeTab(0);
}
//---------------------------------------------------------
// view
//---------------------------------------------------------
ScoreView* ScoreTab::view(int n) const
{
QSplitter* s = viewSplitter(n);
if (s)
return static_cast<ScoreView*>(s->widget(0));
return 0;
}
//---------------------------------------------------------
// viewSplitter
//---------------------------------------------------------
QSplitter* ScoreTab::viewSplitter(int n) const
{
TabScoreView* tsv = static_cast<TabScoreView*>(tab->tabData(n).value<void*>());
if (tsv == 0) {
// qDebug("ScoreTab::viewSplitter %d is zero", n);
return 0;
}
Score* score = tsv->score;
if (tsv->part) {
QList<Excerpt*>& excerpts = score->excerpts();
if (!excerpts.isEmpty() && ((tsv->part - 1) < excerpts.size()))
score = excerpts.at(tsv->part - 1)->partScore();
}
int nn = stack->count();
for (int i = 0; i < nn; ++i) {
QSplitter* sp = static_cast<QSplitter*>(stack->widget(i));
if (sp->count() == 0)
return 0;
ScoreView* v = static_cast<ScoreView*>(sp->widget(0));
if (v->score() == score)
return sp;
}
return 0;
}
//---------------------------------------------------------
// clearTab2
//---------------------------------------------------------
void ScoreTab::clearTab2()
{
tab2->blockSignals(true);
int n = tab2->count();
for (int i = 0; i < n; ++i)
tab2->removeTab(0);
tab2->blockSignals(false);
}
//---------------------------------------------------------
// setCurrent
//---------------------------------------------------------
void ScoreTab::setCurrent(int n)
{
if (n == -1) {
clearTab2();
tab2->setVisible(false);
// clearTab2(); //??
emit currentScoreViewChanged(0);
return;
}
TabScoreView* tsv = static_cast<TabScoreView*>(tab->tabData(n).value<void*>());
QSplitter* vs = viewSplitter(n);
ScoreView* v;
if (!vs) {
vs = new QSplitter;
v = new ScoreView;
tab2->blockSignals(true);
tab2->setCurrentIndex(0);
tab2->blockSignals(false);
vs->addWidget(v);
v->setScore(scoreList->value(n));
stack->addWidget(vs);
}
else {
v = static_cast<ScoreView*>(vs->widget(0));
}
#ifdef OMR
if (v) {
Score* score = v->score();
if (score->showOmr() && score->omr()) {
if (vs->count() < 2) {
Omr* omr = score->omr();
OmrView* sv = omr->newOmrView(v);
v->setOmrView(sv);
vs->addWidget(sv);
connect(v, SIGNAL(scaleChanged(double)), sv, SLOT(setScale(double)));
connect(v, SIGNAL(offsetChanged(double,double)), sv, SLOT(setOffset(double,double)));
const QTransform _matrix = v->matrix();
double _spatium = score->spatium();
double scale = _matrix.m11() * _spatium;
sv->setScale(scale);
sv->setOffset(_matrix.dx(), _matrix.dy());
QList<int> sizes;
sizes << 100 << 100;
vs->setSizes(sizes);
}
}
else {
if (vs->count() > 1) {
QWidget* w = vs->widget(1);
delete w;
}
}
}
#endif
stack->setCurrentWidget(vs);
clearTab2();
if (v) {
Score* score = v->score();
if (score->parentScore())
score = score->parentScore();
QList<Excerpt*>& excerpts = score->excerpts();
if (!excerpts.isEmpty()) {
tab2->blockSignals(true);
tab2->addTab(score->name().replace("&","&&"));
foreach(const Excerpt* excerpt, excerpts) {
tab2->addTab(excerpt->partScore()->name().replace("&","&&"));
}
tab2->setCurrentIndex(tsv->part);
tab2->blockSignals(false);
tab2->setVisible(true);
}
else {
tab2->setVisible(false);
}
}
else {
tab2->setVisible(false);
}
emit currentScoreViewChanged(v);
}
//---------------------------------------------------------
// updateExcerpts
// number of excerpts in score changed
//---------------------------------------------------------
void ScoreTab::updateExcerpts()
{
int idx = currentIndex();
if (idx == -1)
return;
ScoreView* v = view(idx);
if (!v)
return;
Score* score = v->score()->rootScore();
clearTab2();
//delete all scoreviews for parts, especially for the deleted ones
int n = stack->count() - 1;
for (int i = n; i >= 0; --i) {
QSplitter* vs = static_cast<QSplitter*>(stack->widget(i));
ScoreView* sview = static_cast<ScoreView*>(vs->widget(0));
if (sview->score() != score && sview->score()->rootScore() == score) {
stack->takeAt(i);
sview->deleteLater();
}
}
QList<Excerpt*>& excerpts = score->excerpts();
if (!excerpts.isEmpty()) {
tab2->blockSignals(true);
tab2->addTab(score->name().replace("&","&&"));
foreach(const Excerpt* excerpt, excerpts)
tab2->addTab(excerpt->partScore()->name().replace("&","&&"));
tab2->blockSignals(false);
tab2->setVisible(true);
setExcerpt(0);
}
else {
tab2->setVisible(false);
setExcerpt(0);
}
}
//---------------------------------------------------------
// setExcerpt
//---------------------------------------------------------
void ScoreTab::setExcerpt(int n)
{
if (n == -1)
return;
int idx = tab->currentIndex();
TabScoreView* tsv = static_cast<TabScoreView*>(tab->tabData(idx).value<void*>());
if (tsv == 0)
return;
tsv->part = n;
QSplitter* vs = viewSplitter(idx);
ScoreView* v;
Score* score = tsv->score;
if (n) {
QList<Excerpt*>& excerpts = score->excerpts();
if (!excerpts.isEmpty()) {
score = excerpts.at(n - 1)->partScore();
}
}
if (!vs) {
vs = new QSplitter;
v = new ScoreView;
vs->addWidget(v);
v->setScore(score);
stack->addWidget(vs);
}
else
v = static_cast<ScoreView*>(vs->widget(0));
stack->setCurrentWidget(vs);
emit currentScoreViewChanged(v);
}
//---------------------------------------------------------
// insertTab
//---------------------------------------------------------
void ScoreTab::insertTab(Score* s)
{
int idx = scoreList->indexOf(s);
tab->blockSignals(true);
tab->insertTab(idx, s->name().replace("&","&&"));
tab->setTabData(idx, QVariant::fromValue<void*>(new TabScoreView(s)));
tab->blockSignals(false);
}
//---------------------------------------------------------
// setTabText
//---------------------------------------------------------
void ScoreTab::setTabText(int idx, const QString& s)
{
QString text(s);
text.replace("&","&&");
tab->setTabText(idx, text);
if (tab2)
tab2->setTabText(0, text);
}
//---------------------------------------------------------
// currentIndex
//---------------------------------------------------------
int ScoreTab::currentIndex() const
{
return tab->currentIndex();
}
//---------------------------------------------------------
// setCurrentIndex
//---------------------------------------------------------
void ScoreTab::setCurrentIndex(int idx)
{
if (currentIndex() == idx)
setCurrent(idx);
else
tab->setCurrentIndex(idx);
tab->setTabText(idx, tab->tabText(idx)); // HACK
}
//---------------------------------------------------------
// removeTab
//---------------------------------------------------------
void ScoreTab::removeTab(int idx)
{
TabScoreView* tsv = static_cast<TabScoreView*>(tab->tabData(idx).value<void*>());
Score* score = tsv->score;
for (int i = 0; i < stack->count(); ++i) {
QSplitter* vs = static_cast<QSplitter*>(stack->widget(i));
ScoreView* v = static_cast<ScoreView*>(vs->widget(0));
if (v->score() == score) {
stack->takeAt(i);
delete v;
break;
}
}
foreach (Excerpt* excerpt, score->excerpts()) {
Score* sc = excerpt->partScore();
for (int i = 0; i < stack->count(); ++i) {
QSplitter* vs = static_cast<QSplitter*>(stack->widget(i));
ScoreView* v = static_cast<ScoreView*>(vs->widget(0));
if (v->score() == sc) {
stack->takeAt(i);
delete v;
break;
}
}
}
int cidx = currentIndex();
tab->removeTab(idx);
if (cidx > idx)
cidx -= 1;
setCurrentIndex(cidx);
}
//---------------------------------------------------------
// initScoreView
//---------------------------------------------------------
void ScoreTab::initScoreView(int idx, double mag, MagIdx magIdx, double xoffset, double yoffset)
{
ScoreView* v = view(idx);
if (!v) {
v = new ScoreView;
Score* sc = scoreList->value(idx);
if( sc != 0 )
v->setScore(sc);
else {
delete v;
return;
}
QSplitter* vs = new QSplitter;
vs->addWidget(v);
stack->addWidget(vs);
}
v->setMag(magIdx, mag);
v->setOffset(xoffset, yoffset);
}
}