# HG changeset patch # User Chris Cannam # Date 1191515651 0 # Node ID 726b32522e3f9c33c2f785da7155c4560a14ec72 # Parent 73537d900d4b8a223375837d0eb9ff16a07dba91 * Phase 1 of an image layer. diff -r 73537d900d4b -r 726b32522e3f data/data.pro --- a/data/data.pro Thu Oct 04 11:52:38 2007 +0000 +++ b/data/data.pro Thu Oct 04 16:34:11 2007 +0000 @@ -48,6 +48,7 @@ model/DenseTimeValueModel.h \ model/EditableDenseThreeDimensionalModel.h \ model/FFTModel.h \ + model/ImageModel.h \ model/Model.h \ model/NoteModel.h \ model/PowerOfSqrtTwoZoomConstraint.h \ diff -r 73537d900d4b -r 726b32522e3f data/fileio/FileFinder.cpp --- a/data/fileio/FileFinder.cpp Thu Oct 04 11:52:38 2007 +0000 +++ b/data/fileio/FileFinder.cpp Thu Oct 04 16:34:11 2007 +0000 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -89,7 +90,16 @@ case ImageFile: settingsKey = "imagepath"; - filter = tr("Portable Network Graphics files (*.png)\nAll files (*.*)"); + { + QStringList fmts; + QList formats = QImageReader::supportedImageFormats(); + for (QList::iterator i = formats.begin(); + i != formats.end(); ++i) { + fmts.push_back(QString("*.%1") + .arg(QString::fromLocal8Bit(*i).toLower())); + } + filter = tr("Image files (%1)\nAll files (*.*)").arg(fmts.join(" ")); + } break; case AnyFile: diff -r 73537d900d4b -r 726b32522e3f data/model/ImageModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/model/ImageModel.h Thu Oct 04 16:34:11 2007 +0000 @@ -0,0 +1,135 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006-2007 Chris Cannam and QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef _IMAGE_MODEL_H_ +#define _IMAGE_MODEL_H_ + +#include "SparseModel.h" +#include "base/XmlExportable.h" +#include "base/RealTime.h" + +/** + * Image point type for use in a SparseModel. This represents an + * image, identified by filename, at a given time. The filename can + * be empty, in which case we instead have a space to put an image in. + */ + +struct ImagePoint : public XmlExportable +{ +public: + ImagePoint(long _frame) : frame(_frame) { } + ImagePoint(long _frame, QString _image, QString _label) : + frame(_frame), image(_image), label(_label) { } + + int getDimensions() const { return 1; } + + long frame; + QString image; + QString label; + + QString toXmlString(QString indent = "", + QString extraAttributes = "") const + { + return QString("%1\n") + .arg(indent).arg(frame) + .arg(encodeEntities(image)) + .arg(encodeEntities(label)) + .arg(extraAttributes); + } + + QString toDelimitedDataString(QString delimiter, size_t sampleRate) const + { + QStringList list; + list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str(); + list << image; + list << label; + return list.join(delimiter); + } + + struct Comparator { + bool operator()(const ImagePoint &p1, + const ImagePoint &p2) const { + if (p1.frame != p2.frame) return p1.frame < p2.frame; + if (p1.label != p2.label) return p1.label < p2.label; + return p1.image < p2.image; + } + }; + + struct OrderComparator { + bool operator()(const ImagePoint &p1, + const ImagePoint &p2) const { + return p1.frame < p2.frame; + } + }; +}; + + +// Make this a class rather than a typedef so it can be predeclared. + +class ImageModel : public SparseModel +{ +public: + ImageModel(size_t sampleRate, size_t resolution, bool notifyOnAdd = true) : + SparseModel(sampleRate, resolution, notifyOnAdd) + { } + + virtual void toXml(QTextStream &out, + QString indent = "", + QString extraAttributes = "") const + { + SparseModel::toXml + (out, + indent, + QString("%1 subtype=\"image\"") + .arg(extraAttributes)); + } + + /** + * Command to change the image for a point. + */ + class ChangeImageCommand : public Command + { + public: + ChangeImageCommand(ImageModel *model, + const ImagePoint &point, + QString newImage, + QString newLabel) : + m_model(model), m_oldPoint(point), m_newPoint(point) { + m_newPoint.image = newImage; + m_newPoint.label = newLabel; + } + + virtual QString getName() const { return tr("Edit Image"); } + + virtual void execute() { + m_model->deletePoint(m_oldPoint); + m_model->addPoint(m_newPoint); + std::swap(m_oldPoint, m_newPoint); + } + + virtual void unexecute() { execute(); } + + private: + ImageModel *m_model; + ImagePoint m_oldPoint; + ImagePoint m_newPoint; + }; +}; + + +#endif + + + diff -r 73537d900d4b -r 726b32522e3f data/model/TextModel.h --- a/data/model/TextModel.h Thu Oct 04 11:52:38 2007 +0000 +++ b/data/model/TextModel.h Thu Oct 04 16:34:11 2007 +0000 @@ -17,6 +17,7 @@ #define _TEXT_MODEL_H_ #include "SparseModel.h" +#include "base/XmlExportable.h" #include "base/RealTime.h" /** @@ -25,7 +26,7 @@ * of height on the window). Intended for casual textual annotations. */ -struct TextPoint +struct TextPoint : public XmlExportable { public: TextPoint(long _frame) : frame(_frame), height(0.0f) { } @@ -42,7 +43,8 @@ QString extraAttributes = "") const { return QString("%1\n") - .arg(indent).arg(frame).arg(height).arg(label).arg(extraAttributes); + .arg(indent).arg(frame).arg(height) + .arg(encodeEntities(label)).arg(extraAttributes); } QString toDelimitedDataString(QString delimiter, size_t sampleRate) const