diff --git a/core/document.cpp b/core/document.cpp index 1274adccc5f4bc0b8e4121e8192d945b9fc16c33..383361b3a57cc6cedb9a167ee81b2f455f895dc4 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -575,6 +575,26 @@ QStringList KPDFDocument::paperSizes() const return generator ? generator->paperSizes() : QStringList(); } +bool KPDFDocument::canExportToText() const +{ + return generator ? generator->canExportToText() : false; +} + +bool KPDFDocument::exportToText( const QString& fileName ) const +{ + return generator ? generator->exportToText( fileName ) : false; +} + +QList KPDFDocument::exportFormats() const +{ + return generator ? generator->exportFormats() : QList(); +} + +bool KPDFDocument::exportTo( const QString& fileName, const KMimeType::Ptr& mime ) const +{ + return generator ? generator->exportTo( fileName, mime ) : false; +} + bool KPDFDocument::historyAtBegin() const { return d->viewportIterator == d->viewportHistory.begin(); diff --git a/core/document.h b/core/document.h index 322e4285494871b7311aee15b2d2f6a825d9bc97..40e3eaf29e5eb75d34c2d26a50678c348f7bbc33 100644 --- a/core/document.h +++ b/core/document.h @@ -40,6 +40,7 @@ class KActionCollection; class QToolBox; class NotifyRequest; class VisiblePageRect; +class ExportEntry; /** IDs for seaches. Globally defined here. **/ #define PART_SEARCH_ID 1 @@ -104,6 +105,10 @@ class OKULAR_EXPORT KPDFDocument : public QObject bool supportsRotation() const; bool supportsPaperSizes() const; QStringList paperSizes() const; + bool canExportToText() const; + bool exportToText( const QString& fileName ) const; + QList exportFormats() const; + bool exportTo( const QString& fileName, const KMimeType::Ptr& mime ) const; // might be useful later // bool hasFonts() const; bool historyAtBegin() const; diff --git a/core/generator.h b/core/generator.h index 4c104cbf9ee9f1be6aafd3ab745cd789aa5fbb18..6ed174527b43f33e64fd0fc97923cd28b03a583b 100644 --- a/core/generator.h +++ b/core/generator.h @@ -21,8 +21,10 @@ #include #include +#include #include #include +#include #include "document.h" #include "textpage.h" class KPrinter; @@ -30,6 +32,7 @@ class KPDFPage; class KPDFLink; class PixmapRequest; class KConfigDialog; +class ExportEntry; /* Note: on contents generation and asyncronous queries. * Many observers may want to request data syncronously or asyncronously. @@ -118,6 +121,12 @@ class OKULAR_EXPORT Generator : public QObject virtual void addPages( KConfigDialog* /*dlg*/ ) {;}; // virtual void setConfigurationPointer( KConfigDialog* /*dlg*/) { ; } ; + // support for exporting to text and to other formats + virtual bool canExportToText() { return false; }; + virtual bool exportToText( const QString & /*fileName*/ ) { return false; }; + virtual QList exportFormats() { return QList(); }; + virtual bool exportTo( const QString & /*fileName*/, const KMimeType::Ptr & /*mime*/ ) { return false; }; + // capture events // return false if you don't wish okular to use its event handlers // in the pageview after your handling (use with caution) @@ -169,4 +178,23 @@ struct OKULAR_EXPORT PixmapRequest QTextStream& operator<< (QTextStream& str, const PixmapRequest *req); +/** + * @short Defines an entry for the export menu + */ +struct OKULAR_EXPORT ExportEntry +{ + ExportEntry( const QString & desc, const KMimeType::Ptr & _mime ) + : description( desc ), mime( _mime ) {}; + + ExportEntry( const QString & _icon, const QString & desc, const KMimeType::Ptr & _mime ) + : description( desc ), mime( _mime ), icon( _icon ) {}; + + // the description to be shown in the Export menu + QString description; + // the mime associated + KMimeType::Ptr mime; + // the icon to be shown in the menu item + QString icon; +}; + #endif diff --git a/part.cpp b/part.cpp index 47dae944d38b7631ae7acf965b79ba3999450a79..bf93550e2c3e7dcc8ffd6953a918475f841209f9 100644 --- a/part.cpp +++ b/part.cpp @@ -294,6 +294,13 @@ Part::Part(QWidget *parentWidget, m_showPresentation->setShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_P ) ); m_showPresentation->setEnabled( false ); + m_exportAs = new KAction(i18n("E&xport As"), ac, "file_export_as"); + QMenu *menu = new QMenu(); + connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(slotExportAs(QAction *))); + m_exportAs->setMenu( menu ); + m_exportAsText = menu->addAction( KIcon( "text" ), i18n( "Text..." ) ); + m_exportAsText->setEnabled( false ); + // attach the actions of the children widgets too m_pageView->setupActions( ac ); @@ -546,6 +553,26 @@ bool Part::openFile() m_showProperties->setEnabled( ok ); m_showEmbeddedFiles->setEnabled( ok && m_document->embeddedFiles() && m_document->embeddedFiles()->count() > 0); m_showPresentation->setEnabled( ok ); + if ( ok ) + { + m_exportItems = m_document->exportFormats(); + QList::ConstIterator it = m_exportItems.constBegin(); + QList::ConstIterator itEnd = m_exportItems.constEnd(); + QMenu *menu = m_exportAs->menu(); + for ( ; it != itEnd; ++it ) + { + ExportEntry* cur = *it; + if ( !cur->icon.isEmpty() ) + { + menu->addAction( KIcon( cur->icon ), cur->description ); + } + else + { + menu->addAction( cur->description ); + } + } + } + m_exportAsText->setEnabled( ok && m_document->canExportToText() ); // update viewing actions updateViewActions(); @@ -606,6 +633,16 @@ bool Part::closeURL() m_printPreview->setEnabled( false ); m_showProperties->setEnabled( false ); m_showEmbeddedFiles->setEnabled( false ); + m_exportAsText->setEnabled( false ); + m_exportItems.clear(); + QMenu *menu = m_exportAs->menu(); + QList acts = menu->actions(); + int num = acts.count(); + for ( int i = 1; i < num; ++i ) + { + menu->removeAction( acts.at(i) ); + delete acts.at(i); + } m_showPresentation->setEnabled( false ); emit setWindowCaption(""); emit enablePrintAction(false); @@ -1080,6 +1117,23 @@ void Part::slotHidePresentation() delete (PresentationWidget*) m_presentationWidget; } +void Part::slotExportAs(QAction * act) +{ + QList acts = m_exportAs->menu() ? m_exportAs->menu()->actions() : QList(); + int id = acts.indexOf( act ); + if ( ( id < 0 ) || ( id >= acts.count() ) ) + return; + + QString filter = id == 0 ? "text/plain" : m_exportItems.at( id - 1 )->mime->name(); + QString fileName = KFileDialog::getSaveFileName( url().isLocalFile() ? url().fileName() : QString::null, filter, widget() ); + if ( !fileName.isEmpty() ) + { + bool saved = id == 0 ? m_document->exportToText( fileName ) : m_document->exportTo( fileName, m_exportItems.at( id - 1 )->mime ); + if ( !saved ) + KMessageBox::information( widget(), i18n("File could not be saved in '%1'. Try to save it to another location.", fileName ) ); + } +} + void Part::slotPrint() { if (m_document->pages() == 0) return; diff --git a/part.h b/part.h index c3852d3b71a391250bb3496418c221528460a04b..ae90d17e71368ef3d85f96756d989a87cf98b7d5 100644 --- a/part.h +++ b/part.h @@ -18,12 +18,14 @@ #include #include +#include #include #include "core/observer.h" #include "core/document.h" #include +class QAction; class QWidget; class QSplitter; class QToolBox; @@ -46,6 +48,7 @@ class PresentationWidget; class SearchWidget; class TOC; class MiniBar; +class ExportEntry; namespace okular { @@ -121,6 +124,7 @@ protected slots: void slotShowLeftPanel(); void slotShowPresentation(); void slotHidePresentation(); + void slotExportAs(QAction *); bool slotImportPSFile(); void close(); void cannotQuit(); @@ -179,6 +183,8 @@ private: KAction *m_printPreview; KAction *m_showProperties; KAction *m_showEmbeddedFiles; + KAction *m_exportAs; + QAction *m_exportAsText; KAction *m_showPresentation; KToggleAction* m_showMenuBarAction; KToggleAction* m_showLeftPanel; @@ -194,6 +200,7 @@ private: QStringList m_generatorsWithSettings; QStringList m_supportedMimeTypes; KSelectAction * m_confGens; + QList m_exportItems; private slots: void slotGeneratorPreferences(); diff --git a/part.rc b/part.rc index ce91dcb1e03dbc072e5ea50a85c1d9cf3b1f4331..6ad6477294e6fce3a7bf4a08964cc1551faa80ae 100644 --- a/part.rc +++ b/part.rc @@ -9,6 +9,7 @@ + &Edit