[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    Re: Opening "unsupported" file types
From:       Clarence Dang <dang () kde ! org>
Date:       2003-06-07 12:01:11
[Download RAW message or body]

On Mon, 12 May 2003 04:15 am, David Faure wrote:
> On Sunday 11 May 2003 14:12, Clarence Dang wrote:
> > The attached patch makes KoFilterManager to fall back to the ascii filter
> > if it "can't handle" the source mimetype.  This is so that it can open
> > text files other than text/plain such as .cpp files and files that have
> > been misidentified by magic as something other than text/ascii.
> >
> > It is a real hack and probably only makes sense for KWord.  But as the
> > filter system would normally abort in this situation, we have nothing to
> > lose by trying text/plain.
>
> Seeing vector graphics as "text plain" is going to be very confusing to
> users :) I think there _is_ something to lose here: sensible behaviour :)
>
Maybe the graphics file is in XML :)
But refusing to open text files isn't exactly sensible either.

> Yes, as your comment says: what about popping up a dialog that lets the
> user select the type of the file?
I finally found the time to write it :)
The KoFilterChooser declaration is in the .h file because I couldn't convince 
moc to parse the class otherwise.

Cheers,
Clarence

["koffice-filter-dialog.patch" (text/x-diff)]

Index: koFilterManager.cc
===================================================================
RCS file: /home/kde/koffice/lib/kofficecore/koFilterManager.cc,v
retrieving revision 1.127
diff -u -p -r1.127 koFilterManager.cc
--- koFilterManager.cc	14 May 2003 13:10:18 -0000	1.127
+++ koFilterManager.cc	7 Jun 2003 11:51:27 -0000
@@ -22,13 +22,17 @@
 #include <koFilterManager.h>
 
 #include <qfile.h>
+#include <qlabel.h>
+#include <qlayout.h>
 #include <qptrlist.h>
 #include <qapplication.h>
 
+#include <kdialogbase.h>
 #include <klocale.h>
 #include <kmessagebox.h>
 #include <koDocument.h>
 #include <klibloader.h>
+#include <klistbox.h>
 #include <kmimetype.h>
 #include <kdebug.h>
 
@@ -37,6 +41,80 @@
 #include <unistd.h>
 
 
+KoFilterChooser::KoFilterChooser (QWidget *parent, const QStringList &mimeTypes, \
const QString &nativeFormat) +    : KDialogBase (parent, "kofilterchooser", true, \
i18n ("Choose Filter"), +                   KDialogBase::Ok | KDialogBase::Cancel, \
KDialogBase::Ok, true), +    m_mimeTypes (mimeTypes),
+    d (0)
+{
+    setInitialSize (QSize (300, 350));
+
+    QWidget *page = new QWidget (this);
+    setMainWidget (page);
+
+    // looks too squashed together without * 2
+    QVBoxLayout *layout = new QVBoxLayout (page, marginHint (), spacingHint () * 2);
+
+    QLabel *filterLabel = new QLabel (i18n ("Select a filter:"), page, \
"filterlabel"); +    layout->addWidget (filterLabel);
+
+    m_filterList = new KListBox (page, "filterlist");
+    layout->addWidget (m_filterList);
+
+    Q_ASSERT (!m_mimeTypes.isEmpty ());
+    for (QStringList::ConstIterator it = m_mimeTypes.begin ();
+            it != m_mimeTypes.end ();
+            it++)
+    {
+        KMimeType::Ptr mime = KMimeType::mimeType (*it);
+        m_filterList->insertItem (mime->comment ());
+    }
+
+    if (nativeFormat == "application/x-kword")
+    {
+        const int index = m_mimeTypes.findIndex ("text/plain");
+        if (index > -1)
+            m_filterList->setCurrentItem (index);
+    }
+
+    if (m_filterList->currentItem () == -1)
+        m_filterList->setCurrentItem (0);
+
+    m_filterList->centerCurrentItem ();
+    m_filterList->setFocus ();
+
+    connect (m_filterList, SIGNAL (returnPressed (QListBoxItem *)), this, SLOT \
(slotOk ())); +    connect (m_filterList, SIGNAL (doubleClicked (QListBoxItem *, \
const QPoint &)), this, SLOT (slotOk ())); +}
+
+KoFilterChooser::~KoFilterChooser ()
+{
+}
+
+QString KoFilterChooser::filterSelected ()
+{
+    return m_filterSelected;
+}
+
+void KoFilterChooser::slotOk ()
+{
+    const int item = m_filterList->currentItem ();
+    if (item > -1)
+        m_filterSelected = m_mimeTypes [item];
+    else
+        m_filterSelected = QString::null;
+
+    KDialogBase::slotOk ();
+}
+
+void KoFilterChooser::slotCancel ()
+{
+    m_filterSelected = QString::null;
+
+    KDialogBase::slotCancel ();
+}
+
+
 // static cache for filter availability
 QMap<QString, bool> KoFilterManager::m_filterAvailable;
 
