From 13dde4096f2e2b944d2d702f10e6c8e1d7334e3c Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Sun, 28 May 2006 16:54:54 +0000 Subject: [PATCH] use the nice code brad wrote for poppler that allows you to extract embedded files from a pdf document. svn path=/branches/work/kde4/playground/graphics/okular/; revision=545966 --- CMakeLists.txt | 1 + core/document.cpp | 15 +++++++ core/document.h | 20 +++++++++ core/generator.h | 1 + generators/poppler/generator_pdf.cpp | 57 +++++++++++++++++++++-- generators/poppler/generator_pdf.h | 3 ++ part.cpp | 14 ++++++ part.h | 4 +- part.rc | 1 + ui/embeddedfilesdialog.cpp | 67 ++++++++++++++++++++++++++++ ui/embeddedfilesdialog.h | 31 +++++++++++++ 11 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 ui/embeddedfilesdialog.cpp create mode 100644 ui/embeddedfilesdialog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d516e403a..84d852d42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ kde4_add_ui_files(oKularcore_SRCS ) set(oKularui_SRCS + ${CMAKE_SOURCE_DIR}/okular/ui/embeddedfilesdialog.cpp ${CMAKE_SOURCE_DIR}/okular/ui/minibar.cpp ${CMAKE_SOURCE_DIR}/okular/ui/newstuff.cpp ${CMAKE_SOURCE_DIR}/okular/ui/pagepainter.cpp diff --git a/core/document.cpp b/core/document.cpp index 2a042c7bf..1575126f7 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -484,6 +484,11 @@ const DocumentFonts * KPDFDocument::documentFonts() const return generator ? generator->generateDocumentFonts() : NULL; } +const QList *KPDFDocument::embeddedFiles() const +{ + return generator ? generator->embeddedFiles() : NULL; +} + const KPDFPage * KPDFDocument::page( int n ) const { return ( n < pages_vector.count() ) ? pages_vector[n] : 0; @@ -1790,4 +1795,14 @@ DocumentFonts::DocumentFonts() // void implementation, only subclassed for naming } +/** EmbeddedFile **/ + +EmbeddedFile::EmbeddedFile() +{ +} + +EmbeddedFile::~EmbeddedFile() +{ +} + #include "document.moc" diff --git a/core/document.h b/core/document.h index da228861c..3eff39925 100644 --- a/core/document.h +++ b/core/document.h @@ -28,6 +28,7 @@ class DocumentViewport; class DocumentInfo; class DocumentSynopsis; class DocumentFonts; +class EmbeddedFile; class Generator; class PixmapRequest; class Annotation; @@ -87,6 +88,7 @@ class OKULAR_EXPORT KPDFDocument : public QObject const DocumentInfo * documentInfo() const; const DocumentSynopsis * documentSynopsis() const; const DocumentFonts * documentFonts() const; + const QList *embeddedFiles() const; const KPDFPage * page( int page ) const; const DocumentViewport & viewport() const; uint currentPage() const; @@ -269,4 +271,22 @@ class OKULAR_EXPORT DocumentFonts : public QDomDocument DocumentFonts(); }; +/** + * @short An embedded file into the document, has name, description, dates and the data + */ + +class OKULAR_EXPORT EmbeddedFile +{ + public: + EmbeddedFile(); + virtual ~EmbeddedFile(); + + virtual QString name() const = 0; + virtual QString description() const = 0; + virtual QByteArray data() const = 0; + virtual QDateTime modificationDate() const = 0; + virtual QDateTime creationDate() const = 0; + +}; + #endif diff --git a/core/generator.h b/core/generator.h index 6b90ff98b..d102f9358 100644 --- a/core/generator.h +++ b/core/generator.h @@ -70,6 +70,7 @@ class OKULAR_EXPORT Generator : public QObject virtual const DocumentInfo * generateDocumentInfo() { return 0L; } virtual const DocumentSynopsis * generateDocumentSynopsis() { return 0L; } virtual const DocumentFonts * generateDocumentFonts() { return 0L; } + virtual const QList * embeddedFiles() { return 0L; } // DRM handling virtual bool isAllowed( int /*Document::Permisison(s)*/ ) { return true; } diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp index 1e60d2b86..63a2c15c6 100644 --- a/generators/poppler/generator_pdf.cpp +++ b/generators/poppler/generator_pdf.cpp @@ -31,8 +31,41 @@ #include #include -// id for DATA_READY PDFPixmapGeneratorThread Event -#define TGE_DATAREADY_ID 6969 +class PDFEmbeddedFile : public EmbeddedFile +{ + public: + PDFEmbeddedFile(Poppler::EmbeddedFile *f) : ef(f) + { + } + + QString name() const + { + return ef->name(); + } + + QString description() const + { + return ef->description(); + } + + QByteArray data() const + { + return ef->data(); + } + + QDateTime modificationDate() const + { + return ef->modDate(); + } + + QDateTime creationDate() const + { + return ef->createDate(); + } + + private: + Poppler::EmbeddedFile *ef; +}; static void fillViewportFromLinkDestination( DocumentViewport &viewport, const Poppler::LinkDestination &destination, const Poppler::Document *pdfdoc ) { @@ -153,7 +186,7 @@ KPDF_EXPORT_PLUGIN(PDFGenerator) PDFGenerator::PDFGenerator( KPDFDocument * doc ) : Generator( doc ), pdfdoc( 0 ), ready( true ), pixmapRequest( 0 ), docInfoDirty( true ), docSynopsisDirty( true ), - docFontsDirty( true ) + docFontsDirty( true ), docEmbeddedFilesDirty( true ) { // generate kpdfOutputDev and cache page color reparseConfig(); @@ -490,6 +523,24 @@ const DocumentFonts * PDFGenerator::generateDocumentFonts() return &docFonts; } +const QList *PDFGenerator::embeddedFiles() +{ + if (docEmbeddedFilesDirty) + { + docLock.lock(); + const QList &popplerFiles = pdfdoc->embeddedFiles(); + foreach(Poppler::EmbeddedFile* pef, popplerFiles) + { + docEmbeddedFiles.append(new PDFEmbeddedFile(pef)); + } + docLock.unlock(); + + docEmbeddedFilesDirty = false; + } + + return &docEmbeddedFiles; +} + bool PDFGenerator::isAllowed( int permissions ) { #if !OKULAR_FORCE_DRM diff --git a/generators/poppler/generator_pdf.h b/generators/poppler/generator_pdf.h index eafcf4173..585e571ee 100644 --- a/generators/poppler/generator_pdf.h +++ b/generators/poppler/generator_pdf.h @@ -55,6 +55,7 @@ class PDFGenerator : public Generator const DocumentInfo * generateDocumentInfo(); const DocumentSynopsis * generateDocumentSynopsis(); const DocumentFonts * generateDocumentFonts(); + const QList * embeddedFiles(); // [INHERITED] document information bool isAllowed( int permissions ); @@ -127,6 +128,8 @@ class PDFGenerator : public Generator DocumentSynopsis docSyn; bool docFontsDirty; DocumentFonts docFonts; + bool docEmbeddedFilesDirty; + QList docEmbeddedFiles; }; diff --git a/part.cpp b/part.cpp index f531f1fbf..7f5eb3554 100644 --- a/part.cpp +++ b/part.cpp @@ -67,6 +67,7 @@ #include "ui/side_reviews.h" #include "ui/minibar.h" #include "ui/newstuff.h" +#include "ui/embeddedfilesdialog.h" #include "ui/propertiesdialog.h" #include "ui/presentationwidget.h" #include "conf/preferencesdialog.h" @@ -273,6 +274,10 @@ Part::Part(QWidget *parentWidget, m_showProperties = new KAction(KIcon("info"), i18n("&Properties"), ac, "properties"); connect(m_showProperties, SIGNAL(triggered()), this, SLOT(slotShowProperties())); m_showProperties->setEnabled( false ); + + m_showEmbeddedFiles = new KAction(i18n("&Embedded Files"), ac, "embeddedFiles"); + connect(m_showEmbeddedFiles, SIGNAL(triggered()), this, SLOT(slotShowEmbeddedFiles())); + m_showEmbeddedFiles->setEnabled( false ); m_showPresentation = new KAction( KIcon( "kpresenter_kpr" ), i18n("P&resentation"), ac, "presentation"); connect(m_showPresentation, SIGNAL(triggered()), this, SLOT(slotShowPresentation())); @@ -524,6 +529,7 @@ bool Part::openFile() m_saveAs->setEnabled( ok ); m_printPreview->setEnabled( ok ); m_showProperties->setEnabled( ok ); + m_showEmbeddedFiles->setEnabled( ok && m_document->embeddedFiles() && m_document->embeddedFiles()->count() > 0); m_showPresentation->setEnabled( ok ); // update viewing actions @@ -584,6 +590,7 @@ bool Part::closeURL() m_saveAs->setEnabled( false ); m_printPreview->setEnabled( false ); m_showProperties->setEnabled( false ); + m_showEmbeddedFiles->setEnabled( false ); m_showPresentation->setEnabled( false ); emit setWindowCaption(""); emit enablePrintAction(false); @@ -997,6 +1004,13 @@ void Part::slotShowProperties() delete d; } +void Part::slotShowEmbeddedFiles() +{ + EmbeddedFilesDialog *d = new EmbeddedFilesDialog(widget(), m_document); + d->exec(); + delete d; +} + void Part::slotShowPresentation() { if ( !m_presentationWidget ) diff --git a/part.h b/part.h index 553fd0a88..1ba53603e 100644 --- a/part.h +++ b/part.h @@ -112,6 +112,7 @@ protected slots: void slotPrintPreview(); void slotShowMenu(const KPDFPage *page, const QPoint &point); void slotShowProperties(); + void slotShowEmbeddedFiles(); void slotShowLeftPanel(); void slotShowPresentation(); void slotHidePresentation(); @@ -119,7 +120,7 @@ protected slots: void close(); void cannotQuit(); void setMimeTypes(KIO::Job *job); - void saveSplitterSize(); + void saveSplitterSize(); // can be connected to widget elements void updateViewActions(); void enableTOC(bool enable); @@ -170,6 +171,7 @@ private: KAction *m_saveAs; KAction *m_printPreview; KAction *m_showProperties; + KAction *m_showEmbeddedFiles; KAction *m_showPresentation; KToggleAction* m_showMenuBarAction; KToggleAction* m_showLeftPanel; diff --git a/part.rc b/part.rc index ab0b740aa..793cde8b1 100644 --- a/part.rc +++ b/part.rc @@ -8,6 +8,7 @@ + &Edit diff --git a/ui/embeddedfilesdialog.cpp b/ui/embeddedfilesdialog.cpp new file mode 100644 index 000000000..1fc5b3f24 --- /dev/null +++ b/ui/embeddedfilesdialog.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2006 by Albert Astals Cid * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include +#include + +#include +#include +#include + +#include "core/document.h" +#include "embeddedfilesdialog.h" + +EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const KPDFDocument *document) : KDialog(parent, i18n("Embedded Files"), Close | User1, 0, i18n("Save")) +{ + m_tw = new QTreeWidget(this); + setMainWidget(m_tw); + QStringList header; + header.append(i18n("Name")); + header.append(i18n("Description")); + header.append(i18n("Created")); + header.append(i18n("Modificated")); + m_tw->setHeaderLabels(header); + m_tw->setRootIsDecorated(false); + + foreach(EmbeddedFile* ef, *document->embeddedFiles()) + { + QTreeWidgetItem *twi = new QTreeWidgetItem(); + twi->setText(0, ef->name()); + twi->setText(1, ef->description()); + twi->setText(2, KGlobal::locale()->formatDateTime( ef->creationDate(), false, true )); + twi->setText(3, KGlobal::locale()->formatDateTime( ef->modificationDate(), false, true )); + m_tw->addTopLevelItem(twi); + m_files.insert(twi, ef); + } + + connect(this, SIGNAL(user1Clicked()), this, SLOT(saveFile())); +} + +void EmbeddedFilesDialog::saveFile() +{ + QList selected = m_tw->selectedItems(); + foreach(QTreeWidgetItem *twi, selected) + { + EmbeddedFile* ef = m_files[twi]; + QString path = KFileDialog::getSaveFileName(ef->name(), QString(), this, i18n("Where do you want to save %1?", ef->name())); + if (!path.isEmpty()) + { + QFile f(path); + if (!f.exists() || KMessageBox::warningContinueCancel( this, i18n("A file named \"%1\" already exists. Are you sure you want to overwrite it?", path), QString::null, i18n("Overwrite")) == KMessageBox::Continue) + { + f.open(QIODevice::WriteOnly); + f.write(ef->data()); + f.close(); + } + + } + } +} + +#include "embeddedfilesdialog.moc" diff --git a/ui/embeddedfilesdialog.h b/ui/embeddedfilesdialog.h new file mode 100644 index 000000000..2a0cb59d5 --- /dev/null +++ b/ui/embeddedfilesdialog.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2006 by Albert Astals Cid * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#ifndef _EMBEDDEDFILESDIALOG_H_ +#define _EMBEDDEDFILESDIALOG_H_ + +#include + +class KPDFDocument; + +class EmbeddedFilesDialog : public KDialog +{ +Q_OBJECT + public: + EmbeddedFilesDialog(QWidget *parent, const KPDFDocument *document); + + private slots: + void saveFile(); + + private: + QTreeWidget *m_tw; + QHash m_files; +}; + +#endif