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