summaryrefslogtreecommitdiffstats
path: root/src/gui/general/EditView.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/general/EditView.cpp')
-rw-r--r--src/gui/general/EditView.cpp1717
1 files changed, 1717 insertions, 0 deletions
diff --git a/src/gui/general/EditView.cpp b/src/gui/general/EditView.cpp
new file mode 100644
index 0000000..a36b385
--- /dev/null
+++ b/src/gui/general/EditView.cpp
@@ -0,0 +1,1717 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Rosegarden
+ A MIDI and audio sequencer and musical notation editor.
+
+ This program is Copyright 2000-2008
+ Guillaume Laurent <[email protected]>,
+ Chris Cannam <[email protected]>,
+ Richard Bown <[email protected]>
+
+ 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 "EditView.h"
+#include <qlayout.h>
+
+#include "base/BaseProperties.h"
+#include <klocale.h>
+#include <kconfig.h>
+#include "misc/Debug.h"
+#include "misc/Strings.h"
+#include "ActiveItem.h"
+#include "base/AnalysisTypes.h"
+#include "base/Composition.h"
+#include "base/CompositionTimeSliceAdapter.h"
+#include "base/Controllable.h"
+#include "base/ControlParameter.h"
+#include "base/Device.h"
+#include "base/Event.h"
+#include "base/Exception.h"
+#include "base/Instrument.h"
+#include "base/MidiDevice.h"
+#include "base/MidiProgram.h"
+#include "base/MidiTypes.h"
+#include "base/NotationTypes.h"
+#include "base/Profiler.h"
+#include "base/Property.h"
+#include "base/PropertyName.h"
+#include "base/RulerScale.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "base/SoftSynthDevice.h"
+#include "base/Staff.h"
+#include "base/Studio.h"
+#include "base/ViewElement.h"
+#include "commands/edit/InvertCommand.h"
+#include "commands/edit/MoveCommand.h"
+#include "commands/edit/RescaleCommand.h"
+#include "commands/edit/RetrogradeCommand.h"
+#include "commands/edit/RetrogradeInvertCommand.h"
+#include "commands/edit/TransposeCommand.h"
+#include "commands/segment/AddTempoChangeCommand.h"
+#include "commands/segment/AddTimeSignatureAndNormalizeCommand.h"
+#include "commands/segment/AddTimeSignatureCommand.h"
+#include "document/MultiViewCommandHistory.h"
+#include "document/RosegardenGUIDoc.h"
+#include "document/ConfigGroups.h"
+#include "EditViewBase.h"
+#include "gui/dialogs/RescaleDialog.h"
+#include "gui/dialogs/TempoDialog.h"
+#include "gui/dialogs/IntervalDialog.h"
+#include "gui/dialogs/TimeSignatureDialog.h"
+#include "gui/rulers/StandardRuler.h"
+#include "gui/kdeext/KTmpStatusMsg.h"
+#include "gui/kdeext/QCanvasGroupableItem.h"
+#include "gui/rulers/ControllerEventsRuler.h"
+#include "gui/rulers/ControlRuler.h"
+#include "gui/rulers/PropertyControlRuler.h"
+#include "RosegardenCanvasView.h"
+#include <kaction.h>
+#include <kcommand.h>
+#include <kdockwidget.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kstddirs.h>
+#include <ktabwidget.h>
+#include <kxmlguiclient.h>
+#include <qaccel.h>
+#include <qbutton.h>
+#include <qdialog.h>
+#include <qframe.h>
+#include <qinputdialog.h>
+#include <qlabel.h>
+#include <qobjectlist.h>
+#include <qpopupmenu.h>
+#include <qsize.h>
+#include <qstring.h>
+#include <qtabwidget.h>
+#include <qvbox.h>
+#include <qwidget.h>
+#include <qwmatrix.h>
+
+
+namespace Rosegarden
+{
+
+const unsigned int EditView::CONTROLS_ROW = 0;
+const unsigned int EditView::RULERS_ROW = CONTROLS_ROW + 1;
+const unsigned int EditView::TOPBARBUTTONS_ROW = RULERS_ROW + 1;
+const unsigned int EditView::CANVASVIEW_ROW = TOPBARBUTTONS_ROW + 1;
+const unsigned int EditView::CONTROLRULER_ROW = CANVASVIEW_ROW + 1;
+
+// Just some simple features we might want to show - make them bit maskable
+//
+static int FeatureShowVelocity = 0x00001; // show the velocity ruler
+
+EditView::EditView(RosegardenGUIDoc *doc,
+ std::vector<Segment *> segments,
+ unsigned int cols,
+ QWidget *parent, const char *name) :
+ EditViewBase(doc, segments, cols, parent, name),
+ m_currentEventSelection(0),
+ m_activeItem(0),
+ m_canvasView(0),
+ m_rulerBox(new QVBoxLayout), // top ruler box - added to grid later on
+ m_rulerBoxFiller(0), // On the left of m_rulerBox
+ m_controlBox(new QVBoxLayout), // top control ruler box - added to grid later on
+ m_bottomBox(new QVBox(this, "bottomframe")), // bottom box - added to bottom of canvas view by setCanvasView()
+ m_topStandardRuler(0),
+ m_bottomStandardRuler(0),
+ m_controlRuler(0),
+ m_controlRulers(new KTabWidget(getBottomWidget(), "controlrulers"))
+{
+ m_controlRulers->setHoverCloseButton(true);
+ m_controlRulers->setHoverCloseButtonDelayed(false);
+ connect(m_controlRulers, SIGNAL(closeRequest(QWidget*)),
+ this, SLOT(slotRemoveControlRuler(QWidget*)));
+
+ (dynamic_cast<QBoxLayout*>(m_bottomBox->layout()))->setDirection(QBoxLayout::BottomToTop);
+
+ // m_rulerBoxFiller is a white label used to keep m_rulerBox exactly
+ // above the scrolling part of the view (and never above the
+ // RosegardenCanvasView::m_leftWidget).
+ QGridLayout * gl = new QGridLayout(1, 2);
+ gl->setColStretch(0, 0);
+ gl->setColStretch(1, 1);
+ gl->addLayout(m_rulerBox, 0, 1);
+ m_rulerBoxFiller = new QLabel(getCentralWidget());
+ gl->addWidget(m_rulerBoxFiller, 0, 0);
+ m_rulerBoxFiller->hide();
+
+ m_grid->addLayout(gl, RULERS_ROW, m_mainCol);
+
+ m_grid->addMultiCellLayout(m_controlBox, CONTROLS_ROW, CONTROLS_ROW, 0, 1);
+ m_controlBox->setAlignment(AlignRight);
+ // m_grid->addWidget(m_controlRulers, CONTROLRULER_ROW, 2);
+
+ m_controlRulers->hide();
+ m_controlRulers->setTabPosition(QTabWidget::Bottom);
+}
+
+EditView::~EditView()
+{
+ delete m_currentEventSelection;
+ m_currentEventSelection = 0;
+}
+
+void EditView::updateBottomWidgetGeometry()
+{
+ getBottomWidget()->layout()->invalidate();
+ getBottomWidget()->updateGeometry();
+ getCanvasView()->updateBottomWidgetGeometry();
+}
+
+void EditView::paintEvent(QPaintEvent* e)
+{
+ RG_DEBUG << "EditView::paintEvent()\n";
+ EditViewBase::paintEvent(e);
+
+ if (m_needUpdate) {
+ RG_DEBUG << "EditView::paintEvent() - calling updateView\n";
+ updateView();
+ getCanvasView()->slotUpdate();
+
+ // update rulers
+ QLayoutIterator it = m_rulerBox->iterator();
+ QLayoutItem *child;
+ while ( (child = it.current()) != 0 ) {
+ if (child->widget())
+ child->widget()->update();
+ ++it;
+ }
+
+ updateControlRulers();
+
+ } else {
+
+ getCanvasView()->slotUpdate();
+ updateControlRulers();
+
+ }
+
+ m_needUpdate = false;
+}
+
+void EditView::updateControlRulers(bool updateHPos)
+{
+ for (int i = 0; i < m_controlRulers->count(); ++i) {
+ ControlRuler* ruler = dynamic_cast<ControlRuler*>(m_controlRulers->page(i));
+ if (ruler) {
+ if (updateHPos)
+ ruler->slotUpdateElementsHPos();
+ else
+ ruler->slotUpdate();
+ }
+ }
+}
+
+void EditView::setControlRulersZoom(QWMatrix zoomMatrix)
+{
+ m_currentRulerZoomMatrix = zoomMatrix;
+
+ for (int i = 0; i < m_controlRulers->count(); ++i) {
+ ControlRuler* ruler = dynamic_cast<ControlRuler*>(m_controlRulers->page(i));
+ if (ruler)
+ ruler->setWorldMatrix(zoomMatrix);
+ }
+}
+
+void EditView::setControlRulersCurrentSegment()
+{
+ RG_DEBUG << "EditView::setControlRulersCurrentSegment: visible is " << m_controlRulers->isVisible() << endl;
+
+ bool visible = m_controlRulers->isVisible();
+
+ delete m_controlRulers;
+ m_controlRulers = new KTabWidget(getBottomWidget(), "controlrulers");
+
+ bool haveTabs = setupControllerTabs();
+ setupAddControlRulerMenu();
+
+ if (haveTabs)
+ m_controlRulers->show();
+ else
+ m_controlRulers->hide();
+
+ updateBottomWidgetGeometry();
+
+ /*
+ for (int i = 0; i < m_controlRulers->count(); ++i) {
+
+ PropertyControlRuler *pcr = dynamic_cast<PropertyControlRuler *>
+ (m_controlRulers->page(i));
+
+ if (pcr) pcr->setStaff(getCurrentStaff());
+ else {
+
+ ControllerEventsRuler *cer = dynamic_cast<ControllerEventsRuler *>
+ (m_controlRulers->page(i));
+
+ if (cer) cer->setSegment(getCurrentSegment());
+ }
+ }
+ */
+}
+
+void EditView::setTopStandardRuler(StandardRuler* w, QWidget *leftBox)
+{
+ delete m_topStandardRuler;
+ m_topStandardRuler = w;
+
+ QGridLayout * gl = new QGridLayout(1, 2);
+ gl->setColStretch(0, 0);
+ gl->setColStretch(1, 1);
+
+ gl->addWidget(w, 0, 1);
+ if (leftBox) {
+ gl->addWidget(leftBox, 0, 0);
+ }
+
+ m_grid->addLayout(gl, TOPBARBUTTONS_ROW, m_mainCol);
+
+ if (m_canvasView) {
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ m_topStandardRuler, SLOT(slotScrollHoriz(int)));
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(sliderMoved(int)),
+ m_topStandardRuler, SLOT(slotScrollHoriz(int)));
+ }
+}
+
+void EditView::setBottomStandardRuler(StandardRuler* w)
+{
+ delete m_bottomStandardRuler;
+ m_bottomStandardRuler = w;
+
+ // m_bottomBox->insertWidget(0, w);
+
+ if (m_canvasView) {
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ m_bottomStandardRuler, SLOT(slotScrollHoriz(int)));
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(sliderMoved(int)),
+ m_bottomStandardRuler, SLOT(slotScrollHoriz(int)));
+ }
+}
+
+void EditView::setRewFFwdToAutoRepeat()
+{
+ QWidget* transportToolbar = factory()->container("Transport Toolbar", this);
+
+ if (transportToolbar) {
+ QObjectList *l = transportToolbar->queryList();
+ QObjectListIt it(*l); // iterate over the buttons
+ QObject *obj;
+
+ while ( (obj = it.current()) != 0 ) {
+ // for each found object...
+ ++it;
+ // RG_DEBUG << "EditView::setRewFFwdToAutoRepeat() : obj name : " << obj->name() << endl;
+ QString objName = obj->name();
+
+ if (objName.endsWith("playback_pointer_back_bar") || objName.endsWith("playback_pointer_forward_bar")) {
+ QButton* btn = dynamic_cast<QButton*>(obj);
+ if (!btn) {
+ RG_DEBUG << "Very strange - found widgets in Transport Toolbar which aren't buttons\n";
+
+ continue;
+ }
+ btn->setAutoRepeat(true);
+ }
+
+
+ }
+ delete l;
+
+ } else {
+ RG_DEBUG << "transportToolbar == 0\n";
+ }
+
+}
+
+void EditView::addRuler(QWidget* w)
+{
+ m_rulerBox->addWidget(w);
+
+ if (m_canvasView) {
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ w, SLOT(slotScrollHoriz(int)));
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(sliderMoved(int)),
+ w, SLOT(slotScrollHoriz(int)));
+ }
+}
+
+void EditView::addPropertyBox(QWidget *w)
+{
+ m_controlBox->addWidget(w);
+}
+
+void EditView::addControlRuler(ControlRuler* ruler)
+{
+ ruler->setWorldMatrix(m_currentRulerZoomMatrix);
+ m_controlRulers->addTab(ruler, KGlobal::iconLoader()->loadIconSet("fileclose", KIcon::Small),
+ ruler->getName());
+ m_controlRulers->showPage(ruler);
+
+ if (m_canvasView) {
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ ruler->horizontalScrollBar(), SIGNAL(valueChanged(int)));
+ connect(m_canvasView->horizontalScrollBar(), SIGNAL(sliderMoved(int)),
+ ruler->horizontalScrollBar(), SIGNAL(sliderMoved(int)));
+ }
+
+ connect(ruler, SIGNAL(stateChange(const QString&, bool)),
+ this, SLOT(slotStateChanged(const QString&, bool)));
+
+ stateChanged("have_control_ruler", KXMLGUIClient::StateReverse);
+}
+
+void EditView::readjustViewSize(QSize requestedSize, bool exact)
+{
+ Profiler profiler("EditView::readjustViewSize", true);
+
+ if (exact) {
+ RG_DEBUG << "EditView::readjustViewSize: exact size requested ("
+ << requestedSize.width() << ", " << requestedSize.height()
+ << ")\n";
+
+ setViewSize(requestedSize);
+ getCanvasView()->slotUpdate();
+ return ;
+ }
+
+ int requestedWidth = requestedSize.width(),
+ requestedHeight = requestedSize.height(),
+ windowWidth = width(),
+ windowHeight = height();
+
+ QSize newSize;
+
+ newSize.setWidth(((requestedWidth / windowWidth) + 1) * windowWidth);
+ newSize.setHeight(((requestedHeight / windowHeight) + 1) * windowHeight);
+
+ RG_DEBUG << "EditView::readjustViewSize: requested ("
+ << requestedSize.width() << ", " << requestedSize.height()
+ << "), getting (" << newSize.width() << ", "
+ << newSize.height() << ")" << endl;
+
+ setViewSize(newSize);
+
+ getCanvasView()->slotUpdate();
+}
+
+void EditView::setCanvasView(RosegardenCanvasView *canvasView)
+{
+ delete m_canvasView;
+ m_canvasView = canvasView;
+ m_grid->addWidget(m_canvasView, CANVASVIEW_ROW, m_mainCol);
+ m_canvasView->setBottomFixedWidget(m_bottomBox);
+
+ // TODO : connect canvas view's horiz. scrollbar to top/bottom bars and rulers
+
+ // m_horizontalScrollBar->setRange(m_canvasView->horizontalScrollBar()->minValue(),
+ // m_canvasView->horizontalScrollBar()->maxValue());
+
+ // m_horizontalScrollBar->setSteps(m_canvasView->horizontalScrollBar()->lineStep(),
+ // m_canvasView->horizontalScrollBar()->pageStep());
+
+ // connect(m_horizontalScrollBar, SIGNAL(valueChanged(int)),
+ // m_canvasView->horizontalScrollBar(), SIGNAL(valueChanged(int)));
+ // connect(m_horizontalScrollBar, SIGNAL(sliderMoved(int)),
+ // m_canvasView->horizontalScrollBar(), SIGNAL(sliderMoved(int)));
+
+}
+
+Device *
+EditView::getCurrentDevice()
+{
+ Segment *segment = getCurrentSegment();
+ if (!segment)
+ return 0;
+
+ Studio &studio = getDocument()->getStudio();
+ Instrument *instrument =
+ studio.getInstrumentById
+ (segment->getComposition()->getTrackById(segment->getTrack())->
+ getInstrument());
+ if (!instrument)
+ return 0;
+
+ return instrument->getDevice();
+}
+
+timeT
+EditView::getInsertionTime(Clef &clef,
+ Rosegarden::Key &key)
+{
+ timeT t = getInsertionTime();
+ Segment *segment = getCurrentSegment();
+
+ if (segment) {
+ clef = segment->getClefAtTime(t);
+ key = segment->getKeyAtTime(t);
+ } else {
+ clef = Clef();
+ key = ::Rosegarden::Key();
+ }
+
+ return t;
+}
+
+void EditView::slotActiveItemPressed(QMouseEvent* e,
+ QCanvasItem* item)
+{
+ if (!item)
+ return ;
+
+ // Check if it's a groupable item, if so get its group
+ //
+ QCanvasGroupableItem *gitem = dynamic_cast<QCanvasGroupableItem*>(item);
+ if (gitem)
+ item = gitem->group();
+
+ // Check if it's an active item
+ //
+ ActiveItem *activeItem = dynamic_cast<ActiveItem*>(item);
+
+ if (activeItem) {
+
+ setActiveItem(activeItem);
+ activeItem->handleMousePress(e);
+ updateView();
+
+ }
+}
+
+void
+EditView::slotStepBackward()
+{
+ Staff *staff = getCurrentStaff();
+ if (!staff)
+ return ;
+ ViewElementList *vel = staff->getViewElementList();
+
+ timeT time = getInsertionTime();
+ ViewElementList::iterator i = vel->findTime(time);
+
+ while (i != vel->begin() &&
+ (i == vel->end() || (*i)->getViewAbsoluteTime() >= time))
+ --i;
+
+ if (i != vel->end())
+ slotSetInsertCursorPosition((*i)->getViewAbsoluteTime());
+}
+
+void
+EditView::slotStepForward()
+{
+ Staff *staff = getCurrentStaff();
+ if (!staff)
+ return ;
+ ViewElementList *vel = staff->getViewElementList();
+
+ timeT time = getInsertionTime();
+ ViewElementList::iterator i = vel->findTime(time);
+
+ while (i != vel->end() &&
+ (*i)->getViewAbsoluteTime() <= time)
+ ++i;
+
+ if (i == vel->end()) {
+ slotSetInsertCursorPosition(staff->getSegment().getEndMarkerTime());
+ } else {
+ slotSetInsertCursorPosition((*i)->getViewAbsoluteTime());
+ }
+}
+
+void
+EditView::slotJumpBackward()
+{
+ Segment *segment = getCurrentSegment();
+ if (!segment)
+ return ;
+ timeT time = getInsertionTime();
+ time = segment->getBarStartForTime(time - 1);
+ slotSetInsertCursorPosition(time);
+}
+
+void
+EditView::slotJumpForward()
+{
+ Segment *segment = getCurrentSegment();
+ if (!segment)
+ return ;
+ timeT time = getInsertionTime();
+ time = segment->getBarEndForTime(time);
+ slotSetInsertCursorPosition(time);
+}
+
+void
+EditView::slotJumpToStart()
+{
+ Segment *segment = getCurrentSegment();
+ if (!segment)
+ return ;
+ timeT time = segment->getStartTime();
+ slotSetInsertCursorPosition(time);
+}
+
+void
+EditView::slotJumpToEnd()
+{
+ Segment *segment = getCurrentSegment();
+ if (!segment)
+ return ;
+ timeT time = segment->getEndMarkerTime();
+ slotSetInsertCursorPosition(time);
+}
+
+void EditView::slotExtendSelectionBackward()
+{
+ slotExtendSelectionBackward(false);
+}
+
+void EditView::slotExtendSelectionBackwardBar()
+{
+ slotExtendSelectionBackward(true);
+}
+
+void EditView::slotExtendSelectionBackward(bool bar)
+{
+ // If there is no current selection, or the selection is entirely
+ // to the right of the cursor, move the cursor left and add to the
+ // selection
+
+ timeT oldTime = getInsertionTime();
+ if (bar)
+ slotJumpBackward();
+ else
+ slotStepBackward();
+ timeT newTime = getInsertionTime();
+
+ Staff *staff = getCurrentStaff();
+ if (!staff)
+ return ;
+ Segment *segment = &staff->getSegment();
+ ViewElementList *vel = staff->getViewElementList();
+
+ EventSelection *es = new EventSelection(*segment);
+ if (m_currentEventSelection &&
+ &m_currentEventSelection->getSegment() == segment)
+ es->addFromSelection(m_currentEventSelection);
+
+ if (!m_currentEventSelection ||
+ &m_currentEventSelection->getSegment() != segment ||
+ m_currentEventSelection->getSegmentEvents().size() == 0 ||
+ m_currentEventSelection->getStartTime() >= oldTime) {
+
+ ViewElementList::iterator extendFrom = vel->findTime(oldTime);
+
+ while (extendFrom != vel->begin() &&
+ (*--extendFrom)->getViewAbsoluteTime() >= newTime) {
+ if ((*extendFrom)->event()->isa(Note::EventType)) {
+ es->addEvent((*extendFrom)->event());
+ }
+ }
+
+ } else { // remove an event
+
+ EventSelection::eventcontainer::iterator i =
+ es->getSegmentEvents().end();
+
+ std::vector<Event *> toErase;
+
+ while (i != es->getSegmentEvents().begin() &&
+ (*--i)->getAbsoluteTime() >= newTime) {
+ toErase.push_back(*i);
+ }
+
+ for (unsigned int j = 0; j < toErase.size(); ++j) {
+ es->removeEvent(toErase[j]);
+ }
+ }
+
+ setCurrentSelection(es);
+}
+
+void EditView::slotExtendSelectionForward()
+{
+ slotExtendSelectionForward(false);
+}
+
+void EditView::slotExtendSelectionForwardBar()
+{
+ slotExtendSelectionForward(true);
+}
+
+void EditView::slotExtendSelectionForward(bool bar)
+{
+ // If there is no current selection, or the selection is entirely
+ // to the left of the cursor, move the cursor right and add to the
+ // selection
+
+ timeT oldTime = getInsertionTime();
+ if (bar)
+ slotJumpForward();
+ else
+ slotStepForward();
+ timeT newTime = getInsertionTime();
+
+ Staff *staff = getCurrentStaff();
+ if (!staff)
+ return ;
+ Segment *segment = &staff->getSegment();
+ ViewElementList *vel = staff->getViewElementList();
+
+ EventSelection *es = new EventSelection(*segment);
+ if (m_currentEventSelection &&
+ &m_currentEventSelection->getSegment() == segment)
+ es->addFromSelection(m_currentEventSelection);
+
+ if (!m_currentEventSelection ||
+ &m_currentEventSelection->getSegment() != segment ||
+ m_currentEventSelection->getSegmentEvents().size() == 0 ||
+ m_currentEventSelection->getEndTime() <= oldTime) {
+
+ ViewElementList::iterator extendFrom = vel->findTime(oldTime);
+
+ while (extendFrom != vel->end() &&
+ (*extendFrom)->getViewAbsoluteTime() < newTime) {
+ if ((*extendFrom)->event()->isa(Note::EventType)) {
+ es->addEvent((*extendFrom)->event());
+ }
+ ++extendFrom;
+ }
+
+ } else { // remove an event
+
+ EventSelection::eventcontainer::iterator i =
+ es->getSegmentEvents().begin();
+
+ std::vector<Event *> toErase;
+
+ while (i != es->getSegmentEvents().end() &&
+ (*i)->getAbsoluteTime() < newTime) {
+ toErase.push_back(*i);
+ ++i;
+ }
+
+ for (unsigned int j = 0; j < toErase.size(); ++j) {
+ es->removeEvent(toErase[j]);
+ }
+ }
+
+ setCurrentSelection(es);
+}
+
+void
+EditView::setupActions()
+{
+ createInsertPitchActionMenu();
+
+ //
+ // Tempo and time signature changes
+ //
+ QString pixmapDir = KGlobal::dirs()->findResource("appdata", "pixmaps/");
+ QCanvasPixmap pixmap(pixmapDir + "/toolbar/event-insert-tempo.png");
+ QIconSet icon = QIconSet(pixmap);
+ new KAction(AddTempoChangeCommand::getGlobalName(),
+ icon, 0,
+ this, SLOT(slotAddTempo()),
+ actionCollection(), "add_tempo");
+
+ pixmap.load(pixmapDir + "/toolbar/event-insert-timesig.png");
+ icon = QIconSet(pixmap);
+ new KAction(AddTimeSignatureCommand::getGlobalName(),
+ icon, 0,
+ this, SLOT(slotAddTimeSignature()),
+ actionCollection(), "add_time_signature");
+
+ //
+ // Transforms
+ //
+ new KAction(i18n("&Halve Durations"), Key_H + CTRL, this,
+ SLOT(slotHalveDurations()), actionCollection(),
+ "halve_durations");
+
+ new KAction(i18n("&Double Durations"), Key_H + CTRL + SHIFT, this,
+ SLOT(slotDoubleDurations()), actionCollection(),
+ "double_durations");
+
+ new KAction(RescaleCommand::getGlobalName(), 0, this,
+ SLOT(slotRescale()), actionCollection(),
+ "rescale");
+
+ new KAction(TransposeCommand::getGlobalName(1), 0,
+ Key_Up, this,
+ SLOT(slotTransposeUp()), actionCollection(),
+ "transpose_up");
+
+ new KAction(TransposeCommand::getGlobalName(12), 0,
+ Key_Up + CTRL, this,
+ SLOT(slotTransposeUpOctave()), actionCollection(),
+ "transpose_up_octave");
+
+ new KAction(TransposeCommand::getGlobalName( -1), 0,
+ Key_Down, this,
+ SLOT(slotTransposeDown()), actionCollection(),
+ "transpose_down");
+
+ new KAction(TransposeCommand::getGlobalName( -12), 0,
+ Key_Down + CTRL, this,
+ SLOT(slotTransposeDownOctave()), actionCollection(),
+ "transpose_down_octave");
+
+ new KAction(TransposeCommand::getGlobalName(0), 0, this,
+ SLOT(slotTranspose()), actionCollection(),
+ "general_transpose");
+
+ new KAction(TransposeCommand::getDiatonicGlobalName(0,0), 0, this,
+ SLOT(slotDiatonicTranspose()), actionCollection(),
+ "general_diatonic_transpose");
+
+ new KAction(InvertCommand::getGlobalName(0), 0, this,
+ SLOT(slotInvert()), actionCollection(),
+ "invert");
+
+ new KAction(RetrogradeCommand::getGlobalName(0), 0, this,
+ SLOT(slotRetrograde()), actionCollection(),
+ "retrograde");
+
+ new KAction(RetrogradeInvertCommand::getGlobalName(0), 0, this,
+ SLOT(slotRetrogradeInvert()), actionCollection(),
+ "retrograde_invert");
+
+ new KAction(i18n("Jog &Left"), Key_Left + ALT, this,
+ SLOT(slotJogLeft()), actionCollection(),
+ "jog_left");
+
+ new KAction(i18n("Jog &Right"), Key_Right + ALT, this,
+ SLOT(slotJogRight()), actionCollection(),
+ "jog_right");
+
+ // Control rulers
+ //
+ new KAction(i18n("Show Velocity Property Ruler"), 0, this,
+ SLOT(slotShowVelocityControlRuler()), actionCollection(),
+ "show_velocity_control_ruler");
+
+ /*
+ new KAction(i18n("Show Controllers Events Ruler"), 0, this,
+ SLOT(slotShowControllerEventsRuler()), actionCollection(),
+ "show_controller_events_ruler");
+ */
+
+ // Disabled for now
+ //
+ // new KAction(i18n("Add Control Ruler..."), 0, this,
+ // SLOT(slotShowPropertyControlRuler()), actionCollection(),
+ // "add_control_ruler");
+
+ //
+ // Control Ruler context menu
+ //
+ new KAction(i18n("Insert item"), 0, this,
+ SLOT(slotInsertControlRulerItem()), actionCollection(),
+ "insert_control_ruler_item");
+
+ // This was on Key_Delete, but that conflicts with existing Delete commands
+ // on individual edit views
+ new KAction(i18n("Erase selected items"), 0, this,
+ SLOT(slotEraseControlRulerItem()), actionCollection(),
+ "erase_control_ruler_item");
+
+ new KAction(i18n("Clear ruler"), 0, this,
+ SLOT(slotClearControlRulerItem()), actionCollection(),
+ "clear_control_ruler_item");
+
+ new KAction(i18n("Insert line of controllers"), 0, this,
+ SLOT(slotStartControlLineItem()), actionCollection(),
+ "start_control_line_item");
+
+ new KAction(i18n("Flip forward"), Key_BracketRight, this,
+ SLOT(slotFlipForwards()), actionCollection(),
+ "flip_control_events_forward");
+
+ new KAction(i18n("Flip backwards"), Key_BracketLeft, this,
+ SLOT(slotFlipBackwards()), actionCollection(),
+ "flip_control_events_back");
+
+ new KAction(i18n("Draw property line"), 0, this,
+ SLOT(slotDrawPropertyLine()), actionCollection(),
+ "draw_property_line");
+
+ new KAction(i18n("Select all property values"), 0, this,
+ SLOT(slotSelectAllProperties()), actionCollection(),
+ "select_all_properties");
+}
+
+void
+EditView::setupAddControlRulerMenu()
+{
+ RG_DEBUG << "EditView::setupAddControlRulerMenu" << endl;
+
+ QPopupMenu* addControlRulerMenu = dynamic_cast<QPopupMenu*>
+ (factory()->container("add_control_ruler", this));
+
+ if (addControlRulerMenu) {
+
+ addControlRulerMenu->clear();
+
+ //!!! problem here with notation view -- current segment can
+ // change after construction, but this function isn't used again
+
+ Controllable *c =
+ dynamic_cast<MidiDevice *>(getCurrentDevice());
+ if (!c) {
+ c = dynamic_cast<SoftSynthDevice *>(getCurrentDevice());
+ if (!c)
+ return ;
+ }
+
+ const ControlList &list = c->getControlParameters();
+
+ int i = 0;
+ QString itemStr;
+
+ for (ControlList::const_iterator it = list.begin();
+ it != list.end(); ++it) {
+ if (it->getType() == Controller::EventType) {
+ QString hexValue;
+ hexValue.sprintf("(0x%x)", it->getControllerValue());
+
+ itemStr = i18n("%1 Controller %2 %3").arg(strtoqstr(it->getName()))
+ .arg(it->getControllerValue())
+ .arg(hexValue);
+
+ } else if (it->getType() == PitchBend::EventType)
+ itemStr = i18n("Pitch Bend");
+ else
+ itemStr = i18n("Unsupported Event Type");
+
+ addControlRulerMenu->insertItem(itemStr, i++);
+ }
+
+ connect(addControlRulerMenu, SIGNAL(activated(int)),
+ SLOT(slotAddControlRuler(int)));
+ }
+
+}
+
+bool
+EditView::setupControllerTabs()
+{
+ bool have = false;
+
+ // Setup control rulers the Segment already has some stored against it.
+ //
+ Segment *segment = getCurrentSegment();
+ Segment::EventRulerList list = segment->getEventRulerList();
+
+ RG_DEBUG << "EditView::setupControllerTabs - got " << list.size() << " EventRulers" << endl;
+
+ RG_DEBUG << "Segment view features: " << segment->getViewFeatures() << endl;
+ if (segment->getViewFeatures() & FeatureShowVelocity) {
+ showPropertyControlRuler(BaseProperties::VELOCITY);
+ have = true;
+ }
+
+ if (list.size()) {
+ Controllable *c =
+ dynamic_cast<MidiDevice *>(getCurrentDevice());
+ if (!c) {
+ c = dynamic_cast<SoftSynthDevice *>(getCurrentDevice());
+ if (!c)
+ return have;
+ }
+
+ have = true;
+
+ Segment::EventRulerListIterator it;
+
+ for (it = list.begin(); it != list.end(); ++it) {
+ // Get ControlParameter object from controller value
+ //
+ const ControlParameter *controlParameter =
+ c->getControlParameter((*it)->m_type,
+ MidiByte((*it)->m_controllerValue));
+
+ RG_DEBUG << "EditView::setupControllerTabs - "
+ << "Control Parameter type = " << (*it)->m_type << endl;
+
+ if (controlParameter) {
+ ControllerEventsRuler* controlRuler = makeControllerEventRuler(controlParameter);
+ addControlRuler(controlRuler);
+ RG_DEBUG << "EditView::setupControllerTabs - adding Ruler" << endl;
+ }
+ }
+
+ if (!m_controlRulers->isVisible())
+ m_controlRulers->show();
+
+ updateBottomWidgetGeometry();
+ }
+
+ return have;
+}
+
+void
+EditView::slotAddControlRuler(int controller)
+{
+ RG_DEBUG << "EditView::slotAddControlRuler - item = "
+ << controller << endl;
+
+ Controllable *c =
+ dynamic_cast<MidiDevice *>(getCurrentDevice());
+ if (!c) {
+ c = dynamic_cast<SoftSynthDevice *>(getCurrentDevice());
+ if (!c)
+ return ;
+ }
+
+ const ControlList &list = c->getControlParameters();
+ ControlParameter control = list[controller];
+
+ int index = 0;
+
+ ControlRuler* existingRuler = findRuler(control, index);
+
+ if (existingRuler) {
+
+ m_controlRulers->setCurrentPage(index);
+
+ } else {
+
+ // Create control ruler to a specific controller. This duplicates
+ // the control parameter in the supplied pointer.
+ ControllerEventsRuler* controlRuler = makeControllerEventRuler(&control);
+
+ addControlRuler(controlRuler);
+ }
+
+ if (!m_controlRulers->isVisible()) {
+ m_controlRulers->show();
+ }
+
+ updateBottomWidgetGeometry();
+
+ // Add the controller to the segment so the views can
+ // remember what we've opened against it.
+ //
+ Staff *staff = getCurrentStaff();
+ staff->getSegment().addEventRuler(control.getType(), control.getControllerValue());
+
+ getDocument()->slotDocumentModified();
+}
+
+void EditView::slotRemoveControlRuler(QWidget* w)
+{
+ ControllerEventsRuler* ruler = dynamic_cast<ControllerEventsRuler*>(w);
+
+ if (ruler) {
+ ControlParameter *controller = ruler->getControlParameter();
+
+ // remove the control parameter from the "showing controllers" list on the segment
+ //
+ if (controller) {
+ Staff *staff = getCurrentStaff();
+ bool value = staff->getSegment().
+ deleteEventRuler(controller->getType(), controller->getControllerValue());
+
+ if (value)
+ RG_DEBUG << "slotRemoveControlRuler : removed controller from segment\n";
+ else
+ RG_DEBUG << "slotRemoveControlRuler : couldn't remove controller from segment - "
+ << int(controller->getControllerValue())
+ << endl;
+
+ }
+ } else { // else it's probably a velocity ruler
+ PropertyControlRuler *propertyRuler = dynamic_cast<PropertyControlRuler*>(w);
+
+ if (propertyRuler) {
+ Segment &seg = getCurrentStaff()->getSegment();
+ seg.setViewFeatures(0); // for the moment we only have one view feature so
+ // we can just blank it out
+
+ RG_DEBUG << "slotRemoveControlRuler : removed velocity ruler" << endl;
+ }
+ }
+
+ delete w;
+
+ if (m_controlRulers->count() == 0) {
+ m_controlRulers->hide();
+ updateBottomWidgetGeometry();
+ }
+
+ getDocument()->slotDocumentModified();
+}
+
+void
+EditView::createInsertPitchActionMenu()
+{
+ QString notePitchNames[] = {
+ i18n("I"), i18n("II"), i18n("III"), i18n("IV"),
+ i18n("V"), i18n("VI"), i18n("VII"), i18n("VIII")
+ };
+ QString flat = i18n("%1 flat");
+ QString sharp = i18n("%1 sharp");
+
+ const Key notePitchKeys[3][7] = {
+ {
+ Key_A, Key_S, Key_D, Key_F, Key_J, Key_K, Key_L,
+ },
+ {
+ Key_Q, Key_W, Key_E, Key_R, Key_U, Key_I, Key_O,
+ },
+ {
+ Key_Z, Key_X, Key_C, Key_V, Key_B, Key_N, Key_M,
+ },
+ };
+
+ KActionMenu *insertPitchActionMenu =
+ new KActionMenu(i18n("&Insert Note"), this, "insert_note_actionmenu");
+
+ for (int octave = 0; octave <= 2; ++octave) {
+
+ KActionMenu *menu = insertPitchActionMenu;
+ if (octave == 1) {
+ menu = new KActionMenu(i18n("&Upper Octave"), this,
+ "insert_note_actionmenu_upper_octave");
+ insertPitchActionMenu->insert(new KActionSeparator(this));
+ insertPitchActionMenu->insert(menu);
+ } else if (octave == 2) {
+ menu = new KActionMenu(i18n("&Lower Octave"), this,
+ "insert_note_actionmenu_lower_octave");
+ insertPitchActionMenu->insert(menu);
+ }
+
+ for (unsigned int i = 0; i < 7; ++i) {
+
+ KAction *insertPitchAction = 0;
+
+ QString octaveSuffix;
+ if (octave == 1)
+ octaveSuffix = "_high";
+ else if (octave == 2)
+ octaveSuffix = "_low";
+
+ // do and fa lack a flat
+
+ if (i != 0 && i != 3) {
+
+ insertPitchAction =
+ new KAction
+ (flat.arg(notePitchNames[i]),
+ CTRL + SHIFT + notePitchKeys[octave][i],
+ this, SLOT(slotInsertNoteFromAction()), actionCollection(),
+ QString("insert_%1_flat%2").arg(i).arg(octaveSuffix));
+
+ menu->insert(insertPitchAction);
+ }
+
+ insertPitchAction =
+ new KAction
+ (notePitchNames[i],
+ notePitchKeys[octave][i],
+ this, SLOT(slotInsertNoteFromAction()), actionCollection(),
+ QString("insert_%1%2").arg(i).arg(octaveSuffix));
+
+ menu->insert(insertPitchAction);
+
+ // and mi and ti lack a sharp
+
+ if (i != 2 && i != 6) {
+
+ insertPitchAction =
+ new KAction
+ (sharp.arg(notePitchNames[i]),
+ SHIFT + notePitchKeys[octave][i],
+ this, SLOT(slotInsertNoteFromAction()), actionCollection(),
+ QString("insert_%1_sharp%2").arg(i).arg(octaveSuffix));
+
+ menu->insert(insertPitchAction);
+ }
+
+ if (i < 6)
+ menu->insert(new KActionSeparator(this));
+ }
+ }
+
+ actionCollection()->insert(insertPitchActionMenu);
+}
+
+int
+EditView::getPitchFromNoteInsertAction(QString name,
+ Accidental &accidental,
+ const Clef &clef,
+ const ::Rosegarden::Key &key)
+{
+ using namespace Accidentals;
+
+ accidental = NoAccidental;
+
+ if (name.left(7) == "insert_") {
+
+ name = name.right(name.length() - 7);
+
+ int modify = 0;
+ int octave = 0;
+
+ if (name.right(5) == "_high") {
+
+ octave = 1;
+ name = name.left(name.length() - 5);
+
+ } else if (name.right(4) == "_low") {
+
+ octave = -1;
+ name = name.left(name.length() - 4);
+ }
+
+ if (name.right(6) == "_sharp") {
+
+ modify = 1;
+ accidental = Sharp;
+ name = name.left(name.length() - 6);
+
+ } else if (name.right(5) == "_flat") {
+
+ modify = -1;
+ accidental = Flat;
+ name = name.left(name.length() - 5);
+ }
+
+ int scalePitch = name.toInt();
+
+ if (scalePitch < 0 || scalePitch > 7) {
+ NOTATION_DEBUG << "EditView::getPitchFromNoteInsertAction: pitch "
+ << scalePitch << " out of range, using 0" << endl;
+ scalePitch = 0;
+ }
+
+ Pitch pitch
+ (scalePitch, 4 + octave + clef.getOctave(), key, accidental);
+ return pitch.getPerformancePitch();
+
+ } else {
+
+ throw Exception("Not an insert action",
+ __FILE__, __LINE__);
+ }
+}
+
+void EditView::slotAddTempo()
+{
+ timeT insertionTime = getInsertionTime();
+
+ TempoDialog tempoDlg(this, getDocument());
+
+ connect(&tempoDlg,
+ SIGNAL(changeTempo(timeT,
+ tempoT,
+ tempoT,
+ TempoDialog::TempoDialogAction)),
+ this,
+ SIGNAL(changeTempo(timeT,
+ tempoT,
+ tempoT,
+ TempoDialog::TempoDialogAction)));
+
+ tempoDlg.setTempoPosition(insertionTime);
+ tempoDlg.exec();
+}
+
+void EditView::slotAddTimeSignature()
+{
+ Segment *segment = getCurrentSegment();
+ if (!segment)
+ return ;
+ Composition *composition = segment->getComposition();
+ timeT insertionTime = getInsertionTime();
+
+ TimeSignatureDialog *dialog = 0;
+ int timeSigNo = composition->getTimeSignatureNumberAt(insertionTime);
+
+ if (timeSigNo >= 0) {
+
+ dialog = new TimeSignatureDialog
+ (this, composition, insertionTime,
+ composition->getTimeSignatureAt(insertionTime));
+
+ } else {
+
+ timeT endTime = composition->getDuration();
+ if (composition->getTimeSignatureCount() > 0) {
+ endTime = composition->getTimeSignatureChange(0).first;
+ }
+
+ CompositionTimeSliceAdapter adapter
+ (composition, insertionTime, endTime);
+ AnalysisHelper helper;
+ TimeSignature timeSig = helper.guessTimeSignature(adapter);
+
+ dialog = new TimeSignatureDialog
+ (this, composition, insertionTime, timeSig, false,
+ i18n("Estimated time signature shown"));
+ }
+
+ if (dialog->exec() == QDialog::Accepted) {
+
+ insertionTime = dialog->getTime();
+
+ if (dialog->shouldNormalizeRests()) {
+
+ addCommandToHistory(new AddTimeSignatureAndNormalizeCommand
+ (composition, insertionTime,
+ dialog->getTimeSignature()));
+
+ } else {
+
+ addCommandToHistory(new AddTimeSignatureCommand
+ (composition, insertionTime,
+ dialog->getTimeSignature()));
+ }
+ }
+
+ delete dialog;
+}
+
+void EditView::showPropertyControlRuler(PropertyName propertyName)
+{
+ int index = 0;
+
+ ControlRuler* existingRuler = findRuler(propertyName, index);
+
+ if (existingRuler) {
+
+ m_controlRulers->setCurrentPage(index);
+
+ } else {
+
+ PropertyControlRuler* controlRuler = makePropertyControlRuler(propertyName);
+ addControlRuler(controlRuler);
+ }
+
+ if (!m_controlRulers->isVisible()) {
+ m_controlRulers->show();
+ }
+
+ updateBottomWidgetGeometry();
+}
+
+void EditView::slotShowVelocityControlRuler()
+{
+ showPropertyControlRuler(BaseProperties::VELOCITY);
+ Segment &seg = getCurrentStaff()->getSegment();
+ seg.setViewFeatures(seg.getViewFeatures() | FeatureShowVelocity);
+ getDocument()->slotDocumentModified();
+}
+
+void EditView::slotShowControllerEventsRuler()
+{
+
+ // int index = 0;
+
+ // ControlRuler* existingRuler = findRuler(propertyName, index);
+
+ // if (existingRuler) {
+
+ // m_controlRulers->setCurrentPage(index);
+
+ // } else {
+
+ // ControllerEventsRuler* controlRuler = makeControllerEventRuler();
+ // addControlRuler(controlRuler);
+ // }
+
+ // if (!m_controlRulers->isVisible()) {
+ // m_controlRulers->show();
+ // }
+
+ // updateBottomWidgetGeometry();
+}
+
+void EditView::slotShowPropertyControlRuler()
+{
+ /*
+ KDialogBase propChooserDialog(this, "propertychooserdialog", true, i18n("Select event property"),
+ KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok);
+
+ KListBox* propList = new KListBox(propChooserDialog.makeVBoxMainWidget());
+ new QListBoxRGProperty(propList, BaseProperties::VELOCITY.c_str());
+
+ int rc = propChooserDialog.exec();
+ if (rc == QDialog::Accepted) {
+ // fix for KDE 3.0
+ //QListBoxRGProperty* item = dynamic_cast<QListBoxRGProperty*>(propList->selectedItem());
+ QListBoxRGProperty* item = dynamic_cast<QListBoxRGProperty*>
+ (propList->item(propList->currentItem()));
+
+ if (item) {
+ PropertyName property = item->getPropertyName();
+ showPropertyControlRuler(property);
+ }
+ }
+ */
+}
+
+void
+EditView::slotInsertControlRulerItem()
+{
+ ControllerEventsRuler* ruler = dynamic_cast<ControllerEventsRuler*>(getCurrentControlRuler());
+ if (ruler)
+ ruler->insertControllerEvent();
+}
+
+void
+EditView::slotEraseControlRulerItem()
+{
+ ControllerEventsRuler* ruler = dynamic_cast<ControllerEventsRuler*>(getCurrentControlRuler());
+ if (ruler)
+ ruler->eraseControllerEvent();
+}
+
+void
+EditView::slotStartControlLineItem()
+{
+ ControllerEventsRuler* ruler = dynamic_cast<ControllerEventsRuler*>(getCurrentControlRuler());
+ if (ruler)
+ ruler->startControlLine();
+}
+
+void
+EditView::slotDrawPropertyLine()
+{
+ int index = 0;
+ PropertyControlRuler* ruler = dynamic_cast<PropertyControlRuler*>
+ (findRuler(BaseProperties::VELOCITY, index));
+
+ if (ruler)
+ ruler->startPropertyLine();
+}
+
+void
+EditView::slotSelectAllProperties()
+{
+ int index = 0;
+ PropertyControlRuler* ruler = dynamic_cast<PropertyControlRuler*>
+ (findRuler(BaseProperties::VELOCITY, index));
+
+ if (ruler)
+ ruler->selectAllProperties();
+}
+
+void
+EditView::slotClearControlRulerItem()
+{
+ ControllerEventsRuler* ruler = dynamic_cast<ControllerEventsRuler*>(getCurrentControlRuler());
+ if (ruler)
+ ruler->clearControllerEvents();
+}
+
+void
+EditView::slotHalveDurations()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ KTmpStatusMsg msg(i18n("Halving durations..."), this);
+
+ addCommandToHistory(
+ new RescaleCommand(*m_currentEventSelection,
+ m_currentEventSelection->getTotalDuration() / 2,
+ false));
+}
+
+void
+EditView::slotDoubleDurations()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ KTmpStatusMsg msg(i18n("Doubling durations..."), this);
+
+ addCommandToHistory(
+ new RescaleCommand(*m_currentEventSelection,
+ m_currentEventSelection->getTotalDuration() * 2,
+ false));
+}
+
+void
+EditView::slotRescale()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ RescaleDialog dialog
+ (this,
+ &getDocument()->getComposition(),
+ m_currentEventSelection->getStartTime(),
+ m_currentEventSelection->getEndTime() -
+ m_currentEventSelection->getStartTime(),
+ true,
+ true);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ KTmpStatusMsg msg(i18n("Rescaling..."), this);
+ addCommandToHistory(new RescaleCommand
+ (*m_currentEventSelection,
+ dialog.getNewDuration(),
+ dialog.shouldCloseGap()));
+ }
+}
+
+void EditView::slotTranspose()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ m_config->setGroup(EditViewConfigGroup);
+
+ int dialogDefault = m_config->readNumEntry("lasttransposition", 0);
+
+ bool ok = false;
+ int semitones = QInputDialog::getInteger
+ (i18n("Transpose"),
+ i18n("By number of semitones: "),
+ dialogDefault, -127, 127, 1, &ok, this);
+ if (!ok || semitones == 0) return;
+
+ m_config->setGroup(EditViewConfigGroup);
+ m_config->writeEntry("lasttransposition", semitones);
+
+ KTmpStatusMsg msg(i18n("Transposing..."), this);
+ addCommandToHistory(new TransposeCommand
+ (semitones, *m_currentEventSelection));
+}
+
+void EditView::slotDiatonicTranspose()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ m_config->setGroup(EditViewConfigGroup);
+
+ IntervalDialog intervalDialog(this);
+ int ok = intervalDialog.exec();
+ //int dialogDefault = m_config->readNumEntry("lasttransposition", 0);
+ int semitones = intervalDialog.getChromaticDistance();
+ int steps = intervalDialog.getDiatonicDistance();
+
+ if (!ok || (semitones == 0 && steps == 0)) return;
+
+ m_config->setGroup(EditViewConfigGroup);
+
+ KTmpStatusMsg msg(i18n("Transposing..."), this);
+ if (intervalDialog.getChangeKey())
+ {
+ std::cout << "Transposing changing keys is not currently supported on selections" << std::endl;
+ }
+ else
+ {
+ // Transpose within key
+ //std::cout << "Transposing semitones, steps: " << semitones << ", " << steps << std::endl;
+ addCommandToHistory(new TransposeCommand
+ (semitones, steps, *m_currentEventSelection));
+ }
+}
+
+void EditView::slotTransposeUp()
+{
+ if (!m_currentEventSelection)
+ return ;
+ KTmpStatusMsg msg(i18n("Transposing up one semitone..."), this);
+
+ addCommandToHistory(new TransposeCommand(1, *m_currentEventSelection));
+}
+
+void EditView::slotTransposeUpOctave()
+{
+ if (!m_currentEventSelection)
+ return ;
+ KTmpStatusMsg msg(i18n("Transposing up one octave..."), this);
+
+ addCommandToHistory(new TransposeCommand(12, *m_currentEventSelection));
+}
+
+void EditView::slotTransposeDown()
+{
+ if (!m_currentEventSelection)
+ return ;
+ KTmpStatusMsg msg(i18n("Transposing down one semitone..."), this);
+
+ addCommandToHistory(new TransposeCommand( -1, *m_currentEventSelection));
+}
+
+void EditView::slotTransposeDownOctave()
+{
+ if (!m_currentEventSelection)
+ return ;
+ KTmpStatusMsg msg(i18n("Transposing down one octave..."), this);
+
+ addCommandToHistory(new TransposeCommand( -12, *m_currentEventSelection));
+}
+
+void EditView::slotInvert()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ int semitones = 0;
+
+ KTmpStatusMsg msg(i18n("Inverting..."), this);
+ addCommandToHistory(new InvertCommand
+ (semitones, *m_currentEventSelection));
+}
+
+void EditView::slotRetrograde()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ int semitones = 0;
+
+ KTmpStatusMsg msg(i18n("Retrograding..."), this);
+ addCommandToHistory(new RetrogradeCommand
+ (semitones, *m_currentEventSelection));
+}
+
+void EditView::slotRetrogradeInvert()
+{
+ if (!m_currentEventSelection)
+ return ;
+
+ int semitones = 0;
+
+ KTmpStatusMsg msg(i18n("Retrograde inverting..."), this);
+ addCommandToHistory(new RetrogradeInvertCommand
+ (semitones, *m_currentEventSelection));
+}
+
+void EditView::slotJogLeft()
+{
+ if (!m_currentEventSelection)
+ return ;
+ KTmpStatusMsg msg(i18n("Jogging left..."), this);
+
+ RG_DEBUG << "EditView::slotJogLeft" << endl;
+
+ addCommandToHistory(
+ new MoveCommand(*getCurrentSegment(),
+ -Note(Note::Demisemiquaver).getDuration(),
+ false, // don't use notation timings
+ *m_currentEventSelection));
+}
+
+void EditView::slotJogRight()
+{
+ if (!m_currentEventSelection)
+ return ;
+ KTmpStatusMsg msg(i18n("Jogging right..."), this);
+
+ RG_DEBUG << "EditView::slotJogRight" << endl;
+
+ addCommandToHistory(
+ new MoveCommand(*getCurrentSegment(),
+ Note(Note::Demisemiquaver).getDuration(),
+ false, // don't use notation timings
+ *m_currentEventSelection));
+}
+
+void
+EditView::slotFlipForwards()
+{
+ RG_DEBUG << "EditView::slotFlipForwards" << endl;
+ ControlRuler* ruler = getCurrentControlRuler();
+ if (ruler) ruler->flipForwards();
+}
+
+void
+EditView::slotFlipBackwards()
+{
+ RG_DEBUG << "EditView::slotFlipBackwards" << endl;
+ ControlRuler* ruler = getCurrentControlRuler();
+ if (ruler) ruler->flipBackwards();
+}
+
+ControlRuler* EditView::getCurrentControlRuler()
+{
+ return dynamic_cast<ControlRuler*>(m_controlRulers->currentPage());
+}
+
+ControlRuler* EditView::findRuler(PropertyName propertyName, int &index)
+{
+ for(index = 0; index < m_controlRulers->count(); ++index) {
+ PropertyControlRuler* ruler = dynamic_cast<PropertyControlRuler*>(m_controlRulers->page(index));
+ if (ruler && ruler->getPropertyName() == propertyName) return ruler;
+ }
+
+ return 0;
+}
+
+ControlRuler* EditView::findRuler(const ControlParameter& controller, int &index)
+{
+ for(index = 0; index < m_controlRulers->count(); ++index) {
+ ControllerEventsRuler* ruler = dynamic_cast<ControllerEventsRuler*>(m_controlRulers->page(index));
+ if (ruler && *(ruler->getControlParameter()) == controller) return ruler;
+ }
+
+ return 0;
+}
+
+PropertyControlRuler* EditView::makePropertyControlRuler(PropertyName propertyName)
+{
+ QCanvas* controlRulerCanvas = new QCanvas(this);
+ QSize viewSize = getViewSize();
+ controlRulerCanvas->resize(viewSize.width(), ControlRuler::DefaultRulerHeight); // TODO - keep it in sync with main canvas size
+
+// QCanvas* controlRulerCanvas = ControlRulerCanvasRepository::getCanvas(getCurrentSegment(), propertyName,
+// getViewSize());
+
+ PropertyControlRuler* controlRuler = new PropertyControlRuler
+ (propertyName, getCurrentStaff(), getHLayout(), this,
+ controlRulerCanvas, m_controlRulers);
+
+ controlRuler->setMainHorizontalScrollBar(m_canvasView->horizontalScrollBar());
+
+ return controlRuler;
+}
+
+ControllerEventsRuler* EditView::makeControllerEventRuler(const ControlParameter *controller)
+{
+ QCanvas* controlRulerCanvas = new QCanvas(this);
+ QSize viewSize = getViewSize();
+ controlRulerCanvas->resize(viewSize.width(), ControlRuler::DefaultRulerHeight); // TODO - keep it in sync with main canvas size
+// QCanvas* controlRulerCanvas = ControlRulerCanvasRepository::getCanvas(getCurrentSegment(), controller,
+// getViewSize());
+
+
+ ControllerEventsRuler* controlRuler = new ControllerEventsRuler
+ (getCurrentSegment(), getHLayout(), this,
+ controlRulerCanvas, m_controlRulers, controller);
+
+ controlRuler->setMainHorizontalScrollBar(m_canvasView->horizontalScrollBar());
+
+ return controlRuler;
+}
+
+RosegardenCanvasView* EditView::getCanvasView()
+{
+ return m_canvasView;
+}
+
+}
+#include "EditView.moc"