Selection.cpp
Go to the documentation of this file.
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 #include <QTextStream>
18 
20  m_startFrame(0),
21  m_endFrame(0)
22 {
23 }
24 
26  m_startFrame(startFrame),
27  m_endFrame(endFrame)
28 {
29  if (m_startFrame > m_endFrame) {
30  sv_frame_t tmp = m_endFrame;
32  m_startFrame = tmp;
33  }
34 }
35 
39 {
40 }
41 
42 Selection &
44 {
45  if (this != &s) {
48  }
49  return *this;
50 }
51 
53 {
54 }
55 
56 bool
58 {
59  return m_startFrame == m_endFrame;
60 }
61 
64 {
65  return m_startFrame;
66 }
67 
70 {
71  return m_endFrame;
72 }
73 
74 bool
76 {
77  return (frame >= m_startFrame) && (frame < m_endFrame);
78 }
79 
80 bool
82 {
83  if (isEmpty()) {
84  if (s.isEmpty()) return false;
85  else return true;
86  } else {
87  if (s.isEmpty()) return false;
88  else return (m_startFrame < s.m_startFrame);
89  }
90 }
91 
92 bool
94 {
95  if (isEmpty()) return s.isEmpty();
96 
97  return (m_startFrame == s.m_startFrame &&
98  m_endFrame == s.m_endFrame);
99 }
100 
101 
103 {
104 }
105 
107 {
108 }
109 
112 {
113  return m_selections;
114 }
115 
116 void
118 {
119  clearSelections();
120  addSelection(selection);
121 }
122 
123 void
125 {
126  m_selections.insert(selection);
127 
128  // Cope with a sitation where the new selection overlaps one or
129  // more existing ones. This is a terribly inefficient way to do
130  // this, but that probably isn't significant in real life.
131 
132  // It's essential for the correct operation of
133  // getContainingSelection that the selections do not overlap, so
134  // this is not just a frill.
135 
136  for (SelectionList::iterator i = m_selections.begin();
137  i != m_selections.end(); ) {
138 
139  SelectionList::iterator j = i;
140  if (++j == m_selections.end()) break;
141 
142  if (i->getEndFrame() >= j->getStartFrame()) {
143  Selection merged(i->getStartFrame(),
144  std::max(i->getEndFrame(), j->getEndFrame()));
145  m_selections.erase(i);
146  m_selections.erase(j);
147  m_selections.insert(merged);
148  i = m_selections.begin();
149  } else {
150  ++i;
151  }
152  }
153 }
154 
155 void
157 {
159  //where selection is not one of the original selection set but
160  //simply overlaps one of them (cutting down the original selection
161  //appropriately)
162 
163  if (m_selections.find(selection) != m_selections.end()) {
164  m_selections.erase(selection);
165  }
166 }
167 
168 void
170 {
171  if (!m_selections.empty()) {
172  m_selections.clear();
173  }
174 }
175 
176 void
177 MultiSelection::getExtents(sv_frame_t &startFrame, sv_frame_t &endFrame) const
178 {
179  startFrame = 0;
180  endFrame = 0;
181 
182  for (SelectionList::const_iterator i = m_selections.begin();
183  i != m_selections.end(); ++i) {
184 
185  if (i == m_selections.begin() || i->getStartFrame() < startFrame) {
186  startFrame = i->getStartFrame();
187  }
188 
189  if (i == m_selections.begin() || i->getEndFrame() > endFrame) {
190  endFrame = i->getEndFrame();
191  }
192  }
193 }
194 
195 Selection
196 MultiSelection::getContainingSelection(sv_frame_t frame, bool defaultToFollowing) const
197 {
198  // This scales very badly with the number of selections, but it's
199  // more efficient for very small numbers of selections than a more
200  // scalable method, and I think that may be what we need
201 
202  for (SelectionList::const_iterator i = m_selections.begin();
203  i != m_selections.end(); ++i) {
204 
205  if (i->contains(frame)) return *i;
206 
207  if (i->getStartFrame() > frame) {
208  if (defaultToFollowing) return *i;
209  else return Selection();
210  }
211  }
212 
213  return Selection();
214 }
215 
216 void
217 MultiSelection::toXml(QTextStream &stream, QString indent,
218  QString extraAttributes) const
219 {
220  stream << indent << QString("<selections %1>\n").arg(extraAttributes);
221  for (SelectionList::iterator i = m_selections.begin();
222  i != m_selections.end(); ++i) {
223  stream << indent
224  << QString(" <selection start=\"%1\" end=\"%2\"/>\n")
225  .arg(i->getStartFrame()).arg(i->getEndFrame());
226  }
227  stream << indent << "</selections>\n";
228 }
229 
230 QString
232 {
233  QStringList list;
234  for (SelectionList::iterator i = m_selections.begin();
235  i != m_selections.end(); ++i) {
236  list << QString("(%1,%2)")
237  .arg(i->getStartFrame())
238  .arg(i->getEndFrame());
239  }
240  return "(" + list.join(",") + ")";
241 }
sv_frame_t getEndFrame() const
Definition: Selection.cpp:69
void removeSelection(const Selection &selection)
Definition: Selection.cpp:156
const SelectionList & getSelections() const
Definition: Selection.cpp:111
void setSelection(const Selection &selection)
Definition: Selection.cpp:117
int64_t sv_frame_t
Frame index, the unit of our time axis.
Definition: BaseTypes.h:31
A selection object simply represents a range in time, via start and end frame.
Definition: Selection.h:40
sv_frame_t m_endFrame
Definition: Selection.h:60
bool operator==(const Selection &) const
Definition: Selection.cpp:93
virtual ~MultiSelection()
Definition: Selection.cpp:106
bool isEmpty() const
Definition: Selection.cpp:57
Selection getContainingSelection(sv_frame_t frame, bool defaultToFollowing) const
Return the selection that contains a given frame.
Definition: Selection.cpp:196
void addSelection(const Selection &selection)
Definition: Selection.cpp:124
void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const override
Stream this exportable object out to XML on a text stream.
Definition: Selection.cpp:217
sv_frame_t m_startFrame
Definition: Selection.h:59
std::set< Selection > SelectionList
Definition: Selection.h:69
void getExtents(sv_frame_t &startFrame, sv_frame_t &endFrame) const
Definition: Selection.cpp:177
void clearSelections()
Definition: Selection.cpp:169
bool contains(sv_frame_t frame) const
Definition: Selection.cpp:75
QString toString() const
Definition: Selection.cpp:231
Selection & operator=(const Selection &)
Definition: Selection.cpp:43
sv_frame_t getStartFrame() const
Definition: Selection.cpp:63
virtual ~Selection()
Definition: Selection.cpp:52
bool operator<(const Selection &) const
Definition: Selection.cpp:81