From: <ygu...@us...> - 2008-05-28 20:45:04
|
Revision: 8895 http://rosegarden.svn.sourceforge.net/rosegarden/?rev=8895&view=rev Author: yguillemot Date: 2008-05-28 13:44:47 -0700 (Wed, 28 May 2008) Log Message: ----------- Fix bug #1961378 : Crash when cutting a range. Modified Paths: -------------- trunk/rosegarden/src/GUIFileList.txt trunk/rosegarden/src/commands/segment/DeleteRangeCommand.cpp trunk/rosegarden/src/commands/segment/DeleteRangeCommand.h trunk/rosegarden/src/commands/segment/SegmentSplitCommand.h Added Paths: ----------- trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.cpp trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.h Modified: trunk/rosegarden/src/GUIFileList.txt =================================================================== --- trunk/rosegarden/src/GUIFileList.txt 2008-05-20 15:09:53 UTC (rev 8894) +++ trunk/rosegarden/src/GUIFileList.txt 2008-05-28 20:44:47 UTC (rev 8895) @@ -271,6 +271,8 @@ commands/segment/SegmentSplitByRecordingSrcCommand.h commands/segment/SegmentSplitCommand.cpp commands/segment/SegmentSplitCommand.h + commands/segment/SegmentSplitTwiceCommand.cpp + commands/segment/SegmentSplitTwiceCommand.h commands/segment/SegmentSyncClefCommand.cpp commands/segment/SegmentSyncClefCommand.h commands/segment/SegmentSyncCommand.cpp Modified: trunk/rosegarden/src/commands/segment/DeleteRangeCommand.cpp =================================================================== --- trunk/rosegarden/src/commands/segment/DeleteRangeCommand.cpp 2008-05-20 15:09:53 UTC (rev 8894) +++ trunk/rosegarden/src/commands/segment/DeleteRangeCommand.cpp 2008-05-28 20:44:47 UTC (rev 8895) @@ -33,6 +33,7 @@ #include "OpenOrCloseRangeCommand.h" #include "SegmentJoinCommand.h" #include "SegmentSplitCommand.h" +#include "SegmentSplitTwiceCommand.h" namespace Rosegarden @@ -46,8 +47,9 @@ // segments that will need rejoining with their neighbours // afterwards. - std::vector<Segment *> rejoins; + RejoinCommand *rejoinCommand = new RejoinCommand(); + // Audio segments first for (int e = 0; e < 2; ++e) { // Split all segments at the range end first, then the range @@ -69,59 +71,78 @@ if ((*i)->getType() == Segment::Audio) { addCommand(new AudioSegmentSplitCommand(*i, t)); - } else { - addCommand(new SegmentSplitCommand(*i, t)); - - if (t == t0 && (*i)->getEndMarkerTime() > t1) { - rejoins.push_back(*i); - } } } } + + // then non audio segments + for (Composition::iterator i = composition->begin(); + i != composition->end(); ++i) { + + // Split twice all segments at the range limits. + // The first and last from the three resulting segments are + // added to the rejoinCommand to be rejoined later. + + if ((*i)->getStartTime() >= t1 || (*i)->getEndMarkerTime() <= t0) { + continue; + } + + if ((*i)->getType() != Segment::Audio) { + addCommand(new SegmentSplitTwiceCommand(*i, t0, t1, rejoinCommand)); + } + } + + // Then commands to do the rest of the work addCommand(new EraseSegmentsStartingInRangeCommand(composition, t0, t1)); addCommand(new OpenOrCloseRangeCommand(composition, t0, t1, false)); - for (std::vector<Segment *>::iterator i = rejoins.begin(); - i != rejoins.end(); ++i) { - addCommand(new RejoinCommand(composition, *i, - (*i)->getEndMarkerTime() + t0 - t1)); - } + addCommand(rejoinCommand); + } DeleteRangeCommand::~DeleteRangeCommand() -{} +{ +} + +DeleteRangeCommand::RejoinCommand::~RejoinCommand() +{ + for (std::vector<SegmentJoinCommand *>::iterator i = m_rejoins.begin(); + i != m_rejoins.end(); ++i) { + delete *i; + } +} + void DeleteRangeCommand::RejoinCommand::execute() { - if (m_joinCommand) { - m_joinCommand->execute(); - return ; + for (std::vector<SegmentJoinCommand *>::iterator i = m_rejoins.begin(); + i != m_rejoins.end(); ++i) { + (*i)->execute(); } +} - //!!! Need to remove the "(split)" names from the segment bits - - for (Composition::iterator i = m_composition->begin(); - i != m_composition->end(); ++i) { - if ((*i) == m_segment) - continue; - if ((*i)->getTrack() != m_segment->getTrack()) - continue; - if ((*i)->getEndMarkerTime() != m_endMarkerTime) - continue; - if ((*i)->getStartTime() <= m_segment->getStartTime()) - continue; - SegmentSelection selection; - selection.insert(m_segment); - selection.insert(*i); - m_joinCommand = new SegmentJoinCommand(selection); - m_joinCommand->execute(); - break; +void +DeleteRangeCommand::RejoinCommand::unexecute() +{ + for (std::vector<SegmentJoinCommand *>::iterator i = m_rejoins.begin(); + i != m_rejoins.end(); ++i) { + (*i)->unexecute(); } } +void +DeleteRangeCommand::RejoinCommand::addSegmentsPair(Segment *s1, Segment *s2) +{ + SegmentSelection selection; + selection.insert(s1); + selection.insert(s2); + SegmentJoinCommand *joinCommand = new SegmentJoinCommand(selection); + m_rejoins.push_back(joinCommand); } + +} Modified: trunk/rosegarden/src/commands/segment/DeleteRangeCommand.h =================================================================== --- trunk/rosegarden/src/commands/segment/DeleteRangeCommand.h 2008-05-20 15:09:53 UTC (rev 8894) +++ trunk/rosegarden/src/commands/segment/DeleteRangeCommand.h 2008-05-28 20:44:47 UTC (rev 8895) @@ -1,4 +1,3 @@ - /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* @@ -48,32 +47,33 @@ timeT end); virtual ~DeleteRangeCommand(); -private: + class RejoinCommand : public KNamedCommand { public: - // This command rejoins s on to a subsequent segment on the same - // track that ends at endMarkerTime (presumably the original end - // marker time of s, with the range duration subtracted). + // This command rejoins pairs of subsequent segment on the same + // track. Segments pairs are defined using the addSegmentsPair + // method. - RejoinCommand(Composition *c, - Segment *s, - timeT endMarkerTime) : - KNamedCommand(i18n("Rejoin Command")), - m_composition(c), m_segment(s), m_endMarkerTime(endMarkerTime), - m_joinCommand(0) { } + RejoinCommand() : + KNamedCommand(i18n("Rejoin Command")) + { } - ~RejoinCommand() { delete m_joinCommand; } + virtual ~RejoinCommand(); + // Add a pair of segments that will be jointed later + void addSegmentsPair(Segment *s1, Segment *s2); + void execute(); - void unexecute() { if (m_joinCommand) m_joinCommand->unexecute(); } + void unexecute(); + private: - Composition *m_composition; Segment *m_segment; timeT m_endMarkerTime; + Composition *m_composition; - SegmentJoinCommand *m_joinCommand; + std::vector<SegmentJoinCommand *> m_rejoins; }; }; Modified: trunk/rosegarden/src/commands/segment/SegmentSplitCommand.h =================================================================== --- trunk/rosegarden/src/commands/segment/SegmentSplitCommand.h 2008-05-20 15:09:53 UTC (rev 8894) +++ trunk/rosegarden/src/commands/segment/SegmentSplitCommand.h 2008-05-28 20:44:47 UTC (rev 8895) @@ -48,6 +48,9 @@ virtual void execute(); virtual void unexecute(); + + Segment *getSegmentA() { return m_newSegmentA; } + Segment *getSegmentB() { return m_newSegmentB; } private: Segment *m_segment; Added: trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.cpp =================================================================== --- trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.cpp (rev 0) +++ trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.cpp 2008-05-28 20:44:47 UTC (rev 8895) @@ -0,0 +1,109 @@ +/* -*- 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 <gla...@te...>, + Chris Cannam <ca...@al...>, + Richard Bown <ric...@fe...> + + 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 "SegmentSplitTwiceCommand.h" +#include "SegmentSplitCommand.h" +#include "DeleteRangeCommand.h" + +#include <klocale.h> +#include "misc/Strings.h" +#include "base/Event.h" +#include "base/Composition.h" +#include "base/NotationTypes.h" +#include "base/Segment.h" +#include <qstring.h> + + +namespace Rosegarden +{ + +SegmentSplitTwiceCommand::SegmentSplitTwiceCommand(Segment *segment, + timeT splitTime1, timeT splitTime2, + DeleteRangeCommand::RejoinCommand *rejoins) : + KNamedCommand(i18n("Split Twice Segment")), + m_segment(segment), + m_newSegmentA(0), + m_newSegmentB(0), + m_newSegmentC(0), + m_splitTime1(splitTime1), + m_splitTime2(splitTime2), + m_detached(true), + m_composition(segment->getComposition()), + m_rejoins(rejoins) +{ +} + +SegmentSplitTwiceCommand::~SegmentSplitTwiceCommand() +{ + if (m_detached) { + delete m_newSegmentA; + delete m_newSegmentB; + delete m_newSegmentC; + } +} + +void +SegmentSplitTwiceCommand::execute() +{ + if (m_newSegmentA) { + m_composition->addSegment(m_newSegmentA); + m_composition->addSegment(m_newSegmentB); + m_composition->addSegment(m_newSegmentC); + + m_composition->detachSegment(m_segment); + + m_detached = false; // i.e. new segments are not detached + return; + } + + SegmentSplitCommand split1 = SegmentSplitCommand(m_segment, m_splitTime1); + split1.execute(); + m_newSegmentA = split1.getSegmentA(); + m_newSegmentB = split1.getSegmentB(); + + SegmentSplitCommand split2 = SegmentSplitCommand(m_newSegmentB, m_splitTime2); + split2.execute(); + m_newSegmentB = split2.getSegmentA(); + m_newSegmentC = split2.getSegmentB(); + + if ( (m_segment->getStartTime() < m_splitTime1) + && (m_segment->getEndMarkerTime() > m_splitTime2)) { + if (m_rejoins) m_rejoins->addSegmentsPair(m_newSegmentA, m_newSegmentC); + } +} + +void +SegmentSplitTwiceCommand::unexecute() +{ + m_composition->addSegment(m_segment); + + m_composition->detachSegment(m_newSegmentA); + m_composition->detachSegment(m_newSegmentB); + m_composition->detachSegment(m_newSegmentC); + + m_detached = true; // i.e. new segments are detached +} + +} Property changes on: trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.cpp ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native Added: trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.h =================================================================== --- trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.h (rev 0) +++ trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.h 2008-05-28 20:44:47 UTC (rev 8895) @@ -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 <gla...@te...>, + Chris Cannam <ca...@al...>, + Richard Bown <ric...@fe...> + + 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_SEGMENTSPLITTWICECOMMAND_H_ +#define _RG_SEGMENTSPLITTWICECOMMAND_H_ + +#include <string> +#include <kcommand.h> +#include "base/Event.h" + +#include "DeleteRangeCommand.h" + + + + +namespace Rosegarden +{ + +class Segment; +class Composition; + +// Following command replaces two SegmentSplitCommand successive calls +// when cutting a range to fix bug #1961378 (crash when cutting a range)) + + +class SegmentSplitTwiceCommand : public KNamedCommand +{ +public: + SegmentSplitTwiceCommand(Segment *segment, + timeT splitTime1, timeT splitTime2, + DeleteRangeCommand::RejoinCommand *rejoins); + virtual ~SegmentSplitTwiceCommand(); + + virtual void execute(); + virtual void unexecute(); + +private: + Segment *m_segment; + Segment *m_newSegmentA; + Segment *m_newSegmentB; + Segment *m_newSegmentC; + timeT m_splitTime1; + timeT m_splitTime2; + bool m_detached; + Composition *m_composition; + DeleteRangeCommand::RejoinCommand *m_rejoins; +}; + + +} + +#endif Property changes on: trunk/rosegarden/src/commands/segment/SegmentSplitTwiceCommand.h ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |