some more work on collabsible albums. I think I will need to optimize the playlist...
[amarok.git] / src / xmlloader.h
blob57d3311a4e8ca6cdc2eec8e0ac91325b4f31caec
1 /*
2 Copyright (c) 2006 Gábor Lehel <illissius@gmail.com>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
21 #ifndef AMAROK_XML_LOADER_H
22 #define AMAROK_XML_LOADER_H
24 #include "metabundle.h"
26 #include <QEvent>
27 #include <QObject>
28 #include <QtXml/QXmlInputSource>
29 #include <QtXml/QXmlSimpleReader>
30 #include <Q3ValueList>
33 /**
34 * Used for loading XML of the format outputted by MetaBundle::save(),
35 * back into MetaBundle form.
36 * There are four ways of using it:
37 * - the simplest is to use MetaBundle::XmlLoader::loadBundles(), which just
38 * returns a BundleList of the loaded MetaBundles, to load all the bundles
39 * synchronously in a single shot
40 * - you can create a MetaBundle::XmlLoader object and ask it to load(), and
41 * connect to the newBundle() signal to receive the loaded bundles, to load
42 * the bundles synchronously, but one-by-one
43 * - you can use MetaBundle::XmlLoader::loadInThread(), and the loaded bundles
44 * will get posted as BundleLoadedEvents to the object you specify; this way
45 * you can load asynchronously
46 * - or you can derive from MetaBundle::XmlLoader, reimplement the relevant
47 * functions, and do whatever you want
50 /** The type used for extra XML attributes not recognized. */
51 typedef Q3ValueList< QPair<QString, QString> > XmlAttributeList;
52 Q_DECLARE_METATYPE(XmlAttributeList)
55 class MetaBundle::XmlLoader: public QObject, public QXmlDefaultHandler
57 Q_OBJECT
58 public:
59 /** Posted when a MetaBundle has been loaded. */
60 class BundleLoadedEvent: public QEvent
62 public:
63 /** The type() of BundleLoadedEvents. */
64 static const int BundleLoadedEventType = QEvent::User + 127;
66 /** Whether an error occurred. If yes, both bundle and extraAttributes are empty. */
67 bool error;
69 /** A description of the error, if there was one. */
70 QString errorMessage;
72 /** The loaded bundle. */
73 MetaBundle bundle;
75 /** Any extra attributes not recognized. */
76 Q3ValueList< QPair<QString, QString> > extraAttributes;
78 public:
79 BundleLoadedEvent( const MetaBundle &b, const XmlAttributeList &a )
80 : QEvent( Type( BundleLoadedEventType ) ), error( false ), bundle( b ), extraAttributes( a ) { }
81 BundleLoadedEvent( const QString &error )
82 : QEvent( Type( BundleLoadedEventType ) ), error( true ), errorMessage( error ) { }
85 public:
86 /** Construct a MetaBundle::XmlLoader. */
87 XmlLoader();
89 /** Destruct. */
90 virtual ~XmlLoader();
92 /**
93 * Load bundles from \p source. The loaded bundles will be emitted as
94 * newBundle() signals, and if you provide a \p target, also sent as
95 * BundleLoadedEvents to \p target. In case of a fatal error,
96 * processing will stop and false will be returned, and an empty
97 * BundleLoadedEvent with the error flag set will be sent to \p target,
98 * if one is provided.
99 * @param source the source to load from
100 * @param target the target to send events to; if none is provided,
101 * none will be sent
102 * @return whether a fatal error occurred
103 * @see newBundle
104 * @see BundleLoadedEvent
106 bool load( QXmlInputSource *source, QObject *target = 0 );
108 /** Aborts loading. */
109 void abort();
111 /** Returns the last error encountered; empty if there hasn't been an error. */
112 QString lastError() const;
115 * Load bundles from \p source. If a fatal error occurs, processing
116 * will stop and the list of complete bundles at that point will be
117 * returned, and \p ok will be set to true, if provided.
118 * @param source the source to load from
119 * @param ok if provided, will be set to false if a fatal error occurs,
120 and to true otherwise
121 * @return the list of loaded bundles
123 static BundleList loadBundles( QXmlInputSource *source, bool *ok = 0 );
126 * Load bundles from \p source in a separate thread. The loaded bundles
127 * will be posted as BundleLoadedEvents to \p target. If an error
128 * occurs, processing will stop and an empty BundleLoadedEvent will be
129 * posted with the error flag set to true.
130 * This function returns immediately after being called.
131 * @param source the source to load from
132 * @param target the object to post BundleLoadedEvents to
133 * @see BundleLoadedEvent
135 static void loadInThread( QXmlInputSource *source, QObject *target );
137 signals:
139 * Emitted by load() whenever a MetaBundle has been loaded.
140 * @param bundle the loaded MetaBundle
141 * @param extraAttributes any extra attributes in the XML not recognized
143 void newBundle( const MetaBundle &bundle, const XmlAttributeList &extraAttributes );
145 /** Emitted when an error occurs. */
146 void error( const QString &errorMessage );
148 protected:
149 virtual void newAttribute( const QString &key, const QString &value );
150 virtual void newTag( const QString &name, const QString &value );
151 virtual void bundleLoaded();
152 virtual void errorEncountered( const QString &message, int line, int column );
154 protected:
155 /** The bundle currently being loaded. */
156 MetaBundle m_bundle;
158 /** Unrecognized attributes in the XML for the currently loading bundle. */
159 XmlAttributeList m_attributes;
161 /** The message from the last error encountered, empty if there hasn't been an error. */
162 QString m_lastError;
164 /** Whether we have been abort()ed. */
165 bool m_aborted;
167 private:
168 QXmlSimpleReader m_reader;
169 QString m_currentElement;
170 QObject *m_target;
172 protected:
173 virtual bool startElement( const QString&, const QString&, const QString &, const QXmlAttributes& );
174 virtual bool endElement( const QString &namespaceURI, const QString &localName, const QString &qName );
175 virtual bool characters( const QString &ch );
176 virtual bool endDocument();
177 virtual bool fatalError( const QXmlParseException &exception );
179 public: //fucking moc, these should be private
180 class ThreadedLoader;
181 class SimpleLoader;
185 #endif