@@ -76,11 +155,43 @@ QString KoFilterManager::import( const Q
 
     m_graph.setSourceMimeType( t->name().latin1() );  // .latin1() is okay here \
(Werner)  if ( !m_graph.isValid() ) {
-        kdError(s_area) << "Couldn't create a valid graph for this source mimetype: \
                "
-                        << t->name() << endl;
-        importErrorHelper( t->name() );
-        status = KoFilter::BadConversionGraph;
-        return QString::null;
+        bool userCancelled = false;
+
+        kdWarning(s_area) << "Can't open " << t->name () << ", trying filter \
chooser" << endl; +        if ( m_document )
+        {
+            QCString nativeFormat = m_document->nativeFormatMimeType ();
+            KoFilterChooser *chooser = new KoFilterChooser
+                                            (0,
+                                            KoFilterManager::mimeFilter \
(nativeFormat, KoFilterManager::Import), +                                            \
nativeFormat); +            chooser->exec ();
+
+            QString f = chooser->filterSelected ();
+            if (f.isEmpty ())
+                userCancelled = true;
+            else
+            {
+                if (f == QString (nativeFormat))
+                {
+                    status = KoFilter::OK;
+                    return url;
+                }
+
+                m_graph.setSourceMimeType (f.latin1 ());
+            }
+
+            delete chooser;
+        }
+
+        if (!m_graph.isValid())
+        {
+            kdError(s_area) << "Couldn't create a valid graph for this source \
mimetype: " +                            << t->name() << endl;
+            importErrorHelper( t->name(), userCancelled );
+            status = KoFilter::BadConversionGraph;
+            return QString::null;
+        }
     }
 
     KoFilterChain::Ptr chain( 0 );
@@ -118,6 +229,8 @@ QString KoFilterManager::import( const Q
 
 KoFilter::ConversionStatus KoFilterManager::exp0rt( const QString& url, QCString& \
mimeType )  {
+    bool userCancelled = false;
+
     // The import url should already be set correctly (null if we have a KoDocument
     // file manager and to the correct URL if we have an embedded manager)
     m_direction = Export; // vital information!
@@ -138,13 +251,29 @@ KoFilter::ConversionStatus KoFilterManag
             return KoFilter::BadMimeType;
         }
         m_graph.setSourceMimeType( t->name().latin1() );
+
+        if ( !m_graph.isValid() ) {
+            kdWarning(s_area) << "Can't open " << t->name () << ", trying filter \
chooser" << endl; +
+            KoFilterChooser *chooser = new KoFilterChooser (0, \
KoFilterManager::mimeFilter ()); +            chooser->exec ();
+
+            QString f = chooser->filterSelected ();
+            if (f.isEmpty ())
+                userCancelled = true;
+            else
+                m_graph.setSourceMimeType (f.latin1 ());
+
+            delete chooser;
+        }
     }
 
-    if ( !m_graph.isValid() ) {
+    if (!m_graph.isValid ())
+    {
         kdError(s_area) << "Couldn't create a valid graph for this source mimetype." \
<< endl;  QApplication::restoreOverrideCursor();
-        KMessageBox::error( 0L, i18n("Could not export file."), i18n("Missing Export \
                Filter") );
-        return KoFilter::BadConversionGraph;
+        if (!userCancelled) KMessageBox::error( 0L, i18n("Could not export file."), \
i18n("Missing Export Filter") ); +            return KoFilter::BadConversionGraph;
     }
 
     KoFilterChain::Ptr chain = m_graph.chain( this, mimeType );
@@ -369,12 +498,12 @@ bool KoFilterManager::filterAvailable( K
     return m_filterAvailable[ key ];
 }
 
-void KoFilterManager::importErrorHelper( const QString& mimeType )
+void KoFilterManager::importErrorHelper( const QString& mimeType, const bool \
suppressDialog )  {
     QString tmp = i18n("Could not import file of type\n%1").arg( mimeType );
     QApplication::restoreOverrideCursor();
     // ###### FIXME: use KLibLoader::lastErrorMessage() here
-    KMessageBox::error( 0L, tmp, i18n("Missing Import Filter") );
+    if (!suppressDialog) KMessageBox::error( 0L, tmp, i18n("Missing Import Filter") \
);  }
 
 #include <koFilterManager.moc>
Index: koFilterManager.h
===================================================================
RCS file: /home/kde/koffice/lib/kofficecore/koFilterManager.h,v
retrieving revision 1.54
diff -u -p -r1.54 koFilterManager.h
--- koFilterManager.h	13 May 2002 17:52:19 -0000	1.54
+++ koFilterManager.h	7 Jun 2003 11:53:08 -0000
@@ -23,9 +23,41 @@
 
 #include <qobject.h>
 #include <qmap.h>
+#include <qcstring.h>
+#include <qstringlist.h>
+#include <qstring.h>
+#include <kdialogbase.h>
 #include <koFilterChain.h>
 
 class KoDocument;
+class KListBox;
+
+class KoFilterChooser : public KDialogBase
+{
+Q_OBJECT
+
+public:
+    KoFilterChooser (QWidget *parent, const QStringList &mimeTypes,
+                     const QString &nativeFormat = QString::null);
+    virtual ~KoFilterChooser ();
+
+    virtual QString filterSelected ();
+
+protected:
+    QStringList m_mimeTypes;
+    KListBox *m_filterList;
+
+    QString m_filterSelected;
+
+protected slots:
+    virtual void slotOk ();
+    virtual void slotCancel ();
+
+private:
+    class Private;
+    Private *d;
+};
+
 
 /**
  *  This class manages all filters for a KOffice application. Normally
@@ -134,7 +168,7 @@ private:
     KoFilterManager( const KoFilterManager& rhs );
     KoFilterManager &operator=( const KoFilterManager& rhs );
 
-    void importErrorHelper( const QString& mimeType );
+    void importErrorHelper( const QString& mimeType, const bool suppressDialog = \
false );  
     static const int s_area;
 



_______________________________________________
koffice-devel mailing list
koffice-devel@mail.kde.org
http://mail.kde.org/mailman/listinfo/koffice-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic