comparison base/Selection.cpp @ 24:bb9291d84810

* Add ffwd/rewind * Abstract out MultiSelection
author Chris Cannam
date Wed, 08 Feb 2006 17:59:16 +0000
parents 73d85d19919f
children 935a2419a77c
comparison
equal deleted inserted replaced
23:6ace4286ba06 24:bb9291d84810
89 89
90 return (m_startFrame == s.m_startFrame && 90 return (m_startFrame == s.m_startFrame &&
91 m_endFrame == s.m_endFrame); 91 m_endFrame == s.m_endFrame);
92 } 92 }
93 93
94
95 MultiSelection::MultiSelection()
96 {
97 }
98
99 MultiSelection::~MultiSelection()
100 {
101 }
102
103 const MultiSelection::SelectionList &
104 MultiSelection::getSelections() const
105 {
106 return m_selections;
107 }
108
109 void
110 MultiSelection::setSelection(const Selection &selection)
111 {
112 clearSelections();
113 addSelection(selection);
114 }
115
116 void
117 MultiSelection::addSelection(const Selection &selection)
118 {
119 m_selections.insert(selection);
120
121 // Cope with a sitation where the new selection overlaps one or
122 // more existing ones. This is a terribly inefficient way to do
123 // this, but that probably isn't significant in real life.
124
125 // It's essential for the correct operation of
126 // getContainingSelection that the selections do not overlap, so
127 // this is not just a frill.
128
129 for (SelectionList::iterator i = m_selections.begin();
130 i != m_selections.end(); ) {
131
132 SelectionList::iterator j = i;
133 if (++j == m_selections.end()) break;
134
135 if (i->getEndFrame() >= j->getStartFrame()) {
136 Selection merged(i->getStartFrame(),
137 std::max(i->getEndFrame(), j->getEndFrame()));
138 m_selections.erase(i);
139 m_selections.erase(j);
140 m_selections.insert(merged);
141 i = m_selections.begin();
142 } else {
143 ++i;
144 }
145 }
146 }
147
148 void
149 MultiSelection::removeSelection(const Selection &selection)
150 {
151 //!!! Likewise this needs to cope correctly with the situation
152 //where selection is not one of the original selection set but
153 //simply overlaps one of them (cutting down the original selection
154 //appropriately)
155
156 if (m_selections.find(selection) != m_selections.end()) {
157 m_selections.erase(selection);
158 }
159 }
160
161 void
162 MultiSelection::clearSelections()
163 {
164 if (!m_selections.empty()) {
165 m_selections.clear();
166 }
167 }
168
169 Selection
170 MultiSelection::getContainingSelection(size_t frame, bool defaultToFollowing)
171 {
172 // This scales very badly with the number of selections, but it's
173 // more efficient for very small numbers of selections than a more
174 // scalable method, and I think that may be what we need
175
176 for (SelectionList::const_iterator i = m_selections.begin();
177 i != m_selections.end(); ++i) {
178
179 if (i->contains(frame)) return *i;
180
181 if (i->getStartFrame() > frame) {
182 if (defaultToFollowing) return *i;
183 else return Selection();
184 }
185 }
186
187 return Selection();
188 }