/* Copyright (c) 2006 Gábor Lehel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef AMAROK_XML_LOADER_H #define AMAROK_XML_LOADER_H #include #include #include #include "metabundle.h" /** * Used for loading XML of the format outputted by MetaBundle::save(), * back into MetaBundle form. * There are four ways of using it: * - the simplest is to use MetaBundle::XmlLoader::loadBundles(), which just * returns a BundleList of the loaded MetaBundles, to load all the bundles * synchronously in a single shot * - you can create a MetaBundle::XmlLoader object and ask it to load(), and * connect to the newBundle() signal to receive the loaded bundles, to load * the bundles synchronously, but one-by-one * - you can use MetaBundle::XmlLoader::loadInThread(), and the loaded bundles * will get posted as BundleLoadedEvents to the object you specify; this way * you can load asynchronously * - or you can derive from MetaBundle::XmlLoader, reimplement the relevant * functions, and do whatever you want */ /** The type used for extra XML attributes not recognized. */ typedef TQValueList< TQPair > XmlAttributeList; class MetaBundle::XmlLoader: public TQObject, public TQXmlDefaultHandler { Q_OBJECT TQ_OBJECT public: /** Posted when a MetaBundle has been loaded. */ class BundleLoadedEvent: public TQCustomEvent { public: /** The type() of BundleLoadedEvents. */ static const int Type = TQEvent::User + 127; /** Whether an error occurred. If yes, both bundle and extraAttributes are empty. */ bool error; /** A description of the error, if there was one. */ TQString errorMessage; /** The loaded bundle. */ MetaBundle bundle; /** Any extra attributes not recognized. */ TQValueList< TQPair > extraAttributes; public: BundleLoadedEvent( const MetaBundle &b, const XmlAttributeList &a ) : TQCustomEvent( Type ), error( false ), bundle( b ), extraAttributes( a ) { } BundleLoadedEvent( const TQString &error ) : TQCustomEvent( Type ), error( true ), errorMessage( error ) { } }; public: /** Construct a MetaBundle::XmlLoader. */ XmlLoader(); /** Destruct. */ virtual ~XmlLoader(); /** * Load bundles from \p source. The loaded bundles will be emitted as * newBundle() signals, and if you provide a \p target, also sent as * BundleLoadedEvents to \p target. In case of a fatal error, * processing will stop and false will be returned, and an empty * BundleLoadedEvent with the error flag set will be sent to \p target, * if one is provided. * @param source the source to load from * @param target the target to send events to; if none is provided, * none will be sent * @return whether a fatal error occurred * @see newBundle * @see BundleLoadedEvent */ bool load( TQXmlInputSource *source, TQObject *target = 0 ); /** Aborts loading. */ void abort(); /** Returns the last error encountered; empty if there hasn't been an error. */ TQString lastError() const; /** * Load bundles from \p source. If a fatal error occurs, processing * will stop and the list of complete bundles at that point will be * returned, and \p ok will be set to true, if provided. * @param source the source to load from * @param ok if provided, will be set to false if a fatal error occurs, and to true otherwise * @return the list of loaded bundles */ static BundleList loadBundles( TQXmlInputSource *source, bool *ok = 0 ); /** * Load bundles from \p source in a separate thread. The loaded bundles * will be posted as BundleLoadedEvents to \p target. If an error * occurs, processing will stop and an empty BundleLoadedEvent will be * posted with the error flag set to true. * This function returns immediately after being called. * @param source the source to load from * @param target the object to post BundleLoadedEvents to * @see BundleLoadedEvent */ static void loadInThread( TQXmlInputSource *source, TQObject *target ); signals: /** * Emitted by load() whenever a MetaBundle has been loaded. * @param bundle the loaded MetaBundle * @param extraAttributes any extra attributes in the XML not recognized */ void newBundle( const MetaBundle &bundle, const XmlAttributeList &extraAttributes ); /** Emitted when an error occurs. */ void error( const TQString &errorMessage ); protected: virtual void newAttribute( const TQString &key, const TQString &value ); virtual void newTag( const TQString &name, const TQString &value ); virtual void bundleLoaded(); virtual void errorEncountered( const TQString &message, int line, int column ); protected: /** The bundle currently being loaded. */ MetaBundle m_bundle; /** Unrecognized attributes in the XML for the currently loading bundle. */ XmlAttributeList m_attributes; /** The message from the last error encountered, empty if there hasn't been an error. */ TQString m_lastError; /** Whether we have been abort()ed. */ bool m_aborted; private: TQXmlSimpleReader m_reader; TQString m_currentElement; TQObject *m_target; protected: virtual bool startElement( const TQString&, const TQString&, const TQString &, const TQXmlAttributes& ); virtual bool endElement( const TQString &namespaceURI, const TQString &localName, const TQString &qName ); virtual bool characters( const TQString &ch ); virtual bool endDocument(); virtual bool fatalError( const TQXmlParseException &exception ); public: //fucking tqmoc, these should be private class ThreadedLoader; class SimpleLoader; }; #endif