lib

KoFilterManager.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003                  2000, 2001 Werner Trobin <trobin@kde.org>
00004    Copyright (C) 2004 Nicolas Goutte <goutte@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 
00023 #include <KoFilterManager.h>
00024 #include <KoFilterManager_p.h>
00025 
00026 #include <qfile.h>
00027 #include <qlabel.h>
00028 #include <qlayout.h>
00029 #include <qptrlist.h>
00030 #include <qapplication.h>
00031 
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <KoDocument.h>
00035 #include <klibloader.h>
00036 #include <klistbox.h>
00037 #include <kmimetype.h>
00038 #include <kdebug.h>
00039 
00040 #include <queue>
00041 
00042 #include <unistd.h>
00043 
00044 class KoFilterManager::Private
00045 {
00046 public:
00047     bool m_batch;
00048 };
00049 
00050 
00051 KoFilterChooser::KoFilterChooser (QWidget *parent, const QStringList &mimeTypes, const QString &nativeFormat)
00052     : KDialogBase (parent, "kofilterchooser", true, i18n ("Choose Filter"),
00053                    KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, true),
00054     m_mimeTypes (mimeTypes)
00055 {
00056     setInitialSize (QSize (300, 350));
00057 
00058     QWidget *page = new QWidget (this);
00059     setMainWidget (page);
00060 
00061     // looks too squashed together without * 2
00062     QVBoxLayout *layout = new QVBoxLayout (page, marginHint (), spacingHint () * 2);
00063 
00064     QLabel *filterLabel = new QLabel (i18n ("Select a filter:"), page, "filterlabel");
00065     layout->addWidget (filterLabel);
00066 
00067     m_filterList = new KListBox (page, "filterlist");
00068     layout->addWidget (m_filterList);
00069 
00070     Q_ASSERT (!m_mimeTypes.isEmpty ());
00071     for (QStringList::ConstIterator it = m_mimeTypes.begin ();
00072             it != m_mimeTypes.end ();
00073             it++)
00074     {
00075         KMimeType::Ptr mime = KMimeType::mimeType (*it);
00076         m_filterList->insertItem (mime->comment ());
00077     }
00078 
00079     if (nativeFormat == "application/x-kword")
00080     {
00081         const int index = m_mimeTypes.findIndex ("text/plain");
00082         if (index > -1)
00083             m_filterList->setCurrentItem (index);
00084     }
00085 
00086     if (m_filterList->currentItem () == -1)
00087         m_filterList->setCurrentItem (0);
00088 
00089     m_filterList->centerCurrentItem ();
00090     m_filterList->setFocus ();
00091 
00092     connect (m_filterList, SIGNAL (selected (int)), this, SLOT (slotOk ()));
00093 }
00094 
00095 KoFilterChooser::~KoFilterChooser ()
00096 {
00097 }
00098 
00099 QString KoFilterChooser::filterSelected ()
00100 {
00101     const int item = m_filterList->currentItem ();
00102 
00103     if (item > -1)
00104         return m_mimeTypes [item];
00105     else
00106         return QString::null;
00107 }
00108 
00109 
00110 // static cache for filter availability
00111 QMap<QString, bool> KoFilterManager::m_filterAvailable;
00112 
00113 const int KoFilterManager::s_area = 30500;
00114 
00115 
00116 KoFilterManager::KoFilterManager( KoDocument* document ) :
00117     m_document( document ), m_parentChain( 0 ), m_graph( "" ), d( 0 )
00118 {
00119     d = new KoFilterManager::Private;
00120     d -> m_batch = false;
00121     if ( document )
00122         QObject::connect( this, SIGNAL( sigProgress( int ) ),
00123                           document, SIGNAL( sigProgress( int ) ) );
00124 }
00125 
00126 
00127 KoFilterManager::KoFilterManager( const QString& url, const QCString& mimetypeHint,
00128                                   KoFilterChain* const parentChain ) :
00129     m_document( 0 ), m_parentChain( parentChain ), m_importUrl( url ), m_importUrlMimetypeHint( mimetypeHint ),
00130     m_graph( "" ), d( 0 )
00131 {
00132     d = new KoFilterManager::Private;
00133     d -> m_batch = false;
00134 }
00135 
00136 KoFilterManager::~KoFilterManager()
00137 {
00138     delete d;
00139 }
00140 
00141 QString KoFilterManager::import( const QString& url, KoFilter::ConversionStatus& status )
00142 {
00143     // Find the mime type for the file to be imported.
00144     KURL u;
00145     u.setPath( url );
00146     KMimeType::Ptr t = KMimeType::findByURL( u, 0, true );
00147     if ( t->name() == KMimeType::defaultMimeType() ) {
00148         kdError(s_area) << "No mimetype found for " << url << endl;
00149         status = KoFilter::BadMimeType;
00150         return QString::null;
00151     }
00152 
00153     m_graph.setSourceMimeType( t->name().latin1() );  // .latin1() is okay here (Werner)
00154     if ( !m_graph.isValid() ) {
00155         bool userCancelled = false;
00156 
00157         kdWarning(s_area) << "Can't open " << t->name () << ", trying filter chooser" << endl;
00158         if ( m_document )
00159         {
00160         if ( !m_document->isAutoErrorHandlingEnabled() )
00161         {
00162         status = KoFilter::BadConversionGraph;
00163         return QString::null;
00164         }
00165             QCString nativeFormat = m_document->nativeFormatMimeType ();
00166 
00167             QApplication::setOverrideCursor( arrowCursor );
00168             KoFilterChooser chooser(0,
00169                                     KoFilterManager::mimeFilter (nativeFormat, KoFilterManager::Import, m_document->extraNativeMimeTypes()),
00170                                     nativeFormat);
00171             if (chooser.exec ())
00172             {
00173                 QCString f = chooser.filterSelected ().latin1();
00174 
00175                 if (f == nativeFormat)
00176                 {
00177                     status = KoFilter::OK;
00178                     QApplication::restoreOverrideCursor();
00179                     return url;
00180                 }
00181 
00182                 m_graph.setSourceMimeType (f);
00183             }
00184             else
00185                 userCancelled = true;
00186             QApplication::restoreOverrideCursor();
00187         }
00188 
00189         if (!m_graph.isValid())
00190         {
00191             kdError(s_area) << "Couldn't create a valid graph for this source mimetype: "
00192                             << t->name() << endl;
00193             importErrorHelper( t->name(), userCancelled );
00194             status = KoFilter::BadConversionGraph;
00195             return QString::null;
00196         }
00197     }
00198 
00199     KoFilterChain::Ptr chain( 0 );
00200     // Are we owned by a KoDocument?
00201     if ( m_document ) {
00202         QCString mimeType = m_document->nativeFormatMimeType();
00203         QStringList extraMimes = m_document->extraNativeMimeTypes();
00204         int i=0, n = extraMimes.count();
00205         chain = m_graph.chain( this, mimeType );
00206         while( !chain && i<n) {
00207             mimeType = extraMimes[i].utf8();
00208             chain = m_graph.chain( this, mimeType );
00209             ++i;
00210         }
00211     }
00212     else {
00213         kdError(s_area) << "You aren't supposed to use import() from a filter!" << endl;
00214         status = KoFilter::UsageError;
00215         return QString::null;
00216     }
00217 
00218     if ( !chain ) {
00219         kdError(s_area) << "Couldn't create a valid filter chain!" << endl;
00220         importErrorHelper( t->name() );
00221         status = KoFilter::BadConversionGraph;
00222         return QString::null;
00223     }
00224 
00225     // Okay, let's invoke the filters one after the other
00226     m_direction = Import; // vital information!
00227     m_importUrl = url;  // We want to load that file
00228     m_exportUrl = QString::null;  // This is null for sure, as embedded stuff isn't
00229                                   // allowed to use that method
00230     status = chain->invokeChain();
00231 
00232     m_importUrl = QString::null;  // Reset the import URL
00233 
00234     if ( status == KoFilter::OK )
00235         return chain->chainOutput();
00236     return QString::null;
00237 }
00238 
00239 KoFilter::ConversionStatus KoFilterManager::exp0rt( const QString& url, QCString& mimeType )
00240 {
00241     bool userCancelled = false;
00242 
00243     // The import url should already be set correctly (null if we have a KoDocument
00244     // file manager and to the correct URL if we have an embedded manager)
00245     m_direction = Export; // vital information!
00246     m_exportUrl = url;
00247 
00248     KoFilterChain::Ptr chain = 0;
00249     if ( m_document ) {
00250         // We have to pick the right native mimetype as source.
00251         QStringList nativeMimeTypes;
00252         nativeMimeTypes.append( m_document->nativeFormatMimeType() );
00253         nativeMimeTypes += m_document->extraNativeMimeTypes();
00254         QStringList::ConstIterator it = nativeMimeTypes.begin();
00255         const QStringList::ConstIterator end = nativeMimeTypes.end();
00256         for ( ; !chain && it != end; ++it )
00257         {
00258             m_graph.setSourceMimeType( (*it).latin1() );
00259             if ( m_graph.isValid() )
00260                 chain = m_graph.chain( this, mimeType );
00261         }
00262     }
00263     else if ( !m_importUrlMimetypeHint.isEmpty() ) {
00264         kdDebug(s_area) << "Using the mimetype hint: '" << m_importUrlMimetypeHint << "'" << endl;
00265         m_graph.setSourceMimeType( m_importUrlMimetypeHint );
00266     }
00267     else {
00268         KURL u;
00269         u.setPath( m_importUrl );
00270         KMimeType::Ptr t = KMimeType::findByURL( u, 0, true );
00271         if ( t->name() == KMimeType::defaultMimeType() ) {
00272             kdError(s_area) << "No mimetype found for " << m_importUrl << endl;
00273             return KoFilter::BadMimeType;
00274         }
00275         m_graph.setSourceMimeType( t->name().latin1() );
00276 
00277         if ( !m_graph.isValid() ) {
00278             kdWarning(s_area) << "Can't open " << t->name () << ", trying filter chooser" << endl;
00279 
00280             QApplication::setOverrideCursor( arrowCursor );
00281             KoFilterChooser chooser(0, KoFilterManager::mimeFilter ());
00282             if (chooser.exec ())
00283                 m_graph.setSourceMimeType (chooser.filterSelected ().latin1 ());
00284             else
00285                 userCancelled = true;
00286 
00287             QApplication::restoreOverrideCursor();
00288         }
00289     }
00290 
00291     if (!m_graph.isValid ())
00292     {
00293         kdError(s_area) << "Couldn't create a valid graph for this source mimetype." << endl;
00294         if (!userCancelled) KMessageBox::error( 0L, i18n("Could not export file."), i18n("Missing Export Filter") );
00295         return KoFilter::BadConversionGraph;
00296     }
00297 
00298     if ( !chain ) // already set when coming from the m_document case
00299         chain = m_graph.chain( this, mimeType );
00300 
00301     if ( !chain ) {
00302         kdError(s_area) << "Couldn't create a valid filter chain to " << mimeType << " !" << endl;
00303         KMessageBox::error( 0L, i18n("Could not export file."), i18n("Missing Export Filter") );
00304         return KoFilter::BadConversionGraph;
00305     }
00306 
00307     return chain->invokeChain();
00308 }
00309 
00310 namespace  // in order not to mess with the global namespace ;)
00311 {
00312     // This class is needed only for the static mimeFilter method
00313     class Vertex
00314     {
00315     public:
00316         Vertex( const QCString& mimeType ) : m_color( White ), m_mimeType( mimeType ) {}
00317 
00318         enum Color { White, Gray, Black };
00319         Color color() const { return m_color; }
00320         void setColor( Color color ) { m_color = color; }
00321 
00322         QCString mimeType() const { return m_mimeType; }
00323 
00324         void addEdge( Vertex* vertex ) { if ( vertex ) m_edges.append( vertex ); }
00325         QPtrList<Vertex> edges() const { return m_edges; }
00326 
00327     private:
00328         Color m_color;
00329         QCString m_mimeType;
00330         QPtrList<Vertex> m_edges;
00331     };
00332 
00333     // Some helper methods for the static stuff
00334     // This method builds up the graph in the passed ascii dict
00335     void buildGraph( QAsciiDict<Vertex>& vertices, KoFilterManager::Direction direction )
00336     {
00337         QStringList stopList; // Lists of mimetypes that are considered end of chains
00338         stopList << "text/plain";
00339         stopList << "text/csv";
00340         stopList << "text/x-tex";
00341         stopList << "text/html";
00342 
00343         vertices.setAutoDelete( true );
00344 
00345         // partly copied from build graph, but I don't see any other
00346         // way without crude hacks, as we have to obey the direction here
00347         QValueList<KoDocumentEntry> parts( KoDocumentEntry::query(false, QString::null) );
00348         QValueList<KoDocumentEntry>::ConstIterator partIt( parts.begin() );
00349         QValueList<KoDocumentEntry>::ConstIterator partEnd( parts.end() );
00350 
00351         while ( partIt != partEnd ) {
00352             QStringList nativeMimeTypes = ( *partIt ).service()->property( "X-KDE-ExtraNativeMimeTypes" ).toStringList();
00353             nativeMimeTypes += ( *partIt ).service()->property( "X-KDE-NativeMimeType" ).toString();
00354             QStringList::ConstIterator it = nativeMimeTypes.begin();
00355             const QStringList::ConstIterator end = nativeMimeTypes.end();
00356             for ( ; it != end; ++it )
00357                 if ( !(*it).isEmpty() )
00358                     vertices.insert( (*it).latin1(), new Vertex( (*it).latin1() ) );
00359             ++partIt;
00360         }
00361 
00362         QValueList<KoFilterEntry::Ptr> filters = KoFilterEntry::query(); // no constraint here - we want *all* :)
00363         QValueList<KoFilterEntry::Ptr>::ConstIterator it = filters.begin();
00364         const QValueList<KoFilterEntry::Ptr>::ConstIterator end = filters.end();
00365 
00366         for ( ; it != end; ++it ) {
00367 
00368             QStringList impList; // Import list
00369             QStringList expList; // Export list
00370 
00371             const QStringList::Iterator stopEnd = stopList.end();
00372             // Now we have to exclude the "stop" mimetypes (in the right direction!)
00373             if ( direction == KoFilterManager::Import ) {
00374                 // Import: "stop" mime type should not appear in export
00375                 QStringList::ConstIterator testIt = ( *it )->export_.begin();
00376                 QStringList::ConstIterator testEnd = ( *it )->export_.end();
00377                 for ( ; testIt != testEnd ; ++testIt ) {
00378                     if ( stopList.find( *testIt ) == stopEnd ) {
00379                         expList.append( *testIt );
00380                     }
00381                 }
00382                 impList = ( *it )->import;
00383             }
00384             else {
00385                 // Export: "stop" mime type should not appear in import
00386                 QStringList::ConstIterator testIt = ( *it )->import.begin();
00387                 const QStringList::ConstIterator testEnd = ( *it )->import.end();
00388                 for ( ; testIt != testEnd ; ++testIt ) {
00389                     if ( stopList.find( *testIt ) == stopEnd ) {
00390                         impList.append( *testIt );
00391                     }
00392                 }
00393                 expList = ( *it )->export_;
00394             }
00395 
00396             if ( impList.empty() || expList.empty() )
00397             {
00398                 // This filter cannot be used under these conditions
00399                 kdDebug( 30500 ) << "Filter: " << ( *it )->service()->name() << " ruled out" << endl;
00400                 continue;
00401             }
00402 
00403             // First add the "starting points" to the dict
00404             QStringList::ConstIterator importIt = impList.begin();
00405             const QStringList::ConstIterator importEnd = impList.end();
00406             for ( ; importIt != importEnd; ++importIt ) {
00407                 const QCString key = ( *importIt ).latin1();  // latin1 is okay here (werner)
00408                 // already there?
00409                 if ( !vertices[ key ] )
00410                     vertices.insert( key, new Vertex( key ) );
00411             }
00412 
00413             // Are we allowed to use this filter at all?
00414             if ( KoFilterManager::filterAvailable( *it ) ) {
00415                 QStringList::ConstIterator exportIt = expList.begin();
00416                 const QStringList::ConstIterator exportEnd = expList.end();
00417 
00418                 for ( ; exportIt != exportEnd; ++exportIt ) {
00419                     // First make sure the export vertex is in place
00420                     const QCString key = ( *exportIt ).latin1();  // latin1 is okay here
00421                     Vertex* exp = vertices[ key ];
00422                     if ( !exp ) {
00423                         exp = new Vertex( key );
00424                         vertices.insert( key, exp );
00425                     }
00426                     // Then create the appropriate edges depending on the
00427                     // direction (import/export)
00428                     // This is the chunk of code which actually differs from the
00429                     // graph stuff (apart from the different vertex class)
00430                     importIt = impList.begin(); // ### TODO: why only the first one?
00431                     if ( direction == KoFilterManager::Import ) {
00432                         for ( ; importIt != importEnd; ++importIt )
00433                             exp->addEdge( vertices[ ( *importIt ).latin1() ] );
00434                     } else {
00435                         for ( ; importIt != importEnd; ++importIt )
00436                             vertices[ ( *importIt ).latin1() ]->addEdge( exp );
00437                     }
00438                 }
00439             }
00440             else
00441                 kdDebug( 30500 ) << "Filter: " << ( *it )->service()->name() << " does not apply." << endl;
00442         }
00443     }
00444 
00445     // This method runs a BFS on the graph to determine the connected
00446     // nodes. Make sure that the graph is "cleared" (the colors of the
00447     // nodes are all white)
00448     QStringList connected( const QAsciiDict<Vertex>& vertices, const QCString& mimetype )
00449     {
00450         if ( mimetype.isEmpty() )
00451             return QStringList();
00452         Vertex *v = vertices[ mimetype ];
00453         if ( !v )
00454             return QStringList();
00455 
00456         v->setColor( Vertex::Gray );
00457         std::queue<Vertex*> queue;
00458         queue.push( v );
00459         QStringList connected;
00460 
00461         while ( !queue.empty() ) {
00462             v = queue.front();
00463             queue.pop();
00464             QPtrList<Vertex> edges = v->edges();
00465             QPtrListIterator<Vertex> it( edges );
00466             for ( ; it.current(); ++it ) {
00467                 if ( it.current()->color() == Vertex::White ) {
00468                     it.current()->setColor( Vertex::Gray );
00469                     queue.push( it.current() );
00470                 }
00471             }
00472             v->setColor( Vertex::Black );
00473             connected.append( v->mimeType() );
00474         }
00475         return connected;
00476     }
00477 }
00478 
00479 // The static method to figure out to which parts of the
00480 // graph this mimetype has a connection to.
00481 QStringList KoFilterManager::mimeFilter( const QCString& mimetype, Direction direction, const QStringList& extraNativeMimeTypes )
00482 {
00483     //kdDebug(s_area) << "mimetype=" << mimetype << " extraNativeMimeTypes=" << extraNativeMimeTypes << endl;
00484     QAsciiDict<Vertex> vertices;
00485     buildGraph( vertices, direction );
00486 
00487     // TODO maybe use the fake vertex trick from the method below, to make the search faster?
00488 
00489     QStringList nativeMimeTypes;
00490     nativeMimeTypes.append( QString::fromLatin1( mimetype ) );
00491     nativeMimeTypes += extraNativeMimeTypes;
00492 
00493     // Add the native mimetypes first so that they are on top.
00494     QStringList lst = nativeMimeTypes;
00495 
00496     // Now look for filters which output each of those natives mimetypes
00497     for( QStringList::ConstIterator natit = nativeMimeTypes.begin(); natit != nativeMimeTypes.end(); ++natit ) {
00498         const QStringList outMimes = connected( vertices, (*natit).latin1() );
00499         //kdDebug(s_area) << k_funcinfo << "output formats connected to mime " << *natit << " : " << outMimes << endl;
00500         for ( QStringList::ConstIterator mit = outMimes.begin(); mit != outMimes.end(); ++mit )
00501             if ( lst.find( *mit ) == lst.end() ) // append only if not there already. Qt4: QSet<QString>?
00502                 lst.append( *mit );
00503     }
00504     return lst;
00505 }
00506 
00507 QStringList KoFilterManager::mimeFilter()
00508 {
00509     QAsciiDict<Vertex> vertices;
00510     buildGraph( vertices, KoFilterManager::Import );
00511 
00512     QValueList<KoDocumentEntry> parts( KoDocumentEntry::query(false, QString::null) );
00513     QValueList<KoDocumentEntry>::ConstIterator partIt( parts.begin() );
00514     QValueList<KoDocumentEntry>::ConstIterator partEnd( parts.end() );
00515 
00516     if ( partIt == partEnd )
00517         return QStringList();
00518 
00519     // To find *all* reachable mimetypes, we have to resort to
00520     // a small hat trick, in order to avoid multiple searches:
00521     // We introduce a fake vertex, which is connected to every
00522     // single KOffice mimetype. Due to that one BFS is enough :)
00523     // Now we just need an... ehrm.. unique name for our fake mimetype
00524     Vertex *v = new Vertex( "supercalifragilistic/x-pialadocious" );
00525     vertices.insert( "supercalifragilistic/x-pialadocious", v );
00526     while ( partIt != partEnd ) {
00527         QStringList nativeMimeTypes = ( *partIt ).service()->property( "X-KDE-ExtraNativeMimeTypes" ).toStringList();
00528         nativeMimeTypes += ( *partIt ).service()->property( "X-KDE-NativeMimeType" ).toString();
00529         QStringList::ConstIterator it = nativeMimeTypes.begin();
00530         const QStringList::ConstIterator end = nativeMimeTypes.end();
00531         for ( ; it != end; ++it )
00532             if ( !(*it).isEmpty() )
00533                 v->addEdge( vertices[ (*it).latin1() ] );
00534         ++partIt;
00535     }
00536     QStringList result = connected( vertices, "supercalifragilistic/x-pialadocious" );
00537 
00538     // Finally we have to get rid of our fake mimetype again
00539     result.remove( "supercalifragilistic/x-pialadocious" );
00540     return result;
00541 }
00542 
00543 // Here we check whether the filter is available. This stuff is quite slow,
00544 // but I don't see any other convenient (for the user) way out :}
00545 bool KoFilterManager::filterAvailable( KoFilterEntry::Ptr entry )
00546 {
00547     if ( !entry )
00548         return false;
00549     if ( entry->available != "check" )
00550         return true;
00551 
00552     //kdDebug( 30500 ) << "Checking whether " << entry->service()->name() << " applies." << endl;
00553     // generate some "unique" key
00554     QString key( entry->service()->name() );
00555     key += " - ";
00556     key += entry->service()->library();
00557 
00558     if ( !m_filterAvailable.contains( key ) ) {
00559         //kdDebug( 30500 ) << "Not cached, checking..." << endl;
00560 
00561         KLibrary* library = KLibLoader::self()->library( QFile::encodeName( entry->service()->library() ) );
00562         if ( !library ) {
00563             kdWarning( 30500 ) << "Huh?? Couldn't load the lib: "
00564                                << KLibLoader::self()->lastErrorMessage() << endl;
00565             m_filterAvailable[ key ] = false;
00566             return false;
00567         }
00568 
00569         // This code is "borrowed" from klibloader ;)
00570         QCString symname;
00571         symname.sprintf("check_%s", library->name().latin1() );
00572         void* sym = library->symbol( symname );
00573         if ( !sym )
00574         {
00575             kdWarning( 30500 ) << "The library " << library->name()
00576                                << " does not offer a check_" << library->name()
00577                                << " function." << endl;
00578             m_filterAvailable[ key ] = false;
00579         }
00580         else {
00581             typedef int (*t_func)();
00582             t_func check = (t_func)sym;
00583             m_filterAvailable[ key ] = check() == 1;
00584         }
00585     }
00586     return m_filterAvailable[ key ];
00587 }
00588 
00589 void KoFilterManager::importErrorHelper( const QString& mimeType, const bool suppressDialog )
00590 {
00591     QString tmp = i18n("Could not import file of type\n%1").arg( mimeType );
00592     // ###### FIXME: use KLibLoader::lastErrorMessage() here
00593     if (!suppressDialog) KMessageBox::error( 0L, tmp, i18n("Missing Import Filter") );
00594 }
00595 
00596 void KoFilterManager::setBatchMode( const bool batch )
00597 {
00598     d->m_batch = batch;
00599 }
00600 
00601 bool KoFilterManager::getBatchMode( void ) const
00602 {
00603     return d->m_batch;
00604 }
00605 
00606 #include <KoFilterManager.moc>
00607 #include <KoFilterManager_p.moc>
KDE Home | KDE Accessibility Home | Description of Access Keys