comparison data/model/SparseModel.h @ 1429:48e9f538e6e9

Untabify
author Chris Cannam
date Thu, 01 Mar 2018 18:02:22 +0000
parents cbdd534f517a
children b40f67578976
comparison
equal deleted inserted replaced
1428:87ae75da6527 1429:48e9f538e6e9
43 class SparseModel : public Model, 43 class SparseModel : public Model,
44 public TabularModel 44 public TabularModel
45 { 45 {
46 public: 46 public:
47 SparseModel(sv_samplerate_t sampleRate, int resolution, 47 SparseModel(sv_samplerate_t sampleRate, int resolution,
48 bool notifyOnAdd = true); 48 bool notifyOnAdd = true);
49 virtual ~SparseModel() { } 49 virtual ~SparseModel() { }
50 50
51 virtual bool isOK() const { return true; } 51 virtual bool isOK() const { return true; }
52 virtual sv_frame_t getStartFrame() const; 52 virtual sv_frame_t getStartFrame() const;
53 virtual sv_frame_t getEndFrame() const; 53 virtual sv_frame_t getEndFrame() const;
69 // end of the final point. 69 // end of the final point.
70 virtual void extendEndFrame(sv_frame_t to) { m_extendTo = to; } 70 virtual void extendEndFrame(sv_frame_t to) { m_extendTo = to; }
71 71
72 typedef PointType Point; 72 typedef PointType Point;
73 typedef std::multiset<PointType, 73 typedef std::multiset<PointType,
74 typename PointType::OrderComparator> PointList; 74 typename PointType::OrderComparator> PointList;
75 typedef typename PointList::iterator PointListIterator; 75 typedef typename PointList::iterator PointListIterator;
76 typedef typename PointList::const_iterator PointListConstIterator; 76 typedef typename PointList::const_iterator PointListConstIterator;
77 77
78 /** 78 /**
79 * Return whether the model is empty or not. 79 * Return whether the model is empty or not.
194 * Command to add a point, with undo. 194 * Command to add a point, with undo.
195 */ 195 */
196 class AddPointCommand : public Command 196 class AddPointCommand : public Command
197 { 197 {
198 public: 198 public:
199 AddPointCommand(SparseModel<PointType> *model, 199 AddPointCommand(SparseModel<PointType> *model,
200 const PointType &point, 200 const PointType &point,
201 QString name = "") : 201 QString name = "") :
202 m_model(model), m_point(point), m_name(name) { } 202 m_model(model), m_point(point), m_name(name) { }
203 203
204 virtual QString getName() const { 204 virtual QString getName() const {
205 return (m_name == "" ? tr("Add Point") : m_name); 205 return (m_name == "" ? tr("Add Point") : m_name);
206 } 206 }
207 207
208 virtual void execute() { m_model->addPoint(m_point); } 208 virtual void execute() { m_model->addPoint(m_point); }
209 virtual void unexecute() { m_model->deletePoint(m_point); } 209 virtual void unexecute() { m_model->deletePoint(m_point); }
210 210
211 const PointType &getPoint() const { return m_point; } 211 const PointType &getPoint() const { return m_point; }
212 212
213 private: 213 private:
214 SparseModel<PointType> *m_model; 214 SparseModel<PointType> *m_model;
215 PointType m_point; 215 PointType m_point;
216 QString m_name; 216 QString m_name;
217 }; 217 };
218 218
219 219
220 /** 220 /**
221 * Command to remove a point, with undo. 221 * Command to remove a point, with undo.
222 */ 222 */
223 class DeletePointCommand : public Command 223 class DeletePointCommand : public Command
224 { 224 {
225 public: 225 public:
226 DeletePointCommand(SparseModel<PointType> *model, 226 DeletePointCommand(SparseModel<PointType> *model,
227 const PointType &point) : 227 const PointType &point) :
228 m_model(model), m_point(point) { } 228 m_model(model), m_point(point) { }
229 229
230 virtual QString getName() const { return tr("Delete Point"); } 230 virtual QString getName() const { return tr("Delete Point"); }
231 231
232 virtual void execute() { m_model->deletePoint(m_point); } 232 virtual void execute() { m_model->deletePoint(m_point); }
233 virtual void unexecute() { m_model->addPoint(m_point); } 233 virtual void unexecute() { m_model->addPoint(m_point); }
234 234
235 const PointType &getPoint() const { return m_point; } 235 const PointType &getPoint() const { return m_point; }
236 236
237 private: 237 private:
238 SparseModel<PointType> *m_model; 238 SparseModel<PointType> *m_model;
239 PointType m_point; 239 PointType m_point;
240 }; 240 };
241 241
242 242
243 /** 243 /**
244 * Command to add or remove a series of points, with undo. 244 * Command to add or remove a series of points, with undo.
245 * Consecutive add/remove pairs for the same point are collapsed. 245 * Consecutive add/remove pairs for the same point are collapsed.
246 */ 246 */
247 class EditCommand : public MacroCommand 247 class EditCommand : public MacroCommand
248 { 248 {
249 public: 249 public:
250 EditCommand(SparseModel<PointType> *model, QString commandName); 250 EditCommand(SparseModel<PointType> *model, QString commandName);
251 251
252 virtual void addPoint(const PointType &point); 252 virtual void addPoint(const PointType &point);
253 virtual void deletePoint(const PointType &point); 253 virtual void deletePoint(const PointType &point);
254 254
255 /** 255 /**
256 * Stack an arbitrary other command in the same sequence. 256 * Stack an arbitrary other command in the same sequence.
257 */ 257 */
258 virtual void addCommand(Command *command) { addCommand(command, true); } 258 virtual void addCommand(Command *command) { addCommand(command, true); }
259 259
260 /** 260 /**
261 * If any points have been added or deleted, return this 261 * If any points have been added or deleted, return this
262 * command (so the caller can add it to the command history). 262 * command (so the caller can add it to the command history).
263 * Otherwise delete the command and return NULL. 263 * Otherwise delete the command and return NULL.
264 */ 264 */
265 virtual EditCommand *finish(); 265 virtual EditCommand *finish();
266 266
267 protected: 267 protected:
268 virtual void addCommand(Command *command, bool executeFirst); 268 virtual void addCommand(Command *command, bool executeFirst);
269 269
270 SparseModel<PointType> *m_model; 270 SparseModel<PointType> *m_model;
271 }; 271 };
272 272
273 273
274 /** 274 /**
275 * Command to relabel a point. 275 * Command to relabel a point.
276 */ 276 */
277 class RelabelCommand : public Command 277 class RelabelCommand : public Command
278 { 278 {
279 public: 279 public:
280 RelabelCommand(SparseModel<PointType> *model, 280 RelabelCommand(SparseModel<PointType> *model,
281 const PointType &point, 281 const PointType &point,
282 QString newLabel) : 282 QString newLabel) :
283 m_model(model), m_oldPoint(point), m_newPoint(point) { 283 m_model(model), m_oldPoint(point), m_newPoint(point) {
284 m_newPoint.label = newLabel; 284 m_newPoint.label = newLabel;
285 } 285 }
286 286
287 virtual QString getName() const { return tr("Re-Label Point"); } 287 virtual QString getName() const { return tr("Re-Label Point"); }
288 288
289 virtual void execute() { 289 virtual void execute() {
290 m_model->deletePoint(m_oldPoint); 290 m_model->deletePoint(m_oldPoint);
291 m_model->addPoint(m_newPoint); 291 m_model->addPoint(m_newPoint);
292 std::swap(m_oldPoint, m_newPoint); 292 std::swap(m_oldPoint, m_newPoint);
293 } 293 }
294 294
295 virtual void unexecute() { execute(); } 295 virtual void unexecute() { execute(); }
296 296
297 private: 297 private:
298 SparseModel<PointType> *m_model; 298 SparseModel<PointType> *m_model;
299 PointType m_oldPoint; 299 PointType m_oldPoint;
300 PointType m_newPoint; 300 PointType m_newPoint;
301 }; 301 };
302 302
303 /** 303 /**
304 * TabularModel methods. 304 * TabularModel methods.
305 */ 305 */
556 SparseModel<PointType>::getStartFrame() const 556 SparseModel<PointType>::getStartFrame() const
557 { 557 {
558 QMutexLocker locker(&m_mutex); 558 QMutexLocker locker(&m_mutex);
559 sv_frame_t f = 0; 559 sv_frame_t f = 0;
560 if (!m_points.empty()) { 560 if (!m_points.empty()) {
561 f = m_points.begin()->frame; 561 f = m_points.begin()->frame;
562 } 562 }
563 return f; 563 return f;
564 } 564 }
565 565
566 template <typename PointType> 566 template <typename PointType>
568 SparseModel<PointType>::getEndFrame() const 568 SparseModel<PointType>::getEndFrame() const
569 { 569 {
570 QMutexLocker locker(&m_mutex); 570 QMutexLocker locker(&m_mutex);
571 sv_frame_t f = 0; 571 sv_frame_t f = 0;
572 if (!m_points.empty()) { 572 if (!m_points.empty()) {
573 PointListConstIterator i(m_points.end()); 573 PointListConstIterator i(m_points.end());
574 f = (--i)->frame; 574 f = (--i)->frame;
575 } 575 }
576 if (m_extendTo > f) return m_extendTo; 576 if (m_extendTo > f) return m_extendTo;
577 else return f; 577 else return f;
578 } 578 }
579 579
616 if (endItr != m_points.end()) ++endItr; 616 if (endItr != m_points.end()) ++endItr;
617 617
618 PointList rv; 618 PointList rv;
619 619
620 for (PointListConstIterator i = startItr; i != endItr; ++i) { 620 for (PointListConstIterator i = startItr; i != endItr; ++i) {
621 rv.insert(*i); 621 rv.insert(*i);
622 } 622 }
623 623
624 return rv; 624 return rv;
625 } 625 }
626 626
632 getPointIterators(frame, startItr, endItr); 632 getPointIterators(frame, startItr, endItr);
633 633
634 PointList rv; 634 PointList rv;
635 635
636 for (PointListConstIterator i = startItr; i != endItr; ++i) { 636 for (PointListConstIterator i = startItr; i != endItr; ++i) {
637 rv.insert(*i); 637 rv.insert(*i);
638 } 638 }
639 639
640 return rv; 640 return rv;
641 } 641 }
642 642
702 if (i == m_points.begin()) return rv; 702 if (i == m_points.begin()) return rv;
703 703
704 --i; 704 --i;
705 sv_frame_t frame = i->frame; 705 sv_frame_t frame = i->frame;
706 while (i->frame == frame) { 706 while (i->frame == frame) {
707 rv.insert(*i); 707 rv.insert(*i);
708 if (i == m_points.begin()) break; 708 if (i == m_points.begin()) break;
709 --i; 709 --i;
710 } 710 }
711 711
712 return rv; 712 return rv;
713 } 713 }
714 714
724 PointListConstIterator i = m_points.upper_bound(lookupPoint); 724 PointListConstIterator i = m_points.upper_bound(lookupPoint);
725 if (i == m_points.end()) return rv; 725 if (i == m_points.end()) return rv;
726 726
727 sv_frame_t frame = i->frame; 727 sv_frame_t frame = i->frame;
728 while (i != m_points.end() && i->frame == frame) { 728 while (i != m_points.end() && i->frame == frame) {
729 rv.insert(*i); 729 rv.insert(*i);
730 ++i; 730 ++i;
731 } 731 }
732 732
733 return rv; 733 return rv;
734 } 734 }
735 735
736 template <typename PointType> 736 template <typename PointType>
737 void 737 void
738 SparseModel<PointType>::setResolution(int resolution) 738 SparseModel<PointType>::setResolution(int resolution)
739 { 739 {
740 { 740 {
741 QMutexLocker locker(&m_mutex); 741 QMutexLocker locker(&m_mutex);
742 m_resolution = resolution; 742 m_resolution = resolution;
743 m_rows.clear(); 743 m_rows.clear();
744 } 744 }
745 emit modelChanged(); 745 emit modelChanged();
746 } 746 }
747 747
748 template <typename PointType> 748 template <typename PointType>
749 void 749 void
750 SparseModel<PointType>::clear() 750 SparseModel<PointType>::clear()
751 { 751 {
752 { 752 {
753 QMutexLocker locker(&m_mutex); 753 QMutexLocker locker(&m_mutex);
754 m_points.clear(); 754 m_points.clear();
755 m_pointCount = 0; 755 m_pointCount = 0;
756 m_rows.clear(); 756 m_rows.clear();
757 } 757 }
758 emit modelChanged(); 758 emit modelChanged();
759 } 759 }
774 // notifyOnAdd as an option rather than a necessity (the 774 // notifyOnAdd as an option rather than a necessity (the
775 // alternative is to notify on setCompletion). 775 // alternative is to notify on setCompletion).
776 776
777 if (m_notifyOnAdd) { 777 if (m_notifyOnAdd) {
778 m_rows.clear(); //!!! inefficient 778 m_rows.clear(); //!!! inefficient
779 emit modelChangedWithin(point.frame, point.frame + m_resolution); 779 emit modelChangedWithin(point.frame, point.frame + m_resolution);
780 } else { 780 } else {
781 if (m_sinceLastNotifyMin == -1 || 781 if (m_sinceLastNotifyMin == -1 ||
782 point.frame < m_sinceLastNotifyMin) { 782 point.frame < m_sinceLastNotifyMin) {
783 m_sinceLastNotifyMin = point.frame; 783 m_sinceLastNotifyMin = point.frame;
784 } 784 }
785 if (m_sinceLastNotifyMax == -1 || 785 if (m_sinceLastNotifyMax == -1 ||
786 point.frame > m_sinceLastNotifyMax) { 786 point.frame > m_sinceLastNotifyMax) {
787 m_sinceLastNotifyMax = point.frame; 787 m_sinceLastNotifyMax = point.frame;
788 } 788 }
789 } 789 }
790 } 790 }
791 791
792 template <typename PointType> 792 template <typename PointType>
793 bool 793 bool
820 if (i->frame > point.frame) break; 820 if (i->frame > point.frame) break;
821 if (!comparator(*i, point) && !comparator(point, *i)) { 821 if (!comparator(*i, point) && !comparator(point, *i)) {
822 m_points.erase(i); 822 m_points.erase(i);
823 m_pointCount--; 823 m_pointCount--;
824 break; 824 break;
825 } 825 }
826 ++i; 826 ++i;
827 } 827 }
828 828
829 // std::cout << "SparseOneDimensionalModel: emit modelChanged(" 829 // std::cout << "SparseOneDimensionalModel: emit modelChanged("
830 // << point.frame << ")" << std::endl; 830 // << point.frame << ")" << std::endl;
831 m_rows.clear(); //!!! inefficient 831 m_rows.clear(); //!!! inefficient
832 emit modelChangedWithin(point.frame, point.frame + m_resolution); 832 emit modelChangedWithin(point.frame, point.frame + m_resolution);
833 } 833 }
834 834
835 template <typename PointType> 835 template <typename PointType>
839 // std::cerr << "SparseModel::setCompletion(" << completion << ")" << std::endl; 839 // std::cerr << "SparseModel::setCompletion(" << completion << ")" << std::endl;
840 840
841 QMutexLocker locker(&m_mutex); 841 QMutexLocker locker(&m_mutex);
842 842
843 if (m_completion != completion) { 843 if (m_completion != completion) {
844 m_completion = completion; 844 m_completion = completion;
845 845
846 if (completion == 100) { 846 if (completion == 100) {
847 847
848 if (!m_notifyOnAdd) { 848 if (!m_notifyOnAdd) {
849 emit completionChanged(); 849 emit completionChanged();
850 } 850 }
851 851
852 m_notifyOnAdd = true; // henceforth 852 m_notifyOnAdd = true; // henceforth
853 m_rows.clear(); //!!! inefficient 853 m_rows.clear(); //!!! inefficient
854 emit modelChanged(); 854 emit modelChanged();
855 855
856 } else if (!m_notifyOnAdd) { 856 } else if (!m_notifyOnAdd) {
857 857
858 if (update && 858 if (update &&
859 m_sinceLastNotifyMin >= 0 && 859 m_sinceLastNotifyMin >= 0 &&
860 m_sinceLastNotifyMax >= 0) { 860 m_sinceLastNotifyMax >= 0) {
861 m_rows.clear(); //!!! inefficient 861 m_rows.clear(); //!!! inefficient
862 emit modelChangedWithin(m_sinceLastNotifyMin, m_sinceLastNotifyMax); 862 emit modelChangedWithin(m_sinceLastNotifyMin, m_sinceLastNotifyMax);
863 m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1; 863 m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1;
864 } else { 864 } else {
865 emit completionChanged(); 865 emit completionChanged();
866 } 866 }
867 } else { 867 } else {
868 emit completionChanged(); 868 emit completionChanged();
869 } 869 }
870 } 870 }
871 } 871 }
872 872
873 template <typename PointType> 873 template <typename PointType>
874 void 874 void
880 // << extraAttributes.toStdString() << std::endl; 880 // << extraAttributes.toStdString() << std::endl;
881 881
882 QString type = getXmlOutputType(); 882 QString type = getXmlOutputType();
883 883
884 Model::toXml 884 Model::toXml
885 (out, 885 (out,
886 indent, 886 indent,
887 QString("type=\"%1\" dimensions=\"%2\" resolution=\"%3\" notifyOnAdd=\"%4\" dataset=\"%5\" %6") 887 QString("type=\"%1\" dimensions=\"%2\" resolution=\"%3\" notifyOnAdd=\"%4\" dataset=\"%5\" %6")
888 .arg(type) 888 .arg(type)
889 .arg(PointType(0).getDimensions()) 889 .arg(PointType(0).getDimensions())
890 .arg(m_resolution) 890 .arg(m_resolution)
891 .arg(m_notifyOnAdd ? "true" : "false") 891 .arg(m_notifyOnAdd ? "true" : "false")
892 .arg(getObjectExportId(&m_points)) 892 .arg(getObjectExportId(&m_points))
893 .arg(extraAttributes)); 893 .arg(extraAttributes));
894 894
895 out << indent; 895 out << indent;
896 out << QString("<dataset id=\"%1\" dimensions=\"%2\">\n") 896 out << QString("<dataset id=\"%1\" dimensions=\"%2\">\n")
897 .arg(getObjectExportId(&m_points)) 897 .arg(getObjectExportId(&m_points))
898 .arg(PointType(0).getDimensions()); 898 .arg(PointType(0).getDimensions());
899 899
900 for (PointListConstIterator i = m_points.begin(); i != m_points.end(); ++i) { 900 for (PointListConstIterator i = m_points.begin(); i != m_points.end(); ++i) {
901 i->toXml(out, indent + " "); 901 i->toXml(out, indent + " ");
902 } 902 }
903 903
940 } 940 }
941 941
942 template <typename PointType> 942 template <typename PointType>
943 void 943 void
944 SparseModel<PointType>::EditCommand::addCommand(Command *command, 944 SparseModel<PointType>::EditCommand::addCommand(Command *command,
945 bool executeFirst) 945 bool executeFirst)
946 { 946 {
947 if (executeFirst) command->execute(); 947 if (executeFirst) command->execute();
948 948
949 if (!m_commands.empty()) { 949 if (!m_commands.empty()) {
950 DeletePointCommand *dpc = dynamic_cast<DeletePointCommand *>(command); 950 DeletePointCommand *dpc = dynamic_cast<DeletePointCommand *>(command);
951 if (dpc) { 951 if (dpc) {
952 AddPointCommand *apc = dynamic_cast<AddPointCommand *> 952 AddPointCommand *apc = dynamic_cast<AddPointCommand *>
953 (m_commands[m_commands.size() - 1]); 953 (m_commands[m_commands.size() - 1]);
954 typename PointType::Comparator comparator; 954 typename PointType::Comparator comparator;
955 if (apc) { 955 if (apc) {
956 if (!comparator(apc->getPoint(), dpc->getPoint()) && 956 if (!comparator(apc->getPoint(), dpc->getPoint()) &&
957 !comparator(dpc->getPoint(), apc->getPoint())) { 957 !comparator(dpc->getPoint(), apc->getPoint())) {
958 deleteCommand(apc); 958 deleteCommand(apc);
959 return; 959 return;
960 } 960 }
961 } 961 }
962 } 962 }
963 } 963 }
964 964
965 MacroCommand::addCommand(command); 965 MacroCommand::addCommand(command);
966 } 966 }
967 967