23#include <KoFilterManager.h>
24#include <KoFilterManager_p.h>
30#include <tqapplication.h>
33#include <tdemessagebox.h>
34#include <KoDocument.h>
35#include <klibloader.h>
36#include <tdelistbox.h>
44class KoFilterManager::Private
51KoFilterChooser::KoFilterChooser (TQWidget *parent,
const TQStringList &mimeTypes,
const TQString &nativeFormat)
52 :
KDialogBase (parent,
"kofilterchooser", true, i18n (
"Choose Filter"),
54 m_mimeTypes (mimeTypes)
56 setInitialSize (TQSize (300, 350));
58 TQWidget *page =
new TQWidget (
this);
62 TQVBoxLayout *layout =
new TQVBoxLayout (page, marginHint (), spacingHint () * 2);
64 TQLabel *filterLabel =
new TQLabel (i18n (
"Select a filter:"), page,
"filterlabel");
65 layout->addWidget (filterLabel);
67 m_filterList =
new TDEListBox (page,
"filterlist");
68 layout->addWidget (m_filterList);
70 Q_ASSERT (!m_mimeTypes.isEmpty ());
71 for (TQStringList::ConstIterator it = m_mimeTypes.begin ();
72 it != m_mimeTypes.end ();
75 KMimeType::Ptr mime = KMimeType::mimeType (*it);
76 m_filterList->insertItem (mime->comment ());
79 if (nativeFormat ==
"application/x-kword")
81 const int index = m_mimeTypes.findIndex (
"text/plain");
83 m_filterList->setCurrentItem (index);
86 if (m_filterList->currentItem () == -1)
87 m_filterList->setCurrentItem (0);
89 m_filterList->centerCurrentItem ();
90 m_filterList->setFocus ();
92 connect (m_filterList, TQ_SIGNAL (selected (
int)),
this, TQ_SLOT (slotOk ()));
95KoFilterChooser::~KoFilterChooser ()
99TQString KoFilterChooser::filterSelected ()
101 const int item = m_filterList->currentItem ();
104 return m_mimeTypes [item];
111TQMap<TQString, bool> KoFilterManager::m_filterAvailable;
113const int KoFilterManager::s_area = 30500;
117 m_document( document ), m_parentChain( 0 ), m_graph(
"" ), d( 0 )
119 d =
new KoFilterManager::Private;
120 d -> m_batch =
false;
122 TQObject::connect(
this, TQ_SIGNAL( sigProgress(
int ) ),
123 document, TQ_SIGNAL( sigProgress(
int ) ) );
129 m_document( 0 ), m_parentChain( parentChain ), m_importUrl( url ), m_importUrlMimetypeHint( mimetypeHint ),
130 m_graph(
"" ), d( 0 )
132 d =
new KoFilterManager::Private;
133 d -> m_batch =
false;
136KoFilterManager::~KoFilterManager()
146 KMimeType::Ptr t = KMimeType::findByURL( u, 0,
true );
148 m_graph.setSourceMimeType( t->name().latin1() );
149 if ( !m_graph.isValid() ) {
150 bool userCancelled =
false;
152 kdWarning(s_area) <<
"Can't open " << t->name () <<
", trying filter chooser" << endl;
155 if ( !m_document->isAutoErrorHandlingEnabled() )
157 status = KoFilter::BadConversionGraph;
160 TQCString nativeFormat = m_document->nativeFormatMimeType ();
162 TQApplication::setOverrideCursor( arrowCursor );
163 KoFilterChooser chooser(0,
168 TQCString f = chooser.filterSelected ().latin1();
170 if (f == nativeFormat)
172 status = KoFilter::OK;
173 TQApplication::restoreOverrideCursor();
177 m_graph.setSourceMimeType (f);
180 userCancelled =
true;
181 TQApplication::restoreOverrideCursor();
184 if (!m_graph.isValid())
186 kdError(s_area) <<
"Couldn't create a valid graph for this source mimetype: "
187 << t->name() << endl;
188 importErrorHelper( t->name(), userCancelled );
189 status = KoFilter::BadConversionGraph;
194 KoFilterChain::Ptr chain( 0 );
197 TQCString mimeType = m_document->nativeFormatMimeType();
198 TQStringList extraMimes = m_document->extraNativeMimeTypes();
199 int i=0, n = extraMimes.count();
200 chain = m_graph.chain(
this, mimeType );
201 while( !chain && i<n) {
202 mimeType = extraMimes[i].utf8();
203 chain = m_graph.chain(
this, mimeType );
208 kdError(s_area) <<
"You aren't supposed to use import() from a filter!" << endl;
209 status = KoFilter::UsageError;
214 kdError(s_area) <<
"Couldn't create a valid filter chain!" << endl;
215 importErrorHelper( t->name() );
216 status = KoFilter::BadConversionGraph;
221 m_direction = Import;
223 m_exportUrl = TQString();
225 status = chain->invokeChain();
227 m_importUrl = TQString();
229 if ( status == KoFilter::OK )
230 return chain->chainOutput();
236 bool userCancelled =
false;
240 m_direction = Export;
243 KoFilterChain::Ptr chain = 0;
246 TQStringList nativeMimeTypes;
247 nativeMimeTypes.append( m_document->nativeFormatMimeType() );
248 nativeMimeTypes += m_document->extraNativeMimeTypes();
249 TQStringList::ConstIterator it = nativeMimeTypes.begin();
250 const TQStringList::ConstIterator end = nativeMimeTypes.end();
251 for ( ; !chain && it != end; ++it )
253 m_graph.setSourceMimeType( (*it).latin1() );
254 if ( m_graph.isValid() )
255 chain = m_graph.chain(
this, mimeType );
258 else if ( !m_importUrlMimetypeHint.isEmpty() ) {
259 kdDebug(s_area) <<
"Using the mimetype hint: '" << m_importUrlMimetypeHint <<
"'" << endl;
260 m_graph.setSourceMimeType( m_importUrlMimetypeHint );
264 u.setPath( m_importUrl );
265 KMimeType::Ptr t = KMimeType::findByURL( u, 0,
true );
266 if ( t->name() == KMimeType::defaultMimeType() ) {
267 kdError(s_area) <<
"No mimetype found for " << m_importUrl << endl;
268 return KoFilter::BadMimeType;
270 m_graph.setSourceMimeType( t->name().latin1() );
272 if ( !m_graph.isValid() ) {
273 kdWarning(s_area) <<
"Can't open " << t->name () <<
", trying filter chooser" << endl;
275 TQApplication::setOverrideCursor( arrowCursor );
278 m_graph.setSourceMimeType (chooser.filterSelected ().latin1 ());
280 userCancelled =
true;
282 TQApplication::restoreOverrideCursor();
286 if (!m_graph.isValid ())
288 kdError(s_area) <<
"Couldn't create a valid graph for this source mimetype." << endl;
289 if (!userCancelled)
KMessageBox::error( 0L, i18n(
"Could not export file."), i18n(
"Missing Export Filter") );
290 return KoFilter::BadConversionGraph;
294 chain = m_graph.chain(
this, mimeType );
297 kdError(s_area) <<
"Couldn't create a valid filter chain to " << mimeType <<
" !" << endl;
298 KMessageBox::error( 0L, i18n(
"Could not export file."), i18n(
"Missing Export Filter") );
299 return KoFilter::BadConversionGraph;
302 return chain->invokeChain();
311 Vertex(
const TQCString& mimeType ) : m_color( White ), m_mimeType( mimeType ) {}
313 enum Color { White, Gray, Black };
314 Color color()
const {
return m_color; }
315 void setColor( Color color ) { m_color = color; }
317 TQCString mimeType()
const {
return m_mimeType; }
319 void addEdge( Vertex* vertex ) {
if ( vertex ) m_edges.append( vertex ); }
320 TQPtrList<Vertex> edges()
const {
return m_edges; }
324 TQCString m_mimeType;
325 TQPtrList<Vertex> m_edges;
332 TQStringList stopList;
333 stopList <<
"text/plain";
334 stopList <<
"text/csv";
335 stopList <<
"text/x-tex";
336 stopList <<
"text/html";
338 vertices.setAutoDelete(
true );
343 TQValueList<KoDocumentEntry>::ConstIterator partIt( parts.begin() );
344 TQValueList<KoDocumentEntry>::ConstIterator partEnd( parts.end() );
346 while ( partIt != partEnd ) {
347 TQStringList nativeMimeTypes = ( *partIt ).service()->property(
"X-TDE-ExtraNativeMimeTypes" ).toStringList();
348 nativeMimeTypes += ( *partIt ).service()->property(
"X-TDE-NativeMimeType" ).toString();
349 TQStringList::ConstIterator it = nativeMimeTypes.begin();
350 const TQStringList::ConstIterator end = nativeMimeTypes.end();
351 for ( ; it != end; ++it )
352 if ( !(*it).isEmpty() )
353 vertices.insert( (*it).latin1(),
new Vertex( (*it).latin1() ) );
358 TQValueList<KoFilterEntry::Ptr>::ConstIterator it = filters.begin();
359 const TQValueList<KoFilterEntry::Ptr>::ConstIterator end = filters.end();
361 for ( ; it != end; ++it ) {
363 TQStringList impList;
364 TQStringList expList;
366 const TQStringList::Iterator stopEnd = stopList.end();
368 if ( direction == KoFilterManager::Import ) {
370 TQStringList::ConstIterator testIt = ( *it )->export_.begin();
371 TQStringList::ConstIterator testEnd = ( *it )->export_.end();
372 for ( ; testIt != testEnd ; ++testIt ) {
373 if ( stopList.find( *testIt ) == stopEnd ) {
374 expList.append( *testIt );
377 impList = ( *it )->import;
381 TQStringList::ConstIterator testIt = ( *it )->import.begin();
382 const TQStringList::ConstIterator testEnd = ( *it )->import.end();
383 for ( ; testIt != testEnd ; ++testIt ) {
384 if ( stopList.find( *testIt ) == stopEnd ) {
385 impList.append( *testIt );
388 expList = ( *it )->export_;
391 if ( impList.empty() || expList.empty() )
394 kdDebug( 30500 ) <<
"Filter: " << ( *it )->service()->name() <<
" ruled out" << endl;
399 TQStringList::ConstIterator importIt = impList.begin();
400 const TQStringList::ConstIterator importEnd = impList.end();
401 for ( ; importIt != importEnd; ++importIt ) {
402 const TQCString key = ( *importIt ).latin1();
404 if ( !vertices[ key ] )
405 vertices.insert( key,
new Vertex( key ) );
410 TQStringList::ConstIterator exportIt = expList.begin();
411 const TQStringList::ConstIterator exportEnd = expList.end();
413 for ( ; exportIt != exportEnd; ++exportIt ) {
415 const TQCString key = ( *exportIt ).latin1();
416 Vertex* exp = vertices[ key ];
418 exp =
new Vertex( key );
419 vertices.insert( key, exp );
425 importIt = impList.begin();
426 if ( direction == KoFilterManager::Import ) {
427 for ( ; importIt != importEnd; ++importIt )
428 exp->addEdge( vertices[ ( *importIt ).latin1() ] );
430 for ( ; importIt != importEnd; ++importIt )
431 vertices[ ( *importIt ).latin1() ]->addEdge( exp );
436 kdDebug( 30500 ) <<
"Filter: " << ( *it )->service()->name() <<
" does not apply." << endl;
443 TQStringList connected(
const TQAsciiDict<Vertex>& vertices,
const TQCString& mimetype )
445 if ( mimetype.isEmpty() )
446 return TQStringList();
447 Vertex *v = vertices[ mimetype ];
449 return TQStringList();
451 v->setColor( Vertex::Gray );
452 std::queue<Vertex*> queue;
454 TQStringList connected;
456 while ( !queue.empty() ) {
459 TQPtrList<Vertex> edges = v->edges();
460 TQPtrListIterator<Vertex> it( edges );
461 for ( ; it.current(); ++it ) {
462 if ( it.current()->color() == Vertex::White ) {
463 it.current()->setColor( Vertex::Gray );
464 queue.push( it.current() );
467 v->setColor( Vertex::Black );
468 connected.append( v->mimeType() );
479 TQAsciiDict<Vertex> vertices;
480 buildGraph( vertices, direction );
484 TQStringList nativeMimeTypes;
485 nativeMimeTypes.append( TQString::fromLatin1( mimetype ) );
486 nativeMimeTypes += extraNativeMimeTypes;
489 TQStringList lst = nativeMimeTypes;
492 for( TQStringList::ConstIterator natit = nativeMimeTypes.begin(); natit != nativeMimeTypes.end(); ++natit ) {
493 const TQStringList outMimes = connected( vertices, (*natit).latin1() );
495 for ( TQStringList::ConstIterator mit = outMimes.begin(); mit != outMimes.end(); ++mit )
496 if ( lst.find( *mit ) == lst.end() )
504 TQAsciiDict<Vertex> vertices;
505 buildGraph( vertices, KoFilterManager::Import );
508 TQValueList<KoDocumentEntry>::ConstIterator partIt( parts.begin() );
509 TQValueList<KoDocumentEntry>::ConstIterator partEnd( parts.end() );
511 if ( partIt == partEnd )
512 return TQStringList();
519 Vertex *v =
new Vertex(
"supercalifragilistic/x-pialadocious" );
520 vertices.insert(
"supercalifragilistic/x-pialadocious", v );
521 while ( partIt != partEnd ) {
522 TQStringList nativeMimeTypes = ( *partIt ).service()->property(
"X-TDE-ExtraNativeMimeTypes" ).toStringList();
523 nativeMimeTypes += ( *partIt ).service()->property(
"X-TDE-NativeMimeType" ).toString();
524 TQStringList::ConstIterator it = nativeMimeTypes.begin();
525 const TQStringList::ConstIterator end = nativeMimeTypes.end();
526 for ( ; it != end; ++it )
527 if ( !(*it).isEmpty() )
528 v->addEdge( vertices[ (*it).latin1() ] );
531 TQStringList result = connected( vertices,
"supercalifragilistic/x-pialadocious" );
534 result.remove(
"supercalifragilistic/x-pialadocious" );
544 if ( entry->available !=
"check" )
549 TQString key( entry->service()->name() );
551 key += entry->service()->library();
553 if ( !m_filterAvailable.contains( key ) ) {
556 KLibrary* library = KLibLoader::self()->library( TQFile::encodeName( entry->service()->library() ) );
558 kdWarning( 30500 ) <<
"Huh?? Couldn't load the lib: "
559 << KLibLoader::self()->lastErrorMessage() << endl;
560 m_filterAvailable[ key ] =
false;
566 symname.sprintf(
"check_%s", library->name().latin1() );
567 void* sym = library->symbol( symname );
570 kdWarning( 30500 ) <<
"The library " << library->name()
571 <<
" does not offer a check_" << library->name()
572 <<
" function." << endl;
573 m_filterAvailable[ key ] =
false;
576 typedef int (*t_func)();
577 t_func check = (t_func)sym;
578 m_filterAvailable[ key ] = check() == 1;
581 return m_filterAvailable[ key ];
584void KoFilterManager::importErrorHelper(
const TQString& mimeType,
const bool suppressDialog )
586 TQString tmp = i18n(
"Could not import file of type\n%1").arg( mimeType );
601#include <KoFilterManager.moc>
602#include <KoFilterManager_p.moc>
static void error(TQWidget *parent, const TQString &text, const TQString &caption=TQString::null, int options=Notify)
static TQValueList< KoDocumentEntry > query(const TQString &_constr=TQString())
This function will query tdesycoca to find all available components.
The KOffice document class.
This class represents a chain of plain KoFilter instances.
static TQValueList< KoFilterEntry::Ptr > query(const TQString &_constr=TQString())
This function will query KDED to find all available filters.
static KOFFICECORE_EXPORT TQStringList mimeFilter(const TQCString &mimetype, Direction direction, const TQStringList &extraNativeMimeTypes=TQStringList())
Suitable for passing to KFileDialog::setMimeFilter.
Direction
This enum is used to distinguish the import/export cases.
static TQStringList mimeFilter()
The same method as KoFilterManager::mimeFilter but suited for KoShell.
void setBatchMode(const bool batch)
Set the filter manager is batch mode (no dialog shown) instead of the interactive mode (dialog shown)...
static bool filterAvailable(KoFilterEntry::Ptr entry)
Method used to check if that filter is available at all.
TQString import(const TQString &url, KoFilter::ConversionStatus &status)
Imports the passed URL and returns the resultant filename (most likely some file in /tmp).
bool getBatchMode(void) const
Get if the filter manager is batch mode (true) or in interactive mode (true).
KoFilter::ConversionStatus exp0rt(const TQString &url, TQCString &mimeType)
Exports the given file/document to the specified URL/mimetype.
KoFilterManager(KoDocument *document)
Create a filter manager for a document.
ConversionStatus
This enum is used to signal the return state of your filter.