lib

KoFilterChain.h
1/* This file is part of the KOffice libraries
2 Copyright (C) 2001 Werner Trobin <trobin@kde.org>
3
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 version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17*/
18
19#ifndef __koffice_filter_chain_h__
20#define __koffice_filter_chain_h__
21
22#include <tqcstring.h>
23#include <tqasciidict.h>
24#include <tqptrlist.h>
25#include <tqstringlist.h>
26
27#include <KoFilter.h>
28#include <KoQueryTrader.h>
29#include <KoStoreDevice.h>
30#include <koffice_export.h>
31
32class KTempFile;
33class KoFilterManager;
34class KoDocument;
35class TQStrList;
36
37namespace KOffice {
38 class Graph;
39}
40
50class KOFFICECORE_EXPORT KoFilterChain : public TDEShared
51{
52 // Only KOffice::Graph is allowed to construct instances and
53 // add chain links.
54 friend class KOffice::Graph;
55 friend class KoFilterManager;
56
57public:
58 typedef TDESharedPtr<KoFilterChain> Ptr;
59
60 virtual ~KoFilterChain();
61
65 const KoFilterManager* manager() const { return m_manager; }
66
72 KoFilter::ConversionStatus invokeChain();
73
79 TQString chainOutput() const;
80
85 TQString inputFile();
90 TQString outputFile();
91
102 KoStoreDevice* storageFile( const TQString& name = "root", KoStore::Mode mode = KoStore::Read );
103
110 KoDocument* inputDocument();
117 KoDocument* outputDocument();
118
119
120 // debugging
121 void dump() const;
122
123private:
124 // ### API for KOffice::Graph:
125 // Construct a filter chain belonging to some KoFilterManager.
126 // The parent filter manager may be 0.
127 KoFilterChain( const KoFilterManager* manager );
128
129 void appendChainLink( KoFilterEntry::Ptr filterEntry, const TQCString& from, const TQCString& to );
130 void prependChainLink( KoFilterEntry::Ptr filterEntry, const TQCString& from, const TQCString& to );
131
132 // ### API for KoEmbeddingFilter
133 // This is needed as the embedding filter might have to influence
134 // the way we change directories (e.g. in the olefilter case)
135 // The ugly friend methods are needed, but I'd welcome and suggestions for
136 // better design :}
137 friend void KoEmbeddingFilter::filterChainEnterDirectory( const TQString& directory ) const;
138 void enterDirectory( const TQString& directory );
139 friend void KoEmbeddingFilter::filterChainLeaveDirectory() const;
140 void leaveDirectory();
141
142 // These methods are friends of KoFilterManager and provide access
143 // to a private part of its API. As I don't want to include
144 // koFilterManager.h in this header the direction is "int" here.
145 TQString filterManagerImportFile() const;
146 TQString filterManagerExportFile() const;
147 KoDocument* filterManagerKoDocument() const;
148 int filterManagerDirection() const;
149 KoFilterChain* const filterManagerParentChain() const;
150
151
152 // Helper methods which keep track of all the temp files, documents,
153 // storages,... and properly delete them as soon as they are not
154 // needed anymore.
155 void manageIO();
156 void finalizeIO();
157
158 bool createTempFile( KTempFile** tempFile, bool autoDelete = true );
159
160 void inputFileHelper( KoDocument* document, const TQString& alternativeFile );
161 void outputFileHelper( bool autoDelete );
162 KoStoreDevice* storageNewStreamHelper( KoStore** storage, KoStoreDevice** device, const TQString& name );
163 KoStoreDevice* storageHelper( const TQString& file, const TQString& streamName,
164 KoStore::Mode mode, KoStore** storage, KoStoreDevice** device );
165 void storageInit( const TQString& file, KoStore::Mode mode, KoStore** storage );
166 KoStoreDevice* storageInitEmbedding( const TQString& name );
167 KoStoreDevice* storageCreateFirstStream( const TQString& streamName, KoStore** storage, KoStoreDevice** device );
168 KoStoreDevice* storageCleanupHelper( KoStore** storage );
169
170 KoDocument* createDocument( const TQString& file );
171 KoDocument* createDocument( const TQCString& mimeType );
172
178 class ChainLink
179 {
180
181 public:
182 ChainLink( KoFilterChain* chain, KoFilterEntry::Ptr filterEntry,
183 const TQCString& from, const TQCString& to );
184
185 KoFilter::ConversionStatus invokeFilter( const ChainLink* const parentChainLink );
186
187 TQCString from() const { return m_from; }
188 TQCString to() const { return m_to; }
189
190 // debugging
191 void dump() const;
192
193 // This hack is only needed due to crappy Microsoft design and
194 // circular dependencies in their embedded files :}
195 int lruPartIndex() const;
196
197 private:
198 ChainLink( const ChainLink& rhs );
199 ChainLink& operator=( const ChainLink& rhs );
200
201 void setupCommunication( const KoFilter* const parentFilter ) const;
202 void setupConnections( const KoFilter* sender, const TQStrList& sigs,
203 const KoFilter* receiver, const TQStrList& sl0ts ) const;
204
205 KoFilterChain* m_chain;
206 KoFilterEntry::Ptr m_filterEntry;
207 TQCString m_from, m_to;
208
209 // This hack is only needed due to crappy Microsoft design and
210 // circular dependencies in their embedded files :}
211 KoFilter* m_filter;
212
213 class Private;
214 Private* d;
215 };
216
217 // "A whole is that which has beginning, middle, and end" - Aristotle
218 // ...but we also need to signal "Done" state, Mr. Aristotle
219 enum Whole { Beginning = 1, Middle = 2, End = 4, Done = 8 };
220
221 // Don't copy or assign filter chains
222 KoFilterChain( const KoFilterChain& rhs );
223 KoFilterChain& operator=( const KoFilterChain& rhs );
224
225 const KoFilterManager* const m_manager;
226 TQPtrList<ChainLink> m_chainLinks;
227
228 // stuff needed for bookkeeping
229 int m_state;
230
231 TQString m_inputFile; // Did we pass around plain files?
232 TQString m_outputFile;
233
234 KoStore* m_inputStorage; // ...or was it a storage+device?
235 KoStoreDevice* m_inputStorageDevice;
236 KoStore* m_outputStorage;
237 KoStoreDevice* m_outputStorageDevice;
238
239 KoDocument* m_inputDocument; // ...or even documents?
240 KoDocument* m_outputDocument;
241
242 KTempFile* m_inputTempFile;
243 KTempFile* m_outputTempFile;
244
245 // These two flags keep track of the input/output the
246 // filter (=user) asked for
247 enum IOState { Nil, File, Storage, Document };
248 IOState m_inputQueried, m_outputQueried;
249
250 // This stack keeps track of directories we have to enter and
251 // leave due to internal embedding a la OLE filters. This serves
252 // as a kind of "memory" even if we didn't initialize the store yet.
253 // I know that it's ugly, and I'll try to clean up that hack
254 // sooner or later (Werner)
255 TQStringList m_internalEmbeddingDirectories;
256
257 class Private;
258 Private* d;
259};
260
261
262// As we use quite generic classnames...
263namespace KOffice
264{
265 class Vertex;
266 template<class T> class PriorityQueue;
267
272 class Edge
273 {
274
275 public:
276 // creates a new edge to "vertex" with the given weight.
277 Edge( Vertex* vertex, KoFilterEntry::Ptr filterEntry );
278 ~Edge() {}
279
280 unsigned int weight() const { return m_filterEntry ? m_filterEntry->weight : 0; }
281 KoFilterEntry::Ptr filterEntry() const { return m_filterEntry; }
282 const Vertex* vertex() const { return m_vertex; }
283
284 // Relaxes the "connected" vertex (i.e. the weight of the
285 // connected vertex = "predec.->key()" (parameter) + weight of this edge
286 // As this will only be called once we calculate the weight
287 // of the edge "on the fly"
288 // Note: We have to pass the queue as we have to call keyDecreased :}
289 void relax( const Vertex* predecessor, PriorityQueue<Vertex>& queue );
290
291 // debugging
292 void dump( const TQCString& indent ) const;
293
294 private:
295 Edge( const Edge& rhs );
296 Edge& operator=( const Edge& rhs );
297
298 Vertex* m_vertex;
299 KoFilterEntry::Ptr m_filterEntry;
300
301 class Private;
302 Private* d;
303 };
304
305
310 class Vertex
311 {
312
313 public:
314 Vertex( const TQCString& mimeType );
315 ~Vertex() {}
316
317 TQCString mimeType() const { return m_mimeType; }
318
319 // Current "weight" of the vertex - will be "relaxed" when
320 // running the shortest path algorithm. Returns true if it
321 // really has been "relaxed"
322 bool setKey( unsigned int key );
323 unsigned int key() const { return m_weight; }
324 // Can be used to set the key back to "Infinity" (UINT_MAX)
325 // and reset the predecessor of this vertex
326 void reset();
327
328 // Position in the heap, needed for a fast keyDecreased operation
329 void setIndex( int index ) { m_index=index; }
330 int index() const { return m_index; }
331
332 // predecessor on the way from the source to the destination,
333 // needed for the shortest path algorithm
334 void setPredecessor( const Vertex* predecessor ) { m_predecessor=predecessor; }
335 const Vertex* predecessor() const { return m_predecessor; }
336
337 // Adds an outgoing edge to the vertex, transfers ownership
338 void addEdge( const Edge* edge );
339 // Finds the lightest(!) edge pointing to the given vertex, if any (0 if not found)
340 // This means it will always search the whole list of edges
341 const Edge* findEdge( const Vertex* vertex ) const;
342
343 // This method is called when we need to relax all "our" edges.
344 // We need to pass the queue as we have to notify it about key changes - ugly :(
345 void relaxVertices( PriorityQueue<Vertex>& queue );
346
347 // debugging
348 void dump( const TQCString& indent ) const;
349
350 private:
351 Vertex( const Vertex& rhs );
352 Vertex& operator=( const Vertex& rhs );
353
354 TQPtrList<Edge> m_edges;
355 const Vertex* m_predecessor;
356 TQCString m_mimeType;
357 unsigned int m_weight; // "key" inside the queue
358 int m_index; // position inside the queue, needed for a fast keyDecreased()
359
360 class Private;
361 Private* d;
362 };
363
364
370 class Graph
371 {
372
373 public:
374 Graph( const TQCString& from );
375 ~Graph() {}
376
377 bool isValid() const { return m_graphValid; }
378
379 TQCString sourceMimeType() const { return m_from; }
380 void setSourceMimeType( const TQCString& from );
381
382 // Creates a chain from "from" to the "to" mimetype
383 // If the "to" mimetype isEmpty() then we try to find the
384 // closest KOffice mimetype and use that as destination.
385 // After such a search "to" will contain the dest. mimetype (return value)
386 // if the search was successful. Might return 0!
387 KoFilterChain::Ptr chain( const KoFilterManager* manager, TQCString& to ) const;
388
389 // debugging
390 void dump() const;
391
392 private:
393 Graph( const Graph& rhs );
394 Graph& operator=( const Graph& rhs );
395
396 void buildGraph();
397 void shortestPaths();
398 TQCString findKOfficePart() const;
399
400 TQAsciiDict<Vertex> m_vertices;
401 TQCString m_from;
402 bool m_graphValid;
403
404 class Private;
405 Private* d;
406 };
407
408} // namespace KOffice
409
410#endif // __koffice_filter_chain_h__
An internal class representing a filter (=edge) in the filter graph.
The main worker behind the scenes.
This PriorityQueue class is implemented as "upside down" heap, i.e.
An internal class representing a mime type (=node, vertex) in the filter graph.
The KOffice document class.
Definition KoDocument.h:61
This class represents a chain of plain KoFilter instances.
const KoFilterManager * manager() const
The filter manager returned may be 0!
The class managing all the filters.
ConversionStatus
This enum is used to signal the return state of your filter.
Definition KoFilter.h:64
This class implements a TQIODevice around KoStore, so that it can be used to create a TQDomDocument f...
Saves and loads KOffice documents using various backends.
Definition KoStore.h:40
Namespace for general KOFFICE functions.