Chris@302: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@302:
Chris@302: /*
Chris@302: Sonic Visualiser
Chris@302: An audio file viewer and annotation editor.
Chris@302: Centre for Digital Music, Queen Mary, University of London.
Chris@302: This file copyright 2006-2007 Chris Cannam and QMUL.
Chris@302:
Chris@302: This program is free software; you can redistribute it and/or
Chris@302: modify it under the terms of the GNU General Public License as
Chris@302: published by the Free Software Foundation; either version 2 of the
Chris@302: License, or (at your option) any later version. See the file
Chris@302: COPYING included with this distribution for more information.
Chris@302: */
Chris@302:
Chris@302: #ifndef _IMAGE_MODEL_H_
Chris@302: #define _IMAGE_MODEL_H_
Chris@302:
Chris@302: #include "SparseModel.h"
Chris@302: #include "base/XmlExportable.h"
Chris@302: #include "base/RealTime.h"
Chris@302:
Chris@302: /**
Chris@302: * Image point type for use in a SparseModel. This represents an
Chris@302: * image, identified by filename, at a given time. The filename can
Chris@302: * be empty, in which case we instead have a space to put an image in.
Chris@302: */
Chris@302:
Chris@302: struct ImagePoint : public XmlExportable
Chris@302: {
Chris@302: public:
Chris@302: ImagePoint(long _frame) : frame(_frame) { }
Chris@302: ImagePoint(long _frame, QString _image, QString _label) :
Chris@302: frame(_frame), image(_image), label(_label) { }
Chris@302:
Chris@302: int getDimensions() const { return 1; }
Chris@302:
Chris@302: long frame;
Chris@302: QString image;
Chris@302: QString label;
Chris@338:
Chris@338: QString getLabel() const { return label; }
Chris@302:
Chris@314: void toXml(QTextStream &stream,
Chris@314: QString indent = "",
Chris@314: QString extraAttributes = "") const
Chris@302: {
Chris@314: stream <<
Chris@314: QString("%1\n")
Chris@302: .arg(indent).arg(frame)
Chris@302: .arg(encodeEntities(image))
Chris@302: .arg(encodeEntities(label))
Chris@302: .arg(extraAttributes);
Chris@302: }
Chris@302:
Chris@302: QString toDelimitedDataString(QString delimiter, size_t sampleRate) const
Chris@302: {
Chris@302: QStringList list;
Chris@302: list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
Chris@302: list << image;
Chris@318: if (label != "") list << label;
Chris@302: return list.join(delimiter);
Chris@302: }
Chris@302:
Chris@302: struct Comparator {
Chris@302: bool operator()(const ImagePoint &p1,
Chris@302: const ImagePoint &p2) const {
Chris@302: if (p1.frame != p2.frame) return p1.frame < p2.frame;
Chris@302: if (p1.label != p2.label) return p1.label < p2.label;
Chris@302: return p1.image < p2.image;
Chris@302: }
Chris@302: };
Chris@302:
Chris@302: struct OrderComparator {
Chris@302: bool operator()(const ImagePoint &p1,
Chris@302: const ImagePoint &p2) const {
Chris@302: return p1.frame < p2.frame;
Chris@302: }
Chris@302: };
Chris@302: };
Chris@302:
Chris@302:
Chris@302: // Make this a class rather than a typedef so it can be predeclared.
Chris@302:
Chris@302: class ImageModel : public SparseModel
Chris@302: {
Chris@302: public:
Chris@302: ImageModel(size_t sampleRate, size_t resolution, bool notifyOnAdd = true) :
Chris@302: SparseModel(sampleRate, resolution, notifyOnAdd)
Chris@302: { }
Chris@302:
Chris@345: QString getTypeName() const { return tr("Image"); }
Chris@345:
Chris@302: virtual void toXml(QTextStream &out,
Chris@302: QString indent = "",
Chris@302: QString extraAttributes = "") const
Chris@302: {
Chris@302: SparseModel::toXml
Chris@302: (out,
Chris@302: indent,
Chris@302: QString("%1 subtype=\"image\"")
Chris@302: .arg(extraAttributes));
Chris@302: }
Chris@302:
Chris@302: /**
Chris@302: * Command to change the image for a point.
Chris@302: */
Chris@302: class ChangeImageCommand : public Command
Chris@302: {
Chris@302: public:
Chris@302: ChangeImageCommand(ImageModel *model,
Chris@302: const ImagePoint &point,
Chris@302: QString newImage,
Chris@302: QString newLabel) :
Chris@302: m_model(model), m_oldPoint(point), m_newPoint(point) {
Chris@302: m_newPoint.image = newImage;
Chris@302: m_newPoint.label = newLabel;
Chris@302: }
Chris@302:
Chris@302: virtual QString getName() const { return tr("Edit Image"); }
Chris@302:
Chris@302: virtual void execute() {
Chris@302: m_model->deletePoint(m_oldPoint);
Chris@302: m_model->addPoint(m_newPoint);
Chris@302: std::swap(m_oldPoint, m_newPoint);
Chris@302: }
Chris@302:
Chris@302: virtual void unexecute() { execute(); }
Chris@302:
Chris@302: private:
Chris@302: ImageModel *m_model;
Chris@302: ImagePoint m_oldPoint;
Chris@302: ImagePoint m_newPoint;
Chris@302: };
Chris@302: };
Chris@302:
Chris@302:
Chris@302: #endif
Chris@302:
Chris@302:
Chris@302: