lib Library API Documentation

koFilterChain.h

00001 /* This file is part of the KOffice libraries
00002    Copyright (C) 2001 Werner Trobin <trobin@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00016    Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #ifndef __koffice_filter_chain_h__
00020 #define __koffice_filter_chain_h__
00021 
00022 #include <qcstring.h>
00023 #include <qasciidict.h>
00024 #include <qptrlist.h>
00025 #include <qstringlist.h>
00026 
00027 #include <koFilter.h>
00028 #include <koQueryTrader.h>
00029 #include <koStoreDevice.h>
00030 
00031 class KTempFile;
00032 class KoFilterManager;
00033 class KoDocument;
00034 class QStrList;
00035 
00036 namespace KOffice {
00037     class Graph;
00038 }
00039 
00048 class KoFilterChain : public KShared
00049 {
00050     // Only KOffice::Graph is allowed to construct instances and
00051     // add chain links.
00052     friend class KOffice::Graph;
00053     friend class KoFilterManager;
00054 
00055 public:
00056     typedef KSharedPtr<KoFilterChain> Ptr;
00057 
00058     virtual ~KoFilterChain();
00059 
00063     const KoFilterManager* manager() const { return m_manager; }
00064 
00070     KoFilter::ConversionStatus invokeChain();
00071 
00077     QString chainOutput() const;
00078 
00083     QString inputFile();
00088     QString outputFile();
00089 
00100     KoStoreDevice* storageFile( const QString& name = "root", KoStore::Mode mode = KoStore::Read );
00101 
00108     KoDocument* inputDocument();
00115     KoDocument* outputDocument();
00116 
00117 
00118     // debugging
00119     void dump() const;
00120 
00121 private:
00122     // ### API for KOffice::Graph:
00123     // Construct a filter chain belonging to some KoFilterManager.
00124     // The parent filter manager may be 0.
00125     KoFilterChain( const KoFilterManager* manager );
00126 
00127     void appendChainLink( KoFilterEntry::Ptr filterEntry, const QCString& from, const QCString& to );
00128     void prependChainLink( KoFilterEntry::Ptr filterEntry, const QCString& from, const QCString& to );
00129 
00130     // ### API for KoEmbeddingFilter
00131     // This is needed as the embedding filter might have to influence
00132     // the way we change directories (e.g. in the olefilter case)
00133     // The ugly friend methods are needed, but I'd welcome and suggestions for
00134     // better design :}
00135     friend void KoEmbeddingFilter::filterChainEnterDirectory( const QString& directory ) const;
00136     void enterDirectory( const QString& directory );
00137     friend void KoEmbeddingFilter::filterChainLeaveDirectory() const;
00138     void leaveDirectory();
00139 
00140     // These methods are friends of KoFilterManager and provide access
00141     // to a private part of its API. As I don't want to include
00142     // koFilterManager.h in this header the direction is "int" here.
00143     QString filterManagerImportFile() const;
00144     QString filterManagerExportFile() const;
00145     KoDocument* filterManagerKoDocument() const;
00146     int filterManagerDirection() const;
00147     KoFilterChain* const filterManagerParentChain() const;
00148 
00149 
00150     // Helper methods which keep track of all the temp files, documents,
00151     // storages,... and properly delete them as soon as they are not
00152     // needed anymore.
00153     void manageIO();
00154     void finalizeIO();
00155 
00156     bool createTempFile( KTempFile** tempFile, bool autoDelete = true );
00157 
00158     void inputFileHelper( KoDocument* document, const QString& alternativeFile );
00159     void outputFileHelper( bool autoDelete );
00160     KoStoreDevice* storageNewStreamHelper( KoStore** storage, KoStoreDevice** device, const QString& name );
00161     KoStoreDevice* storageHelper( const QString& file, const QString& streamName,
00162                                   KoStore::Mode mode, KoStore** storage, KoStoreDevice** device );
00163     void storageInit( const QString& file, KoStore::Mode mode, KoStore** storage );
00164     KoStoreDevice* storageInitEmbedding( const QString& name );
00165     KoStoreDevice* storageCreateFirstStream( const QString& streamName, KoStore** storage, KoStoreDevice** device );
00166     KoStoreDevice* storageCleanupHelper( KoStore** storage );
00167 
00168     KoDocument* createDocument( const QString& file );
00169     KoDocument* createDocument( const QCString& mimeType );
00170 
00171     // A small private helper class with represents one single filter
00172     // (one link of the chain)
00173     class ChainLink
00174     {
00175 
00176     public:
00177         ChainLink( KoFilterChain* chain, KoFilterEntry::Ptr filterEntry,
00178                    const QCString& from, const QCString& to );
00179 
00180         KoFilter::ConversionStatus invokeFilter( const ChainLink* const parentChainLink );
00181 
00182         QCString from() const { return m_from; }
00183         QCString to() const { return m_to; }
00184 
00185         // debugging
00186         void dump() const;
00187 
00188         // This hack is only needed due to crappy Microsoft design and
00189         // circular dependencies in their embedded files :}
00190         int lruPartIndex() const;
00191 
00192     private:
00193         ChainLink( const ChainLink& rhs );
00194         ChainLink& operator=( const ChainLink& rhs );
00195 
00196         void setupCommunication( const KoFilter* const parentFilter ) const;
00197         void setupConnections( const KoFilter* sender, const QStrList& sigs,
00198                                const KoFilter* receiver, const QStrList& sl0ts ) const;
00199 
00200         KoFilterChain* m_chain;
00201         KoFilterEntry::Ptr m_filterEntry;
00202         QCString m_from, m_to;
00203 
00204         // This hack is only needed due to crappy Microsoft design and
00205         // circular dependencies in their embedded files :}
00206         KoFilter* m_filter;
00207 
00208         class Private;
00209         Private* d;
00210     };
00211 
00212     // "A whole is that which has beginning, middle, and end" - Aristotle
00213     // ...but we also need to signal "Done" state, Mr. Aristotle
00214     enum Whole { Beginning = 1, Middle = 2, End = 4, Done = 8 };
00215 
00216     // Don't copy or assign filter chains
00217     KoFilterChain( const KoFilterChain& rhs );
00218     KoFilterChain& operator=( const KoFilterChain& rhs );
00219 
00220     const KoFilterManager* const m_manager;
00221     QPtrList<ChainLink> m_chainLinks;
00222 
00223     // stuff needed for bookkeeping
00224     int m_state;
00225 
00226     QString m_inputFile;              // Did we pass around plain files?
00227     QString m_outputFile;
00228 
00229     KoStore* m_inputStorage;          // ...or was it a storage+device?
00230     KoStoreDevice* m_inputStorageDevice;
00231     KoStore* m_outputStorage;
00232     KoStoreDevice* m_outputStorageDevice;
00233 
00234     KoDocument* m_inputDocument;      // ...or even documents?
00235     KoDocument* m_outputDocument;
00236 
00237     KTempFile* m_inputTempFile;
00238     KTempFile* m_outputTempFile;
00239 
00240     // These two flags keep track of the input/output the
00241     // filter (=user) asked for
00242     enum IOState { Nil, File, Storage, Document };
00243     IOState m_inputQueried, m_outputQueried;
00244 
00245     // This stack keeps track of directories we have to enter and
00246     // leave due to internal embedding a la OLE filters. This serves
00247     // as a kind of "memory" even if we didn't initialize the store yet.
00248     // I know that it's ugly, and I'll try to clean up that hack
00249     // sooner or later (Werner)
00250     QStringList m_internalEmbeddingDirectories;
00251 
00252     class Private;
00253     Private* d;
00254 };
00255 
00256 
00257 // As we use quite generic classnames...
00258 namespace KOffice
00259 {
00260     class Vertex;
00261     template<class T> class PriorityQueue;
00262 
00263     // An internal class representing a filter (=edge) in the filter graph.
00264     class Edge
00265     {
00266 
00267     public:
00268         // creates a new edge to "vertex" with the given weight.
00269         Edge( Vertex* vertex, KoFilterEntry::Ptr filterEntry );
00270         ~Edge() {}
00271 
00272         unsigned int weight() const { return m_filterEntry ? m_filterEntry->weight : 0; }
00273         KoFilterEntry::Ptr filterEntry() const { return m_filterEntry; }
00274         const Vertex* vertex() const { return m_vertex; }
00275 
00276         // Relaxes the "connected" vertex (i.e. the weight of the
00277         // connected vertex = "predec.->key()" (parameter) + weight of this edge
00278         // As this will only be called once we calculate the weight
00279         // of the edge "on the fly"
00280         // Note: We have to pass the queue as we have to call keyDecreased :}
00281         void relax( const Vertex* predecessor, PriorityQueue<Vertex>& queue );
00282 
00283         // debugging
00284         void dump( const QCString& indent ) const;
00285 
00286     private:
00287         Edge( const Edge& rhs );
00288         Edge& operator=( const Edge& rhs );
00289 
00290         Vertex* m_vertex;
00291         KoFilterEntry::Ptr m_filterEntry;
00292 
00293         class Private;
00294         Private* d;
00295     };
00296 
00297 
00298     // An internal class representing a mime type (=node, vertex) in the filter graph.
00299     class Vertex
00300     {
00301 
00302     public:
00303         Vertex( const QCString& mimeType );
00304         ~Vertex() {}
00305 
00306         QCString mimeType() const { return m_mimeType; }
00307 
00308         // Current "weight" of the vertex - will be "relaxed" when
00309         // running the shortest path algorithm. Returns true if it
00310         // really has been "relaxed"
00311         bool setKey( unsigned int key );
00312         unsigned int key() const { return m_weight; }
00313         // Can be used to set the key back to "Infinity" (UINT_MAX)
00314         // and reset the predecessor of this vertex
00315         void reset();
00316 
00317         // Position in the heap, needed for a fast keyDecreased operation
00318         void setIndex( int index ) { m_index=index; }
00319         int index() const { return m_index; }
00320 
00321         // predecessor on the way from the source to the destination,
00322         // needed for the shortest path algorithm
00323         void setPredecessor( const Vertex* predecessor ) { m_predecessor=predecessor; }
00324         const Vertex* predecessor() const { return m_predecessor; }
00325 
00326         // Adds an outgoing edge to the vertex, transfers ownership
00327         void addEdge( const Edge* edge );
00328         // Finds the lightest(!) edge pointing to the given vertex, if any (0 if not found)
00329         // This means it will always search the whole list of edges
00330         const Edge* findEdge( const Vertex* vertex ) const;
00331 
00332         // This method is called when we need to relax all "our" edges.
00333         // We need to pass the queue as we have to notify it about key changes - ugly :(
00334         void relaxVertices( PriorityQueue<Vertex>& queue );
00335 
00336         // debugging
00337         void dump( const QCString& indent ) const;
00338 
00339     private:
00340         Vertex( const Vertex& rhs );
00341         Vertex& operator=( const Vertex& rhs );
00342 
00343         QPtrList<Edge> m_edges;
00344         const Vertex* m_predecessor;
00345         QCString m_mimeType;
00346         unsigned int m_weight; // "key" inside the queue
00347         int m_index; // position inside the queue, needed for a fast keyDecreased()
00348 
00349         class Private;
00350         Private* d;
00351     };
00352 
00353 
00354     // The main worker behind the scenes. Manages the creation of the graph,
00355     // processing the information in it, and creating the filter chains.
00356     class Graph
00357     {
00358 
00359     public:
00360         Graph( const QCString& from );
00361         ~Graph() {}
00362 
00363         bool isValid() const { return m_graphValid; }
00364 
00365         QCString sourceMimeType() const { return m_from; }
00366         void setSourceMimeType( const QCString& from );
00367 
00368         // Creates a chain from "from" to the "to" mimetype
00369         // If the "to" mimetype isEmpty() then we try to find the
00370         // closest KOffice mimetype and use that as destination.
00371         // After such a search "to" will contain the dest. mimetype (return value)
00372         // if the search was successful. Might return 0!
00373         KoFilterChain::Ptr chain( const KoFilterManager* manager, QCString& to ) const;
00374 
00375         // debugging
00376         void dump() const;
00377 
00378     private:
00379         Graph( const Graph& rhs );
00380         Graph& operator=( const Graph& rhs );
00381 
00382         void buildGraph();
00383         void shortestPaths();
00384         QCString findKOfficePart() const;
00385 
00386         QAsciiDict<Vertex> m_vertices;
00387         QCString m_from;
00388         bool m_graphValid;
00389 
00390         class Private;
00391         Private* d;
00392     };
00393 
00394 } // namespace KOffice
00395 
00396 #endif // __koffice_filter_chain_h__
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Mar 20 14:25:25 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003