diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/commands/edit | |
download | rosegarden-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')
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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + + +#include "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 <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + The moral rights of Guillaume Laurent, Chris Cannam, and Richard + Bown to claim authorship of this work have been asserted. + + Other copyrights also apply to some parts of this work. Please + see the AUTHORS file and individual file headers for details. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#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 |