1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A MIDI and audio sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7 
8     Other copyrights also apply to some parts of this work.  Please
9     see the AUTHORS file and individual file headers for details.
10 
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.  See the file
15     COPYING included with this distribution for more information.
16 */
17 
18 
19 #include "SegmentSplitByRecordingSrcCommand.h"
20 
21 #include "base/BaseProperties.h"
22 #include "misc/AppendLabel.h"
23 #include "misc/Strings.h"
24 #include "base/Composition.h"
25 #include "base/Event.h"
26 #include "base/NotationTypes.h"
27 #include "base/Segment.h"
28 #include <QString>
29 
30 
31 namespace Rosegarden
32 {
33 
SegmentSplitByRecordingSrcCommand(Segment * segment,int channel,int device)34 SegmentSplitByRecordingSrcCommand::SegmentSplitByRecordingSrcCommand (
35     Segment *segment, int channel, int device ) :
36         NamedCommand(tr("Split by Recording Source")),
37         m_composition(segment->getComposition()),
38         m_segment(segment),
39         m_newSegmentA(nullptr),
40         m_channel(channel),
41         m_device(device),
42         m_executed(false)
43 {}
44 
45 void
execute()46 SegmentSplitByRecordingSrcCommand::execute()
47 {
48     if (!m_newSegmentA) {
49 
50         m_newSegmentA = new Segment;
51         m_newSegmentB = new Segment;
52 
53         m_newSegmentA->setTrack(m_segment->getTrack());
54         m_newSegmentA->setStartTime(m_segment->getStartTime());
55 
56         m_newSegmentB->setTrack(m_segment->getTrack());
57         m_newSegmentB->setStartTime(m_segment->getStartTime());
58 
59         bool selectedC = false;
60         bool selectedD = false;
61 
62         for (Segment::iterator i = m_segment->begin();
63                 m_segment->isBeforeEndMarker(i); ++i) {
64 
65             if ((*i)->isa(Note::EventRestType))
66                 continue;
67 
68             if ( (*i)->isa(Clef::EventType) ||
69                     (*i)->isa(Key::EventType) ) {
70 
71                 m_newSegmentA->insert(new Event(**i));
72                 m_newSegmentB->insert(new Event(**i));
73                 continue;
74             }
75 
76             selectedC = false;
77             selectedD = false;
78 
79             if ((*i)->has(BaseProperties::RECORDED_CHANNEL)) {
80                 selectedC = true;
81                 if (m_channel > -1)
82                     selectedC = ( m_channel ==
83                                   (*i)->get
84                                   <Int>(BaseProperties::RECORDED_CHANNEL) );
85             }
86 
87             if ((*i)->has(BaseProperties::RECORDED_PORT)) {
88                 selectedD = true;
89                 if (m_device > -1)
90                     selectedD = ( m_device ==
91                                   (*i)->get
92                                   <Int>(BaseProperties::RECORDED_PORT) );
93             }
94 
95             if (selectedC & selectedD) {
96                 if (m_newSegmentB->empty()) {
97                     m_newSegmentB->fillWithRests((*i)->getAbsoluteTime());
98                 }
99                 m_newSegmentB->insert(new Event(**i));
100             } else {
101                 if (m_newSegmentA->empty()) {
102                     m_newSegmentA->fillWithRests((*i)->getAbsoluteTime());
103                 }
104                 m_newSegmentA->insert(new Event(**i));
105             }
106         }
107 
108         m_newSegmentA->normalizeRests(m_segment->getStartTime(),
109                                       m_segment->getEndMarkerTime());
110         m_newSegmentB->normalizeRests(m_segment->getStartTime(),
111                                       m_segment->getEndMarkerTime());
112 
113         std::string label = m_segment->getLabel();
114         m_newSegmentA->setLabel(appendLabel(label, qstrtostr(tr("(split)"))));
115         m_newSegmentB->setLabel(appendLabel(label, qstrtostr(tr("(split)"))));
116         m_newSegmentA->setColourIndex(m_segment->getColourIndex());
117         m_newSegmentB->setColourIndex(m_segment->getColourIndex());
118     }
119 
120     m_composition->addSegment(m_newSegmentA);
121     m_composition->addSegment(m_newSegmentB);
122     m_composition->detachSegment(m_segment);
123     m_executed = true;
124 }
125 
126 void
unexecute()127 SegmentSplitByRecordingSrcCommand::unexecute()
128 {
129     m_composition->addSegment(m_segment);
130     m_composition->detachSegment(m_newSegmentA);
131     m_composition->detachSegment(m_newSegmentB);
132     m_executed = false;
133 }
134 
~SegmentSplitByRecordingSrcCommand()135 SegmentSplitByRecordingSrcCommand::~SegmentSplitByRecordingSrcCommand()
136 {
137     if (m_executed) {
138         delete m_segment;
139     } else {
140         delete m_newSegmentA;
141         delete m_newSegmentB;
142     }
143 }
144 
145 }
146