Mercurial > hg > easaier-soundaccess
comparison base/Selection.cpp @ 0:fc9323a41f5a
start base : Sonic Visualiser sv1-1.0rc1
author | lbajardsilogic |
---|---|
date | Fri, 11 May 2007 09:08:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:fc9323a41f5a |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2006 Chris Cannam. | |
8 | |
9 This program is free software; you can redistribute it and/or | |
10 modify it under the terms of the GNU General Public License as | |
11 published by the Free Software Foundation; either version 2 of the | |
12 License, or (at your option) any later version. See the file | |
13 COPYING included with this distribution for more information. | |
14 */ | |
15 | |
16 #include "Selection.h" | |
17 | |
18 Selection::Selection() : | |
19 m_startFrame(0), | |
20 m_endFrame(0) | |
21 { | |
22 } | |
23 | |
24 Selection::Selection(size_t startFrame, size_t endFrame) : | |
25 m_startFrame(startFrame), | |
26 m_endFrame(endFrame) | |
27 { | |
28 if (m_startFrame > m_endFrame) { | |
29 size_t tmp = m_endFrame; | |
30 m_endFrame = m_startFrame; | |
31 m_startFrame = tmp; | |
32 } | |
33 } | |
34 | |
35 Selection::Selection(const Selection &s) : | |
36 m_startFrame(s.m_startFrame), | |
37 m_endFrame(s.m_endFrame) | |
38 { | |
39 } | |
40 | |
41 Selection & | |
42 Selection::operator=(const Selection &s) | |
43 { | |
44 if (this != &s) { | |
45 m_startFrame = s.m_startFrame; | |
46 m_endFrame = s.m_endFrame; | |
47 } | |
48 return *this; | |
49 } | |
50 | |
51 Selection::~Selection() | |
52 { | |
53 } | |
54 | |
55 bool | |
56 Selection::isEmpty() const | |
57 { | |
58 return m_startFrame == m_endFrame; | |
59 } | |
60 | |
61 size_t | |
62 Selection::getStartFrame() const | |
63 { | |
64 return m_startFrame; | |
65 } | |
66 | |
67 size_t | |
68 Selection::getEndFrame() const | |
69 { | |
70 return m_endFrame; | |
71 } | |
72 | |
73 bool | |
74 Selection::contains(size_t frame) const | |
75 { | |
76 return (frame >= m_startFrame) && (frame < m_endFrame); | |
77 } | |
78 | |
79 bool | |
80 Selection::operator<(const Selection &s) const | |
81 { | |
82 if (isEmpty()) { | |
83 if (s.isEmpty()) return false; | |
84 else return true; | |
85 } else { | |
86 if (s.isEmpty()) return false; | |
87 else return (m_startFrame < s.m_startFrame); | |
88 } | |
89 } | |
90 | |
91 bool | |
92 Selection::operator==(const Selection &s) const | |
93 { | |
94 if (isEmpty()) return s.isEmpty(); | |
95 | |
96 return (m_startFrame == s.m_startFrame && | |
97 m_endFrame == s.m_endFrame); | |
98 } | |
99 | |
100 | |
101 MultiSelection::MultiSelection() | |
102 { | |
103 } | |
104 | |
105 MultiSelection::~MultiSelection() | |
106 { | |
107 } | |
108 | |
109 const MultiSelection::SelectionList & | |
110 MultiSelection::getSelections() const | |
111 { | |
112 return m_selections; | |
113 } | |
114 | |
115 void | |
116 MultiSelection::setSelection(const Selection &selection) | |
117 { | |
118 clearSelections(); | |
119 addSelection(selection); | |
120 } | |
121 | |
122 void | |
123 MultiSelection::addSelection(const Selection &selection) | |
124 { | |
125 m_selections.insert(selection); | |
126 | |
127 // Cope with a sitation where the new selection overlaps one or | |
128 // more existing ones. This is a terribly inefficient way to do | |
129 // this, but that probably isn't significant in real life. | |
130 | |
131 // It's essential for the correct operation of | |
132 // getContainingSelection that the selections do not overlap, so | |
133 // this is not just a frill. | |
134 | |
135 for (SelectionList::iterator i = m_selections.begin(); | |
136 i != m_selections.end(); ) { | |
137 | |
138 SelectionList::iterator j = i; | |
139 if (++j == m_selections.end()) break; | |
140 | |
141 if (i->getEndFrame() >= j->getStartFrame()) { | |
142 Selection merged(i->getStartFrame(), | |
143 std::max(i->getEndFrame(), j->getEndFrame())); | |
144 m_selections.erase(i); | |
145 m_selections.erase(j); | |
146 m_selections.insert(merged); | |
147 i = m_selections.begin(); | |
148 } else { | |
149 ++i; | |
150 } | |
151 } | |
152 } | |
153 | |
154 void | |
155 MultiSelection::removeSelection(const Selection &selection) | |
156 { | |
157 //!!! Likewise this needs to cope correctly with the situation | |
158 //where selection is not one of the original selection set but | |
159 //simply overlaps one of them (cutting down the original selection | |
160 //appropriately) | |
161 | |
162 if (m_selections.find(selection) != m_selections.end()) { | |
163 m_selections.erase(selection); | |
164 } | |
165 } | |
166 | |
167 void | |
168 MultiSelection::clearSelections() | |
169 { | |
170 if (!m_selections.empty()) { | |
171 m_selections.clear(); | |
172 } | |
173 } | |
174 | |
175 Selection | |
176 MultiSelection::getContainingSelection(size_t frame, bool defaultToFollowing) const | |
177 { | |
178 // This scales very badly with the number of selections, but it's | |
179 // more efficient for very small numbers of selections than a more | |
180 // scalable method, and I think that may be what we need | |
181 | |
182 for (SelectionList::const_iterator i = m_selections.begin(); | |
183 i != m_selections.end(); ++i) { | |
184 | |
185 if (i->contains(frame)) return *i; | |
186 | |
187 if (i->getStartFrame() > frame) { | |
188 if (defaultToFollowing) return *i; | |
189 else return Selection(); | |
190 } | |
191 } | |
192 | |
193 return Selection(); | |
194 } | |
195 | |
196 QString | |
197 MultiSelection::toXmlString(QString indent, | |
198 QString extraAttributes) const | |
199 { | |
200 QString s; | |
201 s += indent + QString("<selections %1>\n").arg(extraAttributes); | |
202 for (SelectionList::const_iterator i = m_selections.begin(); | |
203 i != m_selections.end(); ++i) { | |
204 s += indent + QString(" <selection start=\"%1\" end=\"%2\"/>\n") | |
205 .arg(i->getStartFrame()).arg(i->getEndFrame()); | |
206 } | |
207 s += indent + "</selections>\n"; | |
208 return s; | |
209 } | |
210 |