summaryrefslogtreecommitdiffstats
path: root/src/commands/edit
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
commit145364a8af6a1fec06556221e66d4b724a62fc9a (patch)
tree53bd71a544008c518034f208d64c932dc2883f50 /src/commands/edit
downloadrosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz
rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/commands/edit')
-rw-r--r--src/commands/edit/AddDotCommand.cpp98
-rw-r--r--src/commands/edit/AddDotCommand.h68
-rw-r--r--src/commands/edit/AddMarkerCommand.cpp67
-rw-r--r--src/commands/edit/AddMarkerCommand.h71
-rw-r--r--src/commands/edit/ChangeVelocityCommand.cpp68
-rw-r--r--src/commands/edit/ChangeVelocityCommand.h68
-rw-r--r--src/commands/edit/ClearTriggersCommand.cpp53
-rw-r--r--src/commands/edit/ClearTriggersCommand.h66
-rw-r--r--src/commands/edit/CollapseNotesCommand.cpp79
-rw-r--r--src/commands/edit/CollapseNotesCommand.h65
-rw-r--r--src/commands/edit/CopyCommand.cpp120
-rw-r--r--src/commands/edit/CopyCommand.h82
-rw-r--r--src/commands/edit/CutAndCloseCommand.cpp163
-rw-r--r--src/commands/edit/CutAndCloseCommand.h82
-rw-r--r--src/commands/edit/CutCommand.cpp59
-rw-r--r--src/commands/edit/CutCommand.h62
-rw-r--r--src/commands/edit/EraseCommand.cpp86
-rw-r--r--src/commands/edit/EraseCommand.h66
-rw-r--r--src/commands/edit/EventEditCommand.cpp64
-rw-r--r--src/commands/edit/EventEditCommand.h69
-rw-r--r--src/commands/edit/EventInsertionCommand.cpp58
-rw-r--r--src/commands/edit/EventInsertionCommand.h62
-rw-r--r--src/commands/edit/EventQuantizeCommand.cpp273
-rw-r--r--src/commands/edit/EventQuantizeCommand.h98
-rw-r--r--src/commands/edit/EventUnquantizeCommand.cpp106
-rw-r--r--src/commands/edit/EventUnquantizeCommand.h73
-rw-r--r--src/commands/edit/InsertTriggerNoteCommand.cpp132
-rw-r--r--src/commands/edit/InsertTriggerNoteCommand.h78
-rw-r--r--src/commands/edit/InvertCommand.cpp85
-rw-r--r--src/commands/edit/InvertCommand.h67
-rw-r--r--src/commands/edit/ModifyMarkerCommand.cpp95
-rw-r--r--src/commands/edit/ModifyMarkerCommand.h78
-rw-r--r--src/commands/edit/MoveAcrossSegmentsCommand.cpp76
-rw-r--r--src/commands/edit/MoveAcrossSegmentsCommand.h63
-rw-r--r--src/commands/edit/MoveCommand.cpp159
-rw-r--r--src/commands/edit/MoveCommand.h69
-rw-r--r--src/commands/edit/PasteEventsCommand.cpp321
-rw-r--r--src/commands/edit/PasteEventsCommand.h112
-rw-r--r--src/commands/edit/PasteSegmentsCommand.cpp153
-rw-r--r--src/commands/edit/PasteSegmentsCommand.h79
-rw-r--r--src/commands/edit/RemoveMarkerCommand.cpp83
-rw-r--r--src/commands/edit/RemoveMarkerCommand.h75
-rw-r--r--src/commands/edit/RescaleCommand.cpp138
-rw-r--r--src/commands/edit/RescaleCommand.h71
-rw-r--r--src/commands/edit/RetrogradeCommand.cpp121
-rw-r--r--src/commands/edit/RetrogradeCommand.h67
-rw-r--r--src/commands/edit/RetrogradeInvertCommand.cpp163
-rw-r--r--src/commands/edit/RetrogradeInvertCommand.h67
-rw-r--r--src/commands/edit/SelectionPropertyCommand.cpp128
-rw-r--r--src/commands/edit/SelectionPropertyCommand.h82
-rw-r--r--src/commands/edit/SetLyricsCommand.cpp192
-rw-r--r--src/commands/edit/SetLyricsCommand.h66
-rw-r--r--src/commands/edit/SetNoteTypeCommand.cpp87
-rw-r--r--src/commands/edit/SetNoteTypeCommand.h72
-rw-r--r--src/commands/edit/SetTriggerCommand.cpp74
-rw-r--r--src/commands/edit/SetTriggerCommand.h83
-rw-r--r--src/commands/edit/TransposeCommand.cpp83
-rw-r--r--src/commands/edit/TransposeCommand.h83
58 files changed, 5528 insertions, 0 deletions
diff --git a/src/commands/edit/AddDotCommand.cpp b/src/commands/edit/AddDotCommand.cpp
new file mode 100644
index 0000000..b69a25c
--- /dev/null
+++ b/src/commands/edit/AddDotCommand.cpp
@@ -0,0 +1,98 @@
+/* -*- 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 <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 "AddDotCommand.h"
+
+#include "base/Event.h"
+#include "base/NotationTypes.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+void
+AddDotCommand::modifySegment()
+{
+ std::vector<Event *> toErase;
+ std::vector<Event *> toInsert;
+
+ EventSelection::eventcontainer::iterator i;
+ timeT endTime = getEndTime();
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+
+ Note note = Note::getNearestNote
+ ((*i)->getNotationDuration());
+ int dots = note.getDots();
+ if (++dots > 2)
+ dots = 0;
+
+ toErase.push_back(*i);
+
+ Event *e;
+
+ if (m_notationOnly) {
+ e = new Event(**i,
+ (*i)->getAbsoluteTime(),
+ (*i)->getDuration(),
+ (*i)->getSubOrdering(),
+ (*i)->getNotationAbsoluteTime(),
+ Note(note.getNoteType(),
+ dots).getDuration());
+
+ } else {
+ e = new Event(**i,
+ (*i)->getNotationAbsoluteTime(),
+ Note(note.getNoteType(),
+ dots).getDuration());
+ }
+
+ if (e->getNotationAbsoluteTime() + e->getNotationDuration() > endTime) {
+ endTime = e->getNotationAbsoluteTime() + e->getNotationDuration();
+ }
+
+ toInsert.push_back(e);
+ }
+ }
+
+ for (std::vector<Event *>::iterator i = toErase.begin(); i != toErase.end(); ++i) {
+ m_selection->getSegment().eraseSingle(*i);
+ }
+
+ for (std::vector<Event *>::iterator i = toInsert.begin(); i != toInsert.end(); ++i) {
+ m_selection->getSegment().insert(*i);
+ m_selection->addEvent(*i);
+ }
+
+ m_selection->getSegment().normalizeRests(getStartTime(), endTime);
+}
+
+}
diff --git a/src/commands/edit/AddDotCommand.h b/src/commands/edit/AddDotCommand.h
new file mode 100644
index 0000000..a88da26
--- /dev/null
+++ b/src/commands/edit/AddDotCommand.h
@@ -0,0 +1,68 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_ADDDOTCOMMAND_H_
+#define _RG_ADDDOTCOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class AddDotCommand : public BasicSelectionCommand
+{
+public:
+ AddDotCommand(EventSelection &selection, bool notationOnly) :
+ BasicSelectionCommand(getGlobalName(), selection, true),
+ m_selection(&selection),
+ m_notationOnly(notationOnly)
+ { }
+
+ static QString getGlobalName() {
+ return i18n("&Add Dot");
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ bool m_notationOnly;
+};
+
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/AddMarkerCommand.cpp b/src/commands/edit/AddMarkerCommand.cpp
new file mode 100644
index 0000000..b7c665a
--- /dev/null
+++ b/src/commands/edit/AddMarkerCommand.cpp
@@ -0,0 +1,67 @@
+/* -*- 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 <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 "AddMarkerCommand.h"
+
+#include "base/Composition.h"
+#include "base/Marker.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+AddMarkerCommand::AddMarkerCommand(Composition *comp,
+ timeT time,
+ const std::string &name,
+ const std::string &description):
+ KNamedCommand(getGlobalName()),
+ m_composition(comp),
+ m_detached(true)
+{
+ m_marker = new Marker(time, name, description);
+}
+
+AddMarkerCommand::~AddMarkerCommand()
+{
+ if (m_detached)
+ delete m_marker;
+}
+
+void
+AddMarkerCommand::execute()
+{
+ m_composition->addMarker(m_marker);
+ m_detached = false;
+}
+
+void
+AddMarkerCommand::unexecute()
+{
+ m_composition->detachMarker(m_marker);
+ m_detached = true;
+}
+
+}
diff --git a/src/commands/edit/AddMarkerCommand.h b/src/commands/edit/AddMarkerCommand.h
new file mode 100644
index 0000000..80f15c1
--- /dev/null
+++ b/src/commands/edit/AddMarkerCommand.h
@@ -0,0 +1,71 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_ADDMARKERCOMMAND_H_
+#define _RG_ADDMARKERCOMMAND_H_
+
+#include <string>
+#include <kcommand.h>
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Marker;
+class Composition;
+
+
+class AddMarkerCommand : public KNamedCommand
+{
+public:
+ AddMarkerCommand(Composition *comp,
+ timeT time,
+ const std::string &name,
+ const std::string &description);
+ ~AddMarkerCommand();
+
+ static QString getGlobalName() { return i18n("&Add Marker"); }
+
+ virtual void execute();
+ virtual void unexecute();
+
+protected:
+
+ Composition *m_composition;
+ Marker *m_marker;
+ bool m_detached;
+
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/ChangeVelocityCommand.cpp b/src/commands/edit/ChangeVelocityCommand.cpp
new file mode 100644
index 0000000..fc1c1ea
--- /dev/null
+++ b/src/commands/edit/ChangeVelocityCommand.cpp
@@ -0,0 +1,68 @@
+/* -*- 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 <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 "ChangeVelocityCommand.h"
+
+#include "base/NotationTypes.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include "base/BaseProperties.h"
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+void
+ChangeVelocityCommand::modifySegment()
+{
+ EventSelection::eventcontainer::iterator i;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+
+ long velocity = 100;
+ (*i)->get
+ <Int>(VELOCITY, velocity);
+
+ // round velocity up to the next multiple of delta
+ velocity /= m_delta;
+ velocity *= m_delta;
+ velocity += m_delta;
+
+ if (velocity < 0)
+ velocity = 0;
+ if (velocity > 127)
+ velocity = 127;
+ (*i)->set<Int>(VELOCITY, velocity);
+ }
+ }
+}
+
+}
diff --git a/src/commands/edit/ChangeVelocityCommand.h b/src/commands/edit/ChangeVelocityCommand.h
new file mode 100644
index 0000000..a0a51b1
--- /dev/null
+++ b/src/commands/edit/ChangeVelocityCommand.h
@@ -0,0 +1,68 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_CHANGEVELOCITYCOMMAND_H_
+#define _RG_CHANGEVELOCITYCOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+/** Add or subtract a constant from all event velocities.
+ Use SelectionPropertyCommand if you want to do something more
+ creative. */
+class ChangeVelocityCommand : public BasicSelectionCommand
+{
+public:
+ ChangeVelocityCommand(int delta, EventSelection &selection) :
+ BasicSelectionCommand(getGlobalName(delta), selection, true),
+ m_selection(&selection), m_delta(delta) { }
+
+ static QString getGlobalName(int delta = 0) {
+ if (delta > 0) return i18n("&Increase Velocity");
+ else return i18n("&Reduce Velocity");
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ int m_delta;
+};
+
+
+}
+
+#endif
diff --git a/src/commands/edit/ClearTriggersCommand.cpp b/src/commands/edit/ClearTriggersCommand.cpp
new file mode 100644
index 0000000..3b58405
--- /dev/null
+++ b/src/commands/edit/ClearTriggersCommand.cpp
@@ -0,0 +1,53 @@
+/* -*- 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 <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 "ClearTriggersCommand.h"
+
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include "base/BaseProperties.h"
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+void
+ClearTriggersCommand::modifySegment()
+{
+ EventSelection::eventcontainer::iterator i;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ (*i)->unset(TRIGGER_SEGMENT_ID);
+ (*i)->unset(TRIGGER_SEGMENT_RETUNE);
+ (*i)->unset(TRIGGER_SEGMENT_ADJUST_TIMES);
+ }
+}
+
+}
diff --git a/src/commands/edit/ClearTriggersCommand.h b/src/commands/edit/ClearTriggersCommand.h
new file mode 100644
index 0000000..077e270
--- /dev/null
+++ b/src/commands/edit/ClearTriggersCommand.h
@@ -0,0 +1,66 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_CLEARTRIGGERSCOMMAND_H_
+#define _RG_CLEARTRIGGERSCOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class ClearTriggersCommand : public BasicSelectionCommand
+{
+public:
+ ClearTriggersCommand(EventSelection &selection,
+ QString name = 0) :
+ BasicSelectionCommand(name ? name : getGlobalName(), selection, true),
+ m_selection(&selection)
+ { }
+
+ static QString getGlobalName() {
+ return i18n("&Clear Triggers");
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/CollapseNotesCommand.cpp b/src/commands/edit/CollapseNotesCommand.cpp
new file mode 100644
index 0000000..225d34c
--- /dev/null
+++ b/src/commands/edit/CollapseNotesCommand.cpp
@@ -0,0 +1,79 @@
+/* -*- 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 <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 "CollapseNotesCommand.h"
+
+#include "base/Event.h"
+#include "base/SegmentNotationHelper.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+void
+CollapseNotesCommand::modifySegment()
+{
+ SegmentNotationHelper helper(getSegment());
+ timeT endTime = getEndTime();
+
+ // This is really nasty stuff. We can't go in forward direction
+ // using the j-iterator trick because collapseNoteAggressively may
+ // erase the following iterator as well as the preceding one. We
+ // can't go backward naively, because collapseNoteAggressively
+ // erases i from the EventSelection now that it's a
+ // SegmentObserver. We need the fancy hybrid j-iterator-backward
+ // technique applied to selections instead of segments.
+
+ EventSelection::eventcontainer::iterator i =
+ m_selection->getSegmentEvents().end();
+ EventSelection::eventcontainer::iterator j = i;
+ EventSelection::eventcontainer::iterator beg =
+ m_selection->getSegmentEvents().begin();
+ bool thisOne = false;
+
+ while (i != beg && (!thisOne || (*i != *beg))) {
+
+ --j;
+
+ if (thisOne) {
+ helper.collapseNoteAggressively(*i, endTime);
+ }
+
+ // rather than "true" one could perform a test to see
+ // whether j pointed to a candidate for collapsing:
+ thisOne = true;
+
+ i = j;
+ }
+
+ if (thisOne) {
+ helper.collapseNoteAggressively(*i, endTime);
+ }
+}
+
+}
diff --git a/src/commands/edit/CollapseNotesCommand.h b/src/commands/edit/CollapseNotesCommand.h
new file mode 100644
index 0000000..9d3a0fc
--- /dev/null
+++ b/src/commands/edit/CollapseNotesCommand.h
@@ -0,0 +1,65 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_ADJUSTMENUCOLLAPSENOTESCOMMAND_H_
+#define _RG_ADJUSTMENUCOLLAPSENOTESCOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+class Collapse;
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class CollapseNotesCommand : public BasicSelectionCommand
+{
+public:
+ CollapseNotesCommand(EventSelection &selection) :
+ BasicSelectionCommand(getGlobalName(), selection, true),
+ m_selection(&selection) { }
+
+ static QString getGlobalName() { return i18n("Collapse &Equal-Pitch Notes"); }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+};
+
+
+// Set the (numerical) property of a selection according given pattern.
+//
+
+}
+
+#endif
diff --git a/src/commands/edit/CopyCommand.cpp b/src/commands/edit/CopyCommand.cpp
new file mode 100644
index 0000000..38aa628
--- /dev/null
+++ b/src/commands/edit/CopyCommand.cpp
@@ -0,0 +1,120 @@
+/* -*- 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 <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 "CopyCommand.h"
+
+#include "misc/Strings.h"
+#include "base/Clipboard.h"
+#include "base/Composition.h"
+#include "base/Selection.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+CopyCommand::CopyCommand(EventSelection &selection,
+ Clipboard *clipboard) :
+ KNamedCommand(getGlobalName()),
+ m_targetClipboard(clipboard)
+{
+ m_sourceClipboard = new Clipboard;
+ m_savedClipboard = 0;
+ m_sourceClipboard->newSegment(&selection)->setLabel
+ (selection.getSegment().getLabel() + " " + qstrtostr(i18n("(excerpt)")));
+}
+
+CopyCommand::CopyCommand(SegmentSelection &selection,
+ Clipboard *clipboard) :
+ KNamedCommand(getGlobalName()),
+ m_targetClipboard(clipboard)
+{
+ m_sourceClipboard = new Clipboard;
+ m_savedClipboard = 0;
+
+ for (SegmentSelection::iterator i = selection.begin();
+ i != selection.end(); ++i) {
+ QString newLabel = strtoqstr((*i)->getLabel());
+ if (newLabel.contains(i18n("(copied)"))) {
+ m_sourceClipboard->newSegment(*i);
+ } else {
+ m_sourceClipboard->newSegment(*i)->
+ setLabel(qstrtostr(i18n("%1 (copied)").arg(newLabel)));
+ }
+ }
+}
+
+CopyCommand::CopyCommand(Composition *composition,
+ timeT beginTime,
+ timeT endTime,
+ Clipboard *clipboard) :
+ KNamedCommand(i18n("Copy Range")),
+ m_targetClipboard(clipboard)
+{
+ m_sourceClipboard = new Clipboard;
+ m_savedClipboard = 0;
+
+ for (Composition::iterator i = composition->begin();
+ i != composition->end(); ++i) {
+ if ((*i)->getStartTime() < endTime &&
+ (*i)->getRepeatEndTime() > beginTime) {
+ m_sourceClipboard->newSegment(*i, beginTime, endTime, true);
+ }
+ }
+
+ TimeSignatureSelection tsigsel
+ (*composition, beginTime, endTime, true);
+ m_sourceClipboard->setTimeSignatureSelection(tsigsel);
+
+ TempoSelection temposel
+ (*composition, beginTime, endTime, true);
+ m_sourceClipboard->setTempoSelection(temposel);
+
+ m_sourceClipboard->setNominalRange(beginTime, endTime);
+}
+
+CopyCommand::~CopyCommand()
+{
+ delete m_sourceClipboard;
+ delete m_savedClipboard;
+}
+
+void
+CopyCommand::execute()
+{
+ if (!m_savedClipboard) {
+ m_savedClipboard = new Clipboard(*m_targetClipboard);
+ }
+
+ m_targetClipboard->copyFrom(m_sourceClipboard);
+}
+
+void
+CopyCommand::unexecute()
+{
+ m_targetClipboard->copyFrom(m_savedClipboard);
+}
+
+}
diff --git a/src/commands/edit/CopyCommand.h b/src/commands/edit/CopyCommand.h
new file mode 100644
index 0000000..29d6dc7
--- /dev/null
+++ b/src/commands/edit/CopyCommand.h
@@ -0,0 +1,82 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_COPYCOMMAND_H_
+#define _RG_COPYCOMMAND_H_
+
+#include <kcommand.h>
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class SegmentSelection;
+class EventSelection;
+class Composition;
+class Clipboard;
+
+
+/// Copy a selection
+
+class CopyCommand : public KNamedCommand
+{
+public:
+ /// Make a CopyCommand that copies events from within a Segment
+ CopyCommand(EventSelection &selection,
+ Clipboard *clipboard);
+
+ /// Make a CopyCommand that copies whole Segments
+ CopyCommand(SegmentSelection &selection,
+ Clipboard *clipboard);
+
+ /// Make a CopyCommand that copies a range of a Composition
+ CopyCommand(Composition *composition,
+ timeT beginTime,
+ timeT endTime,
+ Clipboard *clipboard);
+
+ virtual ~CopyCommand();
+
+ static QString getGlobalName() { return i18n("&Copy"); }
+
+ virtual void execute();
+ virtual void unexecute();
+
+protected:
+ Clipboard *m_sourceClipboard;
+ Clipboard *m_targetClipboard;
+ Clipboard *m_savedClipboard;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/CutAndCloseCommand.cpp b/src/commands/edit/CutAndCloseCommand.cpp
new file mode 100644
index 0000000..a99b4ef
--- /dev/null
+++ b/src/commands/edit/CutAndCloseCommand.cpp
@@ -0,0 +1,163 @@
+/* -*- 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 <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 "CutAndCloseCommand.h"
+
+#include "base/Clipboard.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "CutCommand.h"
+#include <qstring.h>
+#include "misc/Debug.h"
+
+
+namespace Rosegarden
+{
+
+CutAndCloseCommand::CutAndCloseCommand(EventSelection &selection,
+ Clipboard *clipboard) :
+ KMacroCommand(getGlobalName())
+{
+ addCommand(new CutCommand(selection, clipboard));
+ addCommand(new CloseCommand(&selection.getSegment(),
+ selection.getEndTime(),
+ selection.getStartTime()));
+}
+
+void
+CutAndCloseCommand::CloseCommand::execute()
+{
+ // We shift all the events from m_gapEnd to the end of the
+ // segment back so that they start at m_gapStart instead of m_gapEnd.
+
+ assert(m_gapEnd >= m_gapStart);
+ if (m_gapEnd == m_gapStart)
+ return ;
+
+ // We also need to record how many events there are already at
+ // m_gapStart so that we can leave those unchanged when we undo.
+ // (This command is executed on the understanding that the area
+ // between m_gapStart and m_gapEnd is empty of all but rests, but
+ // in practice there may be other things such as a clef at the
+ // same time as m_gapStart. This will only work for events that
+ // have smaller subordering than notes etc.)
+
+ m_staticEvents = 0;
+ for (Segment::iterator i = m_segment->findTime(m_gapStart);
+ m_segment->isBeforeEndMarker(i); ++i) {
+ if ((*i)->getAbsoluteTime() > m_gapStart)
+ break;
+ if ((*i)->isa(Note::EventRestType))
+ continue;
+ ++m_staticEvents;
+ }
+
+ std::vector<Event *> events;
+ timeT timeDifference = m_gapEnd - m_gapStart;
+
+ for (Segment::iterator i = m_segment->findTime(m_gapEnd);
+ m_segment->isBeforeEndMarker(i); ++i) {
+ events.push_back((*i)->copyMoving( -timeDifference));
+ }
+
+ timeT oldEndTime = m_segment->getEndTime();
+
+ // remove rests from target area, and everything thereafter
+ for (Segment::iterator i = m_segment->findTime(m_gapStart);
+ m_segment->isBeforeEndMarker(i); ) {
+ if ((*i)->getAbsoluteTime() >= m_gapEnd ||
+ (*i)->isa(Note::EventRestType)) {
+ Segment::iterator j(i);
+ ++j;
+ m_segment->erase(i);
+ i = j;
+ } else {
+ ++i;
+ }
+ }
+
+ for (unsigned int i = 0; i < events.size(); ++i) {
+ m_segment->insert(events[i]);
+ }
+
+ m_segment->normalizeRests(m_segment->getEndTime(), oldEndTime);
+}
+
+void
+CutAndCloseCommand::CloseCommand::unexecute()
+{
+ // We want to shift events from m_gapStart to the end of the
+ // segment forward so as to start at m_gapEnd instead of
+ // m_gapStart.
+
+ assert(m_gapEnd >= m_gapStart);
+ if (m_gapEnd == m_gapStart)
+ return ;
+
+ // May need to ignore some static events at m_gapStart.
+ // These are assumed to have smaller subordering than whatever
+ // we're not ignoring. Actually this still isn't quite right:
+ // it'll do the wrong thing where we have, say, a clef then
+ // some notes then another clef and we cut-and-close all the
+ // notes and then undo. But it's better than we were doing
+ // before.
+
+ Segment::iterator starti = m_segment->findTime(m_gapStart);
+
+ while (m_segment->isBeforeEndMarker(starti)) {
+ if (m_staticEvents == 0)
+ break;
+ if ((*starti)->getAbsoluteTime() > m_gapStart)
+ break;
+ if (!(*starti)->isa(Note::EventRestType))
+ --m_staticEvents;
+ ++starti;
+ }
+
+ std::vector<Event *> events;
+ timeT timeDifference = m_gapEnd - m_gapStart;
+
+ for (Segment::iterator i = starti; m_segment->isBeforeEndMarker(i); ) {
+ Segment::iterator j(i);
+ ++j;
+ events.push_back((*i)->copyMoving(timeDifference));
+ m_segment->erase(i);
+ i = j;
+ }
+
+ for (unsigned int i = 0; i < events.size(); ++i) {
+ m_segment->insert(events[i]);
+ }
+
+ timeT endTime = m_segment->getEndTime();
+ NOTATION_DEBUG << "setting end time to " << (endTime - timeDifference) << endl;
+ //!!! this following is not working for bugaccidentals.rg:
+ m_segment->setEndTime(endTime - timeDifference);
+
+ m_segment->normalizeRests(m_gapStart, m_gapEnd);
+}
+
+}
diff --git a/src/commands/edit/CutAndCloseCommand.h b/src/commands/edit/CutAndCloseCommand.h
new file mode 100644
index 0000000..4be5809
--- /dev/null
+++ b/src/commands/edit/CutAndCloseCommand.h
@@ -0,0 +1,82 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_CUTANDCLOSECOMMAND_H_
+#define _RG_CUTANDCLOSECOMMAND_H_
+
+#include <kcommand.h>
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class EventSelection;
+class Clipboard;
+
+
+/// Cut a selection and close the gap
+
+class CutAndCloseCommand : public KMacroCommand
+{
+public:
+ CutAndCloseCommand(EventSelection &selection,
+ Clipboard *clipboard);
+
+ static QString getGlobalName() { return i18n("C&ut and Close"); }
+
+protected:
+ class CloseCommand : public KNamedCommand
+ {
+ public:
+ CloseCommand(Segment *segment,
+ timeT fromTime,
+ timeT toTime) :
+ KNamedCommand("Close"),
+ m_segment(segment),
+ m_gapEnd(fromTime),
+ m_gapStart(toTime) { }
+
+ virtual void execute();
+ virtual void unexecute();
+
+ private:
+ Segment *m_segment;
+ timeT m_gapEnd;
+ timeT m_gapStart;
+ int m_staticEvents;
+ };
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/CutCommand.cpp b/src/commands/edit/CutCommand.cpp
new file mode 100644
index 0000000..9d54089
--- /dev/null
+++ b/src/commands/edit/CutCommand.cpp
@@ -0,0 +1,59 @@
+/* -*- 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 <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 "CutCommand.h"
+
+#include "base/Clipboard.h"
+#include "base/Selection.h"
+#include "commands/segment/SegmentEraseCommand.h"
+#include "CopyCommand.h"
+#include "EraseCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+CutCommand::CutCommand(EventSelection &selection,
+ Clipboard *clipboard) :
+ KMacroCommand(getGlobalName())
+{
+ addCommand(new CopyCommand(selection, clipboard));
+ addCommand(new EraseCommand(selection));
+}
+
+CutCommand::CutCommand(SegmentSelection &selection,
+ Clipboard *clipboard) :
+ KMacroCommand(getGlobalName())
+{
+ addCommand(new CopyCommand(selection, clipboard));
+
+ for (SegmentSelection::iterator i = selection.begin();
+ i != selection.end(); ++i) {
+ addCommand(new SegmentEraseCommand(*i));
+ }
+}
+
+}
diff --git a/src/commands/edit/CutCommand.h b/src/commands/edit/CutCommand.h
new file mode 100644
index 0000000..186736c
--- /dev/null
+++ b/src/commands/edit/CutCommand.h
@@ -0,0 +1,62 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_CUTCOMMAND_H_
+#define _RG_CUTCOMMAND_H_
+
+#include <qstring.h>
+#include <klocale.h>
+#include <kcommand.h>
+
+
+namespace Rosegarden
+{
+
+class SegmentSelection;
+class EventSelection;
+class Clipboard;
+
+
+/// Cut a selection
+
+class CutCommand : public KMacroCommand
+{
+public:
+ /// Make a CutCommand that cuts events from within a Segment
+ CutCommand(EventSelection &selection,
+ Clipboard *clipboard);
+
+ /// Make a CutCommand that cuts whole Segments
+ CutCommand(SegmentSelection &selection,
+ Clipboard *clipboard);
+
+ static QString getGlobalName() { return i18n("Cu&t"); }
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/EraseCommand.cpp b/src/commands/edit/EraseCommand.cpp
new file mode 100644
index 0000000..8649885
--- /dev/null
+++ b/src/commands/edit/EraseCommand.cpp
@@ -0,0 +1,86 @@
+/* -*- 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 <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 "EraseCommand.h"
+
+#include "misc/Debug.h"
+#include "base/NotationTypes.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+EraseCommand::EraseCommand(EventSelection &selection) :
+ BasicSelectionCommand(getGlobalName(), selection, true),
+ m_selection(&selection),
+ m_relayoutEndTime(getEndTime())
+{
+ // nothing else
+}
+
+void
+EraseCommand::modifySegment()
+{
+ RG_DEBUG << "EraseCommand::modifySegment" << endl;
+
+ std::vector<Event *> toErase;
+ EventSelection::eventcontainer::iterator i;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Clef::EventType) ||
+ (*i)->isa(Key ::EventType)) {
+ m_relayoutEndTime = getSegment().getEndTime();
+ }
+
+ // We used to do this by calling SegmentNotationHelper::deleteEvent
+ // on each event in the selection, but it's probably easier to
+ // cope with general selections by deleting everything in the
+ // selection and then normalizing the rests. The deleteEvent
+ // mechanism is still the more sensitive way to do it for single
+ // events, and it's what's used by EraseEventCommand and thus
+ // the notation eraser tool.
+
+ toErase.push_back(*i);
+ }
+
+ for (unsigned int j = 0; j < toErase.size(); ++j) {
+ getSegment().eraseSingle(toErase[j]);
+ }
+
+ getSegment().normalizeRests(getStartTime(), getEndTime());
+}
+
+timeT
+EraseCommand::getRelayoutEndTime()
+{
+ return m_relayoutEndTime;
+}
+
+}
diff --git a/src/commands/edit/EraseCommand.h b/src/commands/edit/EraseCommand.h
new file mode 100644
index 0000000..4e583ad
--- /dev/null
+++ b/src/commands/edit/EraseCommand.h
@@ -0,0 +1,66 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_ERASECOMMAND_H_
+#define _RG_ERASECOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+/// Erase a selection from within a segment
+
+class EraseCommand : public BasicSelectionCommand
+{
+public:
+ EraseCommand(EventSelection &selection);
+
+ static QString getGlobalName() { return i18n("&Erase"); }
+
+ virtual timeT getRelayoutEndTime();
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ timeT m_relayoutEndTime;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/EventEditCommand.cpp b/src/commands/edit/EventEditCommand.cpp
new file mode 100644
index 0000000..ef31be2
--- /dev/null
+++ b/src/commands/edit/EventEditCommand.cpp
@@ -0,0 +1,64 @@
+/* -*- 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 <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 "EventEditCommand.h"
+
+#include "base/Event.h"
+#include "base/Segment.h"
+#include "document/BasicCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+EventEditCommand::EventEditCommand(Segment &segment,
+ Event *eventToModify,
+ const Event &newEvent) :
+ BasicCommand(getGlobalName(),
+ segment,
+ std::min(eventToModify->getAbsoluteTime(),
+ newEvent.getAbsoluteTime()),
+ std::max(eventToModify->getAbsoluteTime() +
+ eventToModify->getDuration(),
+ newEvent.getAbsoluteTime() +
+ newEvent.getDuration()),
+ true), // bruteForceRedo
+ m_oldEvent(eventToModify),
+ m_newEvent(newEvent)
+{
+ // nothing else to see here
+}
+
+void
+EventEditCommand::modifySegment()
+{
+ Segment &segment(getSegment());
+ segment.eraseSingle(m_oldEvent);
+ segment.insert(new Event(m_newEvent));
+ segment.normalizeRests(getStartTime(), getEndTime());
+}
+
+}
diff --git a/src/commands/edit/EventEditCommand.h b/src/commands/edit/EventEditCommand.h
new file mode 100644
index 0000000..5f22a1e
--- /dev/null
+++ b/src/commands/edit/EventEditCommand.h
@@ -0,0 +1,69 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_EVENTEDITCOMMAND_H_
+#define _RG_EVENTEDITCOMMAND_H_
+
+#include "base/Event.h"
+#include "document/BasicCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+
+
+/**
+ * Replace an event with another one (likely to be used in
+ * conjunction with EventEditDialog)
+ */
+
+class EventEditCommand : public BasicCommand
+{
+public:
+ EventEditCommand(Segment &segment,
+ Event *eventToModify,
+ const Event &newEvent);
+
+ static QString getGlobalName() { return i18n("Edit E&vent"); }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ Event *m_oldEvent; // only used on 1st execute
+ Event m_newEvent; // only used on 1st execute
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/EventInsertionCommand.cpp b/src/commands/edit/EventInsertionCommand.cpp
new file mode 100644
index 0000000..a684883
--- /dev/null
+++ b/src/commands/edit/EventInsertionCommand.cpp
@@ -0,0 +1,58 @@
+/* -*- 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 <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 "EventInsertionCommand.h"
+
+#include <klocale.h>
+#include "base/Event.h"
+#include "base/Segment.h"
+#include "document/BasicCommand.h"
+
+
+namespace Rosegarden
+{
+
+EventInsertionCommand::EventInsertionCommand(Segment &segment,
+ Event *event) :
+ BasicCommand(i18n("Insert Event"), segment, event->getAbsoluteTime(),
+ event->getAbsoluteTime() + event->getDuration()),
+ m_event(new Event(*event))
+{
+ // nothing
+}
+
+EventInsertionCommand::~EventInsertionCommand()
+{
+ delete m_event;
+ // don't want to delete m_lastInsertedEvent, it's just an alias
+}
+
+void EventInsertionCommand::modifySegment()
+{
+ m_lastInsertedEvent = new Event(*m_event);
+ getSegment().insert(m_lastInsertedEvent);
+}
+
+}
diff --git a/src/commands/edit/EventInsertionCommand.h b/src/commands/edit/EventInsertionCommand.h
new file mode 100644
index 0000000..aee9c8b
--- /dev/null
+++ b/src/commands/edit/EventInsertionCommand.h
@@ -0,0 +1,62 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_EVENTINSERTIONCOMMAND_H_
+#define _RG_EVENTINSERTIONCOMMAND_H_
+
+#include "document/BasicCommand.h"
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class Event;
+
+
+class EventInsertionCommand : public BasicCommand
+{
+public:
+ EventInsertionCommand(Segment &segment,
+ Event *event);
+
+ virtual ~EventInsertionCommand();
+
+ Event *getLastInsertedEvent() { return m_lastInsertedEvent; }
+
+protected:
+ virtual void modifySegment();
+
+ Event *m_event;
+ Event *m_lastInsertedEvent; // an alias for another event
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/EventQuantizeCommand.cpp b/src/commands/edit/EventQuantizeCommand.cpp
new file mode 100644
index 0000000..775a32f
--- /dev/null
+++ b/src/commands/edit/EventQuantizeCommand.cpp
@@ -0,0 +1,273 @@
+/* -*- 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 <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 "EventQuantizeCommand.h"
+
+#include <klocale.h>
+#include "base/NotationTypes.h"
+#include "base/Profiler.h"
+#include "base/Quantizer.h"
+#include "base/BasicQuantizer.h"
+#include "base/LegatoQuantizer.h"
+#include "base/NotationQuantizer.h"
+#include "base/Segment.h"
+#include "base/SegmentNotationHelper.h"
+#include "base/Selection.h"
+#include "document/BasicCommand.h"
+#include <kconfig.h>
+#include <qstring.h>
+#include "base/BaseProperties.h"
+#include "gui/application/RosegardenApplication.h"
+#include <kapplication.h>
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+EventQuantizeCommand::EventQuantizeCommand(Segment &segment,
+ timeT startTime,
+ timeT endTime,
+ Quantizer *quantizer):
+ BasicCommand(getGlobalName(quantizer), segment, startTime, endTime,
+ true), // bruteForceRedo
+ m_quantizer(quantizer),
+ m_selection(0)
+{
+ // nothing else
+}
+
+EventQuantizeCommand::EventQuantizeCommand(EventSelection &selection,
+ Quantizer *quantizer):
+ BasicCommand(getGlobalName(quantizer),
+ selection.getSegment(),
+ selection.getStartTime(),
+ selection.getEndTime(),
+ true), // bruteForceRedo
+ m_quantizer(quantizer),
+ m_selection(&selection)
+{
+ // nothing else
+}
+
+EventQuantizeCommand::EventQuantizeCommand(Segment &segment,
+ timeT startTime,
+ timeT endTime,
+ QString configGroup,
+ bool notation):
+ BasicCommand(getGlobalName(makeQuantizer(configGroup, notation)),
+ segment, startTime, endTime,
+ true), // bruteForceRedo
+ m_selection(0),
+ m_configGroup(configGroup)
+{
+ // nothing else -- m_quantizer set by makeQuantizer
+}
+
+EventQuantizeCommand::EventQuantizeCommand(EventSelection &selection,
+ QString configGroup,
+ bool notation):
+ BasicCommand(getGlobalName(makeQuantizer(configGroup, notation)),
+ selection.getSegment(),
+ selection.getStartTime(),
+ selection.getEndTime(),
+ true), // bruteForceRedo
+ m_selection(&selection),
+ m_configGroup(configGroup)
+{
+ // nothing else -- m_quantizer set by makeQuantizer
+}
+
+EventQuantizeCommand::~EventQuantizeCommand()
+{
+ delete m_quantizer;
+}
+
+QString
+EventQuantizeCommand::getGlobalName(Quantizer *quantizer)
+{
+ if (quantizer) {
+ if (dynamic_cast<NotationQuantizer *>(quantizer)) {
+ return i18n("Heuristic Notation &Quantize");
+ } else {
+ return i18n("Grid &Quantize");
+ }
+ }
+
+ return i18n("&Quantize...");
+}
+
+void
+EventQuantizeCommand::modifySegment()
+{
+ Profiler profiler("EventQuantizeCommand::modifySegment", true);
+
+ Segment &segment = getSegment();
+ SegmentNotationHelper helper(segment);
+
+ bool rebeam = false;
+ bool makeviable = false;
+ bool decounterpoint = false;
+
+ if (m_configGroup) {
+ //!!! need way to decide whether to do these even if no config group (i.e. through args to the command)
+ KConfig *config = kapp->config();
+ config->setGroup(m_configGroup);
+
+ rebeam = config->readBoolEntry("quantizerebeam", true);
+ makeviable = config->readBoolEntry("quantizemakeviable", false);
+ decounterpoint = config->readBoolEntry("quantizedecounterpoint", false);
+ }
+
+ if (m_selection) {
+ m_quantizer->quantize(m_selection);
+
+ } else {
+ m_quantizer->quantize(&segment,
+ segment.findTime(getStartTime()),
+ segment.findTime(getEndTime()));
+ }
+
+ if (m_progressTotal > 0) {
+ if (rebeam || makeviable || decounterpoint) {
+ emit incrementProgress(m_progressTotal / 2);
+ rgapp->refreshGUI(50);
+ } else {
+ emit incrementProgress(m_progressTotal);
+ rgapp->refreshGUI(50);
+ }
+ }
+
+ if (m_selection) {
+ EventSelection::RangeTimeList ranges(m_selection->getRangeTimes());
+ for (EventSelection::RangeTimeList::iterator i = ranges.begin();
+ i != ranges.end(); ++i) {
+ if (makeviable) {
+ helper.makeNotesViable(i->first, i->second, true);
+ }
+ if (decounterpoint) {
+ helper.deCounterpoint(i->first, i->second);
+ }
+ if (rebeam) {
+ helper.autoBeam(i->first, i->second, GROUP_TYPE_BEAMED);
+ helper.autoSlur(i->first, i->second, true);
+ }
+ }
+ } else {
+ if (makeviable) {
+ helper.makeNotesViable(getStartTime(), getEndTime(), true);
+ }
+ if (decounterpoint) {
+ helper.deCounterpoint(getStartTime(), getEndTime());
+ }
+ if (rebeam) {
+ helper.autoBeam(getStartTime(), getEndTime(), GROUP_TYPE_BEAMED);
+ helper.autoSlur(getStartTime(), getEndTime(), true);
+ }
+ }
+
+ if (m_progressTotal > 0) {
+ if (rebeam || makeviable || decounterpoint) {
+ emit incrementProgress(m_progressTotal / 2);
+ rgapp->refreshGUI(50);
+ }
+ }
+}
+
+Quantizer *
+EventQuantizeCommand::makeQuantizer(QString configGroup,
+ bool notationDefault)
+{
+ //!!! Excessive duplication with
+ // QuantizeParameters::getQuantizer in widgets.cpp
+
+ KConfig *config = kapp->config();
+ config->setGroup(configGroup);
+
+ timeT defaultUnit =
+ Note(Note::Demisemiquaver).getDuration();
+
+ int type = config->readNumEntry("quantizetype", notationDefault ? 2 : 0);
+ timeT unit = config->readNumEntry("quantizeunit", defaultUnit);
+ bool notateOnly = config->readBoolEntry("quantizenotationonly", notationDefault);
+ bool durations = config->readBoolEntry("quantizedurations", false);
+ int simplicity = config->readNumEntry("quantizesimplicity", 13);
+ int maxTuplet = config->readNumEntry("quantizemaxtuplet", 3);
+ bool counterpoint = config->readNumEntry("quantizecounterpoint", false);
+ bool articulate = config->readBoolEntry("quantizearticulate", true);
+ int swing = config->readNumEntry("quantizeswing", 0);
+ int iterate = config->readNumEntry("quantizeiterate", 100);
+
+ m_quantizer = 0;
+
+ if (type == 0) {
+ if (notateOnly) {
+ m_quantizer = new BasicQuantizer
+ (Quantizer::RawEventData,
+ Quantizer::NotationPrefix,
+ unit, durations, swing, iterate);
+ } else {
+ m_quantizer = new BasicQuantizer
+ (Quantizer::RawEventData,
+ Quantizer::RawEventData,
+ unit, durations, swing, iterate);
+ }
+ } else if (type == 1) {
+ if (notateOnly) {
+ m_quantizer = new LegatoQuantizer
+ (Quantizer::RawEventData,
+ Quantizer::NotationPrefix, unit);
+ } else {
+ m_quantizer = new LegatoQuantizer
+ (Quantizer::RawEventData,
+ Quantizer::RawEventData, unit);
+ }
+ } else {
+
+ NotationQuantizer *nq;
+
+ if (notateOnly) {
+ nq = new NotationQuantizer();
+ } else {
+ nq = new NotationQuantizer
+ (Quantizer::RawEventData,
+ Quantizer::RawEventData);
+ }
+
+ nq->setUnit(unit);
+ nq->setSimplicityFactor(simplicity);
+ nq->setMaxTuplet(maxTuplet);
+ nq->setContrapuntal(counterpoint);
+ nq->setArticulate(articulate);
+
+ m_quantizer = nq;
+ }
+
+ return m_quantizer;
+}
+
+}
+#include "EventQuantizeCommand.moc"
diff --git a/src/commands/edit/EventQuantizeCommand.h b/src/commands/edit/EventQuantizeCommand.h
new file mode 100644
index 0000000..6ae1303
--- /dev/null
+++ b/src/commands/edit/EventQuantizeCommand.h
@@ -0,0 +1,98 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_EVENTQUANTIZECOMMAND_H_
+#define _RG_EVENTQUANTIZECOMMAND_H_
+
+#include "document/BasicCommand.h"
+#include <qobject.h>
+#include <qstring.h>
+#include "base/Event.h"
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class Quantizer;
+class EventSelection;
+
+
+class EventQuantizeCommand : public QObject, public BasicCommand
+{
+ Q_OBJECT
+
+public:
+ /// Quantizer must be on heap (EventQuantizeCommand dtor will delete)
+ EventQuantizeCommand(Segment &segment,
+ timeT startTime,
+ timeT endTime,
+ Quantizer *);
+
+ /// Quantizer must be on heap (EventQuantizeCommand dtor will delete)
+ EventQuantizeCommand(EventSelection &selection,
+ Quantizer *);
+
+ /// Constructs own quantizer based on KConfig data in given group
+ EventQuantizeCommand(Segment &segment,
+ timeT startTime,
+ timeT endTime,
+ QString configGroup,
+ bool notationDefault);
+
+ /// Constructs own quantizer based on KConfig data in given group
+ EventQuantizeCommand(EventSelection &selection,
+ QString configGroup,
+ bool notationDefault);
+
+ ~EventQuantizeCommand();
+
+ static QString getGlobalName(Quantizer *quantizer = 0);
+ void setProgressTotal(int total) { m_progressTotal = total; }
+
+signals:
+ void incrementProgress(int);
+
+protected:
+ virtual void modifySegment();
+
+private:
+ Quantizer *m_quantizer; // I own this
+ EventSelection *m_selection;
+ QString m_configGroup;
+ int m_progressTotal;
+
+ /// Sets to m_quantizer as well as returning value
+ Quantizer *makeQuantizer(QString, bool);
+};
+
+// Collapse equal-pitch notes into one event
+//
+
+}
+
+#endif
diff --git a/src/commands/edit/EventUnquantizeCommand.cpp b/src/commands/edit/EventUnquantizeCommand.cpp
new file mode 100644
index 0000000..5a8a07e
--- /dev/null
+++ b/src/commands/edit/EventUnquantizeCommand.cpp
@@ -0,0 +1,106 @@
+/* -*- 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 <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 "EventUnquantizeCommand.h"
+
+#include <klocale.h>
+#include "base/Quantizer.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "document/BasicCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+EventUnquantizeCommand::EventUnquantizeCommand(Segment &segment,
+ timeT startTime,
+ timeT endTime,
+ Quantizer *quantizer) :
+ BasicCommand(i18n("Unquantize Events"), segment, startTime, endTime,
+ true), // bruteForceRedo
+ m_quantizer(quantizer),
+ m_selection(0)
+{
+ // nothing else
+}
+
+EventUnquantizeCommand::EventUnquantizeCommand(
+ EventSelection &selection,
+ Quantizer *quantizer) :
+ BasicCommand(i18n("Unquantize Events"),
+ selection.getSegment(),
+ selection.getStartTime(),
+ selection.getEndTime(),
+ true), // bruteForceRedo
+ m_quantizer(quantizer),
+ m_selection(&selection)
+{
+ // nothing else
+}
+
+EventUnquantizeCommand::~EventUnquantizeCommand()
+{
+ delete m_quantizer;
+}
+
+QString
+EventUnquantizeCommand::getGlobalName(Quantizer *)
+{
+ /*!!!
+ if (quantizer) {
+ switch (quantizer->getType()) {
+ case Quantizer::PositionQuantize:
+ return i18n("Position &Quantize");
+ case Quantizer::UnitQuantize:
+ return i18n("Unit &Quantize");
+ case Quantizer::NoteQuantize:
+ return i18n("Note &Quantize");
+ case Quantizer::LegatoQuantize:
+ return i18n("Smoothing &Quantize");
+ }
+ }
+ */
+ return i18n("&Quantize...");
+}
+
+void
+EventUnquantizeCommand::modifySegment()
+{
+ Segment &segment = getSegment();
+
+ if (m_selection) {
+
+ m_quantizer->unquantize(m_selection);
+
+ } else {
+ m_quantizer->unquantize(&segment,
+ segment.findTime(getStartTime()),
+ segment.findTime(getEndTime()));
+ }
+}
+
+}
diff --git a/src/commands/edit/EventUnquantizeCommand.h b/src/commands/edit/EventUnquantizeCommand.h
new file mode 100644
index 0000000..fca3a3c
--- /dev/null
+++ b/src/commands/edit/EventUnquantizeCommand.h
@@ -0,0 +1,73 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_EVENTUNQUANTIZECOMMAND_H_
+#define _RG_EVENTUNQUANTIZECOMMAND_H_
+
+#include "document/BasicCommand.h"
+#include <qstring.h>
+#include "base/Event.h"
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class Quantizer;
+class EventSelection;
+
+
+class EventUnquantizeCommand : public BasicCommand
+{
+public:
+ /// Quantizer must be on heap (EventUnquantizeCommand dtor will delete)
+ EventUnquantizeCommand(Segment &segment,
+ timeT startTime,
+ timeT endTime,
+ Quantizer *);
+
+ /// Quantizer must be on heap (EventUnquantizeCommand dtor will delete)
+ EventUnquantizeCommand(EventSelection &selection,
+ Quantizer *);
+
+ ~EventUnquantizeCommand();
+
+ static QString getGlobalName(Quantizer *quantizer = 0);
+
+protected:
+ virtual void modifySegment();
+
+private:
+ Quantizer *m_quantizer;
+ EventSelection *m_selection;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/InsertTriggerNoteCommand.cpp b/src/commands/edit/InsertTriggerNoteCommand.cpp
new file mode 100644
index 0000000..65696f3
--- /dev/null
+++ b/src/commands/edit/InsertTriggerNoteCommand.cpp
@@ -0,0 +1,132 @@
+/* -*- 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 <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 "InsertTriggerNoteCommand.h"
+
+#include <klocale.h>
+#include "base/Event.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/SegmentMatrixHelper.h"
+#include "base/Composition.h"
+#include "base/TriggerSegment.h"
+#include "document/BasicCommand.h"
+#include "gui/editors/notation/NotationProperties.h"
+#include "gui/editors/notation/NoteStyleFactory.h"
+#include "base/BaseProperties.h"
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+InsertTriggerNoteCommand::InsertTriggerNoteCommand(Segment &segment,
+ timeT time,
+ Note note,
+ int pitch,
+ int velocity,
+ NoteStyleName noteStyle,
+ TriggerSegmentId id,
+ bool retune,
+ std::string timeAdjust,
+ Mark mark) :
+ BasicCommand(i18n("Insert Trigger Note"), segment,
+ time, time + note.getDuration()),
+ m_time(time),
+ m_note(note),
+ m_pitch(pitch),
+ m_velocity(velocity),
+ m_noteStyle(noteStyle),
+ m_id(id),
+ m_retune(retune),
+ m_timeAdjust(timeAdjust),
+ m_mark(mark)
+{
+ // nothing
+}
+
+InsertTriggerNoteCommand::~InsertTriggerNoteCommand()
+{
+ // nothing
+}
+
+void
+InsertTriggerNoteCommand::modifySegment()
+{
+ // Insert via a model event, so as to apply the note style.
+ // This is a subset of the work done by NoteInsertionCommand
+
+ Event *e = new Event(Note::EventType, m_time, m_note.getDuration());
+
+ e->set
+ <Int>(PITCH, m_pitch);
+ e->set
+ <Int>(VELOCITY, m_velocity);
+
+ if (m_noteStyle != NoteStyleFactory::DefaultStyle) {
+ e->set
+ <String>(NotationProperties::NOTE_STYLE, m_noteStyle);
+ }
+
+ e->set
+ <Int>(TRIGGER_SEGMENT_ID, m_id);
+ e->set
+ <Bool>(TRIGGER_SEGMENT_RETUNE, m_retune);
+ e->set
+ <String>(TRIGGER_SEGMENT_ADJUST_TIMES, m_timeAdjust);
+
+ if (m_mark != Marks::NoMark) {
+ Marks::addMark(*e, m_mark, true);
+ }
+
+ Segment &s(getSegment());
+ Segment::iterator i = SegmentMatrixHelper(s).insertNote(e);
+
+ Segment::iterator j = i;
+ while (++j != s.end()) {
+ if ((*j)->getAbsoluteTime() >
+ (*i)->getAbsoluteTime() + (*i)->getDuration())
+ break;
+ if ((*j)->isa(Note::EventType)) {
+ if ((*j)->getAbsoluteTime() ==
+ (*i)->getAbsoluteTime() + (*i)->getDuration()) {
+ if ((*j)->has(TIED_BACKWARD) && (*j)->get
+ <Bool>(TIED_BACKWARD) &&
+ (*j)->has(PITCH) && ((*j)->get<Int>(PITCH) == m_pitch)) {
+ (*i)->set
+ <Bool>(TIED_FORWARD, true);
+ }
+ }
+ }
+ }
+
+ TriggerSegmentRec *rec =
+ getSegment().getComposition()->getTriggerSegmentRec(m_id);
+
+ if (rec)
+ rec->updateReferences();
+}
+
+}
diff --git a/src/commands/edit/InsertTriggerNoteCommand.h b/src/commands/edit/InsertTriggerNoteCommand.h
new file mode 100644
index 0000000..4dc1b19
--- /dev/null
+++ b/src/commands/edit/InsertTriggerNoteCommand.h
@@ -0,0 +1,78 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_INSERTTRIGGERNOTECOMMAND_H_
+#define _RG_INSERTTRIGGERNOTECOMMAND_H_
+
+#include "base/NotationTypes.h"
+#include "base/TriggerSegment.h"
+#include "document/BasicCommand.h"
+#include "gui/editors/notation/NoteStyle.h"
+#include <string>
+#include "base/Event.h"
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+
+
+class InsertTriggerNoteCommand : public BasicCommand
+{
+public:
+ InsertTriggerNoteCommand(Segment &,
+ timeT time,
+ Note note,
+ int pitch,
+ int velocity,
+ NoteStyleName noteStyle,
+ TriggerSegmentId id,
+ bool retune,
+ std::string timeAdjust,
+ Mark mark);
+ virtual ~InsertTriggerNoteCommand();
+
+protected:
+ virtual void modifySegment();
+
+ timeT m_time;
+ Note m_note;
+ int m_pitch;
+ int m_velocity;
+ NoteStyleName m_noteStyle;
+ TriggerSegmentId m_id;
+ bool m_retune;
+ std::string m_timeAdjust;
+ Mark m_mark;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/InvertCommand.cpp b/src/commands/edit/InvertCommand.cpp
new file mode 100644
index 0000000..053bcf9
--- /dev/null
+++ b/src/commands/edit/InvertCommand.cpp
@@ -0,0 +1,85 @@
+/* -*- 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 <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 "InvertCommand.h"
+
+#include "base/NotationTypes.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include "base/BaseProperties.h"
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+void
+InvertCommand::modifySegment()
+{
+ EventSelection::eventcontainer::iterator i;
+ long highestPitch, lowestPitch;
+
+ bool firstNote = true;
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+ try {
+ long pitch = (*i)->get
+ <Int>(PITCH);
+ if (firstNote) {
+ highestPitch = pitch;
+ lowestPitch = pitch;
+ firstNote = false;
+ } else {
+ if (pitch > highestPitch)
+ highestPitch = pitch;
+ else if (pitch < lowestPitch)
+ lowestPitch = pitch;
+ }
+ } catch (...) { }
+ }
+ }
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+ try {
+ long pitch = (*i)->get
+ <Int>(PITCH);
+ pitch = lowestPitch + (highestPitch - pitch);
+ pitch += m_semitones;
+ (*i)->set
+ <Int>(PITCH, pitch);
+ (*i)->unset(ACCIDENTAL);
+ } catch (...) { }
+ }
+ }
+}
+
+}
diff --git a/src/commands/edit/InvertCommand.h b/src/commands/edit/InvertCommand.h
new file mode 100644
index 0000000..5bea38d
--- /dev/null
+++ b/src/commands/edit/InvertCommand.h
@@ -0,0 +1,67 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_INVERTCOMMAND_H_
+#define _RG_INVERTCOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class InvertCommand : public BasicSelectionCommand
+{
+public:
+ InvertCommand(int semitones, EventSelection &selection) :
+ BasicSelectionCommand(getGlobalName(semitones), selection, true),
+ m_selection(&selection), m_semitones(semitones) { }
+
+ static QString getGlobalName(int semitones = 0) {
+ switch (semitones) {
+ default: return i18n("&Invert");
+ }
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ int m_semitones;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/ModifyMarkerCommand.cpp b/src/commands/edit/ModifyMarkerCommand.cpp
new file mode 100644
index 0000000..367f545
--- /dev/null
+++ b/src/commands/edit/ModifyMarkerCommand.cpp
@@ -0,0 +1,95 @@
+/* -*- 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 <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 "ModifyMarkerCommand.h"
+
+#include "base/Composition.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+ModifyMarkerCommand::ModifyMarkerCommand(Composition *comp,
+ int id,
+ timeT time,
+ timeT newTime,
+ const std::string &name,
+ const std::string &des):
+ KNamedCommand(getGlobalName()),
+ m_composition(comp),
+ m_id(id),
+ m_time(time),
+ m_newTime(newTime),
+ m_name(name),
+ m_description(des),
+ m_oldName(""),
+ m_oldDescription("")
+{}
+
+ModifyMarkerCommand::~ModifyMarkerCommand()
+{}
+
+void
+ModifyMarkerCommand::execute()
+{
+ Composition::markercontainer markers =
+ m_composition->getMarkers();
+
+ Composition::markerconstiterator it = markers.begin();
+
+ for (; it != markers.end(); ++it) {
+ if ((*it)->getID() == m_id) {
+ if (m_oldName.empty())
+ m_oldName = (*it)->getName();
+ if (m_oldDescription.empty())
+ m_oldDescription = (*it)->getDescription();
+
+ (*it)->setName(m_name);
+ (*it)->setDescription(m_description);
+ (*it)->setTime(m_newTime);
+ return ;
+ }
+ }
+}
+
+void
+ModifyMarkerCommand::unexecute()
+{
+ Composition::markercontainer markers =
+ m_composition->getMarkers();
+
+ Composition::markerconstiterator it = markers.begin();
+
+ for (; it != markers.end(); ++it) {
+ if ((*it)->getID() == m_id) {
+ (*it)->setName(m_oldName);
+ (*it)->setDescription(m_oldDescription);
+ (*it)->setTime(m_time);
+ }
+ }
+}
+
+}
diff --git a/src/commands/edit/ModifyMarkerCommand.h b/src/commands/edit/ModifyMarkerCommand.h
new file mode 100644
index 0000000..6a7e99f
--- /dev/null
+++ b/src/commands/edit/ModifyMarkerCommand.h
@@ -0,0 +1,78 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_MODIFYMARKERCOMMAND_H_
+#define _RG_MODIFYMARKERCOMMAND_H_
+
+#include <string>
+#include <kcommand.h>
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Composition;
+
+
+class ModifyMarkerCommand : public KNamedCommand
+{
+public:
+ ModifyMarkerCommand(Composition *comp,
+ int id,
+ timeT time,
+ timeT newTime,
+ const std::string &name,
+ const std::string &des);
+ ~ModifyMarkerCommand();
+
+ static QString getGlobalName() { return i18n("&Modify Marker"); }
+
+ virtual void execute();
+ virtual void unexecute();
+
+protected:
+
+ Composition *m_composition;
+ timeT m_time;
+ timeT m_newTime;
+
+ int m_id;
+ std::string m_name;
+ std::string m_description;
+ std::string m_oldName;
+ std::string m_oldDescription;
+
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/MoveAcrossSegmentsCommand.cpp b/src/commands/edit/MoveAcrossSegmentsCommand.cpp
new file mode 100644
index 0000000..3363d65
--- /dev/null
+++ b/src/commands/edit/MoveAcrossSegmentsCommand.cpp
@@ -0,0 +1,76 @@
+/* -*- 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 <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 "MoveAcrossSegmentsCommand.h"
+
+#include <klocale.h>
+#include "base/Clipboard.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "CutCommand.h"
+#include "PasteEventsCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+MoveAcrossSegmentsCommand::MoveAcrossSegmentsCommand(Segment &,
+ Segment &secondSegment,
+ timeT newStartTime,
+ bool notation,
+ EventSelection &selection) :
+ KMacroCommand(getGlobalName()),
+ m_clipboard(new Clipboard())
+{
+ addCommand(new CutCommand(selection, m_clipboard));
+
+ timeT newEndTime = newStartTime + selection.getEndTime() - selection.getStartTime();
+ Segment::iterator i = secondSegment.findTime(newEndTime);
+ if (i == secondSegment.end())
+ newEndTime = secondSegment.getEndTime();
+ else
+ newEndTime = (*i)->getAbsoluteTime();
+
+ addCommand(new PasteEventsCommand(secondSegment, m_clipboard,
+ newStartTime,
+ newEndTime,
+ notation ?
+ PasteEventsCommand::NoteOverlay :
+ PasteEventsCommand::MatrixOverlay));
+}
+
+MoveAcrossSegmentsCommand::~MoveAcrossSegmentsCommand()
+{
+ delete m_clipboard;
+}
+
+QString
+MoveAcrossSegmentsCommand::getGlobalName()
+{
+ return i18n("&Move Events to Other Segment");
+}
+
+}
diff --git a/src/commands/edit/MoveAcrossSegmentsCommand.h b/src/commands/edit/MoveAcrossSegmentsCommand.h
new file mode 100644
index 0000000..ac3ee39
--- /dev/null
+++ b/src/commands/edit/MoveAcrossSegmentsCommand.h
@@ -0,0 +1,63 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_MOVEACROSSSEGMENTSCOMMAND_H_
+#define _RG_MOVEACROSSSEGMENTSCOMMAND_H_
+
+#include <qstring.h>
+#include "base/Event.h"
+#include <kcommand.h>
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class EventSelection;
+class Clipboard;
+
+
+class MoveAcrossSegmentsCommand : public KMacroCommand
+{
+public:
+ MoveAcrossSegmentsCommand(Segment &firstSegment,
+ Segment &secondSegment,
+ timeT newStartTime,
+ bool notation,
+ EventSelection &selection);
+ virtual ~MoveAcrossSegmentsCommand();
+
+ static QString getGlobalName();
+
+private:
+ Clipboard *m_clipboard;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/MoveCommand.cpp b/src/commands/edit/MoveCommand.cpp
new file mode 100644
index 0000000..5df08a7
--- /dev/null
+++ b/src/commands/edit/MoveCommand.cpp
@@ -0,0 +1,159 @@
+/* -*- 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 <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 "MoveCommand.h"
+
+#include "misc/Debug.h"
+#include "base/Event.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/SegmentNotationHelper.h"
+#include "base/Selection.h"
+#include "document/BasicCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+MoveCommand::MoveCommand(Segment &s, timeT delta, bool useNotationTimings,
+ EventSelection &sel) :
+ BasicCommand(getGlobalName(), s,
+ delta < 0 ? sel.getStartTime() + delta : sel.getStartTime(),
+ delta < 0 ? sel.getEndTime() + 1 : sel.getEndTime() + 1 + delta,
+ true),
+ m_selection(&sel),
+ m_delta(delta),
+ m_useNotationTimings(useNotationTimings),
+ m_lastInsertedEvent(0)
+{
+ // nothing else
+}
+
+QString
+MoveCommand::getGlobalName(timeT delta)
+{
+ if (delta == 0) {
+ return "&Move Events";
+ } else if (delta < 0) {
+ return "&Move Events Back";
+ } else {
+ return "&Move Events Forward";
+ }
+}
+
+void
+MoveCommand::modifySegment()
+{
+ RG_DEBUG << "MoveCommand::modifySegment: delta is " << m_delta
+ << ", useNotationTimings " << m_useNotationTimings
+ << ", start time " << m_selection->getStartTime()
+ << ", end time " << m_selection->getEndTime() << endl;
+
+ std::vector<Event *> toErase;
+ std::vector<Event *> toInsert;
+
+ timeT a0 = m_selection->getStartTime();
+ timeT a1 = m_selection->getEndTime();
+ timeT b0 = a0 + m_delta;
+ timeT b1 = b0 + (a1 - a0);
+
+ EventSelection::eventcontainer::iterator i;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ RG_DEBUG << "MoveCommand::modifySegment: event at " << (*i)->getAbsoluteTime() << " type " << (*i)->getType() << endl;
+
+ if ((*i)->isa(Note::EventRestType))
+ continue;
+
+ toErase.push_back(*i);
+ timeT newTime =
+ (m_useNotationTimings ?
+ (*i)->getNotationAbsoluteTime() : (*i)->getAbsoluteTime()) + m_delta;
+
+ Event *e;
+ if (m_useNotationTimings) {
+ e = new Event(**i, newTime, (*i)->getDuration(), (*i)->getSubOrdering(),
+ newTime, (*i)->getNotationDuration());
+ } else {
+ e = new Event(**i, newTime);
+ }
+
+ toInsert.push_back(e);
+ }
+
+ Segment &segment(m_selection->getSegment());
+
+ for (unsigned int j = 0; j < toErase.size(); ++j) {
+ Segment::iterator jtr(segment.findSingle(toErase[j]));
+ if (jtr != segment.end()) {
+ RG_DEBUG << "found event " << j << endl;
+ segment.erase(jtr);
+ } else {
+ RG_DEBUG << "failed to find event " << j << endl;
+ }
+ }
+
+ for (unsigned int j = 0; j < toInsert.size(); ++j) {
+
+ Segment::iterator jtr = segment.end();
+
+ // somewhat like the NoteOverlay part of PasteEventsCommand::modifySegment
+ /* nah -- let's do a de-counterpoint afterwards perhaps
+ if (m_useNotationTimings && toInsert[j]->isa(Note::EventType)) {
+ long pitch = 0;
+ Accidental explicitAccidental = NoAccidental;
+ toInsert[j]->get<String>(ACCIDENTAL, explicitAccidental);
+ if (toInsert[j]->get<Int>(PITCH, pitch)) {
+ jtr = SegmentNotationHelper(segment).insertNote
+ (toInsert[j]->getAbsoluteTime(),
+ Note::getNearestNote(toInsert[j]->getDuration()),
+ pitch, explicitAccidental);
+ delete toInsert[j];
+ toInsert[j] = *jtr;
+ }
+ } else {
+ */
+ jtr = segment.insert(toInsert[j]);
+ // }
+
+ // insert new event back into selection
+ m_selection->addEvent(toInsert[j]);
+
+ if (jtr != segment.end())
+ m_lastInsertedEvent = toInsert[j];
+ }
+
+ if (m_useNotationTimings) {
+ SegmentNotationHelper(segment).deCounterpoint(b0, b1);
+ }
+
+ segment.normalizeRests(a0, a1);
+ segment.normalizeRests(b0, b1);
+}
+
+}
diff --git a/src/commands/edit/MoveCommand.h b/src/commands/edit/MoveCommand.h
new file mode 100644
index 0000000..79c0081
--- /dev/null
+++ b/src/commands/edit/MoveCommand.h
@@ -0,0 +1,69 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_MOVECOMMAND_H_
+#define _RG_MOVECOMMAND_H_
+
+#include "document/BasicCommand.h"
+#include <qstring.h>
+#include "base/Event.h"
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class EventSelection;
+class Event;
+
+
+class MoveCommand : public BasicCommand
+{
+public:
+ MoveCommand(Segment &segment,
+ timeT delta,
+ bool useNotationTimings,
+ EventSelection &selection);
+
+ static QString getGlobalName(timeT delta = 0);
+
+ Event *getLastInsertedEvent() { return m_lastInsertedEvent; }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ timeT m_delta;
+ bool m_useNotationTimings;
+ Event *m_lastInsertedEvent;
+};
+
+
+}
+
+#endif
diff --git a/src/commands/edit/PasteEventsCommand.cpp b/src/commands/edit/PasteEventsCommand.cpp
new file mode 100644
index 0000000..f6fd323
--- /dev/null
+++ b/src/commands/edit/PasteEventsCommand.cpp
@@ -0,0 +1,321 @@
+/* -*- 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 <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 "PasteEventsCommand.h"
+
+#include "misc/Debug.h"
+#include "base/Clipboard.h"
+#include "base/Event.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/SegmentNotationHelper.h"
+#include "document/BasicCommand.h"
+#include <qstring.h>
+#include "base/BaseProperties.h"
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+PasteEventsCommand::PasteEventsCommand(Segment &segment,
+ Clipboard *clipboard,
+ timeT pasteTime,
+ PasteType pasteType) :
+ BasicCommand(getGlobalName(), segment, pasteTime,
+ getEffectiveEndTime(segment, clipboard, pasteTime)),
+ m_relayoutEndTime(getEndTime()),
+ m_clipboard(new Clipboard(*clipboard)),
+ m_pasteType(pasteType),
+ m_pastedEvents(segment)
+{
+ if (pasteType != OpenAndPaste) {
+
+ // paste clef or key -> relayout to end
+
+ if (clipboard->isSingleSegment()) {
+
+ Segment *s(clipboard->getSingleSegment());
+ for (Segment::iterator i = s->begin(); i != s->end(); ++i) {
+ if ((*i)->isa(Clef::EventType) ||
+ (*i)->isa(Key::EventType)) {
+ m_relayoutEndTime = s->getEndTime();
+ break;
+ }
+ }
+ }
+ }
+}
+
+PasteEventsCommand::PasteEventsCommand(Segment &segment,
+ Clipboard *clipboard,
+ timeT pasteTime,
+ timeT pasteEndTime,
+ PasteType pasteType) :
+ BasicCommand(getGlobalName(), segment, pasteTime, pasteEndTime),
+ m_relayoutEndTime(getEndTime()),
+ m_clipboard(new Clipboard(*clipboard)),
+ m_pasteType(pasteType),
+ m_pastedEvents(segment)
+{}
+
+PasteEventsCommand::~PasteEventsCommand()
+{
+ delete m_clipboard;
+}
+
+PasteEventsCommand::PasteTypeMap
+
+PasteEventsCommand::getPasteTypes()
+{
+ static PasteTypeMap types;
+ static bool haveTypes = false;
+ if (!haveTypes) {
+ types[Restricted] =
+ i18n("Paste into an existing gap [\"restricted\"]");
+ types[Simple] =
+ i18n("Erase existing events to make room [\"simple\"]");
+ types[OpenAndPaste] =
+ i18n("Move existing events out of the way [\"open-n-paste\"]");
+ types[NoteOverlay] =
+ i18n("Overlay notes, tying against present notes [\"note-overlay\"]");
+ types[MatrixOverlay] =
+ i18n("Overlay notes, ignoring present notes [\"matrix-overlay\"]");
+ }
+ return types;
+}
+
+timeT
+PasteEventsCommand::getEffectiveEndTime(Segment &segment,
+ Clipboard *clipboard,
+ timeT pasteTime)
+{
+ if (!clipboard->isSingleSegment()) {
+ RG_DEBUG << "PasteEventsCommand::getEffectiveEndTime: not single segment" << endl;
+ return pasteTime;
+ }
+
+ RG_DEBUG << "PasteEventsCommand::getEffectiveEndTime: clipboard "
+ << clipboard->getSingleSegment()->getStartTime()
+ << " -> "
+ << clipboard->getSingleSegment()->getEndTime() << endl;
+
+ timeT d = clipboard->getSingleSegment()->getEndTime() -
+ clipboard->getSingleSegment()->getStartTime();
+
+ if (m_pasteType == OpenAndPaste) {
+ return segment.getEndTime() + d;
+ } else {
+ Segment::iterator i = segment.findTime(pasteTime + d);
+ if (i == segment.end())
+ return segment.getEndTime();
+ else
+ return (*i)->getAbsoluteTime();
+ }
+}
+
+timeT
+PasteEventsCommand::getRelayoutEndTime()
+{
+ return m_relayoutEndTime;
+}
+
+bool
+PasteEventsCommand::isPossible()
+{
+ if (m_clipboard->isEmpty() || !m_clipboard->isSingleSegment()) {
+ return false;
+ }
+
+ if (m_pasteType != Restricted) {
+ return true;
+ }
+
+ Segment *source = m_clipboard->getSingleSegment();
+
+ timeT pasteTime = getStartTime();
+ timeT origin = source->getStartTime();
+ timeT duration = source->getEndTime() - origin;
+
+ RG_DEBUG << "PasteEventsCommand::isPossible: paste time is " << pasteTime << ", origin is " << origin << ", duration is " << duration << endl;
+
+ SegmentNotationHelper helper(getSegment());
+ return helper.removeRests(pasteTime, duration, true);
+}
+
+void
+PasteEventsCommand::modifySegment()
+{
+ RG_DEBUG << "PasteEventsCommand::modifySegment" << endl;
+
+ if (!m_clipboard->isSingleSegment())
+ return ;
+
+ Segment *source = m_clipboard->getSingleSegment();
+
+ timeT pasteTime = getStartTime();
+ timeT origin = source->getStartTime();
+ timeT duration = source->getEndTime() - origin;
+
+ Segment *destination(&getSegment());
+ SegmentNotationHelper helper(*destination);
+
+ RG_DEBUG << "PasteEventsCommand::modifySegment() : paste type = "
+ << m_pasteType << " - pasteTime = "
+ << pasteTime << " - origin = " << origin << endl;
+
+ // First check for group IDs, which we want to make unique in the
+ // copies in the destination segment
+
+ std::map<long, long> groupIdMap;
+ for (Segment::iterator i = source->begin(); i != source->end(); ++i) {
+ long groupId = -1;
+ if ((*i)->get
+ <Int>(BEAMED_GROUP_ID, groupId)) {
+ if (groupIdMap.find(groupId) == groupIdMap.end()) {
+ groupIdMap[groupId] = destination->getNextId();
+ }
+ }
+ }
+
+ switch (m_pasteType) {
+
+ // Do some preliminary work to make space or whatever;
+ // we do the actual paste after this switch statement
+ // (except where individual cases do the work and return)
+
+ case Restricted:
+ if (!helper.removeRests(pasteTime, duration))
+ return ;
+ break;
+
+ case Simple:
+ destination->erase(destination->findTime(pasteTime),
+ destination->findTime(pasteTime + duration));
+ break;
+
+ case OpenAndPaste: {
+ std::vector<Event *> copies;
+ for (Segment::iterator i = destination->findTime(pasteTime);
+ i != destination->end(); ++i) {
+ Event *e = (*i)->copyMoving(duration);
+ if (e->has(BEAMED_GROUP_ID)) {
+ e->set
+ <Int>(BEAMED_GROUP_ID, groupIdMap[e->get
+ <Int>(BEAMED_GROUP_ID)]);
+ }
+ copies.push_back(e);
+ }
+
+ destination->erase(destination->findTime(pasteTime),
+ destination->end());
+
+ for (unsigned int i = 0; i < copies.size(); ++i) {
+ destination->insert(copies[i]);
+ m_pastedEvents.addEvent(copies[i]);
+ }
+
+ break;
+ }
+
+ case NoteOverlay:
+ for (Segment::iterator i = source->begin(); i != source->end(); ++i) {
+ if ((*i)->isa(Note::EventRestType))
+ continue;
+ Event *e = (*i)->copyMoving(pasteTime - origin);
+ if (e->has(BEAMED_GROUP_ID)) {
+ e->set<Int>(BEAMED_GROUP_ID,
+ groupIdMap[e->get<Int>(BEAMED_GROUP_ID)]);
+ }
+ if ((*i)->isa(Note::EventType)) {
+ // e is model event: we retain ownership of it
+ Segment::iterator i = helper.insertNote(e);
+ delete e;
+ if (i != destination->end()) m_pastedEvents.addEvent(*i);
+ } else {
+ destination->insert(e);
+ m_pastedEvents.addEvent(e);
+ }
+ }
+
+ return ;
+
+ case MatrixOverlay:
+
+ for (Segment::iterator i = source->begin(); i != source->end(); ++i) {
+
+ if ((*i)->isa(Note::EventRestType))
+ continue;
+
+ Event *e = (*i)->copyMoving(pasteTime - origin);
+
+ if (e->has(BEAMED_GROUP_TYPE) &&
+ e->get
+ <String>(BEAMED_GROUP_TYPE) == GROUP_TYPE_BEAMED) {
+ e->unset(BEAMED_GROUP_ID);
+ e->unset(BEAMED_GROUP_TYPE);
+ }
+
+ if (e->has(BEAMED_GROUP_ID)) {
+ e->set
+ <Int>(BEAMED_GROUP_ID, groupIdMap[e->get
+ <Int>(BEAMED_GROUP_ID)]);
+ }
+
+ destination->insert(e);
+ m_pastedEvents.addEvent(e);
+ }
+
+ destination->normalizeRests
+ (source->getStartTime(), source->getEndTime());
+
+ return ;
+ }
+
+ RG_DEBUG << "PasteEventsCommand::modifySegment() - inserting\n";
+
+ for (Segment::iterator i = source->begin(); i != source->end(); ++i) {
+ Event *e = (*i)->copyMoving(pasteTime - origin);
+ if (e->has(BEAMED_GROUP_ID)) {
+ e->set
+ <Int>(BEAMED_GROUP_ID, groupIdMap[e->get
+ <Int>(BEAMED_GROUP_ID)]);
+ }
+ destination->insert(e);
+ m_pastedEvents.addEvent(e);
+ }
+
+ destination->normalizeRests
+ (source->getStartTime(), source->getEndTime());
+}
+
+EventSelection
+PasteEventsCommand::getPastedEvents()
+{
+ return m_pastedEvents;
+}
+
+}
diff --git a/src/commands/edit/PasteEventsCommand.h b/src/commands/edit/PasteEventsCommand.h
new file mode 100644
index 0000000..3a26b25
--- /dev/null
+++ b/src/commands/edit/PasteEventsCommand.h
@@ -0,0 +1,112 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_PASTEEVENTSCOMMAND_H_
+#define _RG_PASTEEVENTSCOMMAND_H_
+
+#include "document/BasicCommand.h"
+#include "base/Selection.h"
+#include <map>
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class Clipboard;
+
+
+/// Paste from a single-segment clipboard to a segment
+
+class PasteEventsCommand : public BasicCommand
+{
+public:
+ enum PasteType {
+ Restricted, // paste into existing gap
+ Simple, // erase existing events to make room
+ OpenAndPaste, // bump up existing events to make room
+ NoteOverlay, // overlay and tie notation-style
+ MatrixOverlay // overlay raw matrix-style
+ };
+
+ typedef std::map<PasteType, QString> PasteTypeMap;
+ static PasteTypeMap getPasteTypes(); // type, descrip
+
+ /**
+ * Construct a Paste command from a clipboard that already contains
+ * the events to be pasted.
+ */
+ PasteEventsCommand(Segment &segment,
+ Clipboard *clipboard,
+ timeT pasteTime,
+ PasteType pasteType);
+
+ /**
+ * Construct a Paste command from a clipboard that will contain
+ * the events to be pasted by the time the Paste command is
+ * executed, but might not do so yet. This is necessary if the
+ * Paste command is to follow another clipboard-based command
+ * in a KMacroCommand sequence. pasteEndTime must supply the
+ * latest time in the destination segment that may be modified
+ * by the paste.
+ */
+ PasteEventsCommand(Segment &segment,
+ Clipboard *clipboard,
+ timeT pasteTime,
+ timeT pasteEndTime,
+ PasteType pasteType);
+
+ virtual ~PasteEventsCommand();
+
+ EventSelection getPastedEvents();
+
+ static QString getGlobalName() { return i18n("&Paste"); }
+
+ /// Determine whether this paste will succeed (without executing it yet)
+ bool isPossible();
+
+ virtual timeT getRelayoutEndTime();
+
+protected:
+ virtual void modifySegment();
+ timeT getEffectiveEndTime(Segment &,
+ Clipboard *,
+ timeT);
+ timeT m_relayoutEndTime;
+ Clipboard *m_clipboard;
+ PasteType m_pasteType;
+ EventSelection m_pastedEvents;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/PasteSegmentsCommand.cpp b/src/commands/edit/PasteSegmentsCommand.cpp
new file mode 100644
index 0000000..ab3372a
--- /dev/null
+++ b/src/commands/edit/PasteSegmentsCommand.cpp
@@ -0,0 +1,153 @@
+/* -*- 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 <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 "PasteSegmentsCommand.h"
+
+#include "base/Clipboard.h"
+#include "base/Composition.h"
+#include "base/Segment.h"
+#include "base/Track.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+PasteSegmentsCommand::PasteSegmentsCommand(Composition *composition,
+ Clipboard *clipboard,
+ timeT pasteTime,
+ TrackId baseTrack,
+ bool useExactTracks) :
+ KNamedCommand(getGlobalName()),
+ m_composition(composition),
+ m_clipboard(new Clipboard(*clipboard)),
+ m_pasteTime(pasteTime),
+ m_baseTrack(baseTrack),
+ m_exactTracks(useExactTracks),
+ m_detached(false)
+{
+ // nothing else
+}
+
+PasteSegmentsCommand::~PasteSegmentsCommand()
+{
+ if (m_detached) {
+ for (unsigned int i = 0; i < m_addedSegments.size(); ++i) {
+ delete m_addedSegments[i];
+ }
+ }
+
+ delete m_clipboard;
+}
+
+void
+PasteSegmentsCommand::execute()
+{
+ if (m_addedSegments.size() > 0) {
+ // been here before
+ for (unsigned int i = 0; i < m_addedSegments.size(); ++i) {
+ m_composition->addSegment(m_addedSegments[i]);
+ }
+ return ;
+ }
+
+ if (m_clipboard->isEmpty())
+ return ;
+
+ // We want to paste such that the earliest Segment starts at
+ // m_pasteTime and the others start at the same times relative to
+ // that as they did before. Likewise for track, unless
+ // m_exactTracks is set.
+
+ timeT earliestStartTime = m_clipboard->getBaseTime();
+ timeT latestEndTime = 0;
+ int lowestTrackPos = -1;
+
+ for (Clipboard::iterator i = m_clipboard->begin();
+ i != m_clipboard->end(); ++i) {
+
+ int trackPos = m_composition->getTrackPositionById((*i)->getTrack());
+ if (trackPos >= 0 &&
+ (lowestTrackPos < 0 || trackPos < lowestTrackPos)) {
+ lowestTrackPos = trackPos;
+ }
+
+ if ((*i)->getEndMarkerTime() > latestEndTime) {
+ latestEndTime = (*i)->getEndMarkerTime();
+ }
+ }
+
+ if (m_exactTracks)
+ lowestTrackPos = 0;
+ if (lowestTrackPos < 0)
+ lowestTrackPos = 0;
+ timeT offset = m_pasteTime - earliestStartTime;
+ int baseTrackPos = m_composition->getTrackPositionById(m_baseTrack);
+ int trackOffset = baseTrackPos - lowestTrackPos;
+
+ for (Clipboard::iterator i = m_clipboard->begin();
+ i != m_clipboard->end(); ++i) {
+
+ int newTrackPos = trackOffset +
+ m_composition->getTrackPositionById((*i)->getTrack());
+
+ Track *track = m_composition->getTrackByPosition(newTrackPos);
+
+ if (!track) {
+ newTrackPos = 0;
+ track = m_composition->getTrackByPosition(newTrackPos);
+ }
+
+ TrackId newTrackId = track->getId();
+
+ Segment *segment = new Segment(**i);
+ segment->setStartTime(segment->getStartTime() + offset);
+ segment->setTrack(newTrackId);
+ m_composition->addSegment(segment);
+ if (m_clipboard->isPartial()) {
+ segment->normalizeRests(segment->getStartTime(),
+ segment->getEndMarkerTime());
+ }
+ m_addedSegments.push_back(segment);
+ }
+
+ // User preference? Update song pointer position on paste
+ m_composition->setPosition(latestEndTime
+ + m_pasteTime
+ - earliestStartTime);
+
+ m_detached = false;
+}
+
+void
+PasteSegmentsCommand::unexecute()
+{
+ for (unsigned int i = 0; i < m_addedSegments.size(); ++i) {
+ m_composition->detachSegment(m_addedSegments[i]);
+ }
+ m_detached = true;
+}
+
+}
diff --git a/src/commands/edit/PasteSegmentsCommand.h b/src/commands/edit/PasteSegmentsCommand.h
new file mode 100644
index 0000000..3f45914
--- /dev/null
+++ b/src/commands/edit/PasteSegmentsCommand.h
@@ -0,0 +1,79 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_PASTESEGMENTSCOMMAND_H_
+#define _RG_PASTESEGMENTSCOMMAND_H_
+
+#include "base/Track.h"
+#include <kcommand.h>
+#include <qstring.h>
+#include <vector>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class Composition;
+class Clipboard;
+
+
+/// Paste one or more segments from the clipboard into the composition
+
+class PasteSegmentsCommand : public KNamedCommand
+{
+public:
+ PasteSegmentsCommand(Composition *composition,
+ Clipboard *clipboard,
+ timeT pasteTime,
+ TrackId baseTrack,
+ bool useExactTracks);
+
+ virtual ~PasteSegmentsCommand();
+
+ static QString getGlobalName() { return i18n("&Paste"); }
+
+ virtual void execute();
+ virtual void unexecute();
+
+protected:
+ Composition *m_composition;
+ Clipboard *m_clipboard;
+ timeT m_pasteTime;
+ TrackId m_baseTrack;
+ bool m_exactTracks;
+ std::vector<Segment *> m_addedSegments;
+ bool m_detached;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/RemoveMarkerCommand.cpp b/src/commands/edit/RemoveMarkerCommand.cpp
new file mode 100644
index 0000000..af3c839
--- /dev/null
+++ b/src/commands/edit/RemoveMarkerCommand.cpp
@@ -0,0 +1,83 @@
+/* -*- 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 <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 "RemoveMarkerCommand.h"
+
+#include "base/Composition.h"
+#include "base/Marker.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+RemoveMarkerCommand::RemoveMarkerCommand(Composition *comp,
+ int id,
+ timeT time,
+ const std::string &name,
+ const std::string &description):
+ KNamedCommand(getGlobalName()),
+ m_composition(comp),
+ m_marker(0),
+ m_id(id),
+ m_time(time),
+ m_name(name),
+ m_descr(description),
+ m_detached(false)
+{}
+
+RemoveMarkerCommand::~RemoveMarkerCommand()
+{
+ if (m_detached)
+ delete m_marker;
+}
+
+void
+RemoveMarkerCommand::execute()
+{
+ Composition::markercontainer markers =
+ m_composition->getMarkers();
+
+ Composition::markerconstiterator it = markers.begin();
+
+ for (; it != markers.end(); ++it) {
+ if ((*it)->getID() == m_id) {
+ m_marker = (*it);
+ m_composition->detachMarker(m_marker);
+ m_detached = true;
+ return ;
+ }
+ }
+}
+
+void
+RemoveMarkerCommand::unexecute()
+{
+ if (m_marker)
+ m_composition->addMarker(m_marker);
+ m_detached = false;
+}
+
+}
diff --git a/src/commands/edit/RemoveMarkerCommand.h b/src/commands/edit/RemoveMarkerCommand.h
new file mode 100644
index 0000000..2acaf53
--- /dev/null
+++ b/src/commands/edit/RemoveMarkerCommand.h
@@ -0,0 +1,75 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_REMOVEMARKERCOMMAND_H_
+#define _RG_REMOVEMARKERCOMMAND_H_
+
+#include <string>
+#include <kcommand.h>
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Marker;
+class Composition;
+
+
+class RemoveMarkerCommand : public KNamedCommand
+{
+public:
+ RemoveMarkerCommand(Composition *comp,
+ int id,
+ timeT time,
+ const std::string &name,
+ const std::string &description);
+ ~RemoveMarkerCommand();
+
+ static QString getGlobalName() { return i18n("&Remove Marker"); }
+
+ virtual void execute();
+ virtual void unexecute();
+
+protected:
+
+ Composition *m_composition;
+ Marker *m_marker;
+ int m_id;
+ timeT m_time;
+ std::string m_name;
+ std::string m_descr;
+ bool m_detached;
+
+};
+
+
+}
+
+#endif
diff --git a/src/commands/edit/RescaleCommand.cpp b/src/commands/edit/RescaleCommand.cpp
new file mode 100644
index 0000000..764969c
--- /dev/null
+++ b/src/commands/edit/RescaleCommand.cpp
@@ -0,0 +1,138 @@
+/* -*- 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 <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 "RescaleCommand.h"
+
+#include "base/Event.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "document/BasicCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+RescaleCommand::RescaleCommand(EventSelection &sel,
+ timeT newDuration,
+ bool closeGap) :
+ BasicCommand(getGlobalName(), sel.getSegment(),
+ sel.getStartTime(),
+ getAffectedEndTime(sel, newDuration, closeGap),
+ true),
+ m_selection(&sel),
+ m_oldDuration(sel.getTotalDuration()),
+ m_newDuration(newDuration),
+ m_closeGap(closeGap)
+{
+ // nothing else
+}
+
+timeT
+RescaleCommand::getAffectedEndTime(EventSelection &sel,
+ timeT newDuration,
+ bool closeGap)
+{
+ timeT preScaleEnd = sel.getEndTime();
+ if (closeGap)
+ preScaleEnd = sel.getSegment().getEndMarkerTime();
+
+ // dupe of rescale(), but we can't use that here as the m_
+ // variables may not have been set
+ double d = preScaleEnd;
+ d *= newDuration;
+ d /= sel.getTotalDuration();
+ d += 0.5;
+ timeT postScaleEnd = (timeT)d;
+
+ return std::max(preScaleEnd, postScaleEnd);
+}
+
+timeT
+RescaleCommand::rescale(timeT t)
+{
+ // avoid overflows by using doubles
+ double d = t;
+ d *= m_newDuration;
+ d /= m_oldDuration;
+ d += 0.5;
+ return (timeT)d;
+}
+
+void
+RescaleCommand::modifySegment()
+{
+ if (m_oldDuration == m_newDuration)
+ return ;
+
+ timeT startTime = m_selection->getStartTime();
+ timeT diff = m_newDuration - m_oldDuration;
+ std::vector<Event *> toErase;
+ std::vector<Event *> toInsert;
+
+ Segment &segment = m_selection->getSegment();
+
+ for (EventSelection::eventcontainer::iterator i =
+ m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ toErase.push_back(*i);
+
+ timeT t = (*i)->getAbsoluteTime() - startTime;
+ timeT d = (*i)->getDuration();
+ t = rescale(t);
+ d = rescale(d);
+
+ toInsert.push_back(new Event(**i, startTime + t, d));
+ }
+
+ if (m_closeGap) {
+ for (Segment::iterator i = segment.findTime(startTime + m_oldDuration);
+ i != segment.end(); ++i) {
+ // move all events including any following the end marker
+ toErase.push_back(*i);
+ toInsert.push_back((*i)->copyMoving(diff));
+ }
+ }
+
+ for (std::vector<Event *>::iterator i = toErase.begin(); i != toErase.end(); ++i) {
+ m_selection->removeEvent(*i); // remove from selection
+ segment.eraseSingle(*i);
+ }
+
+ for (std::vector<Event *>::iterator i = toInsert.begin(); i != toInsert.end(); ++i) {
+ segment.insert(*i);
+ m_selection->addEvent(*i); // add to selection
+ }
+
+ if (m_closeGap && diff > 0) {
+ segment.setEndMarkerTime(startTime +
+ rescale(segment.getEndMarkerTime() - startTime));
+ }
+
+ segment.normalizeRests(getStartTime(), getEndTime());
+}
+
+}
diff --git a/src/commands/edit/RescaleCommand.h b/src/commands/edit/RescaleCommand.h
new file mode 100644
index 0000000..362de24
--- /dev/null
+++ b/src/commands/edit/RescaleCommand.h
@@ -0,0 +1,71 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_RESCALECOMMAND_H_
+#define _RG_RESCALECOMMAND_H_
+
+#include "document/BasicCommand.h"
+#include <qstring.h>
+#include "base/Event.h"
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class RescaleCommand : public BasicCommand
+{
+public:
+ RescaleCommand(EventSelection &selection,
+ timeT newDuration,
+ bool closeGap);
+
+ static QString getGlobalName() { return i18n("Stretch or S&quash..."); }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ timeT rescale(timeT);
+ timeT getAffectedEndTime(EventSelection &selection,
+ timeT newDuration,
+ bool closeGap);
+
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ timeT m_oldDuration;
+ timeT m_newDuration;
+ bool m_closeGap;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/RetrogradeCommand.cpp b/src/commands/edit/RetrogradeCommand.cpp
new file mode 100644
index 0000000..955f066
--- /dev/null
+++ b/src/commands/edit/RetrogradeCommand.cpp
@@ -0,0 +1,121 @@
+/* -*- 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 <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 "RetrogradeCommand.h"
+
+#include "base/Event.h"
+#include "misc/Debug.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+void
+RetrogradeCommand::modifySegment()
+{
+ std::vector<Event *> toErase;
+ std::vector<Event *> toInsert;
+
+ timeT a0 = m_selection->getStartTime();
+ timeT a1 = m_selection->getEndTime();
+
+ EventSelection::eventcontainer::iterator i;
+
+ bool useNotationTimings = false;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ RG_DEBUG << "RetrogradeCommand::modifySegment: event at " << (*i)->getAbsoluteTime() << " type " << (*i)->getType() << endl;
+
+ if ((*i)->isa(Note::EventRestType))
+ continue;
+
+ toErase.push_back(*i);
+ timeT newTime = a0 + a1 - (*i)->getDuration() -
+ (useNotationTimings ?
+ (*i)->getNotationAbsoluteTime() : (*i)->getAbsoluteTime());
+
+ Event *e;
+ if (useNotationTimings) {
+ e = new Event(**i, newTime, (*i)->getDuration(), (*i)->getSubOrdering(),
+ newTime, (*i)->getNotationDuration());
+ } else {
+ e = new Event(**i, newTime);
+ }
+
+ toInsert.push_back(e);
+ }
+
+ Segment &segment(m_selection->getSegment());
+
+ for (unsigned int j = 0; j < toErase.size(); ++j) {
+ Segment::iterator jtr(segment.findSingle(toErase[j]));
+ if (jtr != segment.end()) {
+ RG_DEBUG << "found event " << j << endl;
+ segment.erase(jtr);
+ } else {
+ RG_DEBUG << "failed to find event " << j << endl;
+ }
+ }
+
+ for (unsigned int j = 0; j < toInsert.size(); ++j) {
+
+ Segment::iterator jtr = segment.end();
+
+ // somewhat like the NoteOverlay part of PasteEventsCommand::modifySegment
+ /* nah -- let's do a de-counterpoint afterwards perhaps
+ if (m_useNotationTimings && toInsert[j]->isa(Note::EventType)) {
+ long pitch = 0;
+ Accidental explicitAccidental = NoAccidental;
+ toInsert[j]->get<String>(ACCIDENTAL, explicitAccidental);
+ if (toInsert[j]->get<Int>(PITCH, pitch)) {
+ jtr = SegmentNotationHelper(segment).insertNote
+ (toInsert[j]->getAbsoluteTime(),
+ Note::getNearestNote(toInsert[j]->getDuration()),
+ pitch, explicitAccidental);
+ delete toInsert[j];
+ toInsert[j] = *jtr;
+ }
+ } else {
+ */
+ jtr = segment.insert(toInsert[j]);
+ // }
+
+ // insert new event back into selection
+ m_selection->addEvent(toInsert[j]);
+
+ // if (jtr != segment.end()) m_lastInsertedEvent = toInsert[j];
+ }
+
+ segment.normalizeRests(a0, a1);
+}
+
+}
diff --git a/src/commands/edit/RetrogradeCommand.h b/src/commands/edit/RetrogradeCommand.h
new file mode 100644
index 0000000..526a95d
--- /dev/null
+++ b/src/commands/edit/RetrogradeCommand.h
@@ -0,0 +1,67 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_RETROGRADECOMMAND_H_
+#define _RG_RETROGRADECOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class RetrogradeCommand : public BasicSelectionCommand
+{
+public:
+ RetrogradeCommand(int semitones, EventSelection &selection) :
+ BasicSelectionCommand(getGlobalName(semitones), selection, true),
+ m_selection(&selection), m_semitones(semitones) { }
+
+ static QString getGlobalName(int semitones = 0) {
+ switch (semitones) {
+ default: return i18n("&Retrograde");
+ }
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ int m_semitones;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/RetrogradeInvertCommand.cpp b/src/commands/edit/RetrogradeInvertCommand.cpp
new file mode 100644
index 0000000..3387c9b
--- /dev/null
+++ b/src/commands/edit/RetrogradeInvertCommand.cpp
@@ -0,0 +1,163 @@
+/* -*- 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 <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 "RetrogradeInvertCommand.h"
+
+#include "base/Event.h"
+#include "misc/Debug.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include "base/BaseProperties.h"
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+void
+RetrogradeInvertCommand::modifySegment()
+{
+ EventSelection::eventcontainer::iterator i;
+
+ long highestPitch, lowestPitch;
+
+ bool firstNote = true;
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+ try {
+ long pitch = (*i)->get
+ <Int>(PITCH);
+ if (firstNote) {
+ highestPitch = pitch;
+ lowestPitch = pitch;
+ firstNote = false;
+ } else {
+ if (pitch > highestPitch)
+ highestPitch = pitch;
+ else if (pitch < lowestPitch)
+ lowestPitch = pitch;
+ }
+ } catch (...) { }
+ }
+ }
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+ try {
+ long pitch = (*i)->get
+ <Int>(PITCH);
+ pitch = lowestPitch + (highestPitch - pitch);
+ pitch += m_semitones;
+ (*i)->set
+ <Int>(PITCH, pitch);
+ (*i)->unset(ACCIDENTAL);
+ } catch (...) { }
+ }
+ }
+ std::vector<Event *> toErase;
+ std::vector<Event *> toInsert;
+
+ timeT a0 = m_selection->getStartTime();
+ timeT a1 = m_selection->getEndTime();
+
+ bool useNotationTimings = false;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ RG_DEBUG << "RetrogradeCommand::modifySegment: event at " << (*i)->getAbsoluteTime() << " type " << (*i)->getType() << endl;
+
+ if ((*i)->isa(Note::EventRestType))
+ continue;
+
+ toErase.push_back(*i);
+ timeT newTime = a0 + a1 - (*i)->getDuration() -
+ (useNotationTimings ?
+ (*i)->getNotationAbsoluteTime() : (*i)->getAbsoluteTime());
+
+ Event *e;
+ if (useNotationTimings) {
+ e = new Event(**i, newTime, (*i)->getDuration(), (*i)->getSubOrdering(),
+ newTime, (*i)->getNotationDuration());
+ } else {
+ e = new Event(**i, newTime);
+ }
+
+ toInsert.push_back(e);
+ }
+
+ Segment &segment(m_selection->getSegment());
+
+ for (unsigned int j = 0; j < toErase.size(); ++j) {
+ Segment::iterator jtr(segment.findSingle(toErase[j]));
+ if (jtr != segment.end()) {
+ RG_DEBUG << "found event " << j << endl;
+ segment.erase(jtr);
+ } else {
+ RG_DEBUG << "failed to find event " << j << endl;
+ }
+ }
+
+ for (unsigned int j = 0; j < toInsert.size(); ++j) {
+
+ Segment::iterator jtr = segment.end();
+
+ // somewhat like the NoteOverlay part of PasteEventsCommand::modifySegment
+ /* nah -- let's do a de-counterpoint afterwards perhaps
+ if (m_useNotationTimings && toInsert[j]->isa(Note::EventType)) {
+ long pitch = 0;
+ Accidental explicitAccidental = NoAccidental;
+ toInsert[j]->get<String>(ACCIDENTAL, explicitAccidental);
+ if (toInsert[j]->get<Int>(PITCH, pitch)) {
+ jtr = SegmentNotationHelper(segment).insertNote
+ (toInsert[j]->getAbsoluteTime(),
+ Note::getNearestNote(toInsert[j]->getDuration()),
+ pitch, explicitAccidental);
+ delete toInsert[j];
+ toInsert[j] = *jtr;
+ }
+ } else {
+ */
+ jtr = segment.insert(toInsert[j]);
+ // }
+
+ // insert new event back into selection
+ m_selection->addEvent(toInsert[j]);
+
+ // if (jtr != segment.end()) m_lastInsertedEvent = toInsert[j];
+ }
+
+ segment.normalizeRests(a0, a1);
+}
+
+}
diff --git a/src/commands/edit/RetrogradeInvertCommand.h b/src/commands/edit/RetrogradeInvertCommand.h
new file mode 100644
index 0000000..ea7d540
--- /dev/null
+++ b/src/commands/edit/RetrogradeInvertCommand.h
@@ -0,0 +1,67 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_RETROGRADEINVERTCOMMAND_H_
+#define _RG_RETROGRADEINVERTCOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class RetrogradeInvertCommand : public BasicSelectionCommand
+{
+public:
+ RetrogradeInvertCommand(int semitones, EventSelection &selection) :
+ BasicSelectionCommand(getGlobalName(semitones), selection, true),
+ m_selection(&selection), m_semitones(semitones) { }
+
+ static QString getGlobalName(int semitones = 0) {
+ switch (semitones) {
+ default: return i18n("Re&trograde Invert");
+ }
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ int m_semitones;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/SelectionPropertyCommand.cpp b/src/commands/edit/SelectionPropertyCommand.cpp
new file mode 100644
index 0000000..3501e5b
--- /dev/null
+++ b/src/commands/edit/SelectionPropertyCommand.cpp
@@ -0,0 +1,128 @@
+/* -*- 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 <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 "SelectionPropertyCommand.h"
+
+#include "base/Event.h"
+#include "base/PropertyName.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+SelectionPropertyCommand::SelectionPropertyCommand(
+ EventSelection *selection,
+ const PropertyName &property,
+ PropertyPattern pattern,
+ int value1,
+ int value2):
+ BasicSelectionCommand(getGlobalName(), *selection, true),
+ m_selection(selection),
+ m_property(property),
+ m_pattern(pattern),
+ m_value1(value1),
+ m_value2(value2)
+{}
+
+void
+SelectionPropertyCommand::modifySegment()
+{
+ EventSelection::eventcontainer::iterator i =
+ m_selection->getSegmentEvents().begin();
+
+ int count = 0;
+
+ timeT endTime = 0;
+ timeT startTime = 0;
+ bool haveStart = false, haveEnd = false;
+
+ // Get start and end times
+ //
+ for (;i != m_selection->getSegmentEvents().end(); ++i) {
+ if ((*i)->getAbsoluteTime() < startTime || !haveStart) {
+ startTime = (*i)->getAbsoluteTime();
+ haveStart = true;
+ }
+
+ if ((*i)->getAbsoluteTime() > endTime || !haveEnd) {
+ endTime = (*i)->getAbsoluteTime();
+ haveEnd = true;
+ }
+ }
+
+ double step = double(m_value1 - m_value2) / double(endTime - startTime);
+ double lowStep = double(m_value2) / double(endTime - startTime);
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+ // flat
+ if (m_pattern == FlatPattern)
+ (*i)->set
+ <Int>(m_property, m_value1);
+ else if (m_pattern == AlternatingPattern) {
+ if (count % 2 == 0)
+ (*i)->set
+ <Int>(m_property, m_value1);
+ else
+ (*i)->set
+ <Int>(m_property, m_value2);
+
+ // crescendo, decrescendo
+ // (determined by step, above, which is in turn influenced by whether
+ // value1 is greater than value2)
+ } else if ((m_pattern == CrescendoPattern) ||
+ (m_pattern == DecrescendoPattern)) {
+ (*i)->set
+ <Int>(m_property,
+ m_value1 -
+ int(step *
+ ((*i)->getAbsoluteTime() - startTime)));
+ // ringing
+ } else if (m_pattern == RingingPattern) {
+ if (count % 2 == 0)
+ (*i)->set
+ <Int>
+ (m_property,
+ m_value1 - int(step *
+ ((*i)->getAbsoluteTime() - startTime)));
+ else {
+ int value = m_value2 - int(lowStep *
+ ((*i)->getAbsoluteTime() - startTime));
+ if (value < 0)
+ value = 0;
+
+ (*i)->set
+ <Int>(m_property, value);
+ }
+ }
+
+ count++;
+ }
+}
+
+}
diff --git a/src/commands/edit/SelectionPropertyCommand.h b/src/commands/edit/SelectionPropertyCommand.h
new file mode 100644
index 0000000..34c5352
--- /dev/null
+++ b/src/commands/edit/SelectionPropertyCommand.h
@@ -0,0 +1,82 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_SELECTIONPROPERTYCOMMAND_H_
+#define _RG_SELECTIONPROPERTYCOMMAND_H_
+
+#include "base/PropertyName.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+class Set;
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+// Patterns of properties
+//
+typedef enum
+{
+ FlatPattern, // set selection to velocity 1.
+ AlternatingPattern, // alternate between velocity 1 and 2 on
+ // subsequent events.
+ CrescendoPattern, // increasing from velocity 1 to velocity 2.
+ DecrescendoPattern, // decreasing from velocity 1 to velocity 2.
+ RingingPattern // between velocity 1 and 2, dying away.
+} PropertyPattern;
+
+
+class SelectionPropertyCommand : public BasicSelectionCommand
+{
+public:
+
+ SelectionPropertyCommand(EventSelection *selection,
+ const PropertyName &property,
+ PropertyPattern pattern,
+ int value1,
+ int value2);
+
+ static QString getGlobalName() { return i18n("Set &Property"); }
+
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;
+ PropertyName m_property;
+ PropertyPattern m_pattern;
+ int m_value1;
+ int m_value2;
+
+};
+
+
+}
+
+#endif
diff --git a/src/commands/edit/SetLyricsCommand.cpp b/src/commands/edit/SetLyricsCommand.cpp
new file mode 100644
index 0000000..16f5be4
--- /dev/null
+++ b/src/commands/edit/SetLyricsCommand.cpp
@@ -0,0 +1,192 @@
+/* -*- 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 <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 "SetLyricsCommand.h"
+
+#include "base/Event.h"
+#include "misc/Strings.h"
+#include "misc/Debug.h"
+#include "base/Composition.h"
+#include "base/NotationTypes.h"
+#include "base/Segment.h"
+#include "base/BaseProperties.h"
+#include <qregexp.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+
+SetLyricsCommand::SetLyricsCommand(Segment *segment, int verse, QString newLyricData) :
+ KNamedCommand(getGlobalName()),
+ m_segment(segment),
+ m_verse(verse),
+ m_newLyricData(newLyricData)
+{
+ // nothing
+}
+
+SetLyricsCommand::~SetLyricsCommand()
+{
+ for (std::vector<Event *>::iterator i = m_oldLyricEvents.begin();
+ i != m_oldLyricEvents.end(); ++i) {
+ delete *i;
+ }
+}
+
+void
+SetLyricsCommand::execute()
+{
+ // This and LyricEditDialog::unparse() are opposites that will
+ // need to be kept in sync with any changes to one another. (They
+ // should really both be in a common lyric management class.)
+
+ // first remove old lyric events
+
+ Segment::iterator i = m_segment->begin();
+
+ while (i != m_segment->end()) {
+
+ Segment::iterator j = i;
+ ++j;
+
+ if ((*i)->isa(Text::EventType)) {
+ std::string textType;
+ if ((*i)->get<String>(Text::TextTypePropertyName, textType) &&
+ textType == Text::Lyric) {
+ long verse = 0;
+ (*i)->get<Int>(Text::LyricVersePropertyName, verse);
+ if (verse == m_verse) {
+ m_oldLyricEvents.push_back(new Event(**i));
+ m_segment->erase(i);
+ }
+ }
+ }
+
+ i = j;
+ }
+
+ // now parse the new string
+
+ QStringList barStrings =
+ QStringList::split("/", m_newLyricData, true); // empties ok
+
+ Composition *comp = m_segment->getComposition();
+ int barNo = comp->getBarNumber(m_segment->getStartTime());
+
+ for (QStringList::Iterator bsi = barStrings.begin();
+ bsi != barStrings.end(); ++bsi) {
+
+ NOTATION_DEBUG << "Parsing lyrics for bar number " << barNo << ": \"" << *bsi << "\"" << endl;
+
+ std::pair<timeT, timeT> barRange = comp->getBarRange(barNo++);
+ QString syllables = *bsi;
+ syllables.replace(QRegExp("\\[\\d+\\] "), " ");
+ QStringList syllableList = QStringList::split(" ", syllables); // no empties
+
+ i = m_segment->findTime(barRange.first);
+ timeT laterThan = barRange.first - 1;
+
+ for (QStringList::Iterator ssi = syllableList.begin();
+ ssi != syllableList.end(); ++ssi) {
+
+ while (m_segment->isBeforeEndMarker(i) &&
+ (*i)->getAbsoluteTime() < barRange.second &&
+ (!(*i)->isa(Note::EventType) ||
+ (*i)->getNotationAbsoluteTime() <= laterThan ||
+ ((*i)->has(TIED_BACKWARD) &&
+ (*i)->get
+ <Bool>(TIED_BACKWARD)))) ++i;
+
+ timeT time = m_segment->getEndMarkerTime();
+ timeT notationTime = time;
+ if (m_segment->isBeforeEndMarker(i)) {
+ time = (*i)->getAbsoluteTime();
+ notationTime = (*i)->getNotationAbsoluteTime();
+ }
+
+ QString syllable = *ssi;
+ syllable.replace(QRegExp("~"), " ");
+ syllable = syllable.simplifyWhiteSpace();
+ if (syllable == "")
+ continue;
+ laterThan = notationTime + 1;
+ if (syllable == ".")
+ continue;
+
+ NOTATION_DEBUG << "Syllable \"" << syllable << "\" at time " << time << endl;
+
+ Text text(qstrtostr(syllable), Text::Lyric);
+ Event *event = text.getAsEvent(time);
+ event->set<Int>(Text::LyricVersePropertyName, m_verse);
+ m_segment->insert(event);
+ }
+ }
+}
+
+void
+SetLyricsCommand::unexecute()
+{
+ // Before we inserted the new lyric events (in execute()), we
+ // removed all the existing ones. That means we know any lyric
+ // events found now must have been inserted by execute(), so we
+ // can safely remove them before restoring the old ones.
+
+ Segment::iterator i = m_segment->begin();
+
+ while (i != m_segment->end()) {
+
+ Segment::iterator j = i;
+ ++j;
+
+ if ((*i)->isa(Text::EventType)) {
+ std::string textType;
+ if ((*i)->get<String>(Text::TextTypePropertyName, textType) &&
+ textType == Text::Lyric) {
+ long verse = 0;
+ (*i)->get<Int>(Text::LyricVersePropertyName, verse);
+ if (verse == m_verse) {
+ m_segment->erase(i);
+ }
+ }
+ }
+
+ i = j;
+ }
+
+ // Now restore the old ones and clear out the vector.
+
+ for (std::vector<Event *>::iterator i = m_oldLyricEvents.begin();
+ i != m_oldLyricEvents.end(); ++i) {
+ m_segment->insert(*i);
+ }
+
+ m_oldLyricEvents.clear();
+}
+
+}
diff --git a/src/commands/edit/SetLyricsCommand.h b/src/commands/edit/SetLyricsCommand.h
new file mode 100644
index 0000000..499f12a
--- /dev/null
+++ b/src/commands/edit/SetLyricsCommand.h
@@ -0,0 +1,66 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_SETLYRICSCOMMAND_H_
+#define _RG_SETLYRICSCOMMAND_H_
+
+#include <kcommand.h>
+#include <qstring.h>
+#include <vector>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class Segment;
+class Event;
+
+
+class SetLyricsCommand : public KNamedCommand
+{
+public:
+ SetLyricsCommand(Segment *segment, int verse, QString newLyricData);
+ ~SetLyricsCommand();
+
+ static QString getGlobalName() { return i18n("Edit L&yrics"); }
+
+ virtual void execute();
+ virtual void unexecute();
+
+private:
+ Segment *m_segment;
+ int m_verse;
+ std::vector<Event *> m_oldLyricEvents;
+ QString m_newLyricData;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/SetNoteTypeCommand.cpp b/src/commands/edit/SetNoteTypeCommand.cpp
new file mode 100644
index 0000000..4dc97b1
--- /dev/null
+++ b/src/commands/edit/SetNoteTypeCommand.cpp
@@ -0,0 +1,87 @@
+/* -*- 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 <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 "SetNoteTypeCommand.h"
+
+#include "base/Event.h"
+#include "base/NotationTypes.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+void
+SetNoteTypeCommand::modifySegment()
+{
+ std::vector<Event *> toErase;
+ std::vector<Event *> toInsert;
+
+ EventSelection::eventcontainer::iterator i;
+ timeT endTime = getEndTime();
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+ toErase.push_back(*i);
+
+ Event *e;
+ if (m_notationOnly) {
+ e = new Event(**i,
+ (*i)->getAbsoluteTime(),
+ (*i)->getDuration(),
+ (*i)->getSubOrdering(),
+ (*i)->getNotationAbsoluteTime(),
+ Note(m_type).getDuration());
+ } else {
+ e = new Event(**i,
+ (*i)->getNotationAbsoluteTime(),
+ Note(m_type).getDuration());
+ }
+
+ if (e->getNotationAbsoluteTime() + e->getNotationDuration() > endTime) {
+ endTime = e->getNotationAbsoluteTime() + e->getNotationDuration();
+ }
+
+ toInsert.push_back(e);
+ }
+ }
+
+ for (std::vector<Event *>::iterator i = toErase.begin(); i != toErase.end(); ++i) {
+ m_selection->getSegment().eraseSingle(*i);
+ }
+
+ for (std::vector<Event *>::iterator i = toInsert.begin(); i != toInsert.end(); ++i) {
+ m_selection->getSegment().insert(*i);
+ m_selection->addEvent(*i);
+ }
+
+ m_selection->getSegment().normalizeRests(getStartTime(), endTime);
+}
+
+}
diff --git a/src/commands/edit/SetNoteTypeCommand.h b/src/commands/edit/SetNoteTypeCommand.h
new file mode 100644
index 0000000..eec4a4c
--- /dev/null
+++ b/src/commands/edit/SetNoteTypeCommand.h
@@ -0,0 +1,72 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_SETNOTETYPECOMMAND_H_
+#define _RG_SETNOTETYPECOMMAND_H_
+
+#include "base/NotationTypes.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class SetNoteTypeCommand : public BasicSelectionCommand
+{
+public:
+ SetNoteTypeCommand(EventSelection &selection,
+ Note::Type type,
+ bool notationOnly) :
+ BasicSelectionCommand(getGlobalName(), selection, true),
+ m_selection(&selection),
+ m_type(type),
+ m_notationOnly(notationOnly)
+ { }
+
+ static QString getGlobalName() {
+ return i18n("&Set Note Type");
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ Note::Type m_type;
+ bool m_notationOnly;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/SetTriggerCommand.cpp b/src/commands/edit/SetTriggerCommand.cpp
new file mode 100644
index 0000000..861796e
--- /dev/null
+++ b/src/commands/edit/SetTriggerCommand.cpp
@@ -0,0 +1,74 @@
+/* -*- 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 <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 "SetTriggerCommand.h"
+
+#include "base/NotationTypes.h"
+#include "base/Selection.h"
+#include "base/TriggerSegment.h"
+#include "document/BasicSelectionCommand.h"
+#include "base/BaseProperties.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+using namespace BaseProperties;
+
+void
+SetTriggerCommand::modifySegment()
+{
+ EventSelection::eventcontainer::iterator i;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if (!m_notesOnly || (*i)->isa(Note::EventType)) {
+ (*i)->set
+ <Int>(TRIGGER_SEGMENT_ID, m_triggerSegmentId);
+ (*i)->set
+ <Bool>(TRIGGER_SEGMENT_RETUNE, m_retune);
+ (*i)->set
+ <String>(TRIGGER_SEGMENT_ADJUST_TIMES, m_timeAdjust);
+ if (m_mark != Marks::NoMark) {
+ Marks::addMark(**i, m_mark, true);
+ }
+ }
+ }
+
+ // Update the rec references here, without bothering to do so in unexecute
+ // or in ClearTriggersCommand -- because it doesn't matter if a trigger
+ // has references to segments that don't actually trigger it, whereas it
+ // does matter if it loses a reference to something that does
+
+ TriggerSegmentRec *rec =
+ m_selection->getSegment().getComposition()->getTriggerSegmentRec
+ (m_triggerSegmentId);
+
+ if (rec)
+ rec->updateReferences();
+}
+
+}
diff --git a/src/commands/edit/SetTriggerCommand.h b/src/commands/edit/SetTriggerCommand.h
new file mode 100644
index 0000000..579bb61
--- /dev/null
+++ b/src/commands/edit/SetTriggerCommand.h
@@ -0,0 +1,83 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_SETTRIGGERCOMMAND_H_
+#define _RG_SETTRIGGERCOMMAND_H_
+
+#include "base/TriggerSegment.h"
+#include "document/BasicSelectionCommand.h"
+#include <string>
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class SetTriggerCommand : public BasicSelectionCommand
+{
+public:
+ SetTriggerCommand(EventSelection &selection,
+ TriggerSegmentId triggerSegmentId,
+ bool notesOnly,
+ bool retune,
+ std::string timeAdjust,
+ Mark mark,
+ QString name = 0) :
+ BasicSelectionCommand(name ? name : getGlobalName(), selection, true),
+ m_selection(&selection),
+ m_triggerSegmentId(triggerSegmentId),
+ m_notesOnly(notesOnly),
+ m_retune(retune),
+ m_timeAdjust(timeAdjust),
+ m_mark(mark)
+ { }
+
+ static QString getGlobalName() {
+ return i18n("Tri&gger Segment");
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ TriggerSegmentId m_triggerSegmentId;
+ bool m_notesOnly;
+ bool m_retune;
+ std::string m_timeAdjust;
+ Mark m_mark;
+};
+
+
+
+}
+
+#endif
diff --git a/src/commands/edit/TransposeCommand.cpp b/src/commands/edit/TransposeCommand.cpp
new file mode 100644
index 0000000..4d08079
--- /dev/null
+++ b/src/commands/edit/TransposeCommand.cpp
@@ -0,0 +1,83 @@
+/* -*- 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 <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 "TransposeCommand.h"
+
+#include <iostream>
+#include "base/NotationTypes.h"
+#include "base/Selection.h"
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include "base/BaseProperties.h"
+
+
+namespace Rosegarden
+{
+
+using namespace BaseProperties;
+using namespace Accidentals;
+
+void
+TransposeCommand::modifySegment()
+{
+ EventSelection::eventcontainer::iterator i;
+
+ for (i = m_selection->getSegmentEvents().begin();
+ i != m_selection->getSegmentEvents().end(); ++i) {
+
+ if ((*i)->isa(Note::EventType)) {
+
+ if (m_diatonic)
+ {
+
+ Pitch oldPitch(**i);
+
+ timeT noteTime = (*i)->getAbsoluteTime();
+ Key key = m_selection->getSegment().getKeyAtTime(noteTime);
+ Pitch newPitch = oldPitch.transpose(key, m_semitones, m_steps);
+ Event * newNoteEvent = newPitch.getAsNoteEvent(0, 0);
+ Accidental newAccidental;
+ newNoteEvent->get<String>(BaseProperties::ACCIDENTAL, newAccidental);
+
+ (*i)->set<Int>(PITCH, newPitch.getPerformancePitch());
+ (*i)->set<String>(ACCIDENTAL, newAccidental);
+ }
+ else
+ {
+ try {
+ long pitch = (*i)->get<Int>(PITCH);
+ pitch += m_semitones;
+ (*i)->set<Int>(PITCH, pitch);
+ if ((m_semitones % 12) != 0) {
+ (*i)->unset(ACCIDENTAL);
+ }
+ } catch (...) { }
+ }
+
+ }
+ }
+}
+
+}
diff --git a/src/commands/edit/TransposeCommand.h b/src/commands/edit/TransposeCommand.h
new file mode 100644
index 0000000..764f72b
--- /dev/null
+++ b/src/commands/edit/TransposeCommand.h
@@ -0,0 +1,83 @@
+
+/* -*- 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 <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.
+*/
+
+#ifndef _RG_TRANSPOSECOMMAND_H_
+#define _RG_TRANSPOSECOMMAND_H_
+
+#include "document/BasicSelectionCommand.h"
+#include <qstring.h>
+#include <klocale.h>
+
+
+
+
+namespace Rosegarden
+{
+
+class EventSelection;
+
+
+class TransposeCommand : public BasicSelectionCommand
+{
+public:
+ TransposeCommand(int semitones, EventSelection &selection) :
+ BasicSelectionCommand(getGlobalName(semitones), selection, true),
+ m_selection(&selection), m_semitones(semitones), m_diatonic(false) { }
+
+ TransposeCommand(int semitones, int steps, EventSelection &selection) :
+ BasicSelectionCommand(getDiatonicGlobalName(semitones, steps), selection, true),
+ m_selection(&selection), m_semitones(semitones), m_steps(steps), m_diatonic(true) { }
+
+ static QString getDiatonicGlobalName(int semitones = 0, int step = 0) {
+ switch (semitones) {
+ default: return i18n("Transpose by &Interval...");
+ }
+ }
+
+ static QString getGlobalName(int semitones = 0) {
+ switch (semitones) {
+ case 1: return i18n("&Up a Semitone");
+ case -1: return i18n("&Down a Semitone");
+ case 12: return i18n("Up an &Octave");
+ case -12: return i18n("Down an Octa&ve");
+ default: return i18n("&Transpose by Semitones...");
+ }
+ }
+
+protected:
+ virtual void modifySegment();
+
+private:
+ EventSelection *m_selection;// only used on 1st execute (cf bruteForceRedo)
+ int m_semitones;
+ int m_steps;
+ bool m_diatonic;
+};
+
+
+
+}
+
+#endif