You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7545 lines
245 KiB
7545 lines
245 KiB
/*
|
|
Rosegarden
|
|
A MIDI and audio sequencer and musical notation editor.
|
|
|
|
This program is Copyright 2000-2008
|
|
Guillaume Laurent <glaurent@telegraph-road.org>,
|
|
Chris Cannam <cannam@all-day-breakfast.com>,
|
|
Richard Bown <richard.bown@ferventsoftware.com>
|
|
|
|
The moral rights of Guillaume Laurent, Chris Cannam, and Richard
|
|
Bown to claim authorship of this work have been asserted.
|
|
|
|
Other copyrights also apply to some parts of this work. Please
|
|
see the AUTHORS file and individual file headers for details.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version. See the file
|
|
COPYING included with this distribution for more information.
|
|
*/
|
|
|
|
|
|
#include "NotationView.h"
|
|
#include <list>
|
|
#include <tqlayout.h>
|
|
#include "misc/Debug.h"
|
|
#include <tdeapplication.h>
|
|
|
|
#include "gui/editors/segment/TrackEditor.h"
|
|
#include "gui/editors/segment/TrackButtons.h"
|
|
#include "base/BaseProperties.h"
|
|
#include <tdelocale.h>
|
|
#include <kstddirs.h>
|
|
#include "misc/Strings.h"
|
|
#include "base/AnalysisTypes.h"
|
|
#include "base/Clipboard.h"
|
|
#include "base/Composition.h"
|
|
#include "base/CompositionTimeSliceAdapter.h"
|
|
#include "base/Configuration.h"
|
|
#include "base/Device.h"
|
|
#include "base/Event.h"
|
|
#include "base/Exception.h"
|
|
#include "base/Instrument.h"
|
|
#include "base/MidiDevice.h"
|
|
#include "base/MidiTypes.h"
|
|
#include "base/NotationTypes.h"
|
|
#include "base/Profiler.h"
|
|
#include "base/PropertyName.h"
|
|
#include "base/NotationQuantizer.h"
|
|
#include "base/RealTime.h"
|
|
#include "base/RulerScale.h"
|
|
#include "base/Segment.h"
|
|
#include "base/Selection.h"
|
|
#include "base/Staff.h"
|
|
#include "base/Studio.h"
|
|
#include "base/Track.h"
|
|
#include "ClefInserter.h"
|
|
#include "commands/edit/AddDotCommand.h"
|
|
#include "commands/edit/ClearTriggersCommand.h"
|
|
#include "commands/edit/CollapseNotesCommand.h"
|
|
#include "commands/edit/CopyCommand.h"
|
|
#include "commands/edit/CutAndCloseCommand.h"
|
|
#include "commands/edit/CutCommand.h"
|
|
#include "commands/edit/EraseCommand.h"
|
|
#include "commands/edit/EventEditCommand.h"
|
|
#include "commands/edit/EventQuantizeCommand.h"
|
|
#include "commands/edit/InsertTriggerNoteCommand.h"
|
|
#include "commands/edit/PasteEventsCommand.h"
|
|
#include "commands/edit/SetLyricsCommand.h"
|
|
#include "commands/edit/SetNoteTypeCommand.h"
|
|
#include "commands/edit/SetTriggerCommand.h"
|
|
#include "commands/edit/TransposeCommand.h"
|
|
#include "commands/notation/AddFingeringMarkCommand.h"
|
|
#include "commands/notation/AddIndicationCommand.h"
|
|
#include "commands/notation/AddMarkCommand.h"
|
|
#include "commands/notation/AddSlashesCommand.h"
|
|
#include "commands/notation/AddTextMarkCommand.h"
|
|
#include "commands/notation/AutoBeamCommand.h"
|
|
#include "commands/notation/BeamCommand.h"
|
|
#include "commands/notation/BreakCommand.h"
|
|
#include "commands/notation/ChangeSlurPositionCommand.h"
|
|
#include "commands/notation/ChangeTiePositionCommand.h"
|
|
#include "commands/notation/ChangeStemsCommand.h"
|
|
#include "commands/notation/ChangeStyleCommand.h"
|
|
#include "commands/notation/ClefInsertionCommand.h"
|
|
#include "commands/notation/CollapseRestsCommand.h"
|
|
#include "commands/notation/DeCounterpointCommand.h"
|
|
#include "commands/notation/EraseEventCommand.h"
|
|
#include "commands/notation/FixNotationQuantizeCommand.h"
|
|
#include "commands/notation/IncrementDisplacementsCommand.h"
|
|
#include "commands/notation/InterpretCommand.h"
|
|
#include "commands/notation/KeyInsertionCommand.h"
|
|
#include "commands/notation/MakeAccidentalsCautionaryCommand.h"
|
|
#include "commands/notation/MakeChordCommand.h"
|
|
#include "commands/notation/MakeNotesViableCommand.h"
|
|
#include "commands/notation/MultiKeyInsertionCommand.h"
|
|
#include "commands/notation/NormalizeRestsCommand.h"
|
|
#include "commands/notation/RemoveFingeringMarksCommand.h"
|
|
#include "commands/notation/RemoveMarksCommand.h"
|
|
#include "commands/notation/RemoveNotationQuantizeCommand.h"
|
|
#include "commands/notation/ResetDisplacementsCommand.h"
|
|
#include "commands/notation/RespellCommand.h"
|
|
#include "commands/notation/RestoreSlursCommand.h"
|
|
#include "commands/notation/RestoreTiesCommand.h"
|
|
#include "commands/notation/RestoreStemsCommand.h"
|
|
#include "commands/notation/SetVisibilityCommand.h"
|
|
#include "commands/notation/SustainInsertionCommand.h"
|
|
#include "commands/notation/TextInsertionCommand.h"
|
|
#include "commands/notation/TieNotesCommand.h"
|
|
#include "commands/notation/TupletCommand.h"
|
|
#include "commands/notation/UntieNotesCommand.h"
|
|
#include "commands/notation/UnTupletCommand.h"
|
|
#include "commands/segment/PasteToTriggerSegmentCommand.h"
|
|
#include "commands/segment/SegmentSyncCommand.h"
|
|
#include "commands/segment/SegmentTransposeCommand.h"
|
|
#include "commands/segment/RenameTrackCommand.h"
|
|
#include "document/RosegardenGUIDoc.h"
|
|
#include "document/ConfigGroups.h"
|
|
#include "document/io/LilyPondExporter.h"
|
|
#include "GuitarChordInserter.h"
|
|
#include "gui/application/SetWaitCursor.h"
|
|
#include "gui/application/RosegardenGUIView.h"
|
|
#include "gui/dialogs/ClefDialog.h"
|
|
#include "gui/dialogs/EventEditDialog.h"
|
|
#include "gui/dialogs/InterpretDialog.h"
|
|
#include "gui/dialogs/IntervalDialog.h"
|
|
#include "gui/dialogs/KeySignatureDialog.h"
|
|
#include "gui/dialogs/LilyPondOptionsDialog.h"
|
|
#include "gui/dialogs/LyricEditDialog.h"
|
|
#include "gui/dialogs/MakeOrnamentDialog.h"
|
|
#include "gui/dialogs/PasteNotationDialog.h"
|
|
#include "gui/dialogs/QuantizeDialog.h"
|
|
#include "gui/dialogs/SimpleEventEditDialog.h"
|
|
#include "gui/dialogs/TextEventDialog.h"
|
|
#include "gui/dialogs/TupletDialog.h"
|
|
#include "gui/dialogs/UseOrnamentDialog.h"
|
|
#include "gui/rulers/StandardRuler.h"
|
|
#include "gui/general/ActiveItem.h"
|
|
#include "gui/general/ClefIndex.h"
|
|
#include "gui/general/EditViewBase.h"
|
|
#include "gui/general/EditView.h"
|
|
#include "gui/general/GUIPalette.h"
|
|
#include "gui/general/LinedStaff.h"
|
|
#include "gui/general/LinedStaffManager.h"
|
|
#include "gui/general/ProgressReporter.h"
|
|
#include "gui/general/PresetHandlerDialog.h"
|
|
#include "gui/general/RosegardenCanvasView.h"
|
|
#include "gui/kdeext/KTmpStatusMsg.h"
|
|
#include "gui/kdeext/QCanvasSimpleSprite.h"
|
|
#include "gui/rulers/ChordNameRuler.h"
|
|
#include "gui/rulers/RawNoteRuler.h"
|
|
#include "gui/rulers/TempoRuler.h"
|
|
#include "gui/rulers/LoopRuler.h"
|
|
#include "gui/studio/StudioControl.h"
|
|
#include "gui/dialogs/EventFilterDialog.h"
|
|
#include "gui/widgets/ProgressBar.h"
|
|
#include "gui/widgets/ProgressDialog.h"
|
|
#include "gui/widgets/ScrollBoxDialog.h"
|
|
#include "gui/widgets/ScrollBox.h"
|
|
#include "gui/widgets/QDeferScrollView.h"
|
|
#include "NotationCanvasView.h"
|
|
#include "NotationElement.h"
|
|
#include "NotationEraser.h"
|
|
#include "NotationHLayout.h"
|
|
#include "NotationProperties.h"
|
|
#include "NotationSelector.h"
|
|
#include "NotationStaff.h"
|
|
#include "NotationStrings.h"
|
|
#include "NotationToolBox.h"
|
|
#include "NotationVLayout.h"
|
|
#include "NoteFontFactory.h"
|
|
#include "NoteInserter.h"
|
|
#include "NotePixmapFactory.h"
|
|
#include "NoteStyleFactory.h"
|
|
#include "NoteStyle.h"
|
|
#include "RestInserter.h"
|
|
#include "sound/MappedEvent.h"
|
|
#include "TextInserter.h"
|
|
#include "HeadersGroup.h"
|
|
#include <tdeaction.h>
|
|
#include <kcombobox.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdeglobal.h>
|
|
#include <klineeditdlg.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kprinter.h>
|
|
#include <kprocess.h>
|
|
#include <kprogress.h>
|
|
#include <kstatusbar.h>
|
|
#include <kstdaction.h>
|
|
#include <tdetempfile.h>
|
|
#include <tdetoolbar.h>
|
|
#include <kxmlguiclient.h>
|
|
#include <tqbrush.h>
|
|
#include <tqcanvas.h>
|
|
#include <tqcursor.h>
|
|
#include <tqdialog.h>
|
|
#include <tqevent.h>
|
|
#include <tqfont.h>
|
|
#include <tqfontmetrics.h>
|
|
#include <tqhbox.h>
|
|
#include <tqiconset.h>
|
|
#include <tqlabel.h>
|
|
#include <tqobject.h>
|
|
#include <tqpaintdevicemetrics.h>
|
|
#include <tqpainter.h>
|
|
#include <tqpixmap.h>
|
|
#include <tqpoint.h>
|
|
#include <tqprinter.h>
|
|
#include <tqrect.h>
|
|
#include <tqregexp.h>
|
|
#include <tqsize.h>
|
|
#include <tqstring.h>
|
|
#include <tqtimer.h>
|
|
#include <tqwidget.h>
|
|
#include <tqvalidator.h>
|
|
#include <algorithm>
|
|
#include <tqpushbutton.h>
|
|
#include <tqtooltip.h>
|
|
|
|
|
|
namespace Rosegarden
|
|
{
|
|
|
|
class NoteActionData
|
|
{
|
|
public:
|
|
NoteActionData();
|
|
NoteActionData(const TQString& _title,
|
|
TQString _actionName,
|
|
TQString _pixmapName,
|
|
int _keycode,
|
|
bool _rest,
|
|
Note::Type _noteType,
|
|
int _dots);
|
|
|
|
TQString title;
|
|
TQString actionName;
|
|
TQString pixmapName;
|
|
int keycode;
|
|
bool rest;
|
|
Note::Type noteType;
|
|
int dots;
|
|
};
|
|
|
|
NoteActionData::NoteActionData()
|
|
: title(0),
|
|
actionName(0),
|
|
pixmapName(0),
|
|
keycode(0),
|
|
rest(false),
|
|
noteType(0),
|
|
dots(0)
|
|
{
|
|
}
|
|
|
|
NoteActionData::NoteActionData(const TQString& _title,
|
|
TQString _actionName,
|
|
TQString _pixmapName,
|
|
int _keycode,
|
|
bool _rest,
|
|
Note::Type _noteType,
|
|
int _dots)
|
|
: title(_title),
|
|
actionName(_actionName),
|
|
pixmapName(_pixmapName),
|
|
keycode(_keycode),
|
|
rest(_rest),
|
|
noteType(_noteType),
|
|
dots(_dots)
|
|
{
|
|
}
|
|
|
|
|
|
class NoteChangeActionData
|
|
{
|
|
public:
|
|
NoteChangeActionData();
|
|
NoteChangeActionData(const TQString &_title,
|
|
TQString _actionName,
|
|
TQString _pixmapName,
|
|
int _keycode,
|
|
bool _notationOnly,
|
|
Note::Type _noteType);
|
|
|
|
TQString title;
|
|
TQString actionName;
|
|
TQString pixmapName;
|
|
int keycode;
|
|
bool notationOnly;
|
|
Note::Type noteType;
|
|
};
|
|
|
|
NoteChangeActionData::NoteChangeActionData()
|
|
: title(0),
|
|
actionName(0),
|
|
pixmapName(0),
|
|
keycode(0),
|
|
notationOnly(false),
|
|
noteType(0)
|
|
{
|
|
}
|
|
|
|
NoteChangeActionData::NoteChangeActionData(const TQString& _title,
|
|
TQString _actionName,
|
|
TQString _pixmapName,
|
|
int _keycode,
|
|
bool _notationOnly,
|
|
Note::Type _noteType)
|
|
: title(_title),
|
|
actionName(_actionName),
|
|
pixmapName(_pixmapName),
|
|
keycode(_keycode),
|
|
notationOnly(_notationOnly),
|
|
noteType(_noteType)
|
|
{
|
|
}
|
|
|
|
|
|
class MarkActionData
|
|
{
|
|
public:
|
|
MarkActionData() :
|
|
title(0),
|
|
actionName(0),
|
|
keycode(0) { }
|
|
|
|
MarkActionData(const TQString &_title,
|
|
TQString _actionName,
|
|
int _keycode,
|
|
Mark _mark) :
|
|
title(_title),
|
|
actionName(_actionName),
|
|
keycode(_keycode),
|
|
mark(_mark) { }
|
|
|
|
TQString title;
|
|
TQString actionName;
|
|
int keycode;
|
|
Mark mark;
|
|
};
|
|
|
|
|
|
NotationView::NotationView(RosegardenGUIDoc *doc,
|
|
std::vector<Segment *> segments,
|
|
TQWidget *parent,
|
|
bool showProgressive) :
|
|
EditView(doc, segments, 2, parent, "notationview"),
|
|
m_properties(getViewLocalPropertyPrefix()),
|
|
m_selectionCounter(0),
|
|
m_insertModeLabel(0),
|
|
m_annotationsLabel(0),
|
|
m_lilyPondDirectivesLabel(0),
|
|
m_progressBar(0),
|
|
m_currentNotePixmap(0),
|
|
m_hoveredOverNoteName(0),
|
|
m_hoveredOverAbsoluteTime(0),
|
|
m_currentStaff( -1),
|
|
m_lastFinishingStaff( -1),
|
|
m_title(0),
|
|
m_subtitle(0),
|
|
m_composer(0),
|
|
m_copyright(0),
|
|
m_insertionTime(0),
|
|
m_deferredCursorMove(NoCursorMoveNeeded),
|
|
m_lastNoteAction("crotchet"),
|
|
m_fontName(NoteFontFactory::getDefaultFontName()),
|
|
m_fontSize(NoteFontFactory::getDefaultSize(m_fontName)),
|
|
m_pageMode(LinedStaff::LinearMode),
|
|
m_leftGutter(20),
|
|
m_notePixmapFactory(new NotePixmapFactory(m_fontName, m_fontSize)),
|
|
m_hlayout(new NotationHLayout(&doc->getComposition(), m_notePixmapFactory,
|
|
m_properties, TQT_TQOBJECT(this))),
|
|
m_vlayout(new NotationVLayout(&doc->getComposition(), m_notePixmapFactory,
|
|
m_properties, TQT_TQOBJECT(this))),
|
|
m_chordNameRuler(0),
|
|
m_tempoRuler(0),
|
|
m_rawNoteRuler(0),
|
|
m_annotationsVisible(false),
|
|
m_lilyPondDirectivesVisible(false),
|
|
m_selectDefaultNote(0),
|
|
m_fontCombo(0),
|
|
m_fontSizeCombo(0),
|
|
m_spacingCombo(0),
|
|
m_fontSizeActionMenu(0),
|
|
m_pannerDialog(new ScrollBoxDialog(this, ScrollBox::FixHeight)),
|
|
m_renderTimer(0),
|
|
m_playTracking(true),
|
|
m_progressDisplayer(PROGRESS_NONE),
|
|
m_inhibitRefresh(true),
|
|
m_ok(false),
|
|
m_printMode(false),
|
|
m_printSize(8), // set in positionStaffs
|
|
m_showHeadersGroup(0),
|
|
m_headersGroupView(0),
|
|
m_headersGroup(0),
|
|
m_headersTopFrame(0),
|
|
m_showHeadersMenuEntry(0)
|
|
{
|
|
initActionDataMaps(); // does something only the 1st time it's called
|
|
|
|
m_toolBox = new NotationToolBox(this);
|
|
|
|
assert(segments.size() > 0);
|
|
NOTATION_DEBUG << "NotationView ctor" << endl;
|
|
|
|
|
|
// Initialise the display-related defaults that will be needed
|
|
// by both the actions and the layout toolbar
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
|
|
m_showHeadersGroup = m_config->readNumEntry("shownotationheader",
|
|
HeadersGroup::DefaultShowMode);
|
|
|
|
m_fontName = qstrtostr(m_config->readEntry
|
|
("notefont",
|
|
strtoqstr(NoteFontFactory::getDefaultFontName())));
|
|
|
|
try
|
|
{
|
|
(void)NoteFontFactory::getFont
|
|
(m_fontName,
|
|
NoteFontFactory::getDefaultSize(m_fontName));
|
|
} catch (Exception e)
|
|
{
|
|
m_fontName = NoteFontFactory::getDefaultFontName();
|
|
}
|
|
|
|
m_fontSize = m_config->readUnsignedNumEntry
|
|
((segments.size() > 1 ? "multistaffnotesize" : "singlestaffnotesize"),
|
|
NoteFontFactory::getDefaultSize(m_fontName));
|
|
|
|
int defaultSpacing = m_config->readNumEntry("spacing", 100);
|
|
m_hlayout->setSpacing(defaultSpacing);
|
|
|
|
int defaultProportion = m_config->readNumEntry("proportion", 60);
|
|
m_hlayout->setProportion(defaultProportion);
|
|
|
|
delete m_notePixmapFactory;
|
|
m_notePixmapFactory = new NotePixmapFactory(m_fontName, m_fontSize);
|
|
m_hlayout->setNotePixmapFactory(m_notePixmapFactory);
|
|
m_vlayout->setNotePixmapFactory(m_notePixmapFactory);
|
|
|
|
setupActions();
|
|
// setupAddControlRulerMenu(); - too early for notation, moved to end of ctor.
|
|
initLayoutToolbar();
|
|
initStatusBar();
|
|
|
|
setBackgroundMode(PaletteBase);
|
|
|
|
TQCanvas *tCanvas = new TQCanvas(TQT_TQOBJECT(this));
|
|
tCanvas->resize(width() * 2, height() * 2);
|
|
|
|
setCanvasView(new NotationCanvasView(*this, tCanvas, getCentralWidget()));
|
|
|
|
updateViewCaption();
|
|
|
|
m_chordNameRuler = new ChordNameRuler
|
|
(m_hlayout, doc, segments, m_leftGutter, 20, getCentralWidget());
|
|
addRuler(m_chordNameRuler);
|
|
if (showProgressive)
|
|
m_chordNameRuler->show();
|
|
|
|
m_tempoRuler = new TempoRuler
|
|
(m_hlayout, doc, this, m_leftGutter, 24, false, getCentralWidget());
|
|
addRuler(m_tempoRuler);
|
|
m_tempoRuler->hide();
|
|
static_cast<TempoRuler *>(m_tempoRuler)->connectSignals();
|
|
|
|
m_rawNoteRuler = new RawNoteRuler
|
|
(m_hlayout, segments[0], m_leftGutter, 20, getCentralWidget());
|
|
addRuler(m_rawNoteRuler);
|
|
m_rawNoteRuler->show();
|
|
|
|
// All toolbars should be created before this is called
|
|
setAutoSaveSettings("NotationView", true);
|
|
|
|
// All rulers must have been created before this is called,
|
|
// or the program will crash
|
|
readOptions();
|
|
|
|
|
|
setBottomStandardRuler(new StandardRuler(getDocument(), m_hlayout, m_leftGutter, 25,
|
|
true, getBottomWidget()));
|
|
|
|
for (unsigned int i = 0; i < segments.size(); ++i)
|
|
{
|
|
m_staffs.push_back(new NotationStaff
|
|
(canvas(), segments[i], 0, // snap
|
|
i, this,
|
|
m_fontName, m_fontSize));
|
|
}
|
|
|
|
|
|
// HeadersGroup ctor must not be called before m_staffs initialization
|
|
m_headersGroupView = new QDeferScrollView(getCentralWidget());
|
|
TQWidget * vport = m_headersGroupView->viewport();
|
|
m_headersGroup = new HeadersGroup(vport, this, &doc->getComposition());
|
|
m_headersGroupView->setVScrollBarMode(TQScrollView::AlwaysOff);
|
|
m_headersGroupView->setHScrollBarMode(TQScrollView::AlwaysOff);
|
|
m_headersGroupView->setFixedWidth(m_headersGroupView->contentsWidth());
|
|
m_canvasView->setLeftFixedWidget(m_headersGroupView);
|
|
|
|
// Add a close button just above the track headers.
|
|
// The grid layout is only here to maintain the button in a
|
|
// right place
|
|
m_headersTopFrame = new TQFrame(getCentralWidget());
|
|
TQGridLayout * headersTopGrid
|
|
= new TQGridLayout(m_headersTopFrame, 2, 2);
|
|
TQString pixmapDir = TDEGlobal::dirs()->findResource("appdata", "pixmaps/");
|
|
TQCanvasPixmap pixmap(pixmapDir + "/misc/close.xpm");
|
|
TQPushButton * hideHeadersButton
|
|
= new TQPushButton(m_headersTopFrame);
|
|
headersTopGrid->addWidget(hideHeadersButton, 1, 1,
|
|
TQt::AlignRight | TQt::AlignBottom);
|
|
hideHeadersButton->setIconSet(TQIconSet(pixmap));
|
|
hideHeadersButton->setFlat(true);
|
|
TQToolTip::add(hideHeadersButton, i18n("Close track headers"));
|
|
headersTopGrid->setMargin(4);
|
|
setTopStandardRuler(new StandardRuler(getDocument(),
|
|
m_hlayout, m_leftGutter, 25,
|
|
false, getCentralWidget()), m_headersTopFrame);
|
|
|
|
m_topStandardRuler->getLoopRuler()->setBackgroundColor
|
|
(GUIPalette::getColour(GUIPalette::InsertCursorRuler));
|
|
|
|
connect(m_topStandardRuler->getLoopRuler(), TQT_SIGNAL(startMouseMove(int)),
|
|
m_canvasView, TQT_SLOT(startAutoScroll(int)));
|
|
connect(m_topStandardRuler->getLoopRuler(), TQT_SIGNAL(stopMouseMove()),
|
|
m_canvasView, TQT_SLOT(stopAutoScroll()));
|
|
|
|
connect(m_bottomStandardRuler->getLoopRuler(), TQT_SIGNAL(startMouseMove(int)),
|
|
m_canvasView, TQT_SLOT(startAutoScroll(int)));
|
|
connect(m_bottomStandardRuler->getLoopRuler(), TQT_SIGNAL(stopMouseMove()),
|
|
m_canvasView, TQT_SLOT(stopAutoScroll()));
|
|
|
|
// Following connection have to be done before calling setPageMode())
|
|
connect(m_headersGroup, TQT_SIGNAL(headersResized(int)),
|
|
this, TQT_SLOT(slotHeadersWidthChanged(int)));
|
|
|
|
|
|
//
|
|
// layout
|
|
//
|
|
ProgressDialog* progressDlg = 0;
|
|
|
|
if (showProgressive)
|
|
{
|
|
show();
|
|
ProgressDialog::processEvents();
|
|
|
|
NOTATION_DEBUG << "NotationView : setting up progress dialog" << endl;
|
|
|
|
progressDlg = new ProgressDialog(i18n("Starting..."),
|
|
100, this);
|
|
progressDlg->setAutoClose(false);
|
|
progressDlg->setAutoReset(true);
|
|
progressDlg->setMinimumDuration(1000);
|
|
setupProgress(progressDlg);
|
|
|
|
m_progressDisplayer = PROGRESS_DIALOG;
|
|
}
|
|
|
|
m_chordNameRuler->setStudio(&getDocument()->getStudio());
|
|
|
|
m_currentStaff = 0;
|
|
m_staffs[0]->setCurrent(true);
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
int layoutMode = m_config->readNumEntry("layoutmode", 0);
|
|
|
|
try
|
|
{
|
|
|
|
LinedStaff::PageMode mode = LinedStaff::LinearMode;
|
|
if (layoutMode == 1)
|
|
mode = LinedStaff::ContinuousPageMode;
|
|
else if (layoutMode == 2)
|
|
mode = LinedStaff::MultiPageMode;
|
|
|
|
setPageMode(mode);
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->getSegment().getRefreshStatus
|
|
(m_segmentsRefreshStatusIds[i]).setNeedsRefresh(false);
|
|
}
|
|
|
|
m_ok = true;
|
|
|
|
} catch (ProgressReporter::Cancelled c)
|
|
{
|
|
// when cancelled, m_ok is false -- checked by calling method
|
|
NOTATION_DEBUG << "NotationView ctor : layout Cancelled" << endl;
|
|
}
|
|
|
|
NOTATION_DEBUG << "NotationView ctor : m_ok = " << m_ok << endl;
|
|
|
|
delete progressDlg;
|
|
|
|
// at this point we can return if operation was cancelled
|
|
if (!isOK())
|
|
{
|
|
setOutOfCtor();
|
|
return ;
|
|
}
|
|
|
|
|
|
// otherwise, carry on
|
|
setupDefaultProgress();
|
|
|
|
//
|
|
// Connect signals
|
|
//
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(renderRequired(double, double)),
|
|
this, TQT_SLOT(slotCheckRendered(double, double)));
|
|
|
|
m_topStandardRuler->connectRulerToDocPointer(doc);
|
|
m_bottomStandardRuler->connectRulerToDocPointer(doc);
|
|
|
|
// Disconnect the default connection for this signal from the
|
|
// top ruler, and connect our own instead
|
|
|
|
TQObject::disconnect
|
|
(m_topStandardRuler->getLoopRuler(),
|
|
TQT_SIGNAL(setPointerPosition(timeT)), 0, 0);
|
|
|
|
TQObject::connect
|
|
(m_topStandardRuler->getLoopRuler(),
|
|
TQT_SIGNAL(setPointerPosition(timeT)),
|
|
this, TQT_SLOT(slotSetInsertCursorPosition(timeT)));
|
|
|
|
TQObject::connect
|
|
(m_topStandardRuler,
|
|
TQT_SIGNAL(dragPointerToPosition(timeT)),
|
|
this, TQT_SLOT(slotSetInsertCursorPosition(timeT)));
|
|
|
|
connect(m_bottomStandardRuler, TQT_SIGNAL(dragPointerToPosition(timeT)),
|
|
this, TQT_SLOT(slotSetPointerPosition(timeT)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(itemPressed(int, int, TQMouseEvent*, NotationElement*)),
|
|
this, TQT_SLOT (slotItemPressed(int, int, TQMouseEvent*, NotationElement*)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(activeItemPressed(TQMouseEvent*, TQCanvasItem*)),
|
|
this, TQT_SLOT (slotActiveItemPressed(TQMouseEvent*, TQCanvasItem*)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(nonNotationItemPressed(TQMouseEvent*, TQCanvasItem*)),
|
|
this, TQT_SLOT (slotNonNotationItemPressed(TQMouseEvent*, TQCanvasItem*)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(textItemPressed(TQMouseEvent*, TQCanvasItem*)),
|
|
this, TQT_SLOT (slotTextItemPressed(TQMouseEvent*, TQCanvasItem*)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(mouseMoved(TQMouseEvent*)),
|
|
this, TQT_SLOT (slotMouseMoved(TQMouseEvent*)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(mouseReleased(TQMouseEvent*)),
|
|
this, TQT_SLOT (slotMouseReleased(TQMouseEvent*)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(hoveredOverNoteChanged(const TQString&)),
|
|
this, TQT_SLOT (slotHoveredOverNoteChanged(const TQString&)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(hoveredOverAbsoluteTimeChanged(unsigned int)),
|
|
this, TQT_SLOT (slotHoveredOverAbsoluteTimeChanged(unsigned int)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(zoomIn()), TQT_TQOBJECT(this), TQT_SLOT(slotZoomIn()));
|
|
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(zoomOut()), TQT_TQOBJECT(this), TQT_SLOT(slotZoomOut()));
|
|
|
|
TQObject::connect
|
|
(m_pannerDialog->scrollbox(), TQT_SIGNAL(valueChanged(const TQPoint &)),
|
|
getCanvasView(), TQT_SLOT(slotSetScrollPos(const TQPoint &)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView()->horizontalScrollBar(), TQT_SIGNAL(valueChanged(int)),
|
|
m_pannerDialog->scrollbox(), TQT_SLOT(setViewX(int)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView()->verticalScrollBar(), TQT_SIGNAL(valueChanged(int)),
|
|
m_pannerDialog->scrollbox(), TQT_SLOT(setViewY(int)));
|
|
|
|
TQObject::connect
|
|
(doc, TQT_SIGNAL(pointerPositionChanged(timeT)),
|
|
this, TQT_SLOT(slotSetPointerPosition(timeT)));
|
|
|
|
//
|
|
// Connect vertical scrollbars between canvas and notation header
|
|
TQObject::connect
|
|
(getCanvasView()->verticalScrollBar(), TQT_SIGNAL(valueChanged(int)),
|
|
this, TQT_SLOT(slotVerticalScrollHeadersGroup(int)));
|
|
|
|
TQObject::connect
|
|
(getCanvasView()->verticalScrollBar(), TQT_SIGNAL(sliderMoved(int)),
|
|
this, TQT_SLOT(slotVerticalScrollHeadersGroup(int)));
|
|
|
|
TQObject::connect
|
|
(m_headersGroupView, TQT_SIGNAL(gotWheelEvent(TQWheelEvent*)),
|
|
getCanvasView(), TQT_SLOT(slotExternalWheelEvent(TQWheelEvent*)));
|
|
|
|
// Ensure notation header keeps the right bottom margin when user
|
|
// toggles the canvas view bottom rulers
|
|
connect(getCanvasView(), TQT_SIGNAL(bottomWidgetHeightChanged(int)),
|
|
this, TQT_SLOT(slotCanvasBottomWidgetHeightChanged(int)));
|
|
|
|
// Signal canvas horizontal scroll to notation header
|
|
TQObject::connect
|
|
(getCanvasView(), TQT_SIGNAL(contentsMoving(int, int)),
|
|
this, TQT_SLOT(slotUpdateHeaders(int, int)));
|
|
|
|
// Connect the close notation headers button
|
|
TQObject::connect(hideHeadersButton, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotHideHeadersGroup()));
|
|
|
|
stateChanged("have_selection", KXMLGUIClient::StateReverse);
|
|
stateChanged("have_notes_in_selection", KXMLGUIClient::StateReverse);
|
|
stateChanged("have_rests_in_selection", KXMLGUIClient::StateReverse);
|
|
stateChanged("have_multiple_staffs",
|
|
(m_staffs.size() > 1 ? KXMLGUIClient::StateNoReverse :
|
|
KXMLGUIClient::StateReverse));
|
|
stateChanged("rest_insert_tool_current", KXMLGUIClient::StateReverse);
|
|
slotTestClipboard();
|
|
|
|
if (getSegmentsOnlyRestsAndClefs())
|
|
{
|
|
m_selectDefaultNote->activate();
|
|
stateChanged("note_insert_tool_current",
|
|
KXMLGUIClient::StateNoReverse);
|
|
} else
|
|
{
|
|
actionCollection()->action("select")->activate();
|
|
stateChanged("note_insert_tool_current",
|
|
KXMLGUIClient::StateReverse);
|
|
}
|
|
|
|
timeT start = doc->getComposition().getLoopStart();
|
|
timeT end = doc->getComposition().getLoopEnd();
|
|
m_topStandardRuler->getLoopRuler()->slotSetLoopMarker(start, end);
|
|
m_bottomStandardRuler->getLoopRuler()->slotSetLoopMarker(start, end);
|
|
|
|
slotSetInsertCursorPosition(0);
|
|
slotSetPointerPosition(doc->getComposition().getPosition());
|
|
setCurrentSelection(0, false, true);
|
|
slotUpdateInsertModeStatus();
|
|
m_chordNameRuler->repaint();
|
|
m_tempoRuler->repaint();
|
|
m_rawNoteRuler->repaint();
|
|
m_inhibitRefresh = false;
|
|
|
|
// slotCheckRendered(0, getCanvasView()->visibleWidth());
|
|
// getCanvasView()->repaintContents();
|
|
updateView();
|
|
|
|
TQObject::connect
|
|
(this, TQT_SIGNAL(renderComplete()),
|
|
getCanvasView(), TQT_SLOT(slotRenderComplete()));
|
|
|
|
if (parent)
|
|
{
|
|
const TrackButtons * trackLabels =
|
|
((RosegardenGUIView*)parent)->getTrackEditor()->getTrackButtons();
|
|
TQObject::connect
|
|
(trackLabels, TQT_SIGNAL(nameChanged()),
|
|
this, TQT_SLOT(slotUpdateStaffName()));
|
|
}
|
|
|
|
setConfigDialogPageIndex(3);
|
|
setOutOfCtor();
|
|
|
|
// Property and Control Rulers
|
|
//
|
|
if (getCurrentSegment()->getViewFeatures())
|
|
slotShowVelocityControlRuler();
|
|
setupControllerTabs();
|
|
|
|
setupAddControlRulerMenu();
|
|
setRewFFwdToAutoRepeat();
|
|
|
|
slotCompositionStateUpdate();
|
|
|
|
NOTATION_DEBUG << "NotationView ctor exiting" << endl;
|
|
}
|
|
|
|
NotationView::NotationView(RosegardenGUIDoc *doc,
|
|
std::vector<Segment *> segments,
|
|
TQWidget *parent,
|
|
NotationView *referenceView)
|
|
: EditView(doc, segments, 1, 0, "printview"),
|
|
m_properties(getViewLocalPropertyPrefix()),
|
|
m_selectionCounter(0),
|
|
m_currentNotePixmap(0),
|
|
m_hoveredOverNoteName(0),
|
|
m_hoveredOverAbsoluteTime(0),
|
|
m_lastFinishingStaff( -1),
|
|
m_title(0),
|
|
m_subtitle(0),
|
|
m_composer(0),
|
|
m_copyright(0),
|
|
m_insertionTime(0),
|
|
m_deferredCursorMove(NoCursorMoveNeeded),
|
|
m_lastNoteAction("crotchet"),
|
|
m_fontName(NoteFontFactory::getDefaultFontName()),
|
|
m_fontSize(NoteFontFactory::getDefaultSize(m_fontName)),
|
|
m_pageMode(LinedStaff::LinearMode),
|
|
m_leftGutter(0),
|
|
m_notePixmapFactory(new NotePixmapFactory(m_fontName, m_fontSize)),
|
|
m_hlayout(new NotationHLayout(&doc->getComposition(), m_notePixmapFactory,
|
|
m_properties, TQT_TQOBJECT(this))),
|
|
m_vlayout(new NotationVLayout(&doc->getComposition(), m_notePixmapFactory,
|
|
m_properties, TQT_TQOBJECT(this))),
|
|
m_chordNameRuler(0),
|
|
m_tempoRuler(0),
|
|
m_rawNoteRuler(0),
|
|
m_annotationsVisible(false),
|
|
m_lilyPondDirectivesVisible(false),
|
|
m_selectDefaultNote(0),
|
|
m_fontCombo(0),
|
|
m_fontSizeCombo(0),
|
|
m_spacingCombo(0),
|
|
m_fontSizeActionMenu(0),
|
|
m_pannerDialog(0),
|
|
m_renderTimer(0),
|
|
m_playTracking(false),
|
|
m_progressDisplayer(PROGRESS_NONE),
|
|
m_inhibitRefresh(true),
|
|
m_ok(false),
|
|
m_printMode(true),
|
|
m_printSize(8), // set in positionStaffs
|
|
m_showHeadersGroup(0),
|
|
m_headersGroupView(0),
|
|
m_headersGroup(0),
|
|
m_headersTopFrame(0),
|
|
m_showHeadersMenuEntry(0)
|
|
{
|
|
assert(segments.size() > 0);
|
|
NOTATION_DEBUG << "NotationView print ctor" << endl;
|
|
|
|
|
|
// Initialise the display-related defaults that will be needed
|
|
// by both the actions and the layout toolbar
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
|
|
if (referenceView)
|
|
{
|
|
m_fontName = referenceView->m_fontName;
|
|
} else
|
|
{
|
|
m_fontName = qstrtostr(m_config->readEntry
|
|
("notefont",
|
|
strtoqstr(NoteFontFactory::getDefaultFontName())));
|
|
}
|
|
|
|
|
|
// Force largest font size
|
|
std::vector<int> sizes = NoteFontFactory::getAllSizes(m_fontName);
|
|
m_fontSize = sizes[sizes.size() - 1];
|
|
|
|
if (referenceView)
|
|
{
|
|
m_hlayout->setSpacing(referenceView->m_hlayout->getSpacing());
|
|
m_hlayout->setProportion(referenceView->m_hlayout->getProportion());
|
|
} else
|
|
{
|
|
int defaultSpacing = m_config->readNumEntry("spacing", 100);
|
|
m_hlayout->setSpacing(defaultSpacing);
|
|
int defaultProportion = m_config->readNumEntry("proportion", 60);
|
|
m_hlayout->setProportion(defaultProportion);
|
|
}
|
|
|
|
delete m_notePixmapFactory;
|
|
m_notePixmapFactory = new NotePixmapFactory(m_fontName, m_fontSize);
|
|
m_hlayout->setNotePixmapFactory(m_notePixmapFactory);
|
|
m_vlayout->setNotePixmapFactory(m_notePixmapFactory);
|
|
|
|
setBackgroundMode(PaletteBase);
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
|
|
TQCanvas *tCanvas = new TQCanvas(TQT_TQOBJECT(this));
|
|
tCanvas->resize(width() * 2, height() * 2); //!!!
|
|
|
|
setCanvasView(new NotationCanvasView(*this, tCanvas, getCentralWidget()));
|
|
canvas()->retune(128); // tune for larger canvas
|
|
|
|
for (unsigned int i = 0; i < segments.size(); ++i)
|
|
{
|
|
m_staffs.push_back(new NotationStaff(canvas(), segments[i], 0, // snap
|
|
i, this,
|
|
m_fontName, m_fontSize));
|
|
}
|
|
|
|
m_currentStaff = 0;
|
|
m_staffs[0]->setCurrent(true);
|
|
|
|
ProgressDialog* progressDlg = 0;
|
|
|
|
if (parent)
|
|
{
|
|
|
|
ProgressDialog::processEvents();
|
|
|
|
NOTATION_DEBUG << "NotationView : setting up progress dialog" << endl;
|
|
|
|
progressDlg = new ProgressDialog(i18n("Preparing to print..."),
|
|
100, parent);
|
|
progressDlg->setAutoClose(false);
|
|
progressDlg->setAutoReset(true);
|
|
progressDlg->setMinimumDuration(1000);
|
|
setupProgress(progressDlg);
|
|
|
|
m_progressDisplayer = PROGRESS_DIALOG;
|
|
}
|
|
|
|
try
|
|
{
|
|
|
|
setPageMode(LinedStaff::MultiPageMode); // also positions and renders the staffs!
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->getSegment().getRefreshStatus
|
|
(m_segmentsRefreshStatusIds[i]).setNeedsRefresh(false);
|
|
}
|
|
|
|
m_ok = true;
|
|
|
|
} catch (ProgressReporter::Cancelled c)
|
|
{
|
|
// when cancelled, m_ok is false -- checked by calling method
|
|
NOTATION_DEBUG << "NotationView ctor : layout Cancelled" << endl;
|
|
}
|
|
|
|
NOTATION_DEBUG << "NotationView ctor : m_ok = " << m_ok << endl;
|
|
|
|
delete progressDlg;
|
|
|
|
if (!isOK())
|
|
{
|
|
setOutOfCtor();
|
|
return ; // In case more code is added there later
|
|
}
|
|
|
|
setOutOfCtor(); // keep this as last call in the ctor
|
|
}
|
|
|
|
NotationView::~NotationView()
|
|
{
|
|
NOTATION_DEBUG << "-> ~NotationView()" << endl;
|
|
|
|
if (!m_printMode && m_ok)
|
|
slotSaveOptions();
|
|
|
|
delete m_chordNameRuler;
|
|
|
|
delete m_renderTimer;
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
for (Segment::iterator j = m_staffs[i]->getSegment().begin();
|
|
j != m_staffs[i]->getSegment().end(); ++j) {
|
|
removeViewLocalProperties(*j);
|
|
}
|
|
delete m_staffs[i]; // this will erase all "notes" canvas items
|
|
}
|
|
|
|
PixmapArrayGC::deleteAll();
|
|
Profiles::getInstance()->dump();
|
|
|
|
NOTATION_DEBUG << "<- ~NotationView()" << endl;
|
|
}
|
|
|
|
void
|
|
NotationView::removeViewLocalProperties(Event *e)
|
|
{
|
|
Event::PropertyNames names(e->getPropertyNames());
|
|
std::string prefix(getViewLocalPropertyPrefix());
|
|
|
|
for (Event::PropertyNames::iterator i = names.begin();
|
|
i != names.end(); ++i) {
|
|
if (i->getName().substr(0, prefix.size()) == prefix) {
|
|
e->unset(*i);
|
|
}
|
|
}
|
|
}
|
|
|
|
const NotationProperties &
|
|
NotationView::getProperties() const
|
|
{
|
|
return m_properties;
|
|
}
|
|
|
|
void NotationView::positionStaffs()
|
|
{
|
|
NOTATION_DEBUG << "NotationView::positionStaffs" << endl;
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
m_printSize = m_config->readUnsignedNumEntry("printingnotesize", 5);
|
|
|
|
int minTrack = 0, maxTrack = 0;
|
|
bool haveMinTrack = false;
|
|
typedef std::map<int, int> TrackIntMap;
|
|
TrackIntMap trackHeights;
|
|
TrackIntMap trackCoords;
|
|
|
|
int pageWidth, pageHeight, leftMargin, topMargin;
|
|
pageWidth = getPageWidth();
|
|
pageHeight = getPageHeight();
|
|
leftMargin = 0, topMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
|
|
int accumulatedHeight;
|
|
int rowsPerPage = 1;
|
|
int legerLines = 8;
|
|
if (m_pageMode != LinedStaff::LinearMode)
|
|
legerLines = 7;
|
|
int rowGapPercent = (m_staffs.size() > 1 ? 40 : 10);
|
|
int aimFor = -1;
|
|
|
|
bool done = false;
|
|
|
|
int titleHeight = 0;
|
|
|
|
if (m_title)
|
|
delete m_title;
|
|
if (m_subtitle)
|
|
delete m_subtitle;
|
|
if (m_composer)
|
|
delete m_composer;
|
|
if (m_copyright)
|
|
delete m_copyright;
|
|
m_title = m_subtitle = m_composer = m_copyright = 0;
|
|
|
|
if (m_pageMode == LinedStaff::MultiPageMode) {
|
|
|
|
const Configuration &metadata =
|
|
getDocument()->getComposition().getMetadata();
|
|
|
|
TQFont defaultFont(NotePixmapFactory::defaultSerifFontFamily);
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
TQFont font = m_config->readFontEntry("textfont", &defaultFont);
|
|
font.setPixelSize(m_fontSize * 5);
|
|
TQFontMetrics metrics(font);
|
|
|
|
if (metadata.has(CompositionMetadataKeys::Title)) {
|
|
TQString title(strtoqstr(metadata.get<String>
|
|
(CompositionMetadataKeys::Title)));
|
|
m_title = new TQCanvasText(title, font, canvas());
|
|
m_title->setX(m_leftGutter + pageWidth / 2 - metrics.width(title) / 2);
|
|
m_title->setY(20 + topMargin / 4 + metrics.ascent());
|
|
m_title->show();
|
|
titleHeight += metrics.height() * 3 / 2 + topMargin / 4;
|
|
}
|
|
|
|
font.setPixelSize(m_fontSize * 3);
|
|
metrics = TQFontMetrics(font);
|
|
|
|
if (metadata.has(CompositionMetadataKeys::Subtitle)) {
|
|
TQString subtitle(strtoqstr(metadata.get<String>
|
|
(CompositionMetadataKeys::Subtitle)));
|
|
m_subtitle = new TQCanvasText(subtitle, font, canvas());
|
|
m_subtitle->setX(m_leftGutter + pageWidth / 2 - metrics.width(subtitle) / 2);
|
|
m_subtitle->setY(20 + titleHeight + metrics.ascent());
|
|
m_subtitle->show();
|
|
titleHeight += metrics.height() * 3 / 2;
|
|
}
|
|
|
|
if (metadata.has(CompositionMetadataKeys::Composer)) {
|
|
TQString composer(strtoqstr(metadata.get<String>
|
|
(CompositionMetadataKeys::Composer)));
|
|
m_composer = new TQCanvasText(composer, font, canvas());
|
|
m_composer->setX(m_leftGutter + pageWidth - metrics.width(composer) - leftMargin);
|
|
m_composer->setY(20 + titleHeight + metrics.ascent());
|
|
m_composer->show();
|
|
titleHeight += metrics.height() * 3 / 2;
|
|
}
|
|
|
|
font.setPixelSize(m_fontSize * 2);
|
|
metrics = TQFontMetrics(font);
|
|
|
|
if (metadata.has(CompositionMetadataKeys::Copyright)) {
|
|
TQString copyright(strtoqstr(metadata.get<String>
|
|
(CompositionMetadataKeys::Copyright)));
|
|
m_copyright = new TQCanvasText(copyright, font, canvas());
|
|
m_copyright->setX(m_leftGutter + leftMargin);
|
|
m_copyright->setY(20 + pageHeight - topMargin - metrics.descent());
|
|
m_copyright->show();
|
|
}
|
|
}
|
|
|
|
while (1) {
|
|
|
|
accumulatedHeight = 0;
|
|
int maxTrackHeight = 0;
|
|
|
|
trackHeights.clear();
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
m_staffs[i]->setLegerLineCount(legerLines);
|
|
|
|
int height = m_staffs[i]->getHeightOfRow();
|
|
TrackId trackId = m_staffs[i]->getSegment().getTrack();
|
|
Track *track =
|
|
m_staffs[i]->getSegment().getComposition()->
|
|
getTrackById(trackId);
|
|
|
|
if (!track)
|
|
continue; // This Should Not Happen, My Friend
|
|
|
|
int trackPosition = track->getPosition();
|
|
|
|
TrackIntMap::iterator hi = trackHeights.find(trackPosition);
|
|
if (hi == trackHeights.end()) {
|
|
trackHeights.insert(TrackIntMap::value_type
|
|
(trackPosition, height));
|
|
} else if (height > hi->second) {
|
|
hi->second = height;
|
|
}
|
|
|
|
if (height > maxTrackHeight)
|
|
maxTrackHeight = height;
|
|
|
|
if (trackPosition < minTrack || !haveMinTrack) {
|
|
minTrack = trackPosition;
|
|
haveMinTrack = true;
|
|
}
|
|
if (trackPosition > maxTrack) {
|
|
maxTrack = trackPosition;
|
|
}
|
|
}
|
|
|
|
for (int i = minTrack; i <= maxTrack; ++i) {
|
|
TrackIntMap::iterator hi = trackHeights.find(i);
|
|
if (hi != trackHeights.end()) {
|
|
trackCoords[i] = accumulatedHeight;
|
|
accumulatedHeight += hi->second;
|
|
}
|
|
}
|
|
|
|
accumulatedHeight += maxTrackHeight * rowGapPercent / 100;
|
|
|
|
if (done)
|
|
break;
|
|
|
|
if (m_pageMode != LinedStaff::MultiPageMode) {
|
|
|
|
rowsPerPage = 0;
|
|
done = true;
|
|
break;
|
|
|
|
} else {
|
|
|
|
// Check how well all this stuff actually fits on the
|
|
// page. If things don't fit as well as we'd like, modify
|
|
// at most one parameter so as to save some space, then
|
|
// loop around again and see if it worked. This iterative
|
|
// approach is inefficient but the time spent here is
|
|
// neglible in context, and it's a simple way to code it.
|
|
|
|
int staffPageHeight = pageHeight - topMargin * 2 - titleHeight;
|
|
rowsPerPage = staffPageHeight / accumulatedHeight;
|
|
|
|
if (rowsPerPage < 1) {
|
|
|
|
if (legerLines > 5)
|
|
--legerLines;
|
|
else if (rowGapPercent > 20)
|
|
rowGapPercent -= 10;
|
|
else if (legerLines > 4)
|
|
--legerLines;
|
|
else if (rowGapPercent > 0)
|
|
rowGapPercent -= 10;
|
|
else if (legerLines > 3)
|
|
--legerLines;
|
|
else if (m_printSize > 3)
|
|
--m_printSize;
|
|
else { // just accept that we'll have to overflow
|
|
rowsPerPage = 1;
|
|
done = true;
|
|
}
|
|
|
|
} else {
|
|
|
|
if (aimFor == rowsPerPage) {
|
|
|
|
titleHeight +=
|
|
(staffPageHeight - (rowsPerPage * accumulatedHeight)) / 2;
|
|
|
|
done = true;
|
|
|
|
} else {
|
|
|
|
if (aimFor == -1)
|
|
aimFor = rowsPerPage + 1;
|
|
|
|
// we can perhaps accommodate another row, with care
|
|
if (legerLines > 5)
|
|
--legerLines;
|
|
else if (rowGapPercent > 20)
|
|
rowGapPercent -= 10;
|
|
else if (legerLines > 3)
|
|
--legerLines;
|
|
else if (rowGapPercent > 0)
|
|
rowGapPercent -= 10;
|
|
else { // no, we can't
|
|
rowGapPercent = 0;
|
|
legerLines = 8;
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_hlayout->setPageWidth(pageWidth - leftMargin * 2);
|
|
|
|
int topGutter = 0;
|
|
|
|
if (m_pageMode == LinedStaff::MultiPageMode) {
|
|
|
|
topGutter = 20;
|
|
|
|
} else if (m_pageMode == LinedStaff::ContinuousPageMode) {
|
|
|
|
// fewer leger lines above staff than in linear mode --
|
|
// compensate for this on the top staff
|
|
topGutter = m_notePixmapFactory->getLineSpacing() * 2;
|
|
}
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
TrackId trackId = m_staffs[i]->getSegment().getTrack();
|
|
Track *track =
|
|
m_staffs[i]->getSegment().getComposition()->
|
|
getTrackById(trackId);
|
|
|
|
if (!track)
|
|
continue; // Once Again, My Friend, You Should Never See Me Here
|
|
|
|
int trackPosition = track->getPosition();
|
|
|
|
m_staffs[i]->setTitleHeight(titleHeight);
|
|
m_staffs[i]->setRowSpacing(accumulatedHeight);
|
|
|
|
if (trackPosition < maxTrack) {
|
|
m_staffs[i]->setConnectingLineLength(trackHeights[trackPosition]);
|
|
}
|
|
|
|
if (trackPosition == minTrack &&
|
|
m_pageMode != LinedStaff::LinearMode) {
|
|
m_staffs[i]->setBarNumbersEvery(5);
|
|
} else {
|
|
m_staffs[i]->setBarNumbersEvery(0);
|
|
}
|
|
|
|
m_staffs[i]->setX(m_leftGutter);
|
|
m_staffs[i]->setY(topGutter + trackCoords[trackPosition] + topMargin);
|
|
m_staffs[i]->setPageWidth(pageWidth - leftMargin * 2);
|
|
m_staffs[i]->setRowsPerPage(rowsPerPage);
|
|
m_staffs[i]->setPageMode(m_pageMode);
|
|
m_staffs[i]->setMargin(leftMargin);
|
|
|
|
NOTATION_DEBUG << "NotationView::positionStaffs: set staff's page width to "
|
|
<< (pageWidth - leftMargin * 2) << endl;
|
|
|
|
}
|
|
|
|
|
|
if (!m_printMode) {
|
|
// Destroy then recreate all track headers
|
|
hideHeadersGroup();
|
|
m_headersGroup->removeAllHeaders();
|
|
if (m_pageMode == LinedStaff::LinearMode) {
|
|
for (int i = minTrack; i <= maxTrack; ++i) {
|
|
TrackIntMap::iterator hi = trackHeights.find(i);
|
|
if (hi != trackHeights.end()) {
|
|
TrackId trackId = getDocument()->getComposition()
|
|
.getTrackByPosition(i)->getId();
|
|
m_headersGroup->addHeader(trackId, trackHeights[i],
|
|
trackCoords[i], getCanvasLeftX());
|
|
}
|
|
}
|
|
|
|
m_headersGroup->completeToHeight(canvas()->height());
|
|
|
|
m_headersGroupView->addChild(m_headersGroup);
|
|
|
|
getCanvasView()->updateLeftWidgetGeometry();
|
|
|
|
if ( (m_showHeadersGroup == HeadersGroup::ShowAlways)
|
|
|| ( (m_showHeadersGroup == HeadersGroup::ShowWhenNeeded)
|
|
&& (m_headersGroup->getUsedHeight()
|
|
> getCanvasView()->visibleHeight()))) {
|
|
m_headersGroup->slotUpdateAllHeaders(getCanvasLeftX(), 0, true);
|
|
showHeadersGroup();
|
|
|
|
// Disable menu entry when headers are shown
|
|
m_showHeadersMenuEntry->setEnabled(false);
|
|
} else {
|
|
// Enable menu entry when headers are hidden
|
|
m_showHeadersMenuEntry->setEnabled(true);
|
|
}
|
|
} else {
|
|
// Disable menu entry when not in linear mode
|
|
m_showHeadersMenuEntry->setEnabled(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotCanvasBottomWidgetHeightChanged(int newHeight)
|
|
{
|
|
getCanvasView()->updateLeftWidgetGeometry();
|
|
}
|
|
|
|
void NotationView::positionPages()
|
|
{
|
|
if (m_printMode)
|
|
return ;
|
|
|
|
TQPixmap background;
|
|
TQPixmap deskBackground;
|
|
bool haveBackground = false;
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
if (m_config->readBoolEntry("backgroundtextures", true)) {
|
|
TQString pixmapDir =
|
|
TDEGlobal::dirs()->findResource("appdata", "pixmaps/");
|
|
if (background.load(TQString("%1/misc/bg-paper-cream.xpm").
|
|
arg(pixmapDir))) {
|
|
haveBackground = true;
|
|
}
|
|
// we're happy to ignore errors from this one:
|
|
deskBackground.load(TQString("%1/misc/bg-desktop.xpm").arg(pixmapDir));
|
|
}
|
|
|
|
int pageWidth = getPageWidth();
|
|
int pageHeight = getPageHeight();
|
|
int leftMargin = 0, topMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
int maxPageCount = 1;
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
int pageCount = m_staffs[i]->getPageCount();
|
|
if (pageCount > maxPageCount)
|
|
maxPageCount = pageCount;
|
|
}
|
|
|
|
for (unsigned int i = 0; i < m_pages.size(); ++i) {
|
|
delete m_pages[i];
|
|
delete m_pageNumbers[i];
|
|
}
|
|
m_pages.clear();
|
|
m_pageNumbers.clear();
|
|
|
|
if (m_pageMode != LinedStaff::MultiPageMode) {
|
|
if (haveBackground) {
|
|
canvas()->setBackgroundPixmap(background);
|
|
getCanvasView()->setBackgroundMode(TQt::FixedPixmap);
|
|
getCanvasView()->setPaletteBackgroundPixmap(background);
|
|
getCanvasView()->setErasePixmap(background);
|
|
}
|
|
} else {
|
|
if (haveBackground) {
|
|
canvas()->setBackgroundPixmap(deskBackground);
|
|
getCanvasView()->setBackgroundMode(TQt::FixedPixmap);
|
|
getCanvasView()->setPaletteBackgroundPixmap(background);
|
|
getCanvasView()->setErasePixmap(background);
|
|
}
|
|
|
|
TQFont pageNumberFont;
|
|
pageNumberFont.setPixelSize(m_fontSize * 2);
|
|
TQFontMetrics pageNumberMetrics(pageNumberFont);
|
|
|
|
for (int page = 0; page < maxPageCount; ++page) {
|
|
|
|
int x = m_leftGutter + pageWidth * page + leftMargin / 4;
|
|
int y = 20;
|
|
int w = pageWidth - leftMargin / 2;
|
|
int h = pageHeight;
|
|
|
|
TQString str = TQString("%1").arg(page + 1);
|
|
TQCanvasText *text = new TQCanvasText(str, pageNumberFont, canvas());
|
|
text->setX(m_leftGutter + pageWidth * page + pageWidth - pageNumberMetrics.width(str) - leftMargin);
|
|
text->setY(y + h - pageNumberMetrics.descent() - topMargin);
|
|
text->setZ( -999);
|
|
text->show();
|
|
m_pageNumbers.push_back(text);
|
|
|
|
TQCanvasRectangle *rect = new TQCanvasRectangle(x, y, w, h, canvas());
|
|
if (haveBackground)
|
|
rect->setBrush(TQBrush(TQt::white, background));
|
|
rect->setPen(TQt::black);
|
|
rect->setZ( -1000);
|
|
rect->show();
|
|
m_pages.push_back(rect);
|
|
}
|
|
|
|
updateThumbnails(false);
|
|
}
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
}
|
|
|
|
void NotationView::slotUpdateStaffName()
|
|
{
|
|
LinedStaff *staff = getLinedStaff(m_currentStaff);
|
|
staff->drawStaffName();
|
|
m_headersGroup->slotUpdateAllHeaders(getCanvasLeftX(), 0, true);
|
|
}
|
|
|
|
void NotationView::slotSaveOptions()
|
|
{
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
|
|
m_config->writeEntry("Show Chord Name Ruler", getToggleAction("show_chords_ruler")->isChecked());
|
|
m_config->writeEntry("Show Raw Note Ruler", getToggleAction("show_raw_note_ruler")->isChecked());
|
|
m_config->writeEntry("Show Tempo Ruler", getToggleAction("show_tempo_ruler")->isChecked());
|
|
m_config->writeEntry("Show Annotations", m_annotationsVisible);
|
|
m_config->writeEntry("Show LilyPond Directives", m_lilyPondDirectivesVisible);
|
|
|
|
m_config->sync();
|
|
}
|
|
|
|
void NotationView::setOneToolbar(const char *actionName,
|
|
const char *toolbarName)
|
|
{
|
|
TDEToggleAction *action = getToggleAction(actionName);
|
|
if (!action) {
|
|
std::cerr << "WARNING: No such action as " << actionName << std::endl;
|
|
return ;
|
|
}
|
|
TQWidget *toolbar = toolBar(toolbarName);
|
|
if (!toolbar) {
|
|
std::cerr << "WARNING: No such toolbar as " << toolbarName << std::endl;
|
|
return ;
|
|
}
|
|
action->setChecked(!toolbar->isHidden());
|
|
}
|
|
|
|
void NotationView::readOptions()
|
|
{
|
|
EditView::readOptions();
|
|
|
|
setOneToolbar("show_tools_toolbar", "Tools Toolbar");
|
|
setOneToolbar("show_notes_toolbar", "Notes Toolbar");
|
|
setOneToolbar("show_rests_toolbar", "Rests Toolbar");
|
|
setOneToolbar("show_clefs_toolbar", "Clefs Toolbar");
|
|
setOneToolbar("show_group_toolbar", "Group Toolbar");
|
|
setOneToolbar("show_marks_toolbar", "Marks Toolbar");
|
|
setOneToolbar("show_layout_toolbar", "Layout Toolbar");
|
|
setOneToolbar("show_transport_toolbar", "Transport Toolbar");
|
|
setOneToolbar("show_accidentals_toolbar", "Accidentals Toolbar");
|
|
setOneToolbar("show_meta_toolbar", "Meta Toolbar");
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
|
|
bool opt;
|
|
|
|
opt = m_config->readBoolEntry("Show Chord Name Ruler", false);
|
|
getToggleAction("show_chords_ruler")->setChecked(opt);
|
|
slotToggleChordsRuler();
|
|
|
|
opt = m_config->readBoolEntry("Show Raw Note Ruler", true);
|
|
getToggleAction("show_raw_note_ruler")->setChecked(opt);
|
|
slotToggleRawNoteRuler();
|
|
|
|
opt = m_config->readBoolEntry("Show Tempo Ruler", true);
|
|
getToggleAction("show_tempo_ruler")->setChecked(opt);
|
|
slotToggleTempoRuler();
|
|
|
|
opt = m_config->readBoolEntry("Show Annotations", true);
|
|
m_annotationsVisible = opt;
|
|
getToggleAction("show_annotations")->setChecked(opt);
|
|
slotUpdateAnnotationsStatus();
|
|
// slotToggleAnnotations();
|
|
|
|
opt = m_config->readBoolEntry("Show LilyPond Directives", true);
|
|
m_lilyPondDirectivesVisible = opt;
|
|
getToggleAction("show_lilypond_directives")->setChecked(opt);
|
|
slotUpdateLilyPondDirectivesStatus();
|
|
}
|
|
|
|
void NotationView::setupActions()
|
|
{
|
|
KStdAction::print(TQT_TQOBJECT(this), TQT_SLOT(slotFilePrint()), actionCollection());
|
|
KStdAction::printPreview(TQT_TQOBJECT(this), TQT_SLOT(slotFilePrintPreview()),
|
|
actionCollection());
|
|
|
|
new TDEAction(i18n("Print &with LilyPond..."), 0, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotPrintLilyPond()), actionCollection(),
|
|
"file_print_lilypond");
|
|
|
|
new TDEAction(i18n("Preview with Lil&yPond..."), 0, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotPreviewLilyPond()), actionCollection(),
|
|
"file_preview_lilypond");
|
|
|
|
EditViewBase::setupActions("notation.rc");
|
|
EditView::setupActions();
|
|
|
|
TDERadioAction* noteAction = 0;
|
|
|
|
// View menu stuff
|
|
|
|
TDEActionMenu *fontActionMenu =
|
|
new TDEActionMenu(i18n("Note &Font"), TQT_TQOBJECT(this), "note_font_actionmenu");
|
|
|
|
std::set
|
|
<std::string> fs(NoteFontFactory::getFontNames());
|
|
std::vector<std::string> f(fs.begin(), fs.end());
|
|
std::sort(f.begin(), f.end());
|
|
|
|
for (std::vector<std::string>::iterator i = f.begin(); i != f.end(); ++i) {
|
|
|
|
TQString fontTQName(strtoqstr(*i));
|
|
|
|
TDEToggleAction *fontAction =
|
|
new TDEToggleAction
|
|
(fontTQName, 0, TQT_TQOBJECT(this), TQT_SLOT(slotChangeFontFromAction()),
|
|
actionCollection(), TQString("note_font_" + fontTQName).ascii());
|
|
|
|
fontAction->setChecked(*i == m_fontName);
|
|
fontActionMenu->insert(fontAction);
|
|
}
|
|
|
|
actionCollection()->insert(fontActionMenu);
|
|
|
|
m_fontSizeActionMenu =
|
|
new TDEActionMenu(i18n("Si&ze"), TQT_TQOBJECT(this), "note_font_size_actionmenu");
|
|
setupFontSizeMenu();
|
|
|
|
actionCollection()->insert(m_fontSizeActionMenu);
|
|
|
|
m_showHeadersMenuEntry
|
|
= new TDEAction(i18n("Show Track Headers"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotShowHeadersGroup()),
|
|
actionCollection(), "show_track_headers");
|
|
|
|
TDEActionMenu *spacingActionMenu =
|
|
new TDEActionMenu(i18n("S&pacing"), TQT_TQOBJECT(this), "stretch_actionmenu");
|
|
|
|
int defaultSpacing = m_hlayout->getSpacing();
|
|
std::vector<int> spacings = NotationHLayout::getAvailableSpacings();
|
|
|
|
for (std::vector<int>::iterator i = spacings.begin();
|
|
i != spacings.end(); ++i) {
|
|
|
|
TDEToggleAction *spacingAction =
|
|
new TDEToggleAction
|
|
(TQString("%1%").arg(*i), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotChangeSpacingFromAction()),
|
|
actionCollection(), TQString("spacing_%1").arg(*i).ascii());
|
|
|
|
spacingAction->setExclusiveGroup("spacing");
|
|
spacingAction->setChecked(*i == defaultSpacing);
|
|
spacingActionMenu->insert(spacingAction);
|
|
}
|
|
|
|
actionCollection()->insert(spacingActionMenu);
|
|
|
|
TDEActionMenu *proportionActionMenu =
|
|
new TDEActionMenu(i18n("Du&ration Factor"), TQT_TQOBJECT(this), "proportion_actionmenu");
|
|
|
|
int defaultProportion = m_hlayout->getProportion();
|
|
std::vector<int> proportions = NotationHLayout::getAvailableProportions();
|
|
|
|
for (std::vector<int>::iterator i = proportions.begin();
|
|
i != proportions.end(); ++i) {
|
|
|
|
TQString name = TQString("%1%").arg(*i);
|
|
if (*i == 0)
|
|
name = i18n("None");
|
|
|
|
TDEToggleAction *proportionAction =
|
|
new TDEToggleAction
|
|
(name, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotChangeProportionFromAction()),
|
|
actionCollection(), TQString("proportion_%1").arg(*i).ascii());
|
|
|
|
proportionAction->setExclusiveGroup("proportion");
|
|
proportionAction->setChecked(*i == defaultProportion);
|
|
proportionActionMenu->insert(proportionAction);
|
|
}
|
|
|
|
actionCollection()->insert(proportionActionMenu);
|
|
|
|
TDEActionMenu *styleActionMenu =
|
|
new TDEActionMenu(i18n("Note &Style"), TQT_TQOBJECT(this), "note_style_actionmenu");
|
|
|
|
std::vector<NoteStyleName> styles
|
|
(NoteStyleFactory::getAvailableStyleNames());
|
|
|
|
for (std::vector<NoteStyleName>::iterator i = styles.begin();
|
|
i != styles.end(); ++i) {
|
|
|
|
TQString styleTQName(strtoqstr(*i));
|
|
|
|
TDEAction *styleAction =
|
|
new TDEAction
|
|
(styleTQName, 0, TQT_TQOBJECT(this), TQT_SLOT(slotSetStyleFromAction()),
|
|
actionCollection(), TQString("style_" + styleTQName).ascii());
|
|
|
|
styleActionMenu->insert(styleAction);
|
|
}
|
|
|
|
actionCollection()->insert(styleActionMenu);
|
|
|
|
TDEActionMenu *ornamentActionMenu =
|
|
new TDEActionMenu(i18n("Use Ornament"), TQT_TQOBJECT(this), "ornament_actionmenu");
|
|
|
|
|
|
|
|
new TDEAction
|
|
(i18n("Insert Rest"), Key_P, TQT_TQOBJECT(this), TQT_SLOT(slotInsertRest()),
|
|
actionCollection(), TQString("insert_rest").ascii());
|
|
|
|
new TDEAction
|
|
(i18n("Switch from Note to Rest"), Key_T, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotSwitchFromNoteToRest()),
|
|
actionCollection(), TQString("switch_from_note_to_rest").ascii());
|
|
|
|
new TDEAction
|
|
(i18n("Switch from Rest to Note"), Key_Y, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotSwitchFromRestToNote()),
|
|
actionCollection(), TQString("switch_from_rest_to_note").ascii());
|
|
|
|
|
|
// setup Notes menu & toolbar
|
|
TQIconSet icon;
|
|
|
|
for (NoteActionDataMap::Iterator actionDataIter = m_noteActionDataMap->begin();
|
|
actionDataIter != m_noteActionDataMap->end();
|
|
++actionDataIter) {
|
|
|
|
NoteActionData noteActionData = **actionDataIter;
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
(noteActionData.pixmapName.ascii())));
|
|
noteAction = new TDERadioAction(noteActionData.title,
|
|
icon,
|
|
noteActionData.keycode,
|
|
TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotNoteAction()),
|
|
actionCollection(),
|
|
noteActionData.actionName.ascii());
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
if (noteActionData.noteType == Note::Crotchet &&
|
|
noteActionData.dots == 0 && !noteActionData.rest) {
|
|
m_selectDefaultNote = noteAction;
|
|
}
|
|
}
|
|
|
|
// Note duration change actions
|
|
for (NoteChangeActionDataMap::Iterator actionDataIter = m_noteChangeActionDataMap->begin();
|
|
actionDataIter != m_noteChangeActionDataMap->end();
|
|
++actionDataIter) {
|
|
|
|
NoteChangeActionData data = **actionDataIter;
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
(data.pixmapName.ascii())));
|
|
|
|
TDEAction *action = new TDEAction(data.title,
|
|
icon,
|
|
data.keycode,
|
|
TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotNoteChangeAction()),
|
|
actionCollection(),
|
|
data.actionName.ascii());
|
|
}
|
|
|
|
//
|
|
// Accidentals
|
|
//
|
|
static TQString actionsAccidental[][4] =
|
|
{
|
|
{ i18n("No accidental"), "1slotNoAccidental()", "no_accidental", "accidental-none" },
|
|
{ i18n("Follow previous accidental"), "1slotFollowAccidental()", "follow_accidental", "accidental-follow" },
|
|
{ i18n("Sharp"), "1slotSharp()", "sharp_accidental", "accidental-sharp" },
|
|
{ i18n("Flat"), "1slotFlat()", "flat_accidental", "accidental-flat" },
|
|
{ i18n("Natural"), "1slotNatural()", "natural_accidental", "accidental-natural" },
|
|
{ i18n("Double sharp"), "1slotDoubleSharp()", "double_sharp_accidental", "accidental-doublesharp" },
|
|
{ i18n("Double flat"), "1slotDoubleFlat()", "double_flat_accidental", "accidental-doubleflat" }
|
|
};
|
|
|
|
for (unsigned int i = 0;
|
|
i < sizeof(actionsAccidental) / sizeof(actionsAccidental[0]); ++i) {
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
(actionsAccidental[i][3].ascii())));
|
|
noteAction = new TDERadioAction(actionsAccidental[i][0], icon, 0, TQT_TQOBJECT(this),
|
|
actionsAccidental[i][1].ascii(),
|
|
actionCollection(), actionsAccidental[i][2].ascii());
|
|
noteAction->setExclusiveGroup("accidentals");
|
|
}
|
|
|
|
|
|
//
|
|
// Clefs
|
|
//
|
|
|
|
// Treble
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-treble")));
|
|
noteAction = new TDERadioAction(i18n("&Treble Clef"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTrebleClef()),
|
|
actionCollection(), "treble_clef");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
// Alto
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-alto")));
|
|
noteAction = new TDERadioAction(i18n("&Alto Clef"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotAltoClef()),
|
|
actionCollection(), "alto_clef");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
// Tenor
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-tenor")));
|
|
noteAction = new TDERadioAction(i18n("Te&nor Clef"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTenorClef()),
|
|
actionCollection(), "tenor_clef");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
// Bass
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-bass")));
|
|
noteAction = new TDERadioAction(i18n("&Bass Clef"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotBassClef()),
|
|
actionCollection(), "bass_clef");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("text")));
|
|
noteAction = new TDERadioAction(i18n("&Text"), icon, Key_F8, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotText()),
|
|
actionCollection(), "text");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("guitarchord")));
|
|
noteAction = new TDERadioAction(i18n("&Guitar Chord"), icon, Key_F9, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGuitarChord()),
|
|
actionCollection(), "guitarchord");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
/* icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("lilypond")));
|
|
noteAction = new TDERadioAction(i18n("Lil&ypond Directive"), icon, Key_F9, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotLilyPondDirective()),
|
|
actionCollection(), "lilypond_directive");
|
|
noteAction->setExclusiveGroup("notes"); */
|
|
|
|
|
|
//
|
|
// Edition tools (eraser, selector...)
|
|
//
|
|
noteAction = new TDERadioAction(i18n("&Erase"), "eraser", Key_F4,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotEraseSelected()),
|
|
actionCollection(), "erase");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("select")));
|
|
noteAction = new TDERadioAction(i18n("&Select and Edit"), icon, Key_F2,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotSelectSelected()),
|
|
actionCollection(), "select");
|
|
noteAction->setExclusiveGroup("notes");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("step_by_step")));
|
|
new TDEToggleAction(i18n("Ste&p Recording"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleStepByStep()), actionCollection(),
|
|
"toggle_step_by_step");
|
|
|
|
|
|
// Edit menu
|
|
new TDEAction(i18n("Select from Sta&rt"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditSelectFromStart()), actionCollection(),
|
|
"select_from_start");
|
|
|
|
new TDEAction(i18n("Select to &End"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditSelectToEnd()), actionCollection(),
|
|
"select_to_end");
|
|
|
|
new TDEAction(i18n("Select Whole St&aff"), Key_A + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditSelectWholeStaff()), actionCollection(),
|
|
"select_whole_staff");
|
|
|
|
new TDEAction(i18n("C&ut and Close"), CTRL + SHIFT + Key_X, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditCutAndClose()), actionCollection(),
|
|
"cut_and_close");
|
|
|
|
new TDEAction(i18n("Pa&ste..."), CTRL + SHIFT + Key_V, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditGeneralPaste()), actionCollection(),
|
|
"general_paste");
|
|
|
|
new TDEAction(i18n("De&lete"), Key_Delete, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditDelete()), actionCollection(),
|
|
"delete");
|
|
|
|
new TDEAction(i18n("Move to Staff Above"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMoveEventsUpStaff()), actionCollection(),
|
|
"move_events_up_staff");
|
|
|
|
new TDEAction(i18n("Move to Staff Below"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMoveEventsDownStaff()), actionCollection(),
|
|
"move_events_down_staff");
|
|
|
|
//
|
|
// Settings menu
|
|
//
|
|
int layoutMode = m_config->readNumEntry("layoutmode", 0);
|
|
|
|
TQString pixmapDir = TDEGlobal::dirs()->findResource("appdata", "pixmaps/");
|
|
|
|
TQCanvasPixmap pixmap(pixmapDir + "/toolbar/linear-layout.xpm");
|
|
icon = TQIconSet(pixmap);
|
|
TDERadioAction *linearModeAction = new TDERadioAction
|
|
(i18n("&Linear Layout"), icon, 0, TQT_TQOBJECT(this), TQT_SLOT(slotLinearMode()),
|
|
actionCollection(), "linear_mode");
|
|
linearModeAction->setExclusiveGroup("layoutMode");
|
|
if (layoutMode == 0)
|
|
linearModeAction->setChecked(true);
|
|
|
|
pixmap.load(pixmapDir + "/toolbar/continuous-page-mode.xpm");
|
|
icon = TQIconSet(pixmap);
|
|
TDERadioAction *continuousPageModeAction = new TDERadioAction
|
|
(i18n("&Continuous Page Layout"), icon, 0, TQT_TQOBJECT(this), TQT_SLOT(slotContinuousPageMode()),
|
|
actionCollection(), "continuous_page_mode");
|
|
continuousPageModeAction->setExclusiveGroup("layoutMode");
|
|
if (layoutMode == 1)
|
|
continuousPageModeAction->setChecked(true);
|
|
|
|
pixmap.load(pixmapDir + "/toolbar/multi-page-mode.xpm");
|
|
icon = TQIconSet(pixmap);
|
|
TDERadioAction *multiPageModeAction = new TDERadioAction
|
|
(i18n("&Multiple Page Layout"), icon, 0, TQT_TQOBJECT(this), TQT_SLOT(slotMultiPageMode()),
|
|
actionCollection(), "multi_page_mode");
|
|
multiPageModeAction->setExclusiveGroup("layoutMode");
|
|
if (layoutMode == 2)
|
|
multiPageModeAction->setChecked(true);
|
|
|
|
new TDEToggleAction(i18n("Show Ch&ord Name Ruler"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleChordsRuler()),
|
|
actionCollection(), "show_chords_ruler");
|
|
|
|
new TDEToggleAction(i18n("Show Ra&w Note Ruler"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleRawNoteRuler()),
|
|
actionCollection(), "show_raw_note_ruler");
|
|
|
|
new TDEToggleAction(i18n("Show &Tempo Ruler"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleTempoRuler()),
|
|
actionCollection(), "show_tempo_ruler");
|
|
|
|
new TDEToggleAction(i18n("Show &Annotations"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleAnnotations()),
|
|
actionCollection(), "show_annotations");
|
|
|
|
new TDEToggleAction(i18n("Show Lily&Pond Directives"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleLilyPondDirectives()),
|
|
actionCollection(), "show_lilypond_directives");
|
|
|
|
new TDEAction(i18n("Open L&yric Editor"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotEditLyrics()),
|
|
actionCollection(), "lyric_editor");
|
|
|
|
//
|
|
// Group menu
|
|
//
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-beam")));
|
|
|
|
new TDEAction(BeamCommand::getGlobalName(), icon, Key_B + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupBeam()), actionCollection(), "beam");
|
|
|
|
new TDEAction(AutoBeamCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupAutoBeam()), actionCollection(), "auto_beam");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-unbeam")));
|
|
|
|
new TDEAction(BreakCommand::getGlobalName(), icon, Key_U + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupBreak()), actionCollection(), "break_group");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-simple-tuplet")));
|
|
|
|
new TDEAction(TupletCommand::getGlobalName(true), icon, Key_R + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupSimpleTuplet()), actionCollection(), "simple_tuplet");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-tuplet")));
|
|
|
|
new TDEAction(TupletCommand::getGlobalName(false), icon, Key_T + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupGeneralTuplet()), actionCollection(), "tuplet");
|
|
|
|
new TDEAction(UnTupletCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupUnTuplet()), actionCollection(), "break_tuplets");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap
|
|
(NotePixmapFactory::makeToolbarPixmap("triplet")));
|
|
(new TDEToggleAction(i18n("Trip&let Insert Mode"), icon, Key_G,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotUpdateInsertModeStatus()),
|
|
actionCollection(), "triplet_mode"))->
|
|
setChecked(false);
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap
|
|
(NotePixmapFactory::makeToolbarPixmap("chord")));
|
|
(new TDEToggleAction(i18n("C&hord Insert Mode"), icon, Key_H,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotUpdateInsertModeStatus()),
|
|
actionCollection(), "chord_mode"))->
|
|
setChecked(false);
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap
|
|
(NotePixmapFactory::makeToolbarPixmap("group-grace")));
|
|
(new TDEToggleAction(i18n("Grace Insert Mode"), icon, 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotUpdateInsertModeStatus()),
|
|
actionCollection(), "grace_mode"))->
|
|
setChecked(false);
|
|
/*!!!
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-grace")));
|
|
|
|
new TDEAction(GraceCommand::getGlobalName(), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupGrace()), actionCollection(), "grace");
|
|
|
|
new TDEAction(UnGraceCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupUnGrace()), actionCollection(), "ungrace");
|
|
*/
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-slur")));
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::Slur), icon, Key_ParenRight, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupSlur()), actionCollection(), "slur");
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::PhrasingSlur), 0, Key_ParenRight + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupPhrasingSlur()), actionCollection(), "phrasing_slur");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-glissando")));
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::Glissando), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupGlissando()), actionCollection(), "glissando");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-crescendo")));
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::Crescendo), icon, Key_Less, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupCrescendo()), actionCollection(), "crescendo");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-decrescendo")));
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::Decrescendo), icon, Key_Greater, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupDecrescendo()), actionCollection(), "decrescendo");
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::QuindicesimaUp), 0, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupOctave2Up()), actionCollection(), "octave_2up");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-ottava")));
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::OttavaUp), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupOctaveUp()), actionCollection(), "octave_up");
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::OttavaDown), 0, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupOctaveDown()), actionCollection(), "octave_down");
|
|
|
|
new TDEAction(AddIndicationCommand::getGlobalName
|
|
(Indication::QuindicesimaDown), 0, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupOctave2Down()), actionCollection(), "octave_2down");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("group-chord")));
|
|
new TDEAction(MakeChordCommand::getGlobalName(), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotGroupMakeChord()), actionCollection(), "make_chord");
|
|
|
|
// setup Transforms menu
|
|
new TDEAction(NormalizeRestsCommand::getGlobalName(), Key_N + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsNormalizeRests()), actionCollection(),
|
|
"normalize_rests");
|
|
|
|
new TDEAction(CollapseRestsCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsCollapseRests()), actionCollection(),
|
|
"collapse_rests_aggressively");
|
|
|
|
new TDEAction(CollapseNotesCommand::getGlobalName(), Key_Equal + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsCollapseNotes()), actionCollection(),
|
|
"collapse_notes");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transforms-tie")));
|
|
|
|
new TDEAction(TieNotesCommand::getGlobalName(), icon, Key_AsciiTilde, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsTieNotes()), actionCollection(),
|
|
"tie_notes");
|
|
|
|
new TDEAction(UntieNotesCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsUntieNotes()), actionCollection(),
|
|
"untie_notes");
|
|
|
|
new TDEAction(MakeNotesViableCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsMakeNotesViable()), actionCollection(),
|
|
"make_notes_viable");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transforms-decounterpoint")));
|
|
|
|
new TDEAction(DeCounterpointCommand::getGlobalName(), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsDeCounterpoint()), actionCollection(),
|
|
"de_counterpoint");
|
|
|
|
new TDEAction(ChangeStemsCommand::getGlobalName(true),
|
|
0, Key_PageUp + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsStemsUp()), actionCollection(),
|
|
"stems_up");
|
|
|
|
new TDEAction(ChangeStemsCommand::getGlobalName(false),
|
|
0, Key_PageDown + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsStemsDown()), actionCollection(),
|
|
"stems_down");
|
|
|
|
new TDEAction(RestoreStemsCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsRestoreStems()), actionCollection(),
|
|
"restore_stems");
|
|
|
|
new TDEAction(ChangeSlurPositionCommand::getGlobalName(true),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsSlursAbove()), actionCollection(),
|
|
"slurs_above");
|
|
|
|
new TDEAction(ChangeSlurPositionCommand::getGlobalName(false),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsSlursBelow()), actionCollection(),
|
|
"slurs_below");
|
|
|
|
new TDEAction(RestoreSlursCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsRestoreSlurs()), actionCollection(),
|
|
"restore_slurs");
|
|
|
|
new TDEAction(ChangeTiePositionCommand::getGlobalName(true),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsTiesAbove()), actionCollection(),
|
|
"ties_above");
|
|
|
|
new TDEAction(ChangeTiePositionCommand::getGlobalName(false),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsTiesBelow()), actionCollection(),
|
|
"ties_below");
|
|
|
|
new TDEAction(RestoreTiesCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsRestoreTies()), actionCollection(),
|
|
"restore_ties");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("accmenu-doubleflat")));
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Set, Accidentals::DoubleFlat),
|
|
icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellDoubleFlat()), actionCollection(),
|
|
"respell_doubleflat");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("accmenu-flat")));
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Set, Accidentals::Flat),
|
|
icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellFlat()), actionCollection(),
|
|
"respell_flat");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("accmenu-natural")));
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Set, Accidentals::Natural),
|
|
icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellNatural()), actionCollection(),
|
|
"respell_natural");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("accmenu-sharp")));
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Set, Accidentals::Sharp),
|
|
icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellSharp()), actionCollection(),
|
|
"respell_sharp");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("accmenu-doublesharp")));
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Set, Accidentals::DoubleSharp),
|
|
icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellDoubleSharp()), actionCollection(),
|
|
"respell_doublesharp");
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Up, Accidentals::NoAccidental),
|
|
Key_Up + CTRL + SHIFT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellUp()), actionCollection(),
|
|
"respell_up");
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Down, Accidentals::NoAccidental),
|
|
Key_Down + CTRL + SHIFT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellDown()), actionCollection(),
|
|
"respell_down");
|
|
|
|
new TDEAction(RespellCommand::getGlobalName
|
|
(RespellCommand::Restore, Accidentals::NoAccidental),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRespellRestore()), actionCollection(),
|
|
"respell_restore");
|
|
|
|
new TDEAction(MakeAccidentalsCautionaryCommand::getGlobalName(true),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotShowCautionary()), actionCollection(),
|
|
"show_cautionary");
|
|
|
|
new TDEAction(MakeAccidentalsCautionaryCommand::getGlobalName(false),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotCancelCautionary()), actionCollection(),
|
|
"cancel_cautionary");
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("quantize")));
|
|
|
|
new TDEAction(EventQuantizeCommand::getGlobalName(), icon, Key_Equal, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotTransformsQuantize()), actionCollection(),
|
|
"quantize");
|
|
|
|
new TDEAction(FixNotationQuantizeCommand::getGlobalName(), 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotTransformsFixQuantization()), actionCollection(),
|
|
"fix_quantization");
|
|
|
|
new TDEAction(RemoveNotationQuantizeCommand::getGlobalName(), 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotTransformsRemoveQuantization()), actionCollection(),
|
|
"remove_quantization");
|
|
|
|
new TDEAction(InterpretCommand::getGlobalName(), 0,
|
|
TQT_TQOBJECT(this), TQT_SLOT(slotTransformsInterpret()), actionCollection(),
|
|
"interpret");
|
|
|
|
new TDEAction(i18n("&Dump selected events to stderr"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotDebugDump()), actionCollection(), "debug_dump");
|
|
|
|
for (MarkActionDataMap::Iterator i = m_markActionDataMap->begin();
|
|
i != m_markActionDataMap->end(); ++i) {
|
|
|
|
const MarkActionData &markActionData = **i;
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap
|
|
(NotePixmapFactory::makeMarkMenuPixmap(markActionData.mark)));
|
|
|
|
new TDEAction(markActionData.title,
|
|
icon,
|
|
markActionData.keycode,
|
|
TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotAddMark()),
|
|
actionCollection(),
|
|
markActionData.actionName.ascii());
|
|
}
|
|
|
|
icon = TQIconSet
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("text-mark")));
|
|
|
|
new TDEAction(AddTextMarkCommand::getGlobalName(), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddTextMark()), actionCollection(),
|
|
"add_text_mark");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName("0"), 0, Key_0 + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMarkFromAction()), actionCollection(),
|
|
"add_fingering_0");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName("1"), 0, Key_1 + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMarkFromAction()), actionCollection(),
|
|
"add_fingering_1");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName("2"), 0, Key_2 + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMarkFromAction()), actionCollection(),
|
|
"add_fingering_2");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName("3"), 0, Key_3 + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMarkFromAction()), actionCollection(),
|
|
"add_fingering_3");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName("4"), 0, Key_4 + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMarkFromAction()), actionCollection(),
|
|
"add_fingering_4");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName("5"), 0, Key_5 + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMarkFromAction()), actionCollection(),
|
|
"add_fingering_5");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName("+"), 0, Key_9 + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMarkFromAction()), actionCollection(),
|
|
"add_fingering_plus");
|
|
|
|
new TDEAction(AddFingeringMarkCommand::getGlobalName(), 0, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksAddFingeringMark()), actionCollection(),
|
|
"add_fingering_mark");
|
|
|
|
new TDEAction(RemoveMarksCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksRemoveMarks()), actionCollection(),
|
|
"remove_marks");
|
|
|
|
new TDEAction(RemoveFingeringMarksCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMarksRemoveFingeringMarks()), actionCollection(),
|
|
"remove_fingering_marks");
|
|
|
|
new TDEAction(i18n("Ma&ke Ornament..."), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMakeOrnament()), actionCollection(),
|
|
"make_ornament");
|
|
|
|
new TDEAction(i18n("Trigger &Ornament..."), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotUseOrnament()), actionCollection(),
|
|
"use_ornament");
|
|
|
|
new TDEAction(i18n("Remove Ornament..."), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotRemoveOrnament()), actionCollection(),
|
|
"remove_ornament");
|
|
|
|
static TQString slashTitles[] = {
|
|
i18n("&None"), "&1", "&2", "&3", "&4", "&5"
|
|
};
|
|
for (int i = 0; i <= 5; ++i) {
|
|
new TDEAction(slashTitles[i], 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotAddSlashes()), actionCollection(),
|
|
TQString("slashes_%1").arg(i).ascii());
|
|
}
|
|
|
|
new TDEAction(ClefInsertionCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditAddClef()), actionCollection(),
|
|
"add_clef");
|
|
|
|
new TDEAction(KeyInsertionCommand::getGlobalName(), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditAddKeySignature()), actionCollection(),
|
|
"add_key_signature");
|
|
|
|
new TDEAction(SustainInsertionCommand::getGlobalName(true), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditAddSustainDown()), actionCollection(),
|
|
"add_sustain_down");
|
|
|
|
new TDEAction(SustainInsertionCommand::getGlobalName(false), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditAddSustainUp()), actionCollection(),
|
|
"add_sustain_up");
|
|
|
|
new TDEAction(TransposeCommand::getDiatonicGlobalName(false), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditTranspose()), actionCollection(),
|
|
"transpose_segment");
|
|
|
|
new TDEAction(i18n("Convert Notation For..."), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotEditSwitchPreset()), actionCollection(),
|
|
"switch_preset");
|
|
|
|
|
|
// setup Settings menu
|
|
static TQString actionsToolbars[][4] =
|
|
{
|
|
{ i18n("Show T&ools Toolbar"), "1slotToggleToolsToolBar()", "show_tools_toolbar", "palette-tools" },
|
|
{ i18n("Show &Notes Toolbar"), "1slotToggleNotesToolBar()", "show_notes_toolbar", "palette-notes" },
|
|
{ i18n("Show &Rests Toolbar"), "1slotToggleRestsToolBar()", "show_rests_toolbar", "palette-rests" },
|
|
{ i18n("Show &Accidentals Toolbar"), "1slotToggleAccidentalsToolBar()", "show_accidentals_toolbar", "palette-accidentals" },
|
|
{ i18n("Show Cle&fs Toolbar"), "1slotToggleClefsToolBar()", "show_clefs_toolbar",
|
|
"palette-clefs" },
|
|
{ i18n("Show &Marks Toolbar"), "1slotToggleMarksToolBar()", "show_marks_toolbar",
|
|
"palette-marks" },
|
|
{ i18n("Show &Group Toolbar"), "1slotToggleGroupToolBar()", "show_group_toolbar",
|
|
"palette-group" },
|
|
{ i18n("Show &Layout Toolbar"), "1slotToggleLayoutToolBar()", "show_layout_toolbar",
|
|
"palette-font" },
|
|
{ i18n("Show Trans&port Toolbar"), "1slotToggleTransportToolBar()", "show_transport_toolbar",
|
|
"palette-transport" },
|
|
{ i18n("Show M&eta Toolbar"), "1slotToggleMetaToolBar()", "show_meta_toolbar",
|
|
"palette-meta" }
|
|
};
|
|
|
|
for (unsigned int i = 0;
|
|
i < sizeof(actionsToolbars) / sizeof(actionsToolbars[0]); ++i) {
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap(actionsToolbars[i][3].ascii())));
|
|
|
|
new TDEToggleAction(actionsToolbars[i][0], icon, 0,
|
|
TQT_TQOBJECT(this), actionsToolbars[i][1].ascii(),
|
|
actionCollection(), actionsToolbars[i][2].ascii());
|
|
}
|
|
|
|
new TDEAction(i18n("Cursor &Back"), 0, Key_Left, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotStepBackward()), actionCollection(),
|
|
"cursor_back");
|
|
|
|
new TDEAction(i18n("Cursor &Forward"), 0, Key_Right, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotStepForward()), actionCollection(),
|
|
"cursor_forward");
|
|
|
|
new TDEAction(i18n("Cursor Ba&ck Bar"), 0, Key_Left + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotJumpBackward()), actionCollection(),
|
|
"cursor_back_bar");
|
|
|
|
new TDEAction(i18n("Cursor For&ward Bar"), 0, Key_Right + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotJumpForward()), actionCollection(),
|
|
"cursor_forward_bar");
|
|
|
|
new TDEAction(i18n("Cursor Back and Se&lect"), SHIFT + Key_Left, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotExtendSelectionBackward()), actionCollection(),
|
|
"extend_selection_backward");
|
|
|
|
new TDEAction(i18n("Cursor Forward and &Select"), SHIFT + Key_Right, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotExtendSelectionForward()), actionCollection(),
|
|
"extend_selection_forward");
|
|
|
|
new TDEAction(i18n("Cursor Back Bar and Select"), SHIFT + CTRL + Key_Left, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotExtendSelectionBackwardBar()), actionCollection(),
|
|
"extend_selection_backward_bar");
|
|
|
|
new TDEAction(i18n("Cursor Forward Bar and Select"), SHIFT + CTRL + Key_Right, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotExtendSelectionForwardBar()), actionCollection(),
|
|
"extend_selection_forward_bar");
|
|
|
|
/*!!! not here yet
|
|
new TDEAction(i18n("Move Selection Left"), Key_Minus, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMoveSelectionLeft()), actionCollection(),
|
|
"move_selection_left");
|
|
*/
|
|
|
|
new TDEAction(i18n("Cursor to St&art"), 0,
|
|
/* #1025717: conflicting meanings for ctrl+a - dupe with Select All
|
|
Key_A + CTRL, */ TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotJumpToStart()), actionCollection(),
|
|
"cursor_start");
|
|
|
|
new TDEAction(i18n("Cursor to &End"), 0, Key_E + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotJumpToEnd()), actionCollection(),
|
|
"cursor_end");
|
|
|
|
new TDEAction(i18n("Cursor &Up Staff"), 0, Key_Up + SHIFT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotCurrentStaffUp()), actionCollection(),
|
|
"cursor_up_staff");
|
|
|
|
new TDEAction(i18n("Cursor &Down Staff"), 0, Key_Down + SHIFT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotCurrentStaffDown()), actionCollection(),
|
|
"cursor_down_staff");
|
|
|
|
new TDEAction(i18n("Cursor Pre&vious Segment"), 0, Key_Prior + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotCurrentSegmentPrior()), actionCollection(),
|
|
"cursor_prior_segment");
|
|
|
|
new TDEAction(i18n("Cursor Ne&xt Segment"), 0, Key_Next + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotCurrentSegmentNext()), actionCollection(),
|
|
"cursor_next_segment");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-cursor-to-pointer")));
|
|
new TDEAction(i18n("Cursor to &Playback Pointer"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotJumpCursorToPlayback()), actionCollection(),
|
|
"cursor_to_playback_pointer");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-play")));
|
|
TDEAction *play = new TDEAction(i18n("&Play"), icon, Key_Enter, TQT_TQOBJECT(this),
|
|
TQT_SIGNAL(play()), actionCollection(), "play");
|
|
// Alternative shortcut for Play
|
|
TDEShortcut playShortcut = play->shortcut();
|
|
playShortcut.append( KKey(Key_Return + CTRL) );
|
|
play->setShortcut(playShortcut);
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-stop")));
|
|
new TDEAction(i18n("&Stop"), icon, Key_Insert, TQT_TQOBJECT(this),
|
|
TQT_SIGNAL(stop()), actionCollection(), "stop");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-rewind")));
|
|
new TDEAction(i18n("Re&wind"), icon, Key_End, TQT_TQOBJECT(this),
|
|
TQT_SIGNAL(rewindPlayback()), actionCollection(),
|
|
"playback_pointer_back_bar");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-ffwd")));
|
|
new TDEAction(i18n("&Fast Forward"), icon, Key_PageDown, TQT_TQOBJECT(this),
|
|
TQT_SIGNAL(fastForwardPlayback()), actionCollection(),
|
|
"playback_pointer_forward_bar");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-rewind-end")));
|
|
new TDEAction(i18n("Rewind to &Beginning"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SIGNAL(rewindPlaybackToBeginning()), actionCollection(),
|
|
"playback_pointer_start");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-ffwd-end")));
|
|
new TDEAction(i18n("Fast Forward to &End"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SIGNAL(fastForwardPlaybackToEnd()), actionCollection(),
|
|
"playback_pointer_end");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-pointer-to-cursor")));
|
|
new TDEAction(i18n("Playback Pointer to &Cursor"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotJumpPlaybackToCursor()), actionCollection(),
|
|
"playback_pointer_to_cursor");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-solo")));
|
|
new TDEToggleAction(i18n("&Solo"), icon, 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleSolo()), actionCollection(),
|
|
"toggle_solo");
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-tracking")));
|
|
(new TDEToggleAction(i18n("Scro&ll to Follow Playback"), icon, Key_Pause, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleTracking()), actionCollection(),
|
|
"toggle_tracking"))->setChecked(m_playTracking);
|
|
|
|
icon = TQIconSet(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap
|
|
("transport-panic")));
|
|
new TDEAction(i18n("Panic"), icon, Key_P + CTRL + ALT, TQT_TQOBJECT(this),
|
|
TQT_SIGNAL(panic()), actionCollection(), "panic");
|
|
|
|
new TDEAction(i18n("Set Loop to Selection"), Key_Semicolon + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotPreviewSelection()), actionCollection(),
|
|
"preview_selection");
|
|
|
|
new TDEAction(i18n("Clear L&oop"), Key_Colon + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotClearLoop()), actionCollection(),
|
|
"clear_loop");
|
|
|
|
new TDEAction(i18n("Clear Selection"), Key_Escape, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotClearSelection()), actionCollection(),
|
|
"clear_selection");
|
|
|
|
// TQString pixmapDir =
|
|
// TDEGlobal::dirs()->findResource("appdata", "pixmaps/");
|
|
// icon = TQIconSet(TQCanvasPixmap(pixmapDir + "/toolbar/eventfilter.xpm"));
|
|
new TDEAction(i18n("&Filter Selection"), "filter", Key_F + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotFilterSelection()), actionCollection(),
|
|
"filter_selection");
|
|
|
|
new TDEAction(i18n("Push &Left"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotFinePositionLeft()), actionCollection(),
|
|
"fine_position_left");
|
|
|
|
new TDEAction(i18n("Push &Right"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotFinePositionRight()), actionCollection(),
|
|
"fine_position_right");
|
|
|
|
new TDEAction(i18n("Push &Up"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotFinePositionUp()), actionCollection(),
|
|
"fine_position_up");
|
|
|
|
new TDEAction(i18n("Push &Down"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotFinePositionDown()), actionCollection(),
|
|
"fine_position_down");
|
|
|
|
new TDEAction(i18n("&Restore Positions"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotFinePositionRestore()), actionCollection(),
|
|
"fine_position_restore");
|
|
|
|
new TDEAction(i18n("Make &Invisible"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMakeInvisible()), actionCollection(),
|
|
"make_invisible");
|
|
|
|
new TDEAction(i18n("Make &Visible"), 0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotMakeVisible()), actionCollection(),
|
|
"make_visible");
|
|
|
|
new TDEAction(i18n("Toggle Dot"), Key_Period, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotToggleDot()), actionCollection(),
|
|
"toggle_dot");
|
|
|
|
new TDEAction(i18n("Add Dot"), Key_Period + CTRL, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotAddDot()), actionCollection(),
|
|
"add_dot");
|
|
|
|
new TDEAction(i18n("Add Dot"), Key_Period + CTRL + ALT, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotAddDotNotationOnly()), actionCollection(),
|
|
"add_notation_dot");
|
|
|
|
createGUI(getRCFileName(), false);
|
|
}
|
|
|
|
bool
|
|
NotationView::isInChordMode()
|
|
{
|
|
return ((TDEToggleAction *)actionCollection()->action("chord_mode"))->
|
|
isChecked();
|
|
}
|
|
|
|
bool
|
|
NotationView::isInTripletMode()
|
|
{
|
|
return ((TDEToggleAction *)actionCollection()->action("triplet_mode"))->
|
|
isChecked();
|
|
}
|
|
|
|
bool
|
|
NotationView::isInGraceMode()
|
|
{
|
|
return ((TDEToggleAction *)actionCollection()->action("grace_mode"))->
|
|
isChecked();
|
|
}
|
|
|
|
void
|
|
NotationView::setupFontSizeMenu(std::string oldFontName)
|
|
{
|
|
if (oldFontName != "") {
|
|
|
|
std::vector<int> sizes = NoteFontFactory::getScreenSizes(oldFontName);
|
|
|
|
for (unsigned int i = 0; i < sizes.size(); ++i) {
|
|
TDEAction *action =
|
|
actionCollection()->action
|
|
(TQString("note_font_size_%1").arg(sizes[i]).ascii());
|
|
m_fontSizeActionMenu->remove
|
|
(action);
|
|
|
|
// Don't delete -- that could cause a crash when this
|
|
// function is called from the action itself. Instead
|
|
// we reuse and reinsert existing actions below.
|
|
}
|
|
}
|
|
|
|
std::vector<int> sizes = NoteFontFactory::getScreenSizes(m_fontName);
|
|
|
|
for (unsigned int i = 0; i < sizes.size(); ++i) {
|
|
|
|
TQString actionName = TQString("note_font_size_%1").arg(sizes[i]);
|
|
|
|
TDEToggleAction *sizeAction = dynamic_cast<TDEToggleAction *>
|
|
(actionCollection()->action(actionName.ascii()));
|
|
|
|
if (!sizeAction) {
|
|
sizeAction =
|
|
new TDEToggleAction(i18n("1 pixel", "%n pixels", sizes[i]),
|
|
0, TQT_TQOBJECT(this),
|
|
TQT_SLOT(slotChangeFontSizeFromAction()),
|
|
actionCollection(), actionName.ascii());
|
|
}
|
|
|
|
sizeAction->setChecked(sizes[i] == m_fontSize);
|
|
m_fontSizeActionMenu->insert(sizeAction);
|
|
}
|
|
}
|
|
|
|
LinedStaff *
|
|
NotationView::getLinedStaff(int i)
|
|
{
|
|
return getNotationStaff(i);
|
|
}
|
|
|
|
LinedStaff *
|
|
NotationView::getLinedStaff(const Segment &segment)
|
|
{
|
|
return getNotationStaff(segment);
|
|
}
|
|
|
|
NotationStaff *
|
|
NotationView::getNotationStaff(const Segment &segment)
|
|
{
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
if (&(m_staffs[i]->getSegment()) == &segment)
|
|
return m_staffs[i];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool NotationView::isCurrentStaff(int i)
|
|
{
|
|
return getCurrentSegment() == &(m_staffs[i]->getSegment());
|
|
}
|
|
|
|
void NotationView::initLayoutToolbar()
|
|
{
|
|
TDEToolBar *layoutToolbar = toolBar("Layout Toolbar");
|
|
|
|
if (!layoutToolbar) {
|
|
std::cerr
|
|
<< "NotationView::initLayoutToolbar() : layout toolbar not found"
|
|
<< std::endl;
|
|
return ;
|
|
}
|
|
|
|
new TQLabel(i18n(" Font: "), layoutToolbar, "font label");
|
|
|
|
//
|
|
// font combo
|
|
//
|
|
m_fontCombo = new KComboBox(layoutToolbar);
|
|
m_fontCombo->setEditable(false);
|
|
|
|
std::set
|
|
<std::string> fs(NoteFontFactory::getFontNames());
|
|
std::vector<std::string> f(fs.begin(), fs.end());
|
|
std::sort(f.begin(), f.end());
|
|
|
|
bool foundFont = false;
|
|
|
|
for (std::vector<std::string>::iterator i = f.begin(); i != f.end(); ++i) {
|
|
|
|
TQString fontTQName(strtoqstr(*i));
|
|
|
|
m_fontCombo->insertItem(fontTQName);
|
|
if (fontTQName.lower() == strtoqstr(m_fontName).lower()) {
|
|
m_fontCombo->setCurrentItem(m_fontCombo->count() - 1);
|
|
foundFont = true;
|
|
}
|
|
}
|
|
|
|
if (!foundFont) {
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown font \"%1\", using default").arg
|
|
(strtoqstr(m_fontName)));
|
|
m_fontName = NoteFontFactory::getDefaultFontName();
|
|
}
|
|
|
|
connect(m_fontCombo, TQT_SIGNAL(activated(const TQString &)),
|
|
this, TQT_SLOT(slotChangeFont(const TQString &)));
|
|
|
|
new TQLabel(i18n(" Size: "), layoutToolbar, "size label");
|
|
|
|
TQString value;
|
|
|
|
//
|
|
// font size combo
|
|
//
|
|
std::vector<int> sizes = NoteFontFactory::getScreenSizes(m_fontName);
|
|
m_fontSizeCombo = new KComboBox(layoutToolbar, "font size combo");
|
|
|
|
for (std::vector<int>::iterator i = sizes.begin(); i != sizes.end(); ++i) {
|
|
|
|
value.setNum(*i);
|
|
m_fontSizeCombo->insertItem(value);
|
|
}
|
|
// set combo's current value to default
|
|
value.setNum(m_fontSize);
|
|
m_fontSizeCombo->setCurrentText(value);
|
|
|
|
connect(m_fontSizeCombo, TQT_SIGNAL(activated(const TQString&)),
|
|
this, TQT_SLOT(slotChangeFontSizeFromStringValue(const TQString&)));
|
|
|
|
new TQLabel(i18n(" Spacing: "), layoutToolbar, "spacing label");
|
|
|
|
//
|
|
// spacing combo
|
|
//
|
|
int defaultSpacing = m_hlayout->getSpacing();
|
|
std::vector<int> spacings = NotationHLayout::getAvailableSpacings();
|
|
|
|
m_spacingCombo = new KComboBox(layoutToolbar, "spacing combo");
|
|
for (std::vector<int>::iterator i = spacings.begin(); i != spacings.end(); ++i) {
|
|
|
|
value.setNum(*i);
|
|
value += "%";
|
|
m_spacingCombo->insertItem(value);
|
|
}
|
|
// set combo's current value to default
|
|
value.setNum(defaultSpacing);
|
|
value += "%";
|
|
m_spacingCombo->setCurrentText(value);
|
|
|
|
connect(m_spacingCombo, TQT_SIGNAL(activated(const TQString&)),
|
|
this, TQT_SLOT(slotChangeSpacingFromStringValue(const TQString&)));
|
|
}
|
|
|
|
void NotationView::initStatusBar()
|
|
{
|
|
KStatusBar* sb = statusBar();
|
|
|
|
m_hoveredOverNoteName = new TQLabel(sb);
|
|
m_hoveredOverNoteName->setMinimumWidth(32);
|
|
|
|
m_hoveredOverAbsoluteTime = new TQLabel(sb);
|
|
m_hoveredOverAbsoluteTime->setMinimumWidth(160);
|
|
|
|
sb->addWidget(m_hoveredOverAbsoluteTime);
|
|
sb->addWidget(m_hoveredOverNoteName);
|
|
|
|
TQHBox *hbox = new TQHBox(sb);
|
|
m_currentNotePixmap = new TQLabel(hbox);
|
|
m_currentNotePixmap->setMinimumWidth(20);
|
|
m_insertModeLabel = new TQLabel(hbox);
|
|
m_annotationsLabel = new TQLabel(hbox);
|
|
m_lilyPondDirectivesLabel = new TQLabel(hbox);
|
|
sb->addWidget(hbox);
|
|
|
|
sb->insertItem(KTmpStatusMsg::getDefaultMsg(),
|
|
KTmpStatusMsg::getDefaultId(), 1);
|
|
sb->setItemAlignment(KTmpStatusMsg::getDefaultId(),
|
|
AlignLeft | AlignVCenter);
|
|
|
|
m_selectionCounter = new TQLabel(sb);
|
|
sb->addWidget(m_selectionCounter);
|
|
|
|
m_progressBar = new ProgressBar(100, true, sb);
|
|
m_progressBar->setMinimumWidth(100);
|
|
sb->addWidget(m_progressBar);
|
|
}
|
|
|
|
TQSize NotationView::getViewSize()
|
|
{
|
|
return canvas()->size();
|
|
}
|
|
|
|
void NotationView::setViewSize(TQSize s)
|
|
{
|
|
canvas()->resize(s.width(), s.height());
|
|
|
|
if ( (m_pageMode == LinedStaff::LinearMode)
|
|
&& (m_showHeadersGroup != HeadersGroup::ShowNever)) {
|
|
m_headersGroup->completeToHeight(s.height());
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::setPageMode(LinedStaff::PageMode pageMode)
|
|
{
|
|
m_pageMode = pageMode;
|
|
|
|
if (pageMode != LinedStaff::LinearMode) {
|
|
if (m_topStandardRuler)
|
|
m_topStandardRuler->hide();
|
|
if (m_bottomStandardRuler)
|
|
m_bottomStandardRuler->hide();
|
|
if (m_chordNameRuler)
|
|
m_chordNameRuler->hide();
|
|
if (m_rawNoteRuler)
|
|
m_rawNoteRuler->hide();
|
|
if (m_tempoRuler)
|
|
m_tempoRuler->hide();
|
|
hideHeadersGroup();
|
|
} else {
|
|
if (m_topStandardRuler)
|
|
m_topStandardRuler->show();
|
|
if (m_bottomStandardRuler)
|
|
m_bottomStandardRuler->show();
|
|
if (m_chordNameRuler && getToggleAction("show_chords_ruler")->isChecked())
|
|
m_chordNameRuler->show();
|
|
if (m_rawNoteRuler && getToggleAction("show_raw_note_ruler")->isChecked())
|
|
m_rawNoteRuler->show();
|
|
if (m_tempoRuler && getToggleAction("show_tempo_ruler")->isChecked())
|
|
m_tempoRuler->show();
|
|
showHeadersGroup();
|
|
}
|
|
|
|
stateChanged("linear_mode",
|
|
(pageMode == LinedStaff::LinearMode ? KXMLGUIClient::StateNoReverse :
|
|
KXMLGUIClient::StateReverse));
|
|
|
|
int pageWidth = getPageWidth();
|
|
int topMargin = 0, leftMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
|
|
m_hlayout->setPageMode(pageMode != LinedStaff::LinearMode);
|
|
m_hlayout->setPageWidth(pageWidth - leftMargin * 2);
|
|
|
|
NOTATION_DEBUG << "NotationView::setPageMode: set layout's page width to "
|
|
<< (pageWidth - leftMargin * 2) << endl;
|
|
|
|
positionStaffs();
|
|
|
|
bool layoutApplied = applyLayout();
|
|
if (!layoutApplied)
|
|
KMessageBox::sorry(0, "Couldn't apply layout");
|
|
else {
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->markChanged();
|
|
}
|
|
}
|
|
|
|
if (!m_printMode) {
|
|
// Layout is done : Time related to left of canvas should now
|
|
// correctly be determined and track headers contents be drawn.
|
|
m_headersGroup->slotUpdateAllHeaders(0, 0, true);
|
|
}
|
|
|
|
positionPages();
|
|
|
|
if (!m_printMode) {
|
|
updateView();
|
|
slotSetInsertCursorPosition(getInsertionTime(), false, false);
|
|
slotSetPointerPosition(getDocument()->getComposition().getPosition(), false);
|
|
}
|
|
|
|
Profiles::getInstance()->dump();
|
|
}
|
|
|
|
int
|
|
NotationView::getPageWidth()
|
|
{
|
|
if (m_pageMode != LinedStaff::MultiPageMode) {
|
|
|
|
if (isInPrintMode() && getCanvasView() && getCanvasView()->canvas())
|
|
return getCanvasView()->canvas()->width();
|
|
|
|
if (getCanvasView()) {
|
|
return
|
|
getCanvasView()->width() -
|
|
getCanvasView()->verticalScrollBar()->width() -
|
|
m_leftGutter - 10;
|
|
}
|
|
|
|
return width() - 50;
|
|
|
|
} else {
|
|
|
|
//!!! For the moment we use A4 for this calculation
|
|
|
|
double printSizeMm = 25.4 * ((double)m_printSize / 72.0);
|
|
double mmPerPixel = printSizeMm / (double)m_notePixmapFactory->getSize();
|
|
return (int)(210.0 / mmPerPixel);
|
|
}
|
|
}
|
|
|
|
int
|
|
NotationView::getPageHeight()
|
|
{
|
|
if (m_pageMode != LinedStaff::MultiPageMode) {
|
|
|
|
if (isInPrintMode() && getCanvasView() && getCanvasView()->canvas())
|
|
return getCanvasView()->canvas()->height();
|
|
|
|
if (getCanvasView()) {
|
|
return getCanvasView()->height();
|
|
}
|
|
|
|
return (height() > 200 ? height() - 100 : height());
|
|
|
|
} else {
|
|
|
|
//!!! For the moment we use A4 for this calculation
|
|
|
|
double printSizeMm = 25.4 * ((double)m_printSize / 72.0);
|
|
double mmPerPixel = printSizeMm / (double)m_notePixmapFactory->getSize();
|
|
return (int)(297.0 / mmPerPixel);
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::getPageMargins(int &left, int &top)
|
|
{
|
|
if (m_pageMode != LinedStaff::MultiPageMode) {
|
|
|
|
left = 0;
|
|
top = 0;
|
|
|
|
} else {
|
|
|
|
//!!! For the moment we use A4 for this calculation
|
|
|
|
double printSizeMm = 25.4 * ((double)m_printSize / 72.0);
|
|
double mmPerPixel = printSizeMm / (double)m_notePixmapFactory->getSize();
|
|
left = (int)(20.0 / mmPerPixel);
|
|
top = (int)(15.0 / mmPerPixel);
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::scrollToTime(timeT t)
|
|
{
|
|
|
|
double notationViewLayoutCoord = m_hlayout->getXForTime(t);
|
|
|
|
// Doesn't appear to matter which staff we use
|
|
//!!! actually it probably does matter, if they don't have the same extents
|
|
double notationViewCanvasCoord =
|
|
getLinedStaff(0)->getCanvasCoordsForLayoutCoords
|
|
(notationViewLayoutCoord, 0).first;
|
|
|
|
// HK: I could have sworn I saw a hard-coded scroll happen somewhere
|
|
// (i.e. a default extra scroll to make up for the staff not beginning on
|
|
// the left edge) but now I can't find it.
|
|
getCanvasView()->slotScrollHorizSmallSteps
|
|
(int(notationViewCanvasCoord)); // + DEFAULT_STAFF_OFFSET);
|
|
}
|
|
|
|
RulerScale*
|
|
NotationView::getHLayout()
|
|
{
|
|
return m_hlayout;
|
|
}
|
|
|
|
void
|
|
NotationView::paintEvent(TQPaintEvent *e)
|
|
{
|
|
m_inPaintEvent = true;
|
|
|
|
// This is duplicated here from EditViewBase, because (a) we need
|
|
// to know about the segment being removed before we try to check
|
|
// the staff names etc., and (b) it's not safe to call close()
|
|
// from EditViewBase::paintEvent if we're then going to try to do
|
|
// some more work afterwards in this function
|
|
|
|
if (isCompositionModified()) {
|
|
|
|
// Check if one of the segments we display has been removed
|
|
// from the composition.
|
|
//
|
|
// For the moment we'll have to close the view if any of the
|
|
// segments we handle has been deleted.
|
|
|
|
for (unsigned int i = 0; i < m_segments.size(); ++i) {
|
|
|
|
if (!m_segments[i]->getComposition()) {
|
|
// oops, I think we've been deleted
|
|
close();
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
|
|
int topMargin = 0, leftMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
|
|
if (m_pageMode == LinedStaff::ContinuousPageMode) {
|
|
// relayout if the window width changes significantly in continuous page mode
|
|
int diff = int(getPageWidth() - leftMargin * 2 - m_hlayout->getPageWidth());
|
|
if (diff < -10 || diff > 10) {
|
|
setPageMode(m_pageMode);
|
|
refreshSegment(0, 0, 0);
|
|
}
|
|
|
|
} else if (m_pageMode == LinedStaff::LinearMode) {
|
|
// resize canvas again if the window height has changed significantly
|
|
if (getCanvasView() && getCanvasView()->canvas()) {
|
|
int diff = int(getPageHeight() - getCanvasView()->canvas()->height());
|
|
if (diff > 10) {
|
|
readjustCanvasSize();
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for staff name changes
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
if (!m_staffs[i]->isStaffNameUpToDate()) {
|
|
refreshSegment(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_inPaintEvent = false;
|
|
|
|
EditView::paintEvent(e);
|
|
|
|
m_inPaintEvent = false;
|
|
|
|
// now deal with any backlog of insertable notes that appeared
|
|
// during paint (because it's not safe to modify a segment from
|
|
// within a sub-event-loop in a processEvents call from a paint)
|
|
if (!m_pendingInsertableNotes.empty()) {
|
|
std::vector<std::pair<int, int> > notes = m_pendingInsertableNotes;
|
|
m_pendingInsertableNotes.clear();
|
|
for (unsigned int i = 0; i < notes.size(); ++i) {
|
|
slotInsertableNoteEventReceived(notes[i].first, notes[i].second, true);
|
|
}
|
|
}
|
|
|
|
slotSetOperationNameAndStatus(i18n(" Ready."));
|
|
}
|
|
|
|
bool NotationView::applyLayout(int staffNo, timeT startTime, timeT endTime)
|
|
{
|
|
slotSetOperationNameAndStatus(i18n("Laying out score..."));
|
|
ProgressDialog::processEvents();
|
|
|
|
m_hlayout->setStaffCount(m_staffs.size());
|
|
|
|
Profiler profiler("NotationView::applyLayout");
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
if (staffNo >= 0 && (int)i != staffNo)
|
|
continue;
|
|
|
|
slotSetOperationNameAndStatus(i18n("Laying out staff %1...").arg(i + 1));
|
|
ProgressDialog::processEvents();
|
|
|
|
m_hlayout->resetStaff(*m_staffs[i], startTime, endTime);
|
|
m_vlayout->resetStaff(*m_staffs[i], startTime, endTime);
|
|
m_hlayout->scanStaff(*m_staffs[i], startTime, endTime);
|
|
m_vlayout->scanStaff(*m_staffs[i], startTime, endTime);
|
|
}
|
|
|
|
slotSetOperationNameAndStatus(i18n("Reconciling staffs..."));
|
|
ProgressDialog::processEvents();
|
|
|
|
m_hlayout->finishLayout(startTime, endTime);
|
|
m_vlayout->finishLayout(startTime, endTime);
|
|
|
|
// find the last finishing staff for future use
|
|
|
|
timeT lastFinishingStaffEndTime = 0;
|
|
bool haveEndTime = false;
|
|
m_lastFinishingStaff = -1;
|
|
|
|
timeT firstStartingStaffStartTime = 0;
|
|
bool haveStartTime = false;
|
|
int firstStartingStaff = -1;
|
|
|
|
for (i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
timeT thisStartTime = m_staffs[i]->getSegment().getStartTime();
|
|
if (thisStartTime < firstStartingStaffStartTime || !haveStartTime) {
|
|
firstStartingStaffStartTime = thisStartTime;
|
|
haveStartTime = true;
|
|
firstStartingStaff = i;
|
|
}
|
|
|
|
timeT thisEndTime = m_staffs[i]->getSegment().getEndTime();
|
|
if (thisEndTime > lastFinishingStaffEndTime || !haveEndTime) {
|
|
lastFinishingStaffEndTime = thisEndTime;
|
|
haveEndTime = true;
|
|
m_lastFinishingStaff = i;
|
|
}
|
|
}
|
|
|
|
readjustCanvasSize();
|
|
if (m_topStandardRuler) {
|
|
m_topStandardRuler->update();
|
|
}
|
|
if (m_bottomStandardRuler) {
|
|
m_bottomStandardRuler->update();
|
|
}
|
|
if (m_tempoRuler && m_tempoRuler->isVisible()) {
|
|
m_tempoRuler->update();
|
|
}
|
|
if (m_rawNoteRuler && m_rawNoteRuler->isVisible()) {
|
|
m_rawNoteRuler->update();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void NotationView::setCurrentSelectedNote(const char *pixmapName,
|
|
bool rest, Note::Type n, int dots)
|
|
{
|
|
NoteInserter* inserter = 0;
|
|
|
|
if (rest)
|
|
inserter = dynamic_cast<NoteInserter*>(m_toolBox->getTool(RestInserter::ToolName));
|
|
else
|
|
inserter = dynamic_cast<NoteInserter*>(m_toolBox->getTool(NoteInserter::ToolName));
|
|
|
|
inserter->slotSetNote(n);
|
|
inserter->slotSetDots(dots);
|
|
|
|
setTool(inserter);
|
|
|
|
m_currentNotePixmap->setPixmap
|
|
(NotePixmapFactory::toTQPixmap
|
|
(NotePixmapFactory::makeToolbarPixmap(pixmapName, true)));
|
|
|
|
emit changeCurrentNote(rest, n);
|
|
}
|
|
|
|
void NotationView::setCurrentSelectedNote(const NoteActionData ¬eAction)
|
|
{
|
|
setCurrentSelectedNote(noteAction.pixmapName.ascii(),
|
|
noteAction.rest,
|
|
noteAction.noteType,
|
|
noteAction.dots);
|
|
}
|
|
|
|
void NotationView::setCurrentSelection(EventSelection* s, bool preview,
|
|
bool redrawNow)
|
|
{
|
|
//!!! rather too much here shared with matrixview -- could much of
|
|
// this be in editview?
|
|
|
|
if (m_currentEventSelection == s)
|
|
return ;
|
|
NOTATION_DEBUG << "XXX " << endl;
|
|
|
|
EventSelection *oldSelection = m_currentEventSelection;
|
|
m_currentEventSelection = s;
|
|
|
|
// positionElements is overkill here, but we hope it's not too
|
|
// much overkill (if that's not a contradiction)
|
|
|
|
timeT startA, endA, startB, endB;
|
|
|
|
if (oldSelection) {
|
|
startA = oldSelection->getStartTime();
|
|
endA = oldSelection->getEndTime();
|
|
startB = s ? s->getStartTime() : startA;
|
|
endB = s ? s->getEndTime() : endA;
|
|
} else {
|
|
// we know they can't both be null -- first thing we tested above
|
|
startA = startB = s->getStartTime();
|
|
endA = endB = s->getEndTime();
|
|
}
|
|
|
|
// refreshSegment takes start==end to mean refresh everything
|
|
if (startA == endA)
|
|
++endA;
|
|
if (startB == endB)
|
|
++endB;
|
|
|
|
bool updateRequired = true;
|
|
|
|
// play previews if appropriate -- also permits an optimisation
|
|
// for the case where the selection is unchanged (quite likely
|
|
// when sweeping)
|
|
|
|
if (s && preview) {
|
|
|
|
bool foundNewEvent = false;
|
|
|
|
for (EventSelection::eventcontainer::iterator i =
|
|
s->getSegmentEvents().begin();
|
|
i != s->getSegmentEvents().end(); ++i) {
|
|
|
|
if (oldSelection && oldSelection->getSegment() == s->getSegment()
|
|
&& oldSelection->contains(*i))
|
|
continue;
|
|
|
|
foundNewEvent = true;
|
|
|
|
long pitch;
|
|
if (!(*i)->get
|
|
<Int>(BaseProperties::PITCH,
|
|
pitch)) continue;
|
|
|
|
long velocity = -1;
|
|
(void)(*i)->get
|
|
<Int>(BaseProperties::VELOCITY,
|
|
velocity);
|
|
|
|
if (!((*i)->has(BaseProperties::TIED_BACKWARD) &&
|
|
(*i)->get
|
|
<Bool>
|
|
(BaseProperties::TIED_BACKWARD)))
|
|
playNote(s->getSegment(), pitch, velocity);
|
|
}
|
|
|
|
if (!foundNewEvent) {
|
|
if (oldSelection &&
|
|
oldSelection->getSegment() == s->getSegment() &&
|
|
oldSelection->getSegmentEvents().size() ==
|
|
s->getSegmentEvents().size())
|
|
updateRequired = false;
|
|
}
|
|
}
|
|
|
|
if (updateRequired) {
|
|
|
|
if (!s || !oldSelection ||
|
|
(endA >= startB && endB >= startA &&
|
|
oldSelection->getSegment() == s->getSegment())) {
|
|
|
|
// the regions overlap: use their union and just do one refresh
|
|
|
|
Segment &segment(s ? s->getSegment() :
|
|
oldSelection->getSegment());
|
|
|
|
if (redrawNow) {
|
|
// recolour the events now
|
|
getLinedStaff(segment)->positionElements(std::min(startA, startB),
|
|
std::max(endA, endB));
|
|
} else {
|
|
// mark refresh status and then request a repaint
|
|
segment.getRefreshStatus
|
|
(m_segmentsRefreshStatusIds
|
|
[getLinedStaff(segment)->getId()]).
|
|
push(std::min(startA, startB), std::max(endA, endB));
|
|
}
|
|
|
|
} else {
|
|
// do two refreshes, one for each -- here we know neither is null
|
|
|
|
if (redrawNow) {
|
|
// recolour the events now
|
|
getLinedStaff(oldSelection->getSegment())->positionElements(startA,
|
|
endA);
|
|
|
|
getLinedStaff(s->getSegment())->positionElements(startB, endB);
|
|
} else {
|
|
// mark refresh status and then request a repaint
|
|
|
|
oldSelection->getSegment().getRefreshStatus
|
|
(m_segmentsRefreshStatusIds
|
|
[getLinedStaff(oldSelection->getSegment())->getId()]).
|
|
push(startA, endA);
|
|
|
|
s->getSegment().getRefreshStatus
|
|
(m_segmentsRefreshStatusIds
|
|
[getLinedStaff(s->getSegment())->getId()]).
|
|
push(startB, endB);
|
|
}
|
|
}
|
|
|
|
if (s) {
|
|
// make the staff containing the selection current
|
|
int staffId = getLinedStaff(s->getSegment())->getId();
|
|
if (staffId != m_currentStaff)
|
|
slotSetCurrentStaff(staffId);
|
|
}
|
|
}
|
|
|
|
delete oldSelection;
|
|
|
|
statusBar()->changeItem(KTmpStatusMsg::getDefaultMsg(),
|
|
KTmpStatusMsg::getDefaultId());
|
|
|
|
if (s) {
|
|
int eventsSelected = s->getSegmentEvents().size();
|
|
m_selectionCounter->setText
|
|
(i18n(" 1 event selected ",
|
|
" %n events selected ", eventsSelected));
|
|
} else {
|
|
m_selectionCounter->setText(i18n(" No selection "));
|
|
}
|
|
m_selectionCounter->update();
|
|
|
|
setMenuStates();
|
|
|
|
if (redrawNow)
|
|
updateView();
|
|
else
|
|
update();
|
|
|
|
NOTATION_DEBUG << "XXX " << endl;
|
|
}
|
|
|
|
void NotationView::setSingleSelectedEvent(int staffNo, Event *event,
|
|
bool preview, bool redrawNow)
|
|
{
|
|
setSingleSelectedEvent(getStaff(staffNo)->getSegment(), event,
|
|
preview, redrawNow);
|
|
}
|
|
|
|
void NotationView::setSingleSelectedEvent(Segment &segment, Event *event,
|
|
bool preview, bool redrawNow)
|
|
{
|
|
EventSelection *selection = new EventSelection(segment);
|
|
selection->addEvent(event);
|
|
setCurrentSelection(selection, preview, redrawNow);
|
|
}
|
|
|
|
bool NotationView::canPreviewAnotherNote()
|
|
{
|
|
static time_t lastCutOff = 0;
|
|
static int sinceLastCutOff = 0;
|
|
|
|
time_t now = time(0);
|
|
++sinceLastCutOff;
|
|
|
|
if ((now - lastCutOff) > 0) {
|
|
sinceLastCutOff = 0;
|
|
lastCutOff = now;
|
|
NOTATION_DEBUG << "NotationView::canPreviewAnotherNote: reset" << endl;
|
|
} else {
|
|
if (sinceLastCutOff >= 20) {
|
|
// don't permit more than 20 notes per second or so, to
|
|
// avoid gungeing up the sound drivers
|
|
NOTATION_DEBUG << "Rejecting preview (too busy)" << endl;
|
|
return false;
|
|
}
|
|
NOTATION_DEBUG << "NotationView::canPreviewAnotherNote: ok" << endl;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void NotationView::playNote(Segment &s, int pitch, int velocity)
|
|
{
|
|
Composition &comp = getDocument()->getComposition();
|
|
Studio &studio = getDocument()->getStudio();
|
|
Track *track = comp.getTrackById(s.getTrack());
|
|
|
|
Instrument *ins =
|
|
studio.getInstrumentById(track->getInstrument());
|
|
|
|
// check for null instrument
|
|
//
|
|
if (ins == 0)
|
|
return ;
|
|
|
|
if (!canPreviewAnotherNote())
|
|
return ;
|
|
|
|
if (velocity < 0)
|
|
velocity = MidiMaxValue;
|
|
|
|
MappedEvent mE(ins->getId(),
|
|
MappedEvent::MidiNoteOneShot,
|
|
pitch + s.getTranspose(),
|
|
velocity,
|
|
RealTime::zeroTime,
|
|
RealTime(0, 250000000),
|
|
RealTime::zeroTime);
|
|
|
|
StudioControl::sendMappedEvent(mE);
|
|
}
|
|
|
|
void NotationView::showPreviewNote(int staffNo, double layoutX,
|
|
int pitch, int height,
|
|
const Note ¬e, bool grace,
|
|
int velocity)
|
|
{
|
|
m_staffs[staffNo]->showPreviewNote(layoutX, height, note, grace);
|
|
playNote(m_staffs[staffNo]->getSegment(), pitch, velocity);
|
|
}
|
|
|
|
void NotationView::clearPreviewNote()
|
|
{
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->clearPreviewNote();
|
|
}
|
|
}
|
|
|
|
void NotationView::setNotePixmapFactory(NotePixmapFactory* f)
|
|
{
|
|
delete m_notePixmapFactory;
|
|
m_notePixmapFactory = f;
|
|
if (m_hlayout)
|
|
m_hlayout->setNotePixmapFactory(m_notePixmapFactory);
|
|
if (m_vlayout)
|
|
m_vlayout->setNotePixmapFactory(m_notePixmapFactory);
|
|
}
|
|
|
|
Segment *
|
|
NotationView::getCurrentSegment()
|
|
{
|
|
Staff *staff = getCurrentStaff();
|
|
return (staff ? &staff->getSegment() : 0);
|
|
}
|
|
|
|
bool
|
|
NotationView::hasSegment(Segment *segment)
|
|
{
|
|
for (unsigned int i = 0; i < m_segments.size(); ++i) {
|
|
if (segment == m_segments[i]) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
LinedStaff *
|
|
NotationView::getCurrentLinedStaff()
|
|
{
|
|
return getLinedStaff(m_currentStaff);
|
|
}
|
|
|
|
LinedStaff *
|
|
NotationView::getStaffAbove()
|
|
{
|
|
if (m_staffs.size() < 2) return 0;
|
|
|
|
Composition *composition =
|
|
m_staffs[m_currentStaff]->getSegment().getComposition();
|
|
|
|
Track *track = composition->
|
|
getTrackById(m_staffs[m_currentStaff]->getSegment().getTrack());
|
|
if (!track) return 0;
|
|
|
|
int position = track->getPosition();
|
|
Track *newTrack = 0;
|
|
|
|
while ((newTrack = composition->getTrackByPosition(--position))) {
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
if (m_staffs[i]->getSegment().getTrack() == newTrack->getId()) {
|
|
return m_staffs[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
LinedStaff *
|
|
NotationView::getStaffBelow()
|
|
{
|
|
if (m_staffs.size() < 2) return 0;
|
|
|
|
Composition *composition =
|
|
m_staffs[m_currentStaff]->getSegment().getComposition();
|
|
|
|
Track *track = composition->
|
|
getTrackById(m_staffs[m_currentStaff]->getSegment().getTrack());
|
|
if (!track) return 0;
|
|
|
|
int position = track->getPosition();
|
|
Track *newTrack = 0;
|
|
|
|
while ((newTrack = composition->getTrackByPosition(++position))) {
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
if (m_staffs[i]->getSegment().getTrack() == newTrack->getId()) {
|
|
return m_staffs[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
timeT
|
|
NotationView::getInsertionTime()
|
|
{
|
|
return m_insertionTime;
|
|
}
|
|
|
|
timeT
|
|
NotationView::getInsertionTime(Clef &clef,
|
|
Rosegarden::Key &key)
|
|
{
|
|
// This fuss is solely to recover the clef and key: we already
|
|
// set m_insertionTime to the right value when we first placed
|
|
// the insert cursor. We could get clef and key directly from
|
|
// the segment but the staff has a more efficient lookup
|
|
|
|
LinedStaff *staff = m_staffs[m_currentStaff];
|
|
double layoutX = staff->getLayoutXOfInsertCursor();
|
|
if (layoutX < 0) layoutX = 0;
|
|
Event *clefEvt = 0, *keyEvt = 0;
|
|
(void)staff->getElementUnderLayoutX(layoutX, clefEvt, keyEvt);
|
|
|
|
if (clefEvt) clef = Clef(*clefEvt);
|
|
else clef = Clef();
|
|
|
|
if (keyEvt) key = Rosegarden::Key(*keyEvt);
|
|
else key = Rosegarden::Key();
|
|
|
|
return m_insertionTime;
|
|
}
|
|
|
|
LinedStaff*
|
|
NotationView::getStaffForCanvasCoords(int x, int y) const
|
|
{
|
|
// (i) Do not change staff, if mouse was clicked within the current staff.
|
|
LinedStaff *s = m_staffs[m_currentStaff];
|
|
if (s->containsCanvasCoords(x, y)) {
|
|
LinedStaff::LinedStaffCoords coords =
|
|
s->getLayoutCoordsForCanvasCoords(x, y);
|
|
|
|
timeT t = m_hlayout->getTimeForX(coords.first);
|
|
// In order to find the correct starting and ending bar of the segment,
|
|
// make infinitesimal shifts (+1 and -1) towards its center.
|
|
timeT t0 = getDocument()->getComposition().getBarStartForTime(m_staffs[m_currentStaff]->getSegment().getStartTime()+1);
|
|
timeT t1 = getDocument()->getComposition().getBarEndForTime(m_staffs[m_currentStaff]->getSegment().getEndTime()-1);
|
|
if (t >= t0 && t < t1) {
|
|
return m_staffs[m_currentStaff];
|
|
}
|
|
}
|
|
// (ii) Find staff under cursor, if clicked outside the current staff.
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
LinedStaff *s = m_staffs[i];
|
|
|
|
if (s->containsCanvasCoords(x, y)) {
|
|
|
|
LinedStaff::LinedStaffCoords coords =
|
|
s->getLayoutCoordsForCanvasCoords(x, y);
|
|
|
|
timeT t = m_hlayout->getTimeForX(coords.first);
|
|
// In order to find the correct starting and ending bar of the segment,
|
|
// make infinitesimal shifts (+1 and -1) towards its center.
|
|
timeT t0 = getDocument()->getComposition().getBarStartForTime(m_staffs[i]->getSegment().getStartTime()+1);
|
|
timeT t1 = getDocument()->getComposition().getBarEndForTime(m_staffs[i]->getSegment().getEndTime()-1);
|
|
if (t >= t0 && t < t1) {
|
|
return m_staffs[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void NotationView::updateView()
|
|
{
|
|
slotCheckRendered
|
|
(getCanvasView()->contentsX(),
|
|
getCanvasView()->contentsX() + getCanvasView()->visibleWidth());
|
|
canvas()->update();
|
|
}
|
|
|
|
void NotationView::print(bool previewOnly)
|
|
{
|
|
if (m_staffs.size() == 0) {
|
|
KMessageBox::error(0, "Nothing to print");
|
|
return ;
|
|
}
|
|
|
|
Profiler profiler("NotationView::print");
|
|
|
|
// We need to be in multi-page mode at this point
|
|
|
|
int pageWidth = getPageWidth();
|
|
int pageHeight = getPageHeight();
|
|
int leftMargin = 0, topMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
int maxPageCount = 1;
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
int pageCount = m_staffs[i]->getPageCount();
|
|
NOTATION_DEBUG << "NotationView::print(): staff " << i << " reports " << pageCount << " pages " << endl;
|
|
if (pageCount > maxPageCount)
|
|
maxPageCount = pageCount;
|
|
}
|
|
|
|
KPrinter printer(true, TQPrinter::HighResolution);
|
|
|
|
printer.setPageSelection(KPrinter::ApplicationSide);
|
|
printer.setMinMax(1, maxPageCount + 1);
|
|
|
|
if (previewOnly)
|
|
printer.setPreviewOnly(true);
|
|
else if (!printer.setup((TQWidget *)parent()))
|
|
return ;
|
|
|
|
TQPaintDeviceMetrics pdm(&printer);
|
|
TQPainter printpainter(&printer);
|
|
|
|
// Ideally we should aim to retain the aspect ratio and to move the
|
|
// staffs so as to be centred after scaling. But because we haven't
|
|
// got around to the latter, let's lose the former too and just
|
|
// expand to fit.
|
|
|
|
// Retain aspect ratio when scaling
|
|
double ratioX = (double)pdm.width() / (double)(pageWidth - leftMargin * 2),
|
|
ratioY = (double)pdm.height() / (double)(pageHeight - topMargin * 2);
|
|
double ratio = std::min(ratioX, ratioY);
|
|
printpainter.scale(ratio, ratio);
|
|
|
|
// printpainter.scale((double)pdm.width() / (double)(pageWidth - leftMargin*2),
|
|
// (double)pdm.height() / (double)(pageHeight - topMargin*2));
|
|
printpainter.translate( -leftMargin, -topMargin);
|
|
|
|
TQValueList<int> pages = printer.pageList();
|
|
|
|
for (TQValueList<int>::Iterator pli = pages.begin();
|
|
pli != pages.end(); ) { // incremented just below
|
|
|
|
int page = *pli - 1;
|
|
++pli;
|
|
if (page < 0 || page >= maxPageCount)
|
|
continue;
|
|
|
|
NOTATION_DEBUG << "Printing page " << page << endl;
|
|
|
|
TQRect pageRect(m_leftGutter + leftMargin + pageWidth * page,
|
|
topMargin,
|
|
pageWidth - leftMargin,
|
|
pageHeight - topMargin);
|
|
|
|
for (size_t i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
LinedStaff *staff = m_staffs[i];
|
|
|
|
LinedStaff::LinedStaffCoords cc0 = staff->getLayoutCoordsForCanvasCoords
|
|
(pageRect.x(), pageRect.y());
|
|
|
|
LinedStaff::LinedStaffCoords cc1 = staff->getLayoutCoordsForCanvasCoords
|
|
(pageRect.x() + pageRect.width(), pageRect.y() + pageRect.height());
|
|
|
|
timeT t0 = m_hlayout->getTimeForX(cc0.first);
|
|
timeT t1 = m_hlayout->getTimeForX(cc1.first);
|
|
|
|
m_staffs[i]->setPrintPainter(&printpainter);
|
|
m_staffs[i]->checkRendered(t0, t1);
|
|
}
|
|
|
|
// Supplying doublebuffer==true to this method appears to
|
|
// slow down printing considerably but without it we get
|
|
// all sorts of horrible artifacts (possibly related to
|
|
// mishandling of pixmap masks?) in qt-3.0. Let's permit
|
|
// it as a "hidden" option.
|
|
|
|
m_config->setGroup(NotationViewConfigGroup);
|
|
|
|
NOTATION_DEBUG << "NotationView::print: calling TQCanvas::drawArea" << endl;
|
|
|
|
{
|
|
Profiler profiler("NotationView::print(TQCanvas::drawArea)");
|
|
|
|
if (m_config->readBoolEntry("forcedoublebufferprinting", false)) {
|
|
getCanvasView()->canvas()->drawArea(pageRect, &printpainter, true);
|
|
} else {
|
|
getCanvasView()->canvas()->drawArea(pageRect, &printpainter, false);
|
|
}
|
|
|
|
}
|
|
|
|
NOTATION_DEBUG << "NotationView::print: TQCanvas::drawArea done" << endl;
|
|
|
|
for (size_t i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
LinedStaff *staff = m_staffs[i];
|
|
|
|
LinedStaff::LinedStaffCoords cc0 = staff->getLayoutCoordsForCanvasCoords
|
|
(pageRect.x(), pageRect.y());
|
|
|
|
LinedStaff::LinedStaffCoords cc1 = staff->getLayoutCoordsForCanvasCoords
|
|
(pageRect.x() + pageRect.width(), pageRect.y() + pageRect.height());
|
|
|
|
timeT t0 = m_hlayout->getTimeForX(cc0.first);
|
|
timeT t1 = m_hlayout->getTimeForX(cc1.first);
|
|
|
|
m_staffs[i]->renderPrintable(t0, t1);
|
|
}
|
|
|
|
printpainter.translate( -pageWidth, 0);
|
|
|
|
if (pli != pages.end() && *pli - 1 < maxPageCount)
|
|
printer.newPage();
|
|
|
|
for (size_t i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->markChanged(); // recover any memory used for this page
|
|
PixmapArrayGC::deleteAll();
|
|
}
|
|
}
|
|
|
|
for (size_t i = 0; i < m_staffs.size(); ++i) {
|
|
for (Segment::iterator j = m_staffs[i]->getSegment().begin();
|
|
j != m_staffs[i]->getSegment().end(); ++j) {
|
|
removeViewLocalProperties(*j);
|
|
}
|
|
delete m_staffs[i];
|
|
}
|
|
m_staffs.clear();
|
|
|
|
printpainter.end();
|
|
|
|
Profiles::getInstance()->dump();
|
|
}
|
|
|
|
void
|
|
NotationView::updateThumbnails(bool complete)
|
|
{
|
|
if (m_pageMode != LinedStaff::MultiPageMode)
|
|
return ;
|
|
|
|
int pageWidth = getPageWidth();
|
|
int pageHeight = getPageHeight();
|
|
int leftMargin = 0, topMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
int maxPageCount = 1;
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
int pageCount = m_staffs[i]->getPageCount();
|
|
if (pageCount > maxPageCount)
|
|
maxPageCount = pageCount;
|
|
}
|
|
|
|
int thumbScale = 20;
|
|
TQPixmap thumbnail(canvas()->width() / thumbScale,
|
|
canvas()->height() / thumbScale);
|
|
thumbnail.fill(TQt::white);
|
|
TQPainter thumbPainter(&thumbnail);
|
|
|
|
if (complete) {
|
|
|
|
thumbPainter.scale(1.0 / double(thumbScale), 1.0 / double(thumbScale));
|
|
thumbPainter.setPen(TQt::black);
|
|
thumbPainter.setBrush(TQt::white);
|
|
|
|
/*
|
|
TQCanvas *canvas = getCanvasView()->canvas();
|
|
canvas->drawArea(TQRect(0, 0, canvas->width(), canvas->height()),
|
|
&thumbPainter, false);
|
|
*/
|
|
// hide small texts, as we get a crash in Xft when trying to
|
|
// render them at this scale
|
|
if (m_title)
|
|
m_title->hide();
|
|
if (m_subtitle)
|
|
m_subtitle->hide();
|
|
if (m_composer)
|
|
m_composer->hide();
|
|
if (m_copyright)
|
|
m_copyright->hide();
|
|
|
|
for (size_t page = 0; page < static_cast<size_t>(maxPageCount); ++page) {
|
|
|
|
bool havePageNumber = ((m_pageNumbers.size() > page) &&
|
|
(m_pageNumbers[page] != 0));
|
|
if (havePageNumber)
|
|
m_pageNumbers[page]->hide();
|
|
|
|
TQRect pageRect(m_leftGutter + leftMargin * 2 + pageWidth * page,
|
|
topMargin * 2,
|
|
pageWidth - leftMargin*3,
|
|
pageHeight - topMargin*3);
|
|
|
|
TQCanvas *canvas = getCanvasView()->canvas();
|
|
canvas->drawArea(pageRect, &thumbPainter, false);
|
|
|
|
if (havePageNumber)
|
|
m_pageNumbers[page]->show();
|
|
}
|
|
|
|
if (m_title)
|
|
m_title->show();
|
|
if (m_subtitle)
|
|
m_subtitle->show();
|
|
if (m_composer)
|
|
m_composer->show();
|
|
if (m_copyright)
|
|
m_copyright->show();
|
|
|
|
} else {
|
|
|
|
thumbPainter.setPen(TQt::black);
|
|
|
|
for (int page = 0; page < maxPageCount; ++page) {
|
|
|
|
int x = m_leftGutter + pageWidth * page + leftMargin / 4;
|
|
int y = 20;
|
|
int w = pageWidth - leftMargin / 2;
|
|
int h = pageHeight;
|
|
|
|
TQString str = TQString("%1").arg(page + 1);
|
|
|
|
thumbPainter.drawRect(x / thumbScale, y / thumbScale,
|
|
w / thumbScale, h / thumbScale);
|
|
|
|
int tx = (x + w / 2) / thumbScale, ty = (y + h / 2) / thumbScale;
|
|
tx -= thumbPainter.fontMetrics().width(str) / 2;
|
|
thumbPainter.drawText(tx, ty, str);
|
|
}
|
|
}
|
|
|
|
thumbPainter.end();
|
|
if (m_pannerDialog)
|
|
m_pannerDialog->scrollbox()->setThumbnail(thumbnail);
|
|
}
|
|
|
|
void NotationView::refreshSegment(Segment *segment,
|
|
timeT startTime, timeT endTime)
|
|
{
|
|
NOTATION_DEBUG << "*** " << endl;
|
|
|
|
if (m_inhibitRefresh)
|
|
return ;
|
|
NOTATION_DEBUG << "NotationView::refreshSegment(" << segment << "," << startTime << "," << endTime << ")" << endl;
|
|
Profiler foo("NotationView::refreshSegment");
|
|
|
|
emit usedSelection();
|
|
|
|
if (segment) {
|
|
LinedStaff *staff = getLinedStaff(*segment);
|
|
if (staff)
|
|
applyLayout(staff->getId(), startTime, endTime);
|
|
} else {
|
|
applyLayout( -1, startTime, endTime);
|
|
}
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
Segment *ssegment = &m_staffs[i]->getSegment();
|
|
bool thisStaff = (ssegment == segment || segment == 0);
|
|
m_staffs[i]->markChanged(startTime, endTime, !thisStaff);
|
|
}
|
|
|
|
PixmapArrayGC::deleteAll();
|
|
|
|
statusBar()->changeItem(KTmpStatusMsg::getDefaultMsg(),
|
|
KTmpStatusMsg::getDefaultId());
|
|
|
|
Event::dumpStats(std::cerr);
|
|
if (m_deferredCursorMove == NoCursorMoveNeeded) {
|
|
slotSetInsertCursorPosition(getInsertionTime(), false, false);
|
|
} else {
|
|
doDeferredCursorMove();
|
|
}
|
|
slotSetPointerPosition(getDocument()->getComposition().getPosition(), false);
|
|
|
|
if (m_currentEventSelection &&
|
|
m_currentEventSelection->getSegmentEvents().size() == 0) {
|
|
delete m_currentEventSelection;
|
|
m_currentEventSelection = 0;
|
|
//!!!??? was that the right thing to do?
|
|
}
|
|
|
|
setMenuStates();
|
|
slotSetOperationNameAndStatus(i18n(" Ready."));
|
|
NOTATION_DEBUG << "*** " << endl;
|
|
}
|
|
|
|
void NotationView::setMenuStates()
|
|
{
|
|
// 1. set selection-related states
|
|
|
|
// Clear states first, then enter only those ones that apply
|
|
// (so as to avoid ever clearing one after entering another, in
|
|
// case the two overlap at all)
|
|
stateChanged("have_selection", KXMLGUIClient::StateReverse);
|
|
stateChanged("have_notes_in_selection", KXMLGUIClient::StateReverse);
|
|
stateChanged("have_rests_in_selection", KXMLGUIClient::StateReverse);
|
|
|
|
if (m_currentEventSelection) {
|
|
|
|
NOTATION_DEBUG << "NotationView::setMenuStates: Have selection; it's " << m_currentEventSelection << " covering range from " << m_currentEventSelection->getStartTime() << " to " << m_currentEventSelection->getEndTime() << " (" << m_currentEventSelection->getSegmentEvents().size() << " events)" << endl;
|
|
|
|
stateChanged("have_selection", KXMLGUIClient::StateNoReverse);
|
|
if (m_currentEventSelection->contains
|
|
(Note::EventType)) {
|
|
stateChanged("have_notes_in_selection",
|
|
KXMLGUIClient::StateNoReverse);
|
|
}
|
|
if (m_currentEventSelection->contains
|
|
(Note::EventRestType)) {
|
|
stateChanged("have_rests_in_selection",
|
|
KXMLGUIClient::StateNoReverse);
|
|
}
|
|
}
|
|
|
|
// 2. set inserter-related states
|
|
|
|
// #1372863 -- RestInserter is a subclass of NoteInserter, so we
|
|
// need to test dynamic_cast<RestInserter *> before
|
|
// dynamic_cast<NoteInserter *> (which will succeed for both)
|
|
|
|
if (dynamic_cast<RestInserter *>(m_tool)) {
|
|
NOTATION_DEBUG << "Have rest inserter " << endl;
|
|
stateChanged("note_insert_tool_current", StateReverse);
|
|
stateChanged("rest_insert_tool_current", StateNoReverse);
|
|
} else if (dynamic_cast<NoteInserter *>(m_tool)) {
|
|
NOTATION_DEBUG << "Have note inserter " << endl;
|
|
stateChanged("note_insert_tool_current", StateNoReverse);
|
|
stateChanged("rest_insert_tool_current", StateReverse);
|
|
} else {
|
|
NOTATION_DEBUG << "Have neither inserter " << endl;
|
|
stateChanged("note_insert_tool_current", StateReverse);
|
|
stateChanged("rest_insert_tool_current", StateReverse);
|
|
}
|
|
}
|
|
|
|
#define UPDATE_PROGRESS(n) \
|
|
progressCount += (n); \
|
|
if (progressTotal > 0) { \
|
|
emit setProgress(progressCount * 100 / progressTotal); \
|
|
ProgressDialog::processEvents(); \
|
|
}
|
|
|
|
void NotationView::readjustCanvasSize()
|
|
{
|
|
Profiler profiler("NotationView::readjustCanvasSize");
|
|
|
|
double maxWidth = 0.0;
|
|
int maxHeight = 0;
|
|
|
|
slotSetOperationNameAndStatus(i18n("Sizing and allocating canvas..."));
|
|
ProgressDialog::processEvents();
|
|
|
|
int progressTotal = m_staffs.size() + 2;
|
|
int progressCount = 0;
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
LinedStaff &staff = *m_staffs[i];
|
|
|
|
staff.sizeStaff(*m_hlayout);
|
|
UPDATE_PROGRESS(1);
|
|
|
|
if (staff.getTotalWidth() + staff.getX() > maxWidth) {
|
|
maxWidth = staff.getTotalWidth() + staff.getX() + 1;
|
|
}
|
|
|
|
if (staff.getTotalHeight() + staff.getY() > maxHeight) {
|
|
maxHeight = staff.getTotalHeight() + staff.getY() + 1;
|
|
}
|
|
}
|
|
|
|
int topMargin = 0, leftMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
|
|
int pageWidth = getPageWidth();
|
|
int pageHeight = getPageHeight();
|
|
|
|
NOTATION_DEBUG << "NotationView::readjustCanvasSize: maxHeight is "
|
|
<< maxHeight << ", page height is " << pageHeight << endl
|
|
<< " - maxWidth is " << maxWidth << ", page width is " << pageWidth << endl;
|
|
|
|
|
|
if (m_pageMode == LinedStaff::LinearMode) {
|
|
maxWidth = ((maxWidth / pageWidth) + 1) * pageWidth;
|
|
if (maxHeight < pageHeight)
|
|
maxHeight = pageHeight;
|
|
} else {
|
|
if (maxWidth < pageWidth)
|
|
maxWidth = pageWidth;
|
|
if (maxHeight < pageHeight + topMargin*2)
|
|
maxHeight = pageHeight + topMargin * 2;
|
|
}
|
|
|
|
// now get the EditView to do the biz
|
|
readjustViewSize(TQSize(int(maxWidth), maxHeight), true);
|
|
|
|
UPDATE_PROGRESS(2);
|
|
|
|
if (m_pannerDialog) {
|
|
|
|
if (m_pageMode != LinedStaff::MultiPageMode) {
|
|
m_pannerDialog->hide();
|
|
|
|
} else {
|
|
|
|
m_pannerDialog->show();
|
|
|
|
m_pannerDialog->setPageSize
|
|
(TQSize(canvas()->width(),
|
|
canvas()->height()));
|
|
|
|
m_pannerDialog->scrollbox()->setViewSize
|
|
(TQSize(getCanvasView()->width(),
|
|
getCanvasView()->height()));
|
|
}
|
|
}
|
|
|
|
// Give a correct vertical alignment to track headers
|
|
if ((m_pageMode == LinedStaff::LinearMode) && m_showHeadersGroup) {
|
|
m_headersGroupView->setContentsPos(0, getCanvasView()->contentsY());
|
|
}
|
|
}
|
|
|
|
void NotationView::slotNoteAction()
|
|
{
|
|
const TQObject* sigSender = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
|
|
NoteActionDataMap::Iterator noteAct =
|
|
m_noteActionDataMap->find(sigSender->name());
|
|
|
|
if (noteAct != m_noteActionDataMap->end()) {
|
|
m_lastNoteAction = sigSender->name();
|
|
setCurrentSelectedNote(**noteAct);
|
|
setMenuStates();
|
|
} else {
|
|
std::cerr << "NotationView::slotNoteAction() : couldn't find NoteActionData named '"
|
|
<< sigSender->name() << "'\n";
|
|
}
|
|
}
|
|
|
|
void NotationView::slotLastNoteAction()
|
|
{
|
|
TDEAction *action = actionCollection()->action(m_lastNoteAction.ascii());
|
|
if (!action)
|
|
action = actionCollection()->action("crotchet");
|
|
|
|
if (action) {
|
|
action->activate();
|
|
} else {
|
|
std::cerr << "NotationView::slotNoteAction() : couldn't find action named '"
|
|
<< m_lastNoteAction.ascii() << "' or 'crotchet'\n";
|
|
}
|
|
}
|
|
|
|
void NotationView::slotAddMark()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
MarkActionDataMap::Iterator i = m_markActionDataMap->find(s->name());
|
|
|
|
if (i != m_markActionDataMap->end()) {
|
|
addCommandToHistory(new AddMarkCommand
|
|
((**i).mark, *m_currentEventSelection));
|
|
}
|
|
}
|
|
|
|
void NotationView::slotNoteChangeAction()
|
|
{
|
|
const TQObject* sigSender = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
|
|
NoteChangeActionDataMap::Iterator noteAct =
|
|
m_noteChangeActionDataMap->find(sigSender->name());
|
|
|
|
if (noteAct != m_noteChangeActionDataMap->end()) {
|
|
slotSetNoteDurations((**noteAct).noteType, (**noteAct).notationOnly);
|
|
} else {
|
|
std::cerr << "NotationView::slotNoteChangeAction() : couldn't find NoteChangeAction named '"
|
|
<< sigSender->name() << "'\n";
|
|
}
|
|
}
|
|
|
|
void NotationView::initActionDataMaps()
|
|
{
|
|
static bool called = false;
|
|
static int keys[] =
|
|
{ Key_0, Key_3, Key_6, Key_8, Key_4, Key_2, Key_1, Key_5 };
|
|
|
|
if (called)
|
|
return ;
|
|
called = true;
|
|
|
|
m_noteActionDataMap = new NoteActionDataMap;
|
|
|
|
for (int rest = 0; rest < 2; ++rest) {
|
|
for (int dots = 0; dots < 2; ++dots) {
|
|
for (int type = Note::Longest; type >= Note::Shortest; --type) {
|
|
if (dots && (type == Note::Longest))
|
|
continue;
|
|
|
|
TQString refName
|
|
(NotationStrings::getReferenceName(Note(type, dots), rest == 1));
|
|
|
|
TQString shortName(refName);
|
|
shortName.replace(TQRegExp("-"), "_");
|
|
|
|
TQString titleName
|
|
(NotationStrings::getNoteName(Note(type, dots)));
|
|
|
|
titleName = titleName.left(1).upper() +
|
|
titleName.right(titleName.length() - 1);
|
|
|
|
if (rest) {
|
|
titleName.replace(TQRegExp(i18n("note")), i18n("rest"));
|
|
}
|
|
|
|
int keycode = keys[type - Note::Shortest];
|
|
if (dots) // keycode += CTRL; -- used below for note change action
|
|
keycode = 0;
|
|
if (rest) // keycode += SHIFT; -- can't do shift+numbers
|
|
keycode = 0;
|
|
|
|
m_noteActionDataMap->insert
|
|
(shortName, new NoteActionData
|
|
(titleName, shortName, refName, keycode,
|
|
rest > 0, type, dots));
|
|
}
|
|
}
|
|
}
|
|
|
|
m_noteChangeActionDataMap = new NoteChangeActionDataMap;
|
|
|
|
for (int notationOnly = 0; notationOnly <= 1; ++notationOnly) {
|
|
for (int type = Note::Longest; type >= Note::Shortest; --type) {
|
|
|
|
TQString refName
|
|
(NotationStrings::getReferenceName(Note(type, 0), false));
|
|
|
|
TQString shortName(TQString("change_%1%2")
|
|
.arg(notationOnly ? "notation_" : "").arg(refName));
|
|
shortName.replace(TQRegExp("-"), "_");
|
|
|
|
TQString titleName
|
|
(NotationStrings::getNoteName(Note(type, 0)));
|
|
|
|
titleName = titleName.left(1).upper() +
|
|
titleName.right(titleName.length() - 1);
|
|
|
|
int keycode = keys[type - Note::Shortest];
|
|
keycode += CTRL;
|
|
if (notationOnly)
|
|
keycode += ALT;
|
|
|
|
m_noteChangeActionDataMap->insert
|
|
(shortName, new NoteChangeActionData
|
|
(titleName, shortName, refName, keycode,
|
|
notationOnly ? true : false, type));
|
|
}
|
|
}
|
|
|
|
m_markActionDataMap = new MarkActionDataMap;
|
|
|
|
std::vector<Mark> marks = Marks::getStandardMarks();
|
|
for (unsigned int i = 0; i < marks.size(); ++i) {
|
|
|
|
Mark mark = marks[i];
|
|
TQString markName(strtoqstr(mark));
|
|
TQString actionName = TQString("add_%1").arg(markName);
|
|
|
|
m_markActionDataMap->insert
|
|
(actionName, new MarkActionData
|
|
(AddMarkCommand::getGlobalName(mark),
|
|
actionName, 0, mark));
|
|
}
|
|
|
|
}
|
|
|
|
void NotationView::setupProgress(KProgress* bar)
|
|
{
|
|
if (bar) {
|
|
NOTATION_DEBUG << "NotationView::setupProgress(bar)\n";
|
|
|
|
connect(m_hlayout, TQT_SIGNAL(setProgress(int)),
|
|
bar, TQT_SLOT(setValue(int)));
|
|
|
|
connect(m_hlayout, TQT_SIGNAL(incrementProgress(int)),
|
|
bar, TQT_SLOT(advance(int)));
|
|
|
|
connect(this, TQT_SIGNAL(setProgress(int)),
|
|
bar, TQT_SLOT(setValue(int)));
|
|
|
|
connect(this, TQT_SIGNAL(incrementProgress(int)),
|
|
bar, TQT_SLOT(advance(int)));
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
connect(m_staffs[i], TQT_SIGNAL(setProgress(int)),
|
|
bar, TQT_SLOT(setValue(int)));
|
|
|
|
connect(m_staffs[i], TQT_SIGNAL(incrementProgress(int)),
|
|
bar, TQT_SLOT(advance(int)));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void NotationView::setupProgress(ProgressDialog* dialog)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::setupProgress(dialog)" << endl;
|
|
disconnectProgress();
|
|
|
|
if (dialog) {
|
|
setupProgress(dialog->progressBar());
|
|
|
|
connect(dialog, TQT_SIGNAL(cancelClicked()),
|
|
m_hlayout, TQT_SLOT(slotCancel()));
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
connect(m_staffs[i], TQT_SIGNAL(setOperationName(TQString)),
|
|
this, TQT_SLOT(slotSetOperationNameAndStatus(TQString)));
|
|
|
|
connect(dialog, TQT_SIGNAL(cancelClicked()),
|
|
m_staffs[i], TQT_SLOT(slotCancel()));
|
|
}
|
|
|
|
connect(this, TQT_SIGNAL(setOperationName(TQString)),
|
|
dialog, TQT_SLOT(slotSetOperationName(TQString)));
|
|
m_progressDisplayer = PROGRESS_DIALOG;
|
|
}
|
|
|
|
}
|
|
|
|
void NotationView::slotSetOperationNameAndStatus(TQString name)
|
|
{
|
|
emit setOperationName(name);
|
|
statusBar()->changeItem(TQString(" %1").arg(name),
|
|
KTmpStatusMsg::getDefaultId());
|
|
}
|
|
|
|
void NotationView::disconnectProgress()
|
|
{
|
|
NOTATION_DEBUG << "NotationView::disconnectProgress()" << endl;
|
|
|
|
m_hlayout->disconnect();
|
|
disconnect(TQT_SIGNAL(setProgress(int)));
|
|
disconnect(TQT_SIGNAL(incrementProgress(int)));
|
|
disconnect(TQT_SIGNAL(setOperationName(TQString)));
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->disconnect();
|
|
}
|
|
}
|
|
|
|
void NotationView::setupDefaultProgress()
|
|
{
|
|
if (m_progressDisplayer != PROGRESS_BAR) {
|
|
NOTATION_DEBUG << "NotationView::setupDefaultProgress()" << endl;
|
|
disconnectProgress();
|
|
setupProgress(m_progressBar);
|
|
m_progressDisplayer = PROGRESS_BAR;
|
|
}
|
|
}
|
|
|
|
void NotationView::updateViewCaption()
|
|
{
|
|
if (m_segments.size() == 1) {
|
|
|
|
TrackId trackId = m_segments[0]->getTrack();
|
|
Track *track =
|
|
m_segments[0]->getComposition()->getTrackById(trackId);
|
|
|
|
int trackPosition = -1;
|
|
if (track)
|
|
trackPosition = track->getPosition();
|
|
// std::cout << std::endl << std::endl << std::endl << "DEBUG TITLE BAR: " << getDocument()->getTitle() << std::endl << std::endl << std::endl;
|
|
setCaption(i18n("%1 - Segment Track #%2 - Notation")
|
|
.arg(getDocument()->getTitle())
|
|
.arg(trackPosition + 1));
|
|
|
|
} else if (m_segments.size() == getDocument()->getComposition().getNbSegments()) {
|
|
|
|
setCaption(i18n("%1 - All Segments - Notation")
|
|
.arg(getDocument()->getTitle()));
|
|
|
|
} else {
|
|
|
|
setCaption(i18n("%1 - Segment - Notation", "%1 - %n Segments - Notation", m_segments.size())
|
|
.arg(getDocument()->getTitle()));
|
|
|
|
}
|
|
}
|
|
|
|
NotationView::NoteActionDataMap* NotationView::m_noteActionDataMap = 0;
|
|
|
|
NotationView::NoteChangeActionDataMap* NotationView::m_noteChangeActionDataMap = 0;
|
|
|
|
NotationView::MarkActionDataMap* NotationView::m_markActionDataMap = 0;
|
|
|
|
|
|
/// SLOTS
|
|
|
|
|
|
void
|
|
NotationView::slotUpdateInsertModeStatus()
|
|
{
|
|
TQString tripletMessage = i18n("Triplet");
|
|
TQString chordMessage = i18n("Chord");
|
|
TQString graceMessage = i18n("Grace");
|
|
TQString message;
|
|
|
|
if (isInTripletMode()) {
|
|
message = i18n("%1 %2").arg(message).arg(tripletMessage);
|
|
}
|
|
|
|
if (isInChordMode()) {
|
|
message = i18n("%1 %2").arg(message).arg(chordMessage);
|
|
}
|
|
|
|
if (isInGraceMode()) {
|
|
message = i18n("%1 %2").arg(message).arg(graceMessage);
|
|
}
|
|
|
|
m_insertModeLabel->setText(message);
|
|
}
|
|
|
|
void
|
|
NotationView::slotUpdateAnnotationsStatus()
|
|
{
|
|
if (!areAnnotationsVisible()) {
|
|
for (int i = 0; i < getStaffCount(); ++i) {
|
|
Segment &s = getStaff(i)->getSegment();
|
|
for (Segment::iterator j = s.begin(); j != s.end(); ++j) {
|
|
if ((*j)->isa(Text::EventType) &&
|
|
((*j)->get<String>(Text::TextTypePropertyName)
|
|
== Text::Annotation)) {
|
|
m_annotationsLabel->setText(i18n("Hidden annotations"));
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
m_annotationsLabel->setText("");
|
|
getToggleAction("show_annotations")->setChecked(areAnnotationsVisible());
|
|
}
|
|
|
|
void
|
|
NotationView::slotUpdateLilyPondDirectivesStatus()
|
|
{
|
|
if (!areLilyPondDirectivesVisible()) {
|
|
for (int i = 0; i < getStaffCount(); ++i) {
|
|
Segment &s = getStaff(i)->getSegment();
|
|
for (Segment::iterator j = s.begin(); j != s.end(); ++j) {
|
|
if ((*j)->isa(Text::EventType) &&
|
|
((*j)->get
|
|
<String>
|
|
(Text::TextTypePropertyName)
|
|
== Text::LilyPondDirective)) {
|
|
m_lilyPondDirectivesLabel->setText(i18n("Hidden LilyPond directives"));
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
m_lilyPondDirectivesLabel->setText("");
|
|
getToggleAction("show_lilypond_directives")->setChecked(areLilyPondDirectivesVisible());
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeSpacingFromStringValue(const TQString& spacingT)
|
|
{
|
|
// spacingT has a '%' at the end
|
|
//
|
|
int spacing = spacingT.left(spacingT.length() - 1).toInt();
|
|
slotChangeSpacing(spacing);
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeSpacingFromAction()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
TQString name = s->name();
|
|
|
|
if (name.left(8) == "spacing_") {
|
|
int spacing = name.right(name.length() - 8).toInt();
|
|
|
|
if (spacing > 0)
|
|
slotChangeSpacing(spacing);
|
|
|
|
} else {
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown spacing action %1").arg(name));
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeSpacing(int spacing)
|
|
{
|
|
if (m_hlayout->getSpacing() == spacing)
|
|
return ;
|
|
|
|
m_hlayout->setSpacing(spacing);
|
|
|
|
// m_spacingSlider->setSize(spacing);
|
|
|
|
TDEToggleAction *action = dynamic_cast<TDEToggleAction *>
|
|
(actionCollection()->action(TQString("spacing_%1").arg(spacing).ascii()));
|
|
if (action)
|
|
action->setChecked(true);
|
|
else {
|
|
std::cerr
|
|
<< "WARNING: Expected action \"spacing_" << spacing
|
|
<< "\" to be a TDEToggleAction, but it isn't (or doesn't exist)"
|
|
<< std::endl;
|
|
}
|
|
|
|
positionStaffs();
|
|
applyLayout();
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->markChanged();
|
|
}
|
|
|
|
positionPages();
|
|
updateControlRulers(true);
|
|
updateView();
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeProportionFromIndex(int n)
|
|
{
|
|
std::vector<int> proportions = m_hlayout->getAvailableProportions();
|
|
if (n >= (int)proportions.size())
|
|
n = proportions.size() - 1;
|
|
slotChangeProportion(proportions[n]);
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeProportionFromAction()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
TQString name = s->name();
|
|
|
|
if (name.left(11) == "proportion_") {
|
|
int proportion = name.right(name.length() - 11).toInt();
|
|
slotChangeProportion(proportion);
|
|
|
|
} else {
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown proportion action %1").arg(name));
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeProportion(int proportion)
|
|
{
|
|
if (m_hlayout->getProportion() == proportion)
|
|
return ;
|
|
|
|
m_hlayout->setProportion(proportion);
|
|
|
|
// m_proportionSlider->setSize(proportion);
|
|
|
|
TDEToggleAction *action = dynamic_cast<TDEToggleAction *>
|
|
(actionCollection()->action(TQString("proportion_%1").arg(proportion).ascii()));
|
|
if (action)
|
|
action->setChecked(true);
|
|
else {
|
|
std::cerr
|
|
<< "WARNING: Expected action \"proportion_" << proportion
|
|
<< "\" to be a TDEToggleAction, but it isn't (or doesn't exist)"
|
|
<< std::endl;
|
|
}
|
|
|
|
positionStaffs();
|
|
applyLayout();
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->markChanged();
|
|
}
|
|
|
|
positionPages();
|
|
updateControlRulers(true);
|
|
updateView();
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeFontFromAction()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
TQString name = s->name();
|
|
if (name.left(10) == "note_font_") {
|
|
name = name.right(name.length() - 10);
|
|
slotChangeFont(name);
|
|
} else {
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown font action %1").arg(name));
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeFontSizeFromAction()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
TQString name = s->name();
|
|
|
|
if (name.left(15) == "note_font_size_") {
|
|
name = name.right(name.length() - 15);
|
|
bool ok = false;
|
|
int size = name.toInt(&ok);
|
|
if (ok)
|
|
slotChangeFont(m_fontName, size);
|
|
else {
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown font size %1").arg(name));
|
|
}
|
|
} else {
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown font size action %1").arg(name));
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeFont(const TQString &newName)
|
|
{
|
|
NOTATION_DEBUG << "changeFont: " << newName << endl;
|
|
slotChangeFont(std::string(newName.utf8()));
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeFont(std::string newName)
|
|
{
|
|
int newSize = m_fontSize;
|
|
|
|
if (!NoteFontFactory::isAvailableInSize(newName, newSize)) {
|
|
|
|
int defaultSize = NoteFontFactory::getDefaultSize(newName);
|
|
newSize = m_config->readUnsignedNumEntry
|
|
((getStaffCount() > 1 ?
|
|
"multistaffnotesize" : "singlestaffnotesize"), defaultSize);
|
|
|
|
if (!NoteFontFactory::isAvailableInSize(newName, newSize)) {
|
|
newSize = defaultSize;
|
|
}
|
|
}
|
|
|
|
slotChangeFont(newName, newSize);
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeFontSize(int newSize)
|
|
{
|
|
slotChangeFont(m_fontName, newSize);
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeFontSizeFromStringValue(const TQString& sizeT)
|
|
{
|
|
int size = sizeT.toInt();
|
|
slotChangeFont(m_fontName, size);
|
|
}
|
|
|
|
void
|
|
NotationView::slotZoomIn()
|
|
{
|
|
std::vector<int> sizes = NoteFontFactory::getScreenSizes(m_fontName);
|
|
for (int i = 0; i + 1 < sizes.size(); ++i) {
|
|
if (sizes[i] == m_fontSize) {
|
|
slotChangeFontSize(sizes[i + 1]);
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotZoomOut()
|
|
{
|
|
std::vector<int> sizes = NoteFontFactory::getScreenSizes(m_fontName);
|
|
for (int i = 1; i < sizes.size(); ++i) {
|
|
if (sizes[i] == m_fontSize) {
|
|
slotChangeFontSize(sizes[i - 1]);
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotChangeFont(std::string newName, int newSize)
|
|
{
|
|
if (newName == m_fontName && newSize == m_fontSize)
|
|
return ;
|
|
|
|
NotePixmapFactory* npf = 0;
|
|
|
|
try {
|
|
npf = new NotePixmapFactory(newName, newSize);
|
|
} catch (...) {
|
|
return ;
|
|
}
|
|
|
|
bool changedFont = (newName != m_fontName || newSize != m_fontSize);
|
|
|
|
std::string oldName = m_fontName;
|
|
m_fontName = newName;
|
|
m_fontSize = newSize;
|
|
setNotePixmapFactory(npf);
|
|
|
|
// update the various GUI elements
|
|
|
|
std::set<std::string> fs(NoteFontFactory::getFontNames());
|
|
std::vector<std::string> f(fs.begin(), fs.end());
|
|
std::sort(f.begin(), f.end());
|
|
|
|
for (unsigned int i = 0; i < f.size(); ++i) {
|
|
bool thisOne = (f[i] == m_fontName);
|
|
if (thisOne)
|
|
m_fontCombo->setCurrentItem(i);
|
|
TDEToggleAction *action = dynamic_cast<TDEToggleAction *>
|
|
(actionCollection()->action(TQString("note_font_" + strtoqstr(f[i])).ascii()));
|
|
NOTATION_DEBUG << "inspecting " << f[i] << (action ? ", have action" : ", no action") << endl;
|
|
if (action)
|
|
action->setChecked(thisOne);
|
|
else {
|
|
std::cerr
|
|
<< "WARNING: Expected action \"note_font_" << f[i]
|
|
<< "\" to be a TDEToggleAction, but it isn't (or doesn't exist)"
|
|
<< std::endl;
|
|
}
|
|
}
|
|
|
|
NOTATION_DEBUG << "about to reinitialise sizes" << endl;
|
|
|
|
std::vector<int> sizes = NoteFontFactory::getScreenSizes(m_fontName);
|
|
m_fontSizeCombo->clear();
|
|
TQString value;
|
|
for (std::vector<int>::iterator i = sizes.begin(); i != sizes.end(); ++i) {
|
|
value.setNum(*i);
|
|
m_fontSizeCombo->insertItem(value);
|
|
}
|
|
value.setNum(m_fontSize);
|
|
m_fontSizeCombo->setCurrentText(value);
|
|
|
|
setupFontSizeMenu(oldName);
|
|
|
|
if (!changedFont)
|
|
return ; // might have been called to initialise menus etc
|
|
|
|
NOTATION_DEBUG << "about to change font" << endl;
|
|
|
|
if (m_pageMode == LinedStaff::MultiPageMode) {
|
|
|
|
int pageWidth = getPageWidth();
|
|
int topMargin = 0, leftMargin = 0;
|
|
getPageMargins(leftMargin, topMargin);
|
|
|
|
m_hlayout->setPageWidth(pageWidth - leftMargin * 2);
|
|
}
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->changeFont(m_fontName, m_fontSize);
|
|
}
|
|
|
|
NOTATION_DEBUG << "about to position staffs" << endl;
|
|
|
|
positionStaffs();
|
|
|
|
bool layoutApplied = applyLayout();
|
|
if (!layoutApplied)
|
|
KMessageBox::sorry(0, "Couldn't apply layout");
|
|
else {
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
m_staffs[i]->markChanged();
|
|
}
|
|
}
|
|
|
|
positionPages();
|
|
updateControlRulers(true);
|
|
updateView();
|
|
}
|
|
|
|
void
|
|
NotationView::slotFilePrint()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Printing..."), this);
|
|
|
|
SetWaitCursor waitCursor;
|
|
NotationView printingView(getDocument(), m_segments,
|
|
(TQWidget *)parent(), this);
|
|
|
|
if (!printingView.isOK()) {
|
|
NOTATION_DEBUG << "Print : operation cancelled\n";
|
|
return ;
|
|
}
|
|
|
|
printingView.print();
|
|
}
|
|
|
|
void
|
|
NotationView::slotFilePrintPreview()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Previewing..."), this);
|
|
|
|
SetWaitCursor waitCursor;
|
|
NotationView printingView(getDocument(), m_segments,
|
|
(TQWidget *)parent(), this);
|
|
|
|
if (!printingView.isOK()) {
|
|
NOTATION_DEBUG << "Print preview : operation cancelled\n";
|
|
return ;
|
|
}
|
|
|
|
printingView.print(true);
|
|
}
|
|
|
|
std::map<TDEProcess *, KTempFile *> NotationView::m_lilyTempFileMap;
|
|
|
|
void NotationView::slotPrintLilyPond()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Printing LilyPond file..."), this);
|
|
KTempFile *file = new KTempFile(TQString(), ".ly");
|
|
file->setAutoDelete(true);
|
|
if (!file->name()) {
|
|
// CurrentProgressDialog::freeze();
|
|
KMessageBox::sorry(this, i18n("Failed to open a temporary file for LilyPond export."));
|
|
delete file;
|
|
}
|
|
if (!exportLilyPondFile(file->name(), true)) {
|
|
return ;
|
|
}
|
|
TDEProcess *proc = new TDEProcess;
|
|
*proc << "rosegarden-lilypondview";
|
|
*proc << "--graphical";
|
|
*proc << "--print";
|
|
*proc << file->name();
|
|
connect(proc, TQT_SIGNAL(processExited(TDEProcess *)),
|
|
this, TQT_SLOT(slotLilyPondViewProcessExited(TDEProcess *)));
|
|
m_lilyTempFileMap[proc] = file;
|
|
proc->start(TDEProcess::NotifyOnExit);
|
|
}
|
|
|
|
void NotationView::slotPreviewLilyPond()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Previewing LilyPond file..."), this);
|
|
KTempFile *file = new KTempFile(TQString(), ".ly");
|
|
file->setAutoDelete(true);
|
|
if (!file->name()) {
|
|
// CurrentProgressDialog::freeze();
|
|
KMessageBox::sorry(this, i18n("Failed to open a temporary file for LilyPond export."));
|
|
delete file;
|
|
}
|
|
if (!exportLilyPondFile(file->name(), true)) {
|
|
return ;
|
|
}
|
|
TDEProcess *proc = new TDEProcess;
|
|
*proc << "rosegarden-lilypondview";
|
|
*proc << "--graphical";
|
|
*proc << "--pdf";
|
|
*proc << file->name();
|
|
connect(proc, TQT_SIGNAL(processExited(TDEProcess *)),
|
|
this, TQT_SLOT(slotLilyPondViewProcessExited(TDEProcess *)));
|
|
m_lilyTempFileMap[proc] = file;
|
|
proc->start(TDEProcess::NotifyOnExit);
|
|
}
|
|
|
|
void NotationView::slotLilyPondViewProcessExited(TDEProcess *p)
|
|
{
|
|
delete m_lilyTempFileMap[p];
|
|
m_lilyTempFileMap.erase(p);
|
|
delete p;
|
|
}
|
|
|
|
bool NotationView::exportLilyPondFile(TQString file, bool forPreview)
|
|
{
|
|
TQString caption = "", heading = "";
|
|
if (forPreview) {
|
|
caption = i18n("LilyPond Preview Options");
|
|
heading = i18n("LilyPond preview options");
|
|
}
|
|
|
|
LilyPondOptionsDialog dialog(this, m_doc, caption, heading);
|
|
if (dialog.exec() != TQDialog::Accepted) {
|
|
return false;
|
|
}
|
|
|
|
ProgressDialog progressDlg(i18n("Exporting LilyPond file..."),
|
|
100,
|
|
this);
|
|
|
|
LilyPondExporter e(this, m_doc, std::string(TQFile::encodeName(file)));
|
|
|
|
connect(&e, TQT_SIGNAL(setProgress(int)),
|
|
progressDlg.progressBar(), TQT_SLOT(setValue(int)));
|
|
|
|
connect(&e, TQT_SIGNAL(incrementProgress(int)),
|
|
progressDlg.progressBar(), TQT_SLOT(advance(int)));
|
|
|
|
if (!e.write()) {
|
|
// CurrentProgressDialog::freeze();
|
|
KMessageBox::sorry(this, i18n("Export failed. The file could not be opened for writing."));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void NotationView::slotEditCut()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Cutting selection to clipboard..."), this);
|
|
|
|
addCommandToHistory(new CutCommand(*m_currentEventSelection,
|
|
getDocument()->getClipboard()));
|
|
}
|
|
|
|
void NotationView::slotEditDelete()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Deleting selection..."), this);
|
|
|
|
addCommandToHistory(new EraseCommand(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotEditCopy()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Copying selection to clipboard..."), this);
|
|
|
|
addCommandToHistory(new CopyCommand(*m_currentEventSelection,
|
|
getDocument()->getClipboard()));
|
|
}
|
|
|
|
void NotationView::slotEditCutAndClose()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Cutting selection to clipboard..."), this);
|
|
|
|
addCommandToHistory(new CutAndCloseCommand(*m_currentEventSelection,
|
|
getDocument()->getClipboard()));
|
|
}
|
|
|
|
static const TQString RESTRICTED_PASTE_FAILED_DESCRIPTION = i18n(
|
|
"The Restricted paste type requires enough empty " \
|
|
"space (containing only rests) at the paste position " \
|
|
"to hold all of the events to be pasted.\n" \
|
|
"Not enough space was found.\n" \
|
|
"If you want to paste anyway, consider using one of " \
|
|
"the other paste types from the \"Paste...\" option " \
|
|
"on the Edit menu. You can also change the default " \
|
|
"paste type to something other than Restricted if " \
|
|
"you wish."
|
|
);
|
|
|
|
void NotationView::slotEditPaste()
|
|
{
|
|
Clipboard * clipboard = getDocument()->getClipboard();
|
|
|
|
if (clipboard->isEmpty()) {
|
|
slotStatusHelpMsg(i18n("Clipboard is empty"));
|
|
return ;
|
|
}
|
|
if (!clipboard->isSingleSegment()) {
|
|
slotStatusHelpMsg(i18n("Can't paste multiple Segments into one"));
|
|
return ;
|
|
}
|
|
|
|
slotStatusHelpMsg(i18n("Inserting clipboard contents..."));
|
|
|
|
LinedStaff *staff = getCurrentLinedStaff();
|
|
Segment &segment = staff->getSegment();
|
|
|
|
// Paste at cursor position
|
|
//
|
|
timeT insertionTime = getInsertionTime();
|
|
timeT endTime = insertionTime +
|
|
(clipboard->getSingleSegment()->getEndTime() -
|
|
clipboard->getSingleSegment()->getStartTime());
|
|
|
|
TDEConfig *config = kapp->config();
|
|
config->setGroup(NotationViewConfigGroup);
|
|
PasteEventsCommand::PasteType defaultType = (PasteEventsCommand::PasteType)
|
|
config->readUnsignedNumEntry("pastetype",
|
|
PasteEventsCommand::Restricted);
|
|
|
|
PasteEventsCommand *command = new PasteEventsCommand
|
|
(segment, clipboard, insertionTime, defaultType);
|
|
|
|
if (!command->isPossible()) {
|
|
KMessageBox::detailedError
|
|
(this,
|
|
i18n("Couldn't paste at this point."), RESTRICTED_PASTE_FAILED_DESCRIPTION);
|
|
} else {
|
|
addCommandToHistory(command);
|
|
setCurrentSelection(new EventSelection(command->getPastedEvents()));
|
|
slotSetInsertCursorPosition(endTime, true, false);
|
|
}
|
|
}
|
|
|
|
void NotationView::slotEditGeneralPaste()
|
|
{
|
|
Clipboard *clipboard = getDocument()->getClipboard();
|
|
|
|
if (clipboard->isEmpty()) {
|
|
slotStatusHelpMsg(i18n("Clipboard is empty"));
|
|
return ;
|
|
}
|
|
|
|
slotStatusHelpMsg(i18n("Inserting clipboard contents..."));
|
|
|
|
LinedStaff *staff = getCurrentLinedStaff();
|
|
Segment &segment = staff->getSegment();
|
|
|
|
TDEConfig *config = kapp->config();
|
|
config->setGroup(NotationViewConfigGroup);
|
|
PasteEventsCommand::PasteType defaultType = (PasteEventsCommand::PasteType)
|
|
config->readUnsignedNumEntry("pastetype",
|
|
PasteEventsCommand::Restricted);
|
|
|
|
PasteNotationDialog dialog(this, defaultType);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
|
|
PasteEventsCommand::PasteType type = dialog.getPasteType();
|
|
if (dialog.setAsDefault()) {
|
|
config->setGroup(NotationViewConfigGroup);
|
|
config->writeEntry("pastetype", type);
|
|
}
|
|
|
|
timeT insertionTime = getInsertionTime();
|
|
timeT endTime = insertionTime +
|
|
(clipboard->getSingleSegment()->getEndTime() -
|
|
clipboard->getSingleSegment()->getStartTime());
|
|
|
|
PasteEventsCommand *command = new PasteEventsCommand
|
|
(segment, clipboard, insertionTime, type);
|
|
|
|
if (!command->isPossible()) {
|
|
KMessageBox::detailedError
|
|
(this,
|
|
i18n("Couldn't paste at this point."),
|
|
i18n(RESTRICTED_PASTE_FAILED_DESCRIPTION.ascii()));
|
|
} else {
|
|
addCommandToHistory(command);
|
|
setCurrentSelection(new EventSelection
|
|
(segment, insertionTime, endTime));
|
|
slotSetInsertCursorPosition(endTime, true, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotMoveEventsUpStaff()
|
|
{
|
|
LinedStaff *targetStaff = getStaffAbove();
|
|
if (!targetStaff) return;
|
|
if (!m_currentEventSelection) return;
|
|
Segment &targetSegment = targetStaff->getSegment();
|
|
|
|
KMacroCommand *command = new KMacroCommand(i18n("Move Events to Staff Above"));
|
|
|
|
timeT insertionTime = m_currentEventSelection->getStartTime();
|
|
|
|
Clipboard *c = new Clipboard;
|
|
CopyCommand *cc = new CopyCommand(*m_currentEventSelection, c);
|
|
cc->execute();
|
|
|
|
command->addCommand(new EraseCommand(*m_currentEventSelection));;
|
|
|
|
command->addCommand(new PasteEventsCommand
|
|
(targetSegment, c,
|
|
insertionTime,
|
|
PasteEventsCommand::NoteOverlay));
|
|
|
|
addCommandToHistory(command);
|
|
|
|
delete c;
|
|
}
|
|
|
|
void
|
|
NotationView::slotMoveEventsDownStaff()
|
|
{
|
|
LinedStaff *targetStaff = getStaffBelow();
|
|
if (!targetStaff) return;
|
|
if (!m_currentEventSelection) return;
|
|
Segment &targetSegment = targetStaff->getSegment();
|
|
|
|
KMacroCommand *command = new KMacroCommand(i18n("Move Events to Staff Below"));
|
|
|
|
timeT insertionTime = m_currentEventSelection->getStartTime();
|
|
|
|
Clipboard *c = new Clipboard;
|
|
CopyCommand *cc = new CopyCommand(*m_currentEventSelection, c);
|
|
cc->execute();
|
|
|
|
command->addCommand(new EraseCommand(*m_currentEventSelection));;
|
|
|
|
command->addCommand(new PasteEventsCommand
|
|
(targetSegment, c,
|
|
insertionTime,
|
|
PasteEventsCommand::NoteOverlay));
|
|
|
|
addCommandToHistory(command);
|
|
|
|
delete c;
|
|
}
|
|
|
|
void NotationView::slotPreviewSelection()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
getDocument()->slotSetLoop(m_currentEventSelection->getStartTime(),
|
|
m_currentEventSelection->getEndTime());
|
|
}
|
|
|
|
void NotationView::slotClearLoop()
|
|
{
|
|
getDocument()->slotSetLoop(0, 0);
|
|
}
|
|
|
|
void NotationView::slotClearSelection()
|
|
{
|
|
// Actually we don't clear the selection immediately: if we're
|
|
// using some tool other than the select tool, then the first
|
|
// press switches us back to the select tool.
|
|
|
|
NotationSelector *selector = dynamic_cast<NotationSelector *>(m_tool);
|
|
|
|
if (!selector) {
|
|
slotSelectSelected();
|
|
} else {
|
|
setCurrentSelection(0);
|
|
}
|
|
}
|
|
|
|
void NotationView::slotEditSelectFromStart()
|
|
{
|
|
timeT t = getInsertionTime();
|
|
Segment &segment = m_staffs[m_currentStaff]->getSegment();
|
|
setCurrentSelection(new EventSelection(segment,
|
|
segment.getStartTime(),
|
|
t));
|
|
}
|
|
|
|
void NotationView::slotEditSelectToEnd()
|
|
{
|
|
timeT t = getInsertionTime();
|
|
Segment &segment = m_staffs[m_currentStaff]->getSegment();
|
|
setCurrentSelection(new EventSelection(segment,
|
|
t,
|
|
segment.getEndMarkerTime()));
|
|
}
|
|
|
|
void NotationView::slotEditSelectWholeStaff()
|
|
{
|
|
Segment &segment = m_staffs[m_currentStaff]->getSegment();
|
|
setCurrentSelection(new EventSelection(segment,
|
|
segment.getStartTime(),
|
|
segment.getEndMarkerTime()));
|
|
}
|
|
|
|
void NotationView::slotFilterSelection()
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotFilterSelection" << endl;
|
|
|
|
Segment *segment = getCurrentSegment();
|
|
EventSelection *existingSelection = m_currentEventSelection;
|
|
if (!segment || !existingSelection)
|
|
return ;
|
|
|
|
EventFilterDialog dialog(this);
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
NOTATION_DEBUG << "slotFilterSelection- accepted" << endl;
|
|
|
|
bool haveEvent = false;
|
|
|
|
EventSelection *newSelection = new EventSelection(*segment);
|
|
EventSelection::eventcontainer &ec =
|
|
existingSelection->getSegmentEvents();
|
|
for (EventSelection::eventcontainer::iterator i =
|
|
ec.begin(); i != ec.end(); ++i) {
|
|
if (dialog.keepEvent(*i)) {
|
|
haveEvent = true;
|
|
newSelection->addEvent(*i);
|
|
}
|
|
}
|
|
|
|
if (haveEvent)
|
|
setCurrentSelection(newSelection);
|
|
else
|
|
setCurrentSelection(0);
|
|
}
|
|
}
|
|
|
|
void NotationView::slotFinePositionLeft()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Pushing selection left..."), this);
|
|
|
|
// half a note body width
|
|
addCommandToHistory(new IncrementDisplacementsCommand
|
|
(*m_currentEventSelection, -500, 0));
|
|
}
|
|
|
|
void NotationView::slotFinePositionRight()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Pushing selection right..."), this);
|
|
|
|
// half a note body width
|
|
addCommandToHistory(new IncrementDisplacementsCommand
|
|
(*m_currentEventSelection, 500, 0));
|
|
}
|
|
|
|
void NotationView::slotFinePositionUp()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Pushing selection up..."), this);
|
|
|
|
// half line height
|
|
addCommandToHistory(new IncrementDisplacementsCommand
|
|
(*m_currentEventSelection, 0, -500));
|
|
}
|
|
|
|
void NotationView::slotFinePositionDown()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Pushing selection down..."), this);
|
|
|
|
// half line height
|
|
addCommandToHistory(new IncrementDisplacementsCommand
|
|
(*m_currentEventSelection, 0, 500));
|
|
}
|
|
|
|
void NotationView::slotFinePositionRestore()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Restoring computed positions..."), this);
|
|
|
|
addCommandToHistory(new ResetDisplacementsCommand(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotMakeVisible()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Making visible..."), this);
|
|
|
|
addCommandToHistory(new SetVisibilityCommand(*m_currentEventSelection, true));
|
|
}
|
|
|
|
void NotationView::slotMakeInvisible()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Making invisible..."), this);
|
|
|
|
addCommandToHistory(new SetVisibilityCommand(*m_currentEventSelection, false));
|
|
}
|
|
|
|
void NotationView::slotToggleToolsToolBar()
|
|
{
|
|
toggleNamedToolBar("Tools Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleNotesToolBar()
|
|
{
|
|
toggleNamedToolBar("Notes Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleRestsToolBar()
|
|
{
|
|
toggleNamedToolBar("Rests Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleAccidentalsToolBar()
|
|
{
|
|
toggleNamedToolBar("Accidentals Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleClefsToolBar()
|
|
{
|
|
toggleNamedToolBar("Clefs Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleMetaToolBar()
|
|
{
|
|
toggleNamedToolBar("Meta Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleMarksToolBar()
|
|
{
|
|
toggleNamedToolBar("Marks Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleGroupToolBar()
|
|
{
|
|
toggleNamedToolBar("Group Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleLayoutToolBar()
|
|
{
|
|
toggleNamedToolBar("Layout Toolbar");
|
|
}
|
|
|
|
void NotationView::slotToggleTransportToolBar()
|
|
{
|
|
toggleNamedToolBar("Transport Toolbar");
|
|
}
|
|
|
|
void NotationView::toggleNamedToolBar(const TQString& toolBarName, bool* force)
|
|
{
|
|
TDEToolBar *namedToolBar = toolBar(toolBarName.ascii());
|
|
|
|
if (!namedToolBar) {
|
|
NOTATION_DEBUG << "NotationView::toggleNamedToolBar() : toolBar "
|
|
<< toolBarName << " not found" << endl;
|
|
return ;
|
|
}
|
|
|
|
if (!force) {
|
|
|
|
if (namedToolBar->isVisible())
|
|
namedToolBar->hide();
|
|
else
|
|
namedToolBar->show();
|
|
} else {
|
|
|
|
if (*force)
|
|
namedToolBar->show();
|
|
else
|
|
namedToolBar->hide();
|
|
}
|
|
|
|
setSettingsDirty();
|
|
|
|
}
|
|
|
|
void NotationView::slotGroupBeam()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Beaming group..."), this);
|
|
|
|
addCommandToHistory(new BeamCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotGroupAutoBeam()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Auto-beaming selection..."), this);
|
|
|
|
addCommandToHistory(new AutoBeamCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotGroupBreak()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Breaking groups..."), this);
|
|
|
|
addCommandToHistory(new BreakCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotGroupSimpleTuplet()
|
|
{
|
|
slotGroupTuplet(true);
|
|
}
|
|
|
|
void NotationView::slotGroupGeneralTuplet()
|
|
{
|
|
slotGroupTuplet(false);
|
|
}
|
|
|
|
void NotationView::slotGroupTuplet(bool simple)
|
|
{
|
|
timeT t = 0;
|
|
timeT unit = 0;
|
|
int tupled = 2;
|
|
int untupled = 3;
|
|
Segment *segment = 0;
|
|
bool hasTimingAlready = false;
|
|
|
|
if (m_currentEventSelection) {
|
|
|
|
t = m_currentEventSelection->getStartTime();
|
|
|
|
timeT duration = m_currentEventSelection->getTotalDuration();
|
|
Note::Type unitType =
|
|
Note::getNearestNote(duration / 3, 0).getNoteType();
|
|
unit = Note(unitType).getDuration();
|
|
|
|
if (!simple) {
|
|
TupletDialog dialog(this, unitType, duration);
|
|
if (dialog.exec() != TQDialog::Accepted)
|
|
return ;
|
|
unit = Note(dialog.getUnitType()).getDuration();
|
|
tupled = dialog.getTupledCount();
|
|
untupled = dialog.getUntupledCount();
|
|
hasTimingAlready = dialog.hasTimingAlready();
|
|
}
|
|
|
|
segment = &m_currentEventSelection->getSegment();
|
|
|
|
} else {
|
|
|
|
t = getInsertionTime();
|
|
|
|
NoteInserter *currentInserter = dynamic_cast<NoteInserter *>
|
|
(m_toolBox->getTool(NoteInserter::ToolName));
|
|
|
|
Note::Type unitType;
|
|
|
|
if (currentInserter) {
|
|
unitType = currentInserter->getCurrentNote().getNoteType();
|
|
} else {
|
|
unitType = Note::Quaver;
|
|
}
|
|
|
|
unit = Note(unitType).getDuration();
|
|
|
|
if (!simple) {
|
|
TupletDialog dialog(this, unitType);
|
|
if (dialog.exec() != TQDialog::Accepted)
|
|
return ;
|
|
unit = Note(dialog.getUnitType()).getDuration();
|
|
tupled = dialog.getTupledCount();
|
|
untupled = dialog.getUntupledCount();
|
|
hasTimingAlready = dialog.hasTimingAlready();
|
|
}
|
|
|
|
segment = &m_staffs[m_currentStaff]->getSegment();
|
|
}
|
|
|
|
addCommandToHistory(new TupletCommand
|
|
(*segment, t, unit, untupled, tupled, hasTimingAlready));
|
|
|
|
if (!hasTimingAlready) {
|
|
slotSetInsertCursorPosition(t + (unit * tupled), true, false);
|
|
}
|
|
}
|
|
|
|
void NotationView::slotGroupUnTuplet()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Untupleting..."), this);
|
|
|
|
addCommandToHistory(new UnTupletCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotGroupSlur()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding slur..."), this);
|
|
slotAddIndication(Indication::Slur, i18n("slur"));
|
|
}
|
|
|
|
void NotationView::slotGroupPhrasingSlur()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding phrasing slur..."), this);
|
|
slotAddIndication(Indication::PhrasingSlur, i18n("phrasing slur"));
|
|
}
|
|
|
|
void NotationView::slotGroupGlissando()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding glissando..."), this);
|
|
slotAddIndication(Indication::Glissando, i18n("glissando"));
|
|
}
|
|
|
|
void NotationView::slotGroupCrescendo()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding crescendo..."), this);
|
|
slotAddIndication(Indication::Crescendo, i18n("dynamic"));
|
|
}
|
|
|
|
void NotationView::slotGroupDecrescendo()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding decrescendo..."), this);
|
|
slotAddIndication(Indication::Decrescendo, i18n("dynamic"));
|
|
}
|
|
|
|
void NotationView::slotGroupOctave2Up()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding octave..."), this);
|
|
slotAddIndication(Indication::QuindicesimaUp, i18n("ottava"));
|
|
}
|
|
|
|
void NotationView::slotGroupOctaveUp()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding octave..."), this);
|
|
slotAddIndication(Indication::OttavaUp, i18n("ottava"));
|
|
}
|
|
|
|
void NotationView::slotGroupOctaveDown()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding octave..."), this);
|
|
slotAddIndication(Indication::OttavaDown, i18n("ottava"));
|
|
}
|
|
|
|
void NotationView::slotGroupOctave2Down()
|
|
{
|
|
KTmpStatusMsg msg(i18n("Adding octave..."), this);
|
|
slotAddIndication(Indication::QuindicesimaDown, i18n("ottava"));
|
|
}
|
|
|
|
void NotationView::slotAddIndication(std::string type, TQString desc)
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
AddIndicationCommand *command =
|
|
new AddIndicationCommand(type, *m_currentEventSelection);
|
|
|
|
if (command->canExecute()) {
|
|
addCommandToHistory(command);
|
|
setSingleSelectedEvent(m_currentEventSelection->getSegment(),
|
|
command->getLastInsertedEvent());
|
|
} else {
|
|
KMessageBox::sorry(this, i18n("Can't add overlapping %1 indications").arg(desc)); // TODO PLURAL - how many 'indications' ?
|
|
delete command;
|
|
}
|
|
}
|
|
|
|
void NotationView::slotGroupMakeChord()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Making chord..."), this);
|
|
|
|
MakeChordCommand *command =
|
|
new MakeChordCommand(*m_currentEventSelection);
|
|
|
|
addCommandToHistory(command);
|
|
}
|
|
|
|
void NotationView::slotTransformsNormalizeRests()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Normalizing rests..."), this);
|
|
|
|
addCommandToHistory(new NormalizeRestsCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsCollapseRests()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Collapsing rests..."), this);
|
|
|
|
addCommandToHistory(new CollapseRestsCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsCollapseNotes()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Collapsing notes..."), this);
|
|
|
|
addCommandToHistory(new CollapseNotesCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsTieNotes()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Tying notes..."), this);
|
|
|
|
addCommandToHistory(new TieNotesCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsUntieNotes()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Untying notes..."), this);
|
|
|
|
addCommandToHistory(new UntieNotesCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsMakeNotesViable()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Making notes viable..."), this);
|
|
|
|
addCommandToHistory(new MakeNotesViableCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsDeCounterpoint()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Removing counterpoint..."), this);
|
|
|
|
addCommandToHistory(new DeCounterpointCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsStemsUp()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Pointing stems up..."), this);
|
|
|
|
addCommandToHistory(new ChangeStemsCommand
|
|
(true, *m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsStemsDown()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Pointing stems down..."), this);
|
|
|
|
addCommandToHistory(new ChangeStemsCommand
|
|
(false, *m_currentEventSelection));
|
|
|
|
}
|
|
|
|
void NotationView::slotTransformsRestoreStems()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Restoring computed stem directions..."), this);
|
|
|
|
addCommandToHistory(new RestoreStemsCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsSlursAbove()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Positioning slurs..."), this);
|
|
|
|
addCommandToHistory(new ChangeSlurPositionCommand
|
|
(true, *m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsSlursBelow()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Positioning slurs..."), this);
|
|
|
|
addCommandToHistory(new ChangeSlurPositionCommand
|
|
(false, *m_currentEventSelection));
|
|
|
|
}
|
|
|
|
void NotationView::slotTransformsRestoreSlurs()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Restoring slur positions..."), this);
|
|
|
|
addCommandToHistory(new RestoreSlursCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsTiesAbove()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Positioning ties..."), this);
|
|
|
|
addCommandToHistory(new ChangeTiePositionCommand
|
|
(true, *m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsTiesBelow()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Positioning ties..."), this);
|
|
|
|
addCommandToHistory(new ChangeTiePositionCommand
|
|
(false, *m_currentEventSelection));
|
|
|
|
}
|
|
|
|
void NotationView::slotTransformsRestoreTies()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Restoring tie positions..."), this);
|
|
|
|
addCommandToHistory(new RestoreTiesCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsFixQuantization()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Fixing notation quantization..."), this);
|
|
|
|
addCommandToHistory(new FixNotationQuantizeCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsRemoveQuantization()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Removing notation quantization..."), this);
|
|
|
|
addCommandToHistory(new RemoveNotationQuantizeCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotSetStyleFromAction()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
TQString name = s->name();
|
|
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
if (name.left(6) == "style_") {
|
|
name = name.right(name.length() - 6);
|
|
|
|
KTmpStatusMsg msg(i18n("Changing to %1 style...").arg(name),
|
|
this);
|
|
|
|
addCommandToHistory(new ChangeStyleCommand
|
|
(NoteStyleName(qstrtostr(name)),
|
|
*m_currentEventSelection));
|
|
} else {
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown style action %1").arg(name));
|
|
}
|
|
}
|
|
|
|
void NotationView::slotInsertNoteFromAction()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
TQString name = s->name();
|
|
|
|
Segment &segment = m_staffs[m_currentStaff]->getSegment();
|
|
|
|
NoteInserter *noteInserter = dynamic_cast<NoteInserter *>(m_tool);
|
|
if (!noteInserter) {
|
|
KMessageBox::sorry(this, i18n("No note duration selected"));
|
|
return ;
|
|
}
|
|
|
|
int pitch = 0;
|
|
Accidental accidental =
|
|
Accidentals::NoAccidental;
|
|
|
|
timeT time(getInsertionTime());
|
|
Rosegarden::Key key = segment.getKeyAtTime(time);
|
|
Clef clef = segment.getClefAtTime(time);
|
|
|
|
try {
|
|
|
|
pitch = getPitchFromNoteInsertAction(name, accidental, clef, key);
|
|
|
|
} catch (...) {
|
|
|
|
KMessageBox::sorry
|
|
(this, i18n("Unknown note insert action %1").arg(name));
|
|
return ;
|
|
}
|
|
|
|
KTmpStatusMsg msg(i18n("Inserting note"), this);
|
|
|
|
NOTATION_DEBUG << "Inserting note at pitch " << pitch << endl;
|
|
|
|
noteInserter->insertNote(segment, time, pitch, accidental);
|
|
}
|
|
|
|
void NotationView::slotInsertRest()
|
|
{
|
|
Segment &segment = m_staffs[m_currentStaff]->getSegment();
|
|
timeT time = getInsertionTime();
|
|
|
|
RestInserter *restInserter = dynamic_cast<RestInserter *>(m_tool);
|
|
|
|
if (!restInserter) {
|
|
|
|
NoteInserter *noteInserter = dynamic_cast<NoteInserter *>(m_tool);
|
|
if (!noteInserter) {
|
|
KMessageBox::sorry(this, i18n("No note duration selected"));
|
|
return ;
|
|
}
|
|
|
|
Note note(noteInserter->getCurrentNote());
|
|
|
|
restInserter = dynamic_cast<RestInserter*>
|
|
(m_toolBox->getTool(RestInserter::ToolName));
|
|
|
|
restInserter->slotSetNote(note.getNoteType());
|
|
restInserter->slotSetDots(note.getDots());
|
|
}
|
|
|
|
restInserter->insertNote(segment, time,
|
|
0, Accidentals::NoAccidental, true);
|
|
}
|
|
|
|
void NotationView::slotSwitchFromRestToNote()
|
|
{
|
|
RestInserter *restInserter = dynamic_cast<RestInserter *>(m_tool);
|
|
if (!restInserter) {
|
|
KMessageBox::sorry(this, i18n("No rest duration selected"));
|
|
return ;
|
|
}
|
|
|
|
Note note(restInserter->getCurrentNote());
|
|
|
|
TQString actionName = NotationStrings::getReferenceName(note, false);
|
|
actionName = actionName.replace("-", "_");
|
|
|
|
TDERadioAction *action = dynamic_cast<TDERadioAction *>
|
|
(actionCollection()->action(actionName.ascii()));
|
|
|
|
if (!action) {
|
|
std::cerr << "WARNING: Failed to find note action \""
|
|
<< actionName.ascii() << "\"" << std::endl;
|
|
} else {
|
|
action->activate();
|
|
}
|
|
|
|
NoteInserter *noteInserter = dynamic_cast<NoteInserter*>
|
|
(m_toolBox->getTool(NoteInserter::ToolName));
|
|
|
|
if (noteInserter) {
|
|
noteInserter->slotSetNote(note.getNoteType());
|
|
noteInserter->slotSetDots(note.getDots());
|
|
setTool(noteInserter);
|
|
}
|
|
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotSwitchFromNoteToRest()
|
|
{
|
|
NoteInserter *noteInserter = dynamic_cast<NoteInserter *>(m_tool);
|
|
if (!noteInserter) {
|
|
KMessageBox::sorry(this, i18n("No note duration selected"));
|
|
return ;
|
|
}
|
|
|
|
Note note(noteInserter->getCurrentNote());
|
|
|
|
TQString actionName = NotationStrings::getReferenceName(note, true);
|
|
actionName = actionName.replace("-", "_");
|
|
|
|
TDERadioAction *action = dynamic_cast<TDERadioAction *>
|
|
(actionCollection()->action(actionName.ascii()));
|
|
|
|
if (!action) {
|
|
std::cerr << "WARNING: Failed to find rest action \""
|
|
<< actionName.ascii() << "\"" << std::endl;
|
|
} else {
|
|
action->activate();
|
|
}
|
|
|
|
RestInserter *restInserter = dynamic_cast<RestInserter*>
|
|
(m_toolBox->getTool(RestInserter::ToolName));
|
|
|
|
if (restInserter) {
|
|
restInserter->slotSetNote(note.getNoteType());
|
|
restInserter->slotSetDots(note.getDots());
|
|
setTool(restInserter);
|
|
}
|
|
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotToggleDot()
|
|
{
|
|
NoteInserter *noteInserter = dynamic_cast<NoteInserter *>(m_tool);
|
|
if (noteInserter) {
|
|
Note note(noteInserter->getCurrentNote());
|
|
if (note.getNoteType() == Note::Shortest ||
|
|
note.getNoteType() == Note::Longest)
|
|
return ;
|
|
noteInserter->slotSetDots(note.getDots() ? 0 : 1);
|
|
setTool(noteInserter);
|
|
} else {
|
|
RestInserter *restInserter = dynamic_cast<RestInserter *>(m_tool);
|
|
if (restInserter) {
|
|
Note note(restInserter->getCurrentNote());
|
|
if (note.getNoteType() == Note::Shortest ||
|
|
note.getNoteType() == Note::Longest)
|
|
return ;
|
|
restInserter->slotSetDots(note.getDots() ? 0 : 1);
|
|
setTool(restInserter);
|
|
} else {
|
|
KMessageBox::sorry(this, i18n("No note or rest duration selected"));
|
|
}
|
|
}
|
|
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotRespellDoubleFlat()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Forcing accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Set,
|
|
Accidentals::DoubleFlat,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotRespellFlat()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Forcing accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Set,
|
|
Accidentals::Flat,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotRespellNatural()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Forcing accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Set,
|
|
Accidentals::Natural,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotRespellSharp()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Forcing accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Set,
|
|
Accidentals::Sharp,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotRespellDoubleSharp()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Forcing accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Set,
|
|
Accidentals::DoubleSharp,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotRespellUp()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Forcing accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Up,
|
|
Accidentals::NoAccidental,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotRespellDown()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Forcing accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Down,
|
|
Accidentals::NoAccidental,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotRespellRestore()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Restoring accidentals..."), this);
|
|
|
|
addCommandToHistory(new RespellCommand(RespellCommand::Restore,
|
|
Accidentals::NoAccidental,
|
|
*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotShowCautionary()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Showing cautionary accidentals..."), this);
|
|
|
|
addCommandToHistory(new MakeAccidentalsCautionaryCommand
|
|
(true, *m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotCancelCautionary()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Cancelling cautionary accidentals..."), this);
|
|
|
|
addCommandToHistory(new MakeAccidentalsCautionaryCommand
|
|
(false, *m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotTransformsQuantize()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
QuantizeDialog dialog(this, true);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
KTmpStatusMsg msg(i18n("Quantizing..."), this);
|
|
addCommandToHistory(new EventQuantizeCommand
|
|
(*m_currentEventSelection,
|
|
dialog.getQuantizer()));
|
|
}
|
|
}
|
|
|
|
void NotationView::slotTransformsInterpret()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
InterpretDialog dialog(this);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
KTmpStatusMsg msg(i18n("Interpreting selection..."), this);
|
|
addCommandToHistory(new InterpretCommand
|
|
(*m_currentEventSelection,
|
|
getDocument()->getComposition().getNotationQuantizer(),
|
|
dialog.getInterpretations()));
|
|
}
|
|
}
|
|
|
|
void NotationView::slotSetNoteDurations(Note::Type type, bool notationOnly)
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Setting note durations..."), this);
|
|
addCommandToHistory(new SetNoteTypeCommand(*m_currentEventSelection, type, notationOnly));
|
|
}
|
|
|
|
void NotationView::slotAddDot()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Adding dot..."), this);
|
|
addCommandToHistory(new AddDotCommand(*m_currentEventSelection, false));
|
|
}
|
|
|
|
void NotationView::slotAddDotNotationOnly()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
KTmpStatusMsg msg(i18n("Adding dot..."), this);
|
|
addCommandToHistory(new AddDotCommand(*m_currentEventSelection, true));
|
|
}
|
|
|
|
void NotationView::slotAddSlashes()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
TQString name = s->name();
|
|
int slashes = name.right(1).toInt();
|
|
|
|
addCommandToHistory(new AddSlashesCommand
|
|
(slashes, *m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotMarksAddTextMark()
|
|
{
|
|
if (m_currentEventSelection) {
|
|
bool pressedOK = false;
|
|
|
|
TQString txt = KLineEditDlg::getText(i18n("Text: "), "", &pressedOK, this);
|
|
|
|
if (pressedOK) {
|
|
addCommandToHistory(new AddTextMarkCommand
|
|
(qstrtostr(txt), *m_currentEventSelection));
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotMarksAddFingeringMark()
|
|
{
|
|
if (m_currentEventSelection) {
|
|
bool pressedOK = false;
|
|
|
|
TQString txt = KLineEditDlg::getText(i18n("Fingering: "), "", &pressedOK, this);
|
|
|
|
if (pressedOK) {
|
|
addCommandToHistory(new AddFingeringMarkCommand
|
|
(qstrtostr(txt), *m_currentEventSelection));
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotMarksAddFingeringMarkFromAction()
|
|
{
|
|
const TQObject *s = TQT_TQOBJECT_CONST(const_cast<const TQT_BASE_OBJECT_NAME*>(sender()));
|
|
TQString name = s->name();
|
|
|
|
if (name.left(14) == "add_fingering_") {
|
|
|
|
TQString fingering = name.right(name.length() - 14);
|
|
|
|
if (fingering == "plus")
|
|
fingering = "+";
|
|
|
|
if (m_currentEventSelection) {
|
|
addCommandToHistory(new AddFingeringMarkCommand
|
|
(qstrtostr(fingering), *m_currentEventSelection));
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotMarksRemoveMarks()
|
|
{
|
|
if (m_currentEventSelection)
|
|
addCommandToHistory(new RemoveMarksCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void NotationView::slotMarksRemoveFingeringMarks()
|
|
{
|
|
if (m_currentEventSelection)
|
|
addCommandToHistory(new RemoveFingeringMarksCommand
|
|
(*m_currentEventSelection));
|
|
}
|
|
|
|
void
|
|
NotationView::slotMakeOrnament()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
EventSelection::eventcontainer &ec =
|
|
m_currentEventSelection->getSegmentEvents();
|
|
|
|
int basePitch = -1;
|
|
int baseVelocity = -1;
|
|
NoteStyle *style = NoteStyleFactory::getStyle(NoteStyleFactory::DefaultStyle);
|
|
|
|
for (EventSelection::eventcontainer::iterator i =
|
|
ec.begin(); i != ec.end(); ++i) {
|
|
if ((*i)->isa(Note::EventType)) {
|
|
if ((*i)->has(BaseProperties::PITCH)) {
|
|
basePitch = (*i)->get
|
|
<Int>
|
|
(BaseProperties::PITCH);
|
|
style = NoteStyleFactory::getStyleForEvent(*i);
|
|
if (baseVelocity != -1)
|
|
break;
|
|
}
|
|
if ((*i)->has(BaseProperties::VELOCITY)) {
|
|
baseVelocity = (*i)->get
|
|
<Int>
|
|
(BaseProperties::VELOCITY);
|
|
if (basePitch != -1)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Staff *staff = getCurrentStaff();
|
|
Segment &segment = staff->getSegment();
|
|
|
|
timeT absTime = m_currentEventSelection->getStartTime();
|
|
timeT duration = m_currentEventSelection->getTotalDuration();
|
|
Note note(Note::getNearestNote(duration));
|
|
|
|
Track *track =
|
|
segment.getComposition()->getTrackById(segment.getTrack());
|
|
TQString name;
|
|
int barNo = segment.getComposition()->getBarNumber(absTime);
|
|
if (track) {
|
|
name = TQString(i18n("Ornament track %1 bar %2").arg(track->getPosition() + 1).arg(barNo + 1));
|
|
} else {
|
|
name = TQString(i18n("Ornament bar %1").arg(barNo + 1));
|
|
}
|
|
|
|
MakeOrnamentDialog dialog(this, name, basePitch);
|
|
if (dialog.exec() != TQDialog::Accepted)
|
|
return ;
|
|
|
|
name = dialog.getName();
|
|
basePitch = dialog.getBasePitch();
|
|
|
|
KMacroCommand *command = new KMacroCommand(i18n("Make Ornament"));
|
|
|
|
command->addCommand(new CutCommand
|
|
(*m_currentEventSelection,
|
|
getDocument()->getClipboard()));
|
|
|
|
command->addCommand(new PasteToTriggerSegmentCommand
|
|
(&getDocument()->getComposition(),
|
|
getDocument()->getClipboard(),
|
|
name, basePitch));
|
|
|
|
command->addCommand(new InsertTriggerNoteCommand
|
|
(segment, absTime, note, basePitch, baseVelocity,
|
|
style->getName(),
|
|
getDocument()->getComposition().getNextTriggerSegmentId(),
|
|
true,
|
|
BaseProperties::TRIGGER_SEGMENT_ADJUST_SQUISH,
|
|
Marks::NoMark)); //!!!
|
|
|
|
addCommandToHistory(command);
|
|
}
|
|
|
|
void
|
|
NotationView::slotUseOrnament()
|
|
{
|
|
// Take an existing note and match an ornament to it.
|
|
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
UseOrnamentDialog dialog(this, &getDocument()->getComposition());
|
|
if (dialog.exec() != TQDialog::Accepted)
|
|
return ;
|
|
|
|
addCommandToHistory(new SetTriggerCommand(*m_currentEventSelection,
|
|
dialog.getId(),
|
|
true,
|
|
dialog.getRetune(),
|
|
dialog.getTimeAdjust(),
|
|
dialog.getMark(),
|
|
i18n("Use Ornament")));
|
|
}
|
|
|
|
void
|
|
NotationView::slotRemoveOrnament()
|
|
{
|
|
if (!m_currentEventSelection)
|
|
return ;
|
|
|
|
addCommandToHistory(new ClearTriggersCommand(*m_currentEventSelection,
|
|
i18n("Remove Ornaments")));
|
|
}
|
|
|
|
void NotationView::slotEditAddClef()
|
|
{
|
|
Staff *staff = getCurrentStaff();
|
|
Segment &segment = staff->getSegment();
|
|
static Clef lastClef;
|
|
Clef clef;
|
|
Rosegarden::Key key;
|
|
timeT insertionTime = getInsertionTime(clef, key);
|
|
|
|
ClefDialog dialog(this, m_notePixmapFactory, lastClef);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
|
|
ClefDialog::ConversionType conversion = dialog.getConversionType();
|
|
|
|
bool shouldChangeOctave = (conversion != ClefDialog::NoConversion);
|
|
bool shouldTranspose = (conversion == ClefDialog::Transpose);
|
|
|
|
addCommandToHistory
|
|
(new ClefInsertionCommand
|
|
(segment, insertionTime, dialog.getClef(),
|
|
shouldChangeOctave, shouldTranspose));
|
|
|
|
lastClef = dialog.getClef();
|
|
}
|
|
}
|
|
|
|
void NotationView::slotEditAddKeySignature()
|
|
{
|
|
Staff *staff = getCurrentStaff();
|
|
Segment &segment = staff->getSegment();
|
|
Clef clef;
|
|
Rosegarden::Key key;
|
|
timeT insertionTime = getInsertionTime(clef, key);
|
|
|
|
//!!! experimental:
|
|
CompositionTimeSliceAdapter adapter
|
|
(&getDocument()->getComposition(), insertionTime,
|
|
getDocument()->getComposition().getDuration());
|
|
AnalysisHelper helper;
|
|
key = helper.guessKey(adapter);
|
|
|
|
KeySignatureDialog dialog
|
|
(this, m_notePixmapFactory, clef, key, true, true,
|
|
i18n("Estimated key signature shown"));
|
|
|
|
if (dialog.exec() == TQDialog::Accepted &&
|
|
dialog.isValid()) {
|
|
|
|
KeySignatureDialog::ConversionType conversion =
|
|
dialog.getConversionType();
|
|
|
|
bool transposeKey = dialog.shouldBeTransposed();
|
|
bool applyToAll = dialog.shouldApplyToAll();
|
|
bool ignorePercussion = dialog.shouldIgnorePercussion();
|
|
|
|
if (applyToAll) {
|
|
addCommandToHistory
|
|
(new MultiKeyInsertionCommand
|
|
(getDocument(),
|
|
insertionTime, dialog.getKey(),
|
|
conversion == KeySignatureDialog::Convert,
|
|
conversion == KeySignatureDialog::Transpose,
|
|
transposeKey,
|
|
ignorePercussion));
|
|
} else {
|
|
addCommandToHistory
|
|
(new KeyInsertionCommand
|
|
(segment,
|
|
insertionTime, dialog.getKey(),
|
|
conversion == KeySignatureDialog::Convert,
|
|
conversion == KeySignatureDialog::Transpose,
|
|
transposeKey,
|
|
false));
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotEditAddSustain(bool down)
|
|
{
|
|
Staff *staff = getCurrentStaff();
|
|
Segment &segment = staff->getSegment();
|
|
timeT insertionTime = getInsertionTime();
|
|
|
|
Studio *studio = &getDocument()->getStudio();
|
|
Track *track = segment.getComposition()->getTrackById(segment.getTrack());
|
|
|
|
if (track) {
|
|
|
|
Instrument *instrument = studio->getInstrumentById
|
|
(track->getInstrument());
|
|
if (instrument) {
|
|
MidiDevice *device = dynamic_cast<MidiDevice *>
|
|
(instrument->getDevice());
|
|
if (device) {
|
|
for (ControlList::const_iterator i =
|
|
device->getControlParameters().begin();
|
|
i != device->getControlParameters().end(); ++i) {
|
|
|
|
if (i->getType() == Controller::EventType &&
|
|
(i->getName() == "Sustain" ||
|
|
strtoqstr(i->getName()) == i18n("Sustain"))) {
|
|
|
|
addCommandToHistory
|
|
(new SustainInsertionCommand(segment, insertionTime, down,
|
|
i->getControllerValue()));
|
|
return ;
|
|
}
|
|
}
|
|
} else if (instrument->getDevice() &&
|
|
instrument->getDevice()->getType() == Device::SoftSynth) {
|
|
addCommandToHistory
|
|
(new SustainInsertionCommand(segment, insertionTime, down, 64));
|
|
}
|
|
}
|
|
}
|
|
|
|
KMessageBox::sorry(this, i18n("There is no sustain controller defined for this device.\nPlease ensure the device is configured correctly in the Manage MIDI Devices dialog in the main window."));
|
|
}
|
|
|
|
void NotationView::slotEditAddSustainDown()
|
|
{
|
|
slotEditAddSustain(true);
|
|
}
|
|
|
|
void NotationView::slotEditAddSustainUp()
|
|
{
|
|
slotEditAddSustain(false);
|
|
}
|
|
|
|
void NotationView::slotEditTranspose()
|
|
{
|
|
IntervalDialog intervalDialog(this, true, true);
|
|
int ok = intervalDialog.exec();
|
|
|
|
int semitones = intervalDialog.getChromaticDistance();
|
|
int steps = intervalDialog.getDiatonicDistance();
|
|
|
|
if (!ok || (semitones == 0 && steps == 0)) return;
|
|
|
|
// TODO combine commands into one
|
|
for (int i = 0; i < m_segments.size(); i++)
|
|
{
|
|
addCommandToHistory(new SegmentTransposeCommand(*(m_segments[i]),
|
|
intervalDialog.getChangeKey(), steps, semitones,
|
|
intervalDialog.getTransposeSegmentBack()));
|
|
}
|
|
}
|
|
|
|
void NotationView::slotEditSwitchPreset()
|
|
{
|
|
PresetHandlerDialog dialog(this, true);
|
|
|
|
if (dialog.exec() != TQDialog::Accepted) return;
|
|
|
|
if (dialog.getConvertAllSegments()) {
|
|
// get all segments for this track and convert them.
|
|
Composition& comp = getDocument()->getComposition();
|
|
TrackId selectedTrack = getCurrentSegment()->getTrack();
|
|
|
|
// satisfy #1885251 the way that seems most reasonble to me at the
|
|
// moment, only changing track parameters when acting on all segments on
|
|
// this track from the notation view
|
|
//
|
|
//!!! This won't be undoable, and I'm not sure if that's seriously
|
|
// wrong, or just mildly wrong, but I'm betting somebody will tell me
|
|
// about it if this was inappropriate
|
|
Track *track = comp.getTrackById(selectedTrack);
|
|
track->setPresetLabel(dialog.getName().ascii());
|
|
track->setClef(dialog.getClef());
|
|
track->setTranspose(dialog.getTranspose());
|
|
track->setLowestPlayable(dialog.getLowRange());
|
|
track->setHighestPlayable(dialog.getHighRange());
|
|
|
|
addCommandToHistory(new SegmentSyncCommand(comp.getSegments(), selectedTrack,
|
|
dialog.getTranspose(),
|
|
dialog.getLowRange(),
|
|
dialog.getHighRange(),
|
|
clefIndexToClef(dialog.getClef())));
|
|
} else {
|
|
addCommandToHistory(new SegmentSyncCommand(m_segments,
|
|
dialog.getTranspose(),
|
|
dialog.getLowRange(),
|
|
dialog.getHighRange(),
|
|
clefIndexToClef(dialog.getClef())));
|
|
}
|
|
|
|
m_doc->slotDocumentModified();
|
|
emit updateView();
|
|
}
|
|
|
|
void NotationView::slotEditElement(NotationStaff *staff,
|
|
NotationElement *element, bool advanced)
|
|
{
|
|
if (advanced) {
|
|
|
|
EventEditDialog dialog(this, *element->event(), true);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted &&
|
|
dialog.isModified()) {
|
|
|
|
EventEditCommand *command = new EventEditCommand
|
|
(staff->getSegment(),
|
|
element->event(),
|
|
dialog.getEvent());
|
|
|
|
addCommandToHistory(command);
|
|
}
|
|
|
|
} else if (element->event()->isa(Clef::EventType)) {
|
|
|
|
try {
|
|
ClefDialog dialog(this, m_notePixmapFactory,
|
|
Clef(*element->event()));
|
|
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
|
|
ClefDialog::ConversionType conversion = dialog.getConversionType();
|
|
bool shouldChangeOctave = (conversion != ClefDialog::NoConversion);
|
|
bool shouldTranspose = (conversion == ClefDialog::Transpose);
|
|
addCommandToHistory
|
|
(new ClefInsertionCommand
|
|
(staff->getSegment(), element->event()->getAbsoluteTime(),
|
|
dialog.getClef(), shouldChangeOctave, shouldTranspose));
|
|
}
|
|
} catch (Exception e) {
|
|
std::cerr << e.getMessage() << std::endl;
|
|
}
|
|
|
|
return ;
|
|
|
|
} else if (element->event()->isa(Rosegarden::Key::EventType)) {
|
|
|
|
try {
|
|
Clef clef(staff->getSegment().getClefAtTime
|
|
(element->event()->getAbsoluteTime()));
|
|
KeySignatureDialog dialog
|
|
(this, m_notePixmapFactory, clef, Rosegarden::Key(*element->event()),
|
|
false, true);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted &&
|
|
dialog.isValid()) {
|
|
|
|
KeySignatureDialog::ConversionType conversion =
|
|
dialog.getConversionType();
|
|
|
|
addCommandToHistory
|
|
(new KeyInsertionCommand
|
|
(staff->getSegment(),
|
|
element->event()->getAbsoluteTime(), dialog.getKey(),
|
|
conversion == KeySignatureDialog::Convert,
|
|
conversion == KeySignatureDialog::Transpose,
|
|
dialog.shouldBeTransposed(),
|
|
dialog.shouldIgnorePercussion()));
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
std::cerr << e.getMessage() << std::endl;
|
|
}
|
|
|
|
return ;
|
|
|
|
} else if (element->event()->isa(Text::EventType)) {
|
|
|
|
try {
|
|
TextEventDialog dialog
|
|
(this, m_notePixmapFactory, Text(*element->event()));
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
TextInsertionCommand *command = new TextInsertionCommand
|
|
(staff->getSegment(),
|
|
element->event()->getAbsoluteTime(),
|
|
dialog.getText());
|
|
KMacroCommand *macroCommand = new KMacroCommand(command->name());
|
|
macroCommand->addCommand(new EraseEventCommand(staff->getSegment(),
|
|
element->event(), false));
|
|
macroCommand->addCommand(command);
|
|
addCommandToHistory(macroCommand);
|
|
}
|
|
} catch (Exception e) {
|
|
std::cerr << e.getMessage() << std::endl;
|
|
}
|
|
|
|
return ;
|
|
|
|
} else if (element->isNote() &&
|
|
element->event()->has(BaseProperties::TRIGGER_SEGMENT_ID)) {
|
|
|
|
int id = element->event()->get
|
|
<Int>
|
|
(BaseProperties::TRIGGER_SEGMENT_ID);
|
|
emit editTriggerSegment(id);
|
|
return ;
|
|
|
|
} else {
|
|
|
|
SimpleEventEditDialog dialog(this, getDocument(), *element->event(), false);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted &&
|
|
dialog.isModified()) {
|
|
|
|
EventEditCommand *command = new EventEditCommand
|
|
(staff->getSegment(),
|
|
element->event(),
|
|
dialog.getEvent());
|
|
|
|
addCommandToHistory(command);
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotBeginLilyPondRepeat()
|
|
{}
|
|
|
|
void NotationView::slotDebugDump()
|
|
{
|
|
if (m_currentEventSelection) {
|
|
EventSelection::eventcontainer &ec =
|
|
m_currentEventSelection->getSegmentEvents();
|
|
int n = 0;
|
|
for (EventSelection::eventcontainer::iterator i =
|
|
ec.begin();
|
|
i != ec.end(); ++i) {
|
|
std::cerr << "\n" << n++ << " [" << (*i) << "]" << std::endl;
|
|
(*i)->dump(std::cerr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotSetPointerPosition(timeT time)
|
|
{
|
|
slotSetPointerPosition(time, m_playTracking);
|
|
}
|
|
|
|
void
|
|
NotationView::slotSetPointerPosition(timeT time, bool scroll)
|
|
{
|
|
Composition &comp = getDocument()->getComposition();
|
|
int barNo = comp.getBarNumber(time);
|
|
|
|
int minCy = 0;
|
|
double cx = 0;
|
|
bool haveMinCy = false;
|
|
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
double layoutX = m_hlayout->getXForTimeByEvent(time);
|
|
Segment &seg = m_staffs[i]->getSegment();
|
|
|
|
bool good = true;
|
|
|
|
if (barNo >= m_hlayout->getLastVisibleBarOnStaff(*m_staffs[i])) {
|
|
if (seg.isRepeating() && time < seg.getRepeatEndTime()) {
|
|
timeT mappedTime =
|
|
seg.getStartTime() +
|
|
((time - seg.getStartTime()) %
|
|
(seg.getEndMarkerTime() - seg.getStartTime()));
|
|
layoutX = m_hlayout->getXForTimeByEvent(mappedTime);
|
|
} else {
|
|
good = false;
|
|
}
|
|
} else if (barNo < m_hlayout->getFirstVisibleBarOnStaff(*m_staffs[i])) {
|
|
good = false;
|
|
}
|
|
|
|
if (!good) {
|
|
|
|
m_staffs[i]->hidePointer();
|
|
|
|
} else {
|
|
|
|
m_staffs[i]->setPointerPosition(layoutX);
|
|
|
|
int cy;
|
|
m_staffs[i]->getPointerPosition(cx, cy);
|
|
|
|
if (!haveMinCy || cy < minCy) {
|
|
minCy = cy;
|
|
haveMinCy = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_pageMode == LinedStaff::LinearMode) {
|
|
// be careful not to prevent user from scrolling up and down
|
|
haveMinCy = false;
|
|
}
|
|
|
|
if (scroll) {
|
|
getCanvasView()->slotScrollHoriz(int(cx));
|
|
if (haveMinCy) {
|
|
getCanvasView()->slotScrollVertToTop(minCy);
|
|
}
|
|
}
|
|
|
|
updateView();
|
|
}
|
|
|
|
void
|
|
NotationView::slotUpdateRecordingSegment(Segment *segment,
|
|
timeT updateFrom)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotUpdateRecordingSegment: segment " << segment << ", updateFrom " << updateFrom << ", end time " << segment->getEndMarkerTime() << endl;
|
|
if (updateFrom >= segment->getEndMarkerTime())
|
|
return ;
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
if (&m_staffs[i]->getSegment() == segment) {
|
|
refreshSegment(segment, 0, 0);
|
|
}
|
|
}
|
|
NOTATION_DEBUG << "NotationView::slotUpdateRecordingSegment: don't have segment " << segment << endl;
|
|
}
|
|
|
|
void
|
|
NotationView::slotSetCurrentStaff(double x, int y)
|
|
{
|
|
unsigned int staffNo;
|
|
for (staffNo = 0; staffNo < m_staffs.size(); ++staffNo) {
|
|
if (m_staffs[staffNo]->containsCanvasCoords(x, y))
|
|
break;
|
|
}
|
|
|
|
if (staffNo < m_staffs.size()) {
|
|
slotSetCurrentStaff(staffNo);
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotSetCurrentStaff(int staffNo)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotSetCurrentStaff(" << staffNo << ")" << endl;
|
|
|
|
if (m_currentStaff != staffNo) {
|
|
|
|
m_staffs[m_currentStaff]->setCurrent(false);
|
|
|
|
m_currentStaff = staffNo;
|
|
|
|
m_staffs[m_currentStaff]->setCurrent(true);
|
|
|
|
Segment *segment = &m_staffs[m_currentStaff]->getSegment();
|
|
|
|
m_chordNameRuler->setCurrentSegment(segment);
|
|
m_rawNoteRuler->setCurrentSegment(segment);
|
|
m_rawNoteRuler->repaint();
|
|
setControlRulersCurrentSegment();
|
|
|
|
updateView();
|
|
|
|
slotSetInsertCursorPosition(getInsertionTime(), false, false);
|
|
|
|
m_headersGroup->setCurrent(
|
|
m_staffs[staffNo]->getSegment().getTrack());
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotCurrentStaffUp()
|
|
{
|
|
LinedStaff *staff = getStaffAbove();
|
|
if (!staff) return;
|
|
slotSetCurrentStaff(staff->getId());
|
|
}
|
|
|
|
void
|
|
NotationView::slotCurrentStaffDown()
|
|
{
|
|
LinedStaff *staff = getStaffBelow();
|
|
if (!staff) return;
|
|
slotSetCurrentStaff(staff->getId());
|
|
}
|
|
|
|
void
|
|
NotationView::slotCurrentSegmentPrior()
|
|
{
|
|
if (m_staffs.size() < 2)
|
|
return ;
|
|
|
|
Composition *composition =
|
|
m_staffs[m_currentStaff]->getSegment().getComposition();
|
|
|
|
Track *track = composition->
|
|
getTrackById(m_staffs[m_currentStaff]->getSegment().getTrack());
|
|
if (!track)
|
|
return ;
|
|
|
|
int lastStaffOnTrack = -1;
|
|
|
|
//
|
|
// TODO: Cycle segments through rather in time order?
|
|
// Cycle only segments in the field of view?
|
|
//
|
|
for (int i = m_staffs.size()-1; i >= 0; --i) {
|
|
if (m_staffs[i]->getSegment().getTrack() == track->getId()) {
|
|
if (lastStaffOnTrack < 0) {
|
|
lastStaffOnTrack = i;
|
|
}
|
|
if (i < m_currentStaff) {
|
|
slotSetCurrentStaff(i);
|
|
slotEditSelectWholeStaff();
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
if (lastStaffOnTrack >= 0) {
|
|
slotSetCurrentStaff(lastStaffOnTrack);
|
|
slotEditSelectWholeStaff();
|
|
return ;
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotCurrentSegmentNext()
|
|
{
|
|
if (m_staffs.size() < 2)
|
|
return ;
|
|
|
|
Composition *composition =
|
|
m_staffs[m_currentStaff]->getSegment().getComposition();
|
|
|
|
Track *track = composition->
|
|
getTrackById(m_staffs[m_currentStaff]->getSegment().getTrack());
|
|
if (!track)
|
|
return ;
|
|
|
|
int firstStaffOnTrack = -1;
|
|
|
|
//
|
|
// TODO: Cycle segments through rather in time order?
|
|
// Cycle only segments in the field of view?
|
|
//
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
if (m_staffs[i]->getSegment().getTrack() == track->getId()) {
|
|
if (firstStaffOnTrack < 0) {
|
|
firstStaffOnTrack = i;
|
|
}
|
|
if (i > m_currentStaff) {
|
|
slotSetCurrentStaff(i);
|
|
slotEditSelectWholeStaff();
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
if (firstStaffOnTrack >= 0) {
|
|
slotSetCurrentStaff(firstStaffOnTrack);
|
|
slotEditSelectWholeStaff();
|
|
return ;
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotSetInsertCursorPosition(double x, int y, bool scroll,
|
|
bool updateNow)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotSetInsertCursorPosition: x " << x << ", y " << y << ", scroll " << scroll << ", now " << updateNow << endl;
|
|
|
|
slotSetCurrentStaff(x, y);
|
|
|
|
LinedStaff *staff = getLinedStaff(m_currentStaff);
|
|
Event *clefEvt, *keyEvt;
|
|
NotationElementList::iterator i =
|
|
staff->getElementUnderCanvasCoords(x, y, clefEvt, keyEvt);
|
|
|
|
if (i == staff->getViewElementList()->end()) {
|
|
slotSetInsertCursorPosition(staff->getSegment().getEndTime(), scroll,
|
|
updateNow);
|
|
} else {
|
|
slotSetInsertCursorPosition((*i)->getViewAbsoluteTime(), scroll,
|
|
updateNow);
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotSetInsertCursorPosition(timeT t, bool scroll, bool updateNow)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotSetInsertCursorPosition: time " << t << ", scroll " << scroll << ", now " << updateNow << endl;
|
|
|
|
m_insertionTime = t;
|
|
if (scroll) {
|
|
m_deferredCursorMove = CursorMoveAndMakeVisible;
|
|
} else {
|
|
m_deferredCursorMove = CursorMoveOnly;
|
|
}
|
|
if (updateNow)
|
|
doDeferredCursorMove();
|
|
}
|
|
|
|
void
|
|
NotationView::slotSetInsertCursorAndRecentre(timeT t, double cx, int,
|
|
bool updateNow)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotSetInsertCursorAndRecentre: time " << t << ", cx " << cx << ", now " << updateNow << ", contentsx" << getCanvasView()->contentsX() << ", w " << getCanvasView()->visibleWidth() << endl;
|
|
|
|
m_insertionTime = t;
|
|
|
|
// We only do the scroll bit if cx is in the right two-thirds of
|
|
// the window
|
|
|
|
if (cx < (getCanvasView()->contentsX() +
|
|
getCanvasView()->visibleWidth() / 3)) {
|
|
|
|
m_deferredCursorMove = CursorMoveOnly;
|
|
} else {
|
|
m_deferredCursorMove = CursorMoveAndScrollToPosition;
|
|
m_deferredCursorScrollToX = cx;
|
|
}
|
|
|
|
if (updateNow)
|
|
doDeferredCursorMove();
|
|
}
|
|
|
|
void
|
|
NotationView::doDeferredCursorMove()
|
|
{
|
|
NOTATION_DEBUG << "NotationView::doDeferredCursorMove: m_deferredCursorMove == " << m_deferredCursorMove << endl;
|
|
|
|
if (m_deferredCursorMove == NoCursorMoveNeeded) {
|
|
return ;
|
|
}
|
|
|
|
DeferredCursorMoveType type = m_deferredCursorMove;
|
|
m_deferredCursorMove = NoCursorMoveNeeded;
|
|
|
|
timeT t = m_insertionTime;
|
|
|
|
if (m_staffs.size() == 0)
|
|
return ;
|
|
LinedStaff *staff = getCurrentLinedStaff();
|
|
Segment &segment = staff->getSegment();
|
|
|
|
if (t < segment.getStartTime()) {
|
|
t = segment.getStartTime();
|
|
}
|
|
if (t > segment.getEndTime()) {
|
|
t = segment.getEndTime();
|
|
}
|
|
|
|
NotationElementList::iterator i =
|
|
staff->getViewElementList()->findNearestTime(t);
|
|
|
|
while (i != staff->getViewElementList()->end() &&
|
|
!static_cast<NotationElement*>(*i)->getCanvasItem())
|
|
++i;
|
|
|
|
if (i == staff->getViewElementList()->end()) {
|
|
//!!! ???
|
|
if (m_insertionTime >= staff->getSegment().getStartTime()) {
|
|
i = staff->getViewElementList()->begin();
|
|
}
|
|
m_insertionTime = staff->getSegment().getStartTime();
|
|
} else {
|
|
m_insertionTime = static_cast<NotationElement*>(*i)->getViewAbsoluteTime();
|
|
}
|
|
|
|
if (i == staff->getViewElementList()->end() ||
|
|
t == segment.getEndTime() ||
|
|
t == segment.getBarStartForTime(t)) {
|
|
|
|
staff->setInsertCursorPosition(*m_hlayout, t);
|
|
|
|
if (type == CursorMoveAndMakeVisible) {
|
|
double cx;
|
|
int cy;
|
|
staff->getInsertCursorPosition(cx, cy);
|
|
getCanvasView()->slotScrollHoriz(int(cx));
|
|
getCanvasView()->slotScrollVertSmallSteps(cy);
|
|
}
|
|
|
|
} else {
|
|
|
|
// prefer a note or rest, if there is one, to a non-spacing event
|
|
if (!static_cast<NotationElement*>(*i)->isNote() &&
|
|
!static_cast<NotationElement*>(*i)->isRest()) {
|
|
NotationElementList::iterator j = i;
|
|
while (j != staff->getViewElementList()->end()) {
|
|
if (static_cast<NotationElement*>(*j)->getViewAbsoluteTime() !=
|
|
static_cast<NotationElement*>(*i)->getViewAbsoluteTime())
|
|
break;
|
|
if (static_cast<NotationElement*>(*j)->getCanvasItem()) {
|
|
if (static_cast<NotationElement*>(*j)->isNote() ||
|
|
static_cast<NotationElement*>(*j)->isRest()) {
|
|
i = j;
|
|
break;
|
|
}
|
|
}
|
|
++j;
|
|
}
|
|
}
|
|
|
|
if (static_cast<NotationElement*>(*i)->getCanvasItem()) {
|
|
|
|
staff->setInsertCursorPosition
|
|
(static_cast<NotationElement*>(*i)->getCanvasX() - 2,
|
|
int(static_cast<NotationElement*>(*i)->getCanvasY()));
|
|
|
|
if (type == CursorMoveAndMakeVisible) {
|
|
getCanvasView()->slotScrollHoriz
|
|
(int(static_cast<NotationElement*>(*i)->getCanvasX()) - 4);
|
|
}
|
|
} else {
|
|
std::cerr << "WARNING: No canvas item for this notation element:";
|
|
(*i)->event()->dump(std::cerr);
|
|
}
|
|
}
|
|
|
|
if (type == CursorMoveAndScrollToPosition) {
|
|
|
|
// get current canvas x of insert cursor, which might not be
|
|
// what we just set
|
|
|
|
double ccx = 0.0;
|
|
|
|
NotationElementList::iterator i =
|
|
staff->getViewElementList()->findTime(t);
|
|
|
|
if (i == staff->getViewElementList()->end()) {
|
|
if (i == staff->getViewElementList()->begin())
|
|
return ;
|
|
double lx, lwidth;
|
|
--i;
|
|
if (static_cast<NotationElement*>(*i)->getCanvasItem()) {
|
|
ccx = static_cast<NotationElement*>(*i)->getCanvasX();
|
|
static_cast<NotationElement*>(*i)->getLayoutAirspace(lx, lwidth);
|
|
} else {
|
|
std::cerr << "WARNING: No canvas item for this notation element*:";
|
|
(*i)->event()->dump(std::cerr);
|
|
}
|
|
ccx += lwidth;
|
|
} else {
|
|
if (static_cast<NotationElement*>(*i)->getCanvasItem()) {
|
|
ccx = static_cast<NotationElement*>(*i)->getCanvasX();
|
|
} else {
|
|
std::cerr << "WARNING: No canvas item for this notation element*:";
|
|
(*i)->event()->dump(std::cerr);
|
|
}
|
|
}
|
|
|
|
TQScrollBar* hbar = getCanvasView()->horizontalScrollBar();
|
|
hbar->setValue(int(hbar->value() - (m_deferredCursorScrollToX - ccx)));
|
|
}
|
|
|
|
updateView();
|
|
}
|
|
|
|
void
|
|
NotationView::slotJumpCursorToPlayback()
|
|
{
|
|
slotSetInsertCursorPosition(getDocument()->getComposition().getPosition());
|
|
}
|
|
|
|
void
|
|
NotationView::slotJumpPlaybackToCursor()
|
|
{
|
|
emit jumpPlaybackTo(getInsertionTime());
|
|
}
|
|
|
|
void
|
|
NotationView::slotToggleTracking()
|
|
{
|
|
m_playTracking = !m_playTracking;
|
|
}
|
|
|
|
void NotationView::slotNoAccidental()
|
|
{
|
|
emit changeAccidental(Accidentals::NoAccidental, false);
|
|
}
|
|
|
|
void NotationView::slotFollowAccidental()
|
|
{
|
|
emit changeAccidental(Accidentals::NoAccidental, true);
|
|
}
|
|
|
|
void NotationView::slotSharp()
|
|
{
|
|
emit changeAccidental(Accidentals::Sharp, false);
|
|
}
|
|
|
|
void NotationView::slotFlat()
|
|
{
|
|
emit changeAccidental(Accidentals::Flat, false);
|
|
}
|
|
|
|
void NotationView::slotNatural()
|
|
{
|
|
emit changeAccidental(Accidentals::Natural, false);
|
|
}
|
|
|
|
void NotationView::slotDoubleSharp()
|
|
{
|
|
emit changeAccidental(Accidentals::DoubleSharp, false);
|
|
}
|
|
|
|
void NotationView::slotDoubleFlat()
|
|
{
|
|
emit changeAccidental(Accidentals::DoubleFlat, false);
|
|
}
|
|
|
|
void NotationView::slotTrebleClef()
|
|
{
|
|
m_currentNotePixmap->setPixmap
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-treble")));
|
|
setTool(m_toolBox->getTool(ClefInserter::ToolName));
|
|
|
|
dynamic_cast<ClefInserter*>(m_tool)->setClef(Clef::Treble);
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotAltoClef()
|
|
{
|
|
m_currentNotePixmap->setPixmap
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-alto")));
|
|
setTool(m_toolBox->getTool(ClefInserter::ToolName));
|
|
|
|
dynamic_cast<ClefInserter*>(m_tool)->setClef(Clef::Alto);
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotTenorClef()
|
|
{
|
|
m_currentNotePixmap->setPixmap
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-tenor")));
|
|
setTool(m_toolBox->getTool(ClefInserter::ToolName));
|
|
|
|
dynamic_cast<ClefInserter*>(m_tool)->setClef(Clef::Tenor);
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotBassClef()
|
|
{
|
|
m_currentNotePixmap->setPixmap
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("clef-bass")));
|
|
setTool(m_toolBox->getTool(ClefInserter::ToolName));
|
|
|
|
dynamic_cast<ClefInserter*>(m_tool)->setClef(Clef::Bass);
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotText()
|
|
{
|
|
m_currentNotePixmap->setPixmap
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("text")));
|
|
setTool(m_toolBox->getTool(TextInserter::ToolName));
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotGuitarChord()
|
|
{
|
|
m_currentNotePixmap->setPixmap
|
|
(NotePixmapFactory::toTQPixmap(NotePixmapFactory::makeToolbarPixmap("guitarchord")));
|
|
setTool(m_toolBox->getTool(GuitarChordInserter::ToolName));
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotEraseSelected()
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotEraseSelected()" << endl;
|
|
setTool(m_toolBox->getTool(NotationEraser::ToolName));
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotSelectSelected()
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotSelectSelected()" << endl;
|
|
setTool(m_toolBox->getTool(NotationSelector::ToolName));
|
|
setMenuStates();
|
|
}
|
|
|
|
void NotationView::slotLinearMode()
|
|
{
|
|
setPageMode(LinedStaff::LinearMode);
|
|
}
|
|
|
|
void NotationView::slotContinuousPageMode()
|
|
{
|
|
setPageMode(LinedStaff::ContinuousPageMode);
|
|
}
|
|
|
|
void NotationView::slotMultiPageMode()
|
|
{
|
|
setPageMode(LinedStaff::MultiPageMode);
|
|
}
|
|
|
|
void NotationView::slotToggleChordsRuler()
|
|
{
|
|
if (m_hlayout->isPageMode())
|
|
return ;
|
|
toggleWidget(m_chordNameRuler, "show_chords_ruler");
|
|
}
|
|
|
|
void NotationView::slotToggleRawNoteRuler()
|
|
{
|
|
if (m_hlayout->isPageMode())
|
|
return ;
|
|
toggleWidget(m_rawNoteRuler, "show_raw_note_ruler");
|
|
}
|
|
|
|
void NotationView::slotToggleTempoRuler()
|
|
{
|
|
if (m_hlayout->isPageMode())
|
|
return ;
|
|
toggleWidget(m_tempoRuler, "show_tempo_ruler");
|
|
}
|
|
|
|
void NotationView::slotToggleAnnotations()
|
|
{
|
|
m_annotationsVisible = !m_annotationsVisible;
|
|
slotUpdateAnnotationsStatus();
|
|
//!!! use refresh mechanism
|
|
refreshSegment(0, 0, 0);
|
|
}
|
|
|
|
void NotationView::slotToggleLilyPondDirectives()
|
|
{
|
|
m_lilyPondDirectivesVisible = !m_lilyPondDirectivesVisible;
|
|
slotUpdateLilyPondDirectivesStatus();
|
|
//!!! use refresh mechanism
|
|
refreshSegment(0, 0, 0);
|
|
}
|
|
|
|
void NotationView::slotEditLyrics()
|
|
{
|
|
Staff *staff = getCurrentStaff();
|
|
Segment &segment = staff->getSegment();
|
|
|
|
LyricEditDialog dialog(this, &segment);
|
|
|
|
if (dialog.exec() == TQDialog::Accepted) {
|
|
|
|
KMacroCommand *macro = new KMacroCommand
|
|
(SetLyricsCommand::getGlobalName());
|
|
|
|
for (int i = 0; i < dialog.getVerseCount(); ++i) {
|
|
SetLyricsCommand *command = new SetLyricsCommand
|
|
(&segment, i, dialog.getLyricData(i));
|
|
macro->addCommand(command);
|
|
}
|
|
|
|
addCommandToHistory(macro);
|
|
}
|
|
}
|
|
|
|
void NotationView::slotItemPressed(int height, int staffNo,
|
|
TQMouseEvent* e,
|
|
NotationElement* el)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotItemPressed(height = "
|
|
<< height << ", staffNo = " << staffNo
|
|
<< ")" << endl;
|
|
|
|
if (staffNo < 0 && el != 0) {
|
|
// We have an element but no staff -- that's because the
|
|
// element extended outside the staff region. But we need
|
|
// to handle it properly, so we rather laboriously need to
|
|
// find out which staff it was.
|
|
for (unsigned int i = 0; i < m_staffs.size(); ++i) {
|
|
if (m_staffs[i]->getViewElementList()->findSingle(el) !=
|
|
m_staffs[i]->getViewElementList()->end()) {
|
|
staffNo = m_staffs[i]->getId();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ButtonState btnState = e->state();
|
|
|
|
if (btnState & ControlButton) { // on ctrl-click, set cursor position
|
|
|
|
slotSetInsertCursorPosition(e->x(), (int)e->y());
|
|
|
|
} else {
|
|
|
|
setActiveItem(0);
|
|
|
|
timeT unknownTime = 0;
|
|
|
|
if (e->type() == TQEvent::MouseButtonDblClick) {
|
|
m_tool->handleMouseDoubleClick(unknownTime, height,
|
|
staffNo, e, el);
|
|
} else {
|
|
m_tool->handleMousePress(unknownTime, height,
|
|
staffNo, e, el);
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotNonNotationItemPressed(TQMouseEvent *e, TQCanvasItem *it)
|
|
{
|
|
if (e->type() != TQEvent::MouseButtonDblClick)
|
|
return ;
|
|
|
|
Staff *staff = getStaffForCanvasCoords(e->x(), e->y());
|
|
if (!staff)
|
|
return ;
|
|
|
|
NOTATION_DEBUG << "NotationView::slotNonNotationItemPressed(doubly)" << endl;
|
|
|
|
if (dynamic_cast<QCanvasStaffNameSprite *>(it)) {
|
|
|
|
std::string name =
|
|
staff->getSegment().getComposition()->
|
|
getTrackById(staff->getSegment().getTrack())->getLabel();
|
|
|
|
bool ok = false;
|
|
TQRegExpValidator validator(TQRegExp(".*"), TQT_TQOBJECT(this)); // empty is OK
|
|
|
|
TQString newText = KLineEditDlg::getText(TQString("Change staff name"),
|
|
TQString("Enter new staff name"),
|
|
strtoqstr(name),
|
|
&ok,
|
|
this,
|
|
&validator);
|
|
|
|
if (ok) {
|
|
addCommandToHistory(new RenameTrackCommand
|
|
(staff->getSegment().getComposition(),
|
|
staff->getSegment().getTrack(),
|
|
qstrtostr(newText)));
|
|
|
|
emit staffLabelChanged(staff->getSegment().getTrack(), newText);
|
|
}
|
|
|
|
} else if (dynamic_cast<TQCanvasTimeSigSprite *>(it)) {
|
|
|
|
double layoutX = (dynamic_cast<TQCanvasTimeSigSprite *>(it))->getLayoutX();
|
|
emit editTimeSignature(m_hlayout->getTimeForX(layoutX));
|
|
}
|
|
}
|
|
|
|
void NotationView::slotTextItemPressed(TQMouseEvent *e, TQCanvasItem *it)
|
|
{
|
|
if (e->type() != TQEvent::MouseButtonDblClick)
|
|
return ;
|
|
|
|
if (it == m_title) {
|
|
emit editMetadata(strtoqstr(CompositionMetadataKeys::Title.getName()));
|
|
} else if (it == m_subtitle) {
|
|
emit editMetadata(strtoqstr(CompositionMetadataKeys::Subtitle.getName()));
|
|
} else if (it == m_composer) {
|
|
emit editMetadata(strtoqstr(CompositionMetadataKeys::Composer.getName()));
|
|
} else if (it == m_copyright) {
|
|
emit editMetadata(strtoqstr(CompositionMetadataKeys::Copyright.getName()));
|
|
} else {
|
|
return ;
|
|
}
|
|
|
|
positionStaffs();
|
|
}
|
|
|
|
void NotationView::slotMouseMoved(TQMouseEvent *e)
|
|
{
|
|
if (activeItem()) {
|
|
activeItem()->handleMouseMove(e);
|
|
updateView();
|
|
} else {
|
|
int follow = m_tool->handleMouseMove(0, 0, // unknown time and height
|
|
e);
|
|
|
|
if (getCanvasView()->isTimeForSmoothScroll()) {
|
|
|
|
if (follow & RosegardenCanvasView::FollowHorizontal) {
|
|
getCanvasView()->slotScrollHorizSmallSteps(e->x());
|
|
}
|
|
|
|
if (follow & RosegardenCanvasView::FollowVertical) {
|
|
getCanvasView()->slotScrollVertSmallSteps(e->y());
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void NotationView::slotMouseReleased(TQMouseEvent *e)
|
|
{
|
|
if (activeItem()) {
|
|
activeItem()->handleMouseRelease(e);
|
|
setActiveItem(0);
|
|
updateView();
|
|
} else
|
|
m_tool->handleMouseRelease(0, 0, // unknown time and height
|
|
e);
|
|
}
|
|
|
|
void
|
|
NotationView::slotHoveredOverNoteChanged(const TQString ¬eName)
|
|
{
|
|
m_hoveredOverNoteName->setText(TQString(" ") + noteName);
|
|
}
|
|
|
|
void
|
|
NotationView::slotHoveredOverAbsoluteTimeChanged(unsigned int time)
|
|
{
|
|
timeT t = time;
|
|
RealTime rt =
|
|
getDocument()->getComposition().getElapsedRealTime(t);
|
|
long ms = rt.msec();
|
|
|
|
int bar, beat, fraction, remainder;
|
|
getDocument()->getComposition().getMusicalTimeForAbsoluteTime
|
|
(t, bar, beat, fraction, remainder);
|
|
|
|
// TQString message;
|
|
// TQString format("%ld (%ld.%03lds)");
|
|
// format = i18n("Time: %1").arg(format);
|
|
// message.sprintf(format, t, rt.sec, ms);
|
|
|
|
TQString message = i18n("Time: %1 (%2.%3s)")
|
|
.arg(TQString("%1-%2-%3-%4")
|
|
.arg(TQString("%1").arg(bar + 1).rightJustify(3, '0'))
|
|
.arg(TQString("%1").arg(beat).rightJustify(2, '0'))
|
|
.arg(TQString("%1").arg(fraction).rightJustify(2, '0'))
|
|
.arg(TQString("%1").arg(remainder).rightJustify(2, '0')))
|
|
.arg(rt.sec)
|
|
.arg(TQString("%1").arg(ms).rightJustify(3, '0'));
|
|
|
|
m_hoveredOverAbsoluteTime->setText(message);
|
|
}
|
|
|
|
void
|
|
NotationView::slotInsertableNoteEventReceived(int pitch, int velocity, bool noteOn)
|
|
{
|
|
//!!! Problematic. Ideally we wouldn't insert events into windows
|
|
//that weren't actually visible, otherwise all hell could break
|
|
//loose (metaphorically speaking, I should probably add). I did
|
|
//think of checking isActiveWindow() and returning if the current
|
|
//window wasn't active, but that will prevent anyone from
|
|
//step-recording from e.g. vkeybd, which cannot be used without
|
|
//losing focus (and thus active-ness) from the Rosegarden window.
|
|
|
|
//!!! I know -- we'll keep track of which edit view (or main view,
|
|
//or mixer, etc) is active, and we'll only allow insertion into
|
|
//the most recently activated. How about that?
|
|
|
|
TDEToggleAction *action = dynamic_cast<TDEToggleAction *>
|
|
(actionCollection()->action("toggle_step_by_step"));
|
|
if (!action) {
|
|
NOTATION_DEBUG << "WARNING: No toggle_step_by_step action" << endl;
|
|
return ;
|
|
}
|
|
if (!action->isChecked())
|
|
return ;
|
|
|
|
Segment &segment = m_staffs[m_currentStaff]->getSegment();
|
|
|
|
NoteInserter *noteInserter = dynamic_cast<NoteInserter *>(m_tool);
|
|
if (!noteInserter) {
|
|
static bool showingError = false;
|
|
if (showingError)
|
|
return ;
|
|
showingError = true;
|
|
KMessageBox::sorry(this, i18n("Can't insert note: No note duration selected"));
|
|
showingError = false;
|
|
return ;
|
|
}
|
|
|
|
if (m_inPaintEvent) {
|
|
NOTATION_DEBUG << "NotationView::slotInsertableNoteEventReceived: in paint event already" << endl;
|
|
if (noteOn) {
|
|
m_pendingInsertableNotes.push_back(std::pair<int, int>(pitch, velocity));
|
|
}
|
|
return ;
|
|
}
|
|
|
|
// If the segment is transposed, we want to take that into
|
|
// account. But the note has already been played back to the user
|
|
// at its untransposed pitch, because that's done by the MIDI THRU
|
|
// code in the sequencer which has no way to know whether a note
|
|
// was intended for step recording. So rather than adjust the
|
|
// pitch for playback according to the transpose setting, we have
|
|
// to adjust the stored pitch in the opposite direction.
|
|
|
|
pitch -= segment.getTranspose();
|
|
|
|
// KTmpStatusMsg msg(i18n("Inserting note"), this);
|
|
|
|
// We need to ensure that multiple notes hit at once come out as
|
|
// chords, without imposing the interpretation that overlapping
|
|
// notes are always chords and without getting too involved with
|
|
// the actual absolute times of the notes (this is still step
|
|
// editing, not proper recording).
|
|
|
|
// First, if we're in chord mode, there's no problem.
|
|
|
|
static int numberOfNotesOn = 0;
|
|
static timeT insertionTime = getInsertionTime();
|
|
static time_t lastInsertionTime = 0;
|
|
|
|
if (isInChordMode()) {
|
|
if (!noteOn)
|
|
return ;
|
|
NOTATION_DEBUG << "Inserting note in chord at pitch " << pitch << endl;
|
|
noteInserter->insertNote(segment, getInsertionTime(), pitch,
|
|
Accidentals::NoAccidental,
|
|
true);
|
|
|
|
} else {
|
|
|
|
if (!noteOn) {
|
|
numberOfNotesOn--;
|
|
} else if (noteOn) {
|
|
// Rules:
|
|
//
|
|
// * If no other note event has turned up within half a
|
|
// second, insert this note and advance.
|
|
//
|
|
// * Relatedly, if this note is within half a second of
|
|
// the previous one, they're chords. Insert the previous
|
|
// one, don't advance, and use the same rules for this.
|
|
//
|
|
// * If a note event turns up before that time has elapsed,
|
|
// we need to wait for the note-off events: if the second
|
|
// note happened less than half way through the first,
|
|
// it's a chord.
|
|
//
|
|
// We haven't implemented these yet... For now:
|
|
//
|
|
// Rules (hjj):
|
|
//
|
|
// * The overlapping notes are always included in to a chord.
|
|
// This is the most convenient for step inserting of chords.
|
|
//
|
|
// * The timer resets the numberOfNotesOn, if noteOff signals were
|
|
// drop out for some reason (which has not been encountered yet).
|
|
|
|
time_t now;
|
|
time (&now);
|
|
double elapsed = difftime(now, lastInsertionTime);
|
|
time (&lastInsertionTime);
|
|
|
|
if (numberOfNotesOn <= 0 || elapsed > 10.0 ) {
|
|
numberOfNotesOn = 0;
|
|
insertionTime = getInsertionTime();
|
|
}
|
|
numberOfNotesOn++;
|
|
|
|
noteInserter->insertNote(segment, insertionTime, pitch,
|
|
Accidentals::NoAccidental,
|
|
true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotInsertableNoteOnReceived(int pitch, int velocity)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotInsertableNoteOnReceived: " << pitch << endl;
|
|
slotInsertableNoteEventReceived(pitch, velocity, true);
|
|
}
|
|
|
|
void
|
|
NotationView::slotInsertableNoteOffReceived(int pitch, int velocity)
|
|
{
|
|
NOTATION_DEBUG << "NotationView::slotInsertableNoteOffReceived: " << pitch << endl;
|
|
slotInsertableNoteEventReceived(pitch, velocity, false);
|
|
}
|
|
|
|
void
|
|
NotationView::slotInsertableTimerElapsed()
|
|
{}
|
|
|
|
void
|
|
NotationView::slotToggleStepByStep()
|
|
{
|
|
TDEToggleAction *action = dynamic_cast<TDEToggleAction *>
|
|
(actionCollection()->action("toggle_step_by_step"));
|
|
if (!action) {
|
|
NOTATION_DEBUG << "WARNING: No toggle_step_by_step action" << endl;
|
|
return ;
|
|
}
|
|
if (action->isChecked()) { // after toggling, that is
|
|
emit stepByStepTargetRequested(TQT_TQOBJECT(this));
|
|
} else {
|
|
emit stepByStepTargetRequested(0);
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotStepByStepTargetRequested(TQObject *obj)
|
|
{
|
|
TDEToggleAction *action = dynamic_cast<TDEToggleAction *>
|
|
(actionCollection()->action("toggle_step_by_step"));
|
|
if (!action) {
|
|
NOTATION_DEBUG << "WARNING: No toggle_step_by_step action" << endl;
|
|
return ;
|
|
}
|
|
action->setChecked(TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(this));
|
|
}
|
|
|
|
void
|
|
NotationView::slotCheckRendered(double cx0, double cx1)
|
|
{
|
|
// NOTATION_DEBUG << "slotCheckRendered(" << cx0 << "," << cx1 << ")" << endl;
|
|
|
|
bool something = false;
|
|
|
|
for (size_t i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
LinedStaff *staff = m_staffs[i];
|
|
|
|
LinedStaff::LinedStaffCoords cc0 = staff->getLayoutCoordsForCanvasCoords
|
|
(cx0, 0);
|
|
|
|
LinedStaff::LinedStaffCoords cc1 = staff->getLayoutCoordsForCanvasCoords
|
|
(cx1, staff->getTotalHeight() + staff->getY());
|
|
|
|
timeT t0 = m_hlayout->getTimeForX(cc0.first);
|
|
timeT t1 = m_hlayout->getTimeForX(cc1.first);
|
|
|
|
if (dynamic_cast<NotationStaff *>(staff)->checkRendered(t0, t1)) {
|
|
something = true; //!!!
|
|
}
|
|
}
|
|
|
|
if (something) {
|
|
emit renderComplete();
|
|
if (m_renderTimer)
|
|
delete m_renderTimer;
|
|
m_renderTimer = new TQTimer(this);
|
|
connect(m_renderTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotRenderSomething()));
|
|
m_renderTimer->start(0, true);
|
|
}
|
|
|
|
if (m_deferredCursorMove != NoCursorMoveNeeded)
|
|
doDeferredCursorMove();
|
|
}
|
|
|
|
void
|
|
NotationView::slotRenderSomething()
|
|
{
|
|
delete m_renderTimer;
|
|
m_renderTimer = 0;
|
|
static clock_t lastWork = 0;
|
|
|
|
clock_t now = clock();
|
|
long elapsed = ((now - lastWork) * 1000 / CLOCKS_PER_SEC);
|
|
if (elapsed < 70) {
|
|
m_renderTimer = new TQTimer(this);
|
|
connect(m_renderTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotRenderSomething()));
|
|
m_renderTimer->start(0, true);
|
|
return ;
|
|
}
|
|
lastWork = now;
|
|
|
|
for (size_t i = 0; i < m_staffs.size(); ++i) {
|
|
|
|
if (m_staffs[i]->doRenderWork(m_staffs[i]->getSegment().getStartTime(),
|
|
m_staffs[i]->getSegment().getEndTime())) {
|
|
m_renderTimer = new TQTimer(this);
|
|
connect(m_renderTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotRenderSomething()));
|
|
m_renderTimer->start(0, true);
|
|
return ;
|
|
}
|
|
}
|
|
|
|
PixmapArrayGC::deleteAll();
|
|
NOTATION_DEBUG << "NotationView::slotRenderSomething: updating thumbnails" << endl;
|
|
updateThumbnails(true);
|
|
|
|
// Update track headers when rendering is done
|
|
// (better late than never)
|
|
m_headersGroup->slotUpdateAllHeaders(getCanvasLeftX(), 0, true);
|
|
m_headersGroupView->setContentsPos(getCanvasView()->contentsX(),
|
|
getCanvasView()->contentsY());
|
|
}
|
|
|
|
NotationCanvasView* NotationView::getCanvasView()
|
|
{
|
|
return dynamic_cast<NotationCanvasView *>(m_canvasView);
|
|
}
|
|
|
|
void
|
|
NotationView::slotVerticalScrollHeadersGroup(int y)
|
|
{
|
|
m_headersGroupView->setContentsPos(0, y);
|
|
}
|
|
|
|
void
|
|
NotationView::slotShowHeadersGroup()
|
|
{
|
|
m_showHeadersGroup = HeadersGroup::ShowAlways;
|
|
showHeadersGroup();
|
|
|
|
// Disable menu entry when headers are shown
|
|
m_showHeadersMenuEntry->setEnabled(false);
|
|
}
|
|
|
|
void
|
|
NotationView::slotHideHeadersGroup()
|
|
{
|
|
m_showHeadersGroup = HeadersGroup::ShowNever;
|
|
hideHeadersGroup();
|
|
|
|
// Enable menu entry when headers are hidden
|
|
m_showHeadersMenuEntry->setEnabled(true);
|
|
}
|
|
|
|
void
|
|
NotationView::showHeadersGroup()
|
|
{
|
|
if (m_headersGroupView && (m_pageMode == LinedStaff::LinearMode)) {
|
|
m_headersGroupView->show();
|
|
m_headersTopFrame->show();
|
|
m_rulerBoxFiller->show();
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::hideHeadersGroup()
|
|
{
|
|
if (m_headersGroupView) {
|
|
m_headersGroupView->hide();
|
|
m_headersTopFrame->hide();
|
|
m_rulerBoxFiller->hide();
|
|
}
|
|
}
|
|
|
|
void
|
|
NotationView::slotUpdateHeaders(int x, int y)
|
|
{
|
|
m_headersGroup->slotUpdateAllHeaders(x, y);
|
|
m_headersGroupView->setContentsPos(x, y);
|
|
}
|
|
|
|
void
|
|
NotationView::slotHeadersWidthChanged(int w)
|
|
{
|
|
m_headersTopFrame->setFixedWidth(w);
|
|
m_rulerBoxFiller->setFixedWidth(w);
|
|
m_canvasView->updateLeftWidgetGeometry();
|
|
}
|
|
|
|
|
|
int
|
|
NotationView::getCanvasVisibleWidth()
|
|
{
|
|
if (getCanvasView()) {
|
|
return getCanvasView()->visibleWidth();
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int
|
|
NotationView::getHeadersTopFrameMinWidth()
|
|
{
|
|
/// TODO : use a real button width got from a real button
|
|
|
|
// 2 buttons (2 x 24) + 2 margins (2 x 4) + buttons spacing (4)
|
|
return 4 + 24 + 4 + 24 + 4;
|
|
}
|
|
|
|
}
|
|
#include "NotationView.moc"
|