Commit d2fab9ae authored by Albert Astals Cid's avatar Albert Astals Cid

PDF properties dialog

svn path=/branches/kpdf_experiments/kdegraphics/kpdf/; revision=368769
parent 57b31da3
...@@ -42,7 +42,7 @@ shellrc_DATA = kpdf_shell.rc ...@@ -42,7 +42,7 @@ shellrc_DATA = kpdf_shell.rc
kde_module_LTLIBRARIES = libkpdfpart.la kde_module_LTLIBRARIES = libkpdfpart.la
# the Part's source, library search path, and link libraries # the Part's source, library search path, and link libraries
libkpdfpart_la_SOURCES = QOutputDev.cpp kpdf_part.cpp pageview.cpp thumbnaillist.cpp kpdf_error.cpp thumbnailgenerator.cpp document.cpp page.cpp searchwidget.cpp toc.cpp kpdf_dcop.skel pageviewutils.cpp libkpdfpart_la_SOURCES = QOutputDev.cpp kpdf_part.cpp pageview.cpp thumbnaillist.cpp kpdf_error.cpp thumbnailgenerator.cpp document.cpp page.cpp searchwidget.cpp toc.cpp kpdf_dcop.skel pageviewutils.cpp properties.ui propertiesdialog.cpp
libkpdfpart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) libkpdfpart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
libkpdfpart_la_LIBADD = ../xpdf/libxpdf.la conf/libconf.la $(LIB_KPARTS) $(LIB_KFILE) $(LIB_KDEPRINT) $(LIB_KUTILS) -lm libkpdfpart_la_LIBADD = ../xpdf/libxpdf.la conf/libconf.la $(LIB_KPARTS) $(LIB_KFILE) $(LIB_KDEPRINT) $(LIB_KUTILS) -lm
......
...@@ -53,6 +53,7 @@ More items (first items will enter 'In progress list' first): ...@@ -53,6 +53,7 @@ More items (first items will enter 'In progress list' first):
-> incremental zoom with fast-refresh (tested but flickering!) or contour tracing -> incremental zoom with fast-refresh (tested but flickering!) or contour tracing
Done (newest feature comes firts): Done (newest feature comes firts):
-> ADD: Add properties dialog (Albert)
-> ADD: Support for show/hide menubar in rmb menu, different from HEAD so that supports Konqueror too (Albert) -> ADD: Support for show/hide menubar in rmb menu, different from HEAD so that supports Konqueror too (Albert)
-> ADD: Watch File option (Albert) -> ADD: Watch File option (Albert)
-> ADD: import Marco Martin's "another kpdf icon" (kde-look: 16146) (Albert) -> ADD: import Marco Martin's "another kpdf icon" (kde-look: 16146) (Albert)
...@@ -114,3 +115,4 @@ BR74435: (smooth transition/continous mode) It's in from sept-27. ...@@ -114,3 +115,4 @@ BR74435: (smooth transition/continous mode) It's in from sept-27.
BR80164: (2-up view of pdf pages) It's in from sept-26. BR80164: (2-up view of pdf pages) It's in from sept-26.
BR69092: Zoom displayed/internal values synced with fixed value or displayed page. BR69092: Zoom displayed/internal values synced with fixed value or displayed page.
It is editable and the list gets cleaned and rebuilt on changes. It is editable and the list gets cleaned and rebuilt on changes.
BR94385: PDF doesn't show PDF properties
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
***************************************************************************/ ***************************************************************************/
// qt/kde/system includes // qt/kde/system includes
#include <qdatetime.h>
#include <qdir.h> #include <qdir.h>
#include <qfile.h> #include <qfile.h>
#include <qfileinfo.h> #include <qfileinfo.h>
...@@ -35,6 +36,7 @@ ...@@ -35,6 +36,7 @@
#include "PDFDoc.h" #include "PDFDoc.h"
#include "PSOutputDev.h" #include "PSOutputDev.h"
#include "QOutputDev.h" #include "QOutputDev.h"
#include "UnicodeMap.h"
#include "document.h" #include "document.h"
#include "page.h" #include "page.h"
...@@ -49,6 +51,109 @@ ...@@ -49,6 +51,109 @@
class KPDFDocumentPrivate class KPDFDocumentPrivate
{ {
public: public:
// Albert says: I've put that two functions here but they could go
// elsewhere, i leave it up to you if you want to change them Enrico
QString getDocumentInfo(const QString &data) const
{
// Code adapted from pdfinfo.cc on xpdf
Object info;
if (pdfdoc)
{
pdfdoc->getDocInfo(&info);
if (info.isDict())
{
QCString result;
Object obj;
GString *s1;
GBool isUnicode;
Unicode u;
char buf[8];
int i, n;
Dict *infoDict = info.getDict();
UnicodeMap *uMap = globalParams->getTextEncoding();
if (!uMap) return i18n("Unknown");
if (infoDict->lookup(data.latin1(), &obj)->isString())
{
s1 = obj.getString();
if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff)
{
isUnicode = gTrue;
i = 2;
}
else
{
isUnicode = gFalse;
i = 0;
}
while (i < obj.getString()->getLength())
{
if (isUnicode)
{
u = ((s1->getChar(i) & 0xff) << 8) | (s1->getChar(i+1) & 0xff);
i += 2;
}
else
{
u = s1->getChar(i) & 0xff;
++i;
}
n = uMap->mapUnicode(u, buf, sizeof(buf));
result += QCString(buf, n + 1);
}
obj.free();
return result;
}
obj.free();
return i18n("Unknown");
}
else return i18n("Unknown");
}
else return i18n("Unknown");
}
QString getDocumentDate(const QString &data) const
{
// Code adapted from pdfinfo.cc on xpdf
Object info;
if (pdfdoc)
{
pdfdoc->getDocInfo(&info);
if (info.isDict())
{
Object obj;
char *s;
int year, mon, day, hour, min, sec;
Dict *infoDict = info.getDict();
UnicodeMap *uMap = globalParams->getTextEncoding();
if (!uMap) return i18n("Unknown");
if (infoDict->lookup(data.latin1(), &obj)->isString())
{
s = obj.getString()->getCString();
if (s[0] == 'D' && s[1] == ':') s += 2;
if (sscanf(s, "%4d%2d%2d%2d%2d%2d", &year, &mon, &day, &hour, &min, &sec) == 6)
{
QDate d(year, mon - 1, day);
QTime t(hour, min, sec);
if (d.isValid() && t.isValid()) return KGlobal::locale()->formatDateTime(QDateTime(d, t), false, true);
else return s;
}
else return s;
fputc('\n', stdout);
obj.free();
//return result;
}
obj.free();
return i18n("Unknown");
}
else return i18n("Unknown");
}
else return i18n("Unknown");
}
// document related // document related
QMutex docLock; QMutex docLock;
PDFDoc * pdfdoc; PDFDoc * pdfdoc;
...@@ -250,6 +355,64 @@ uint KPDFDocument::pages() const ...@@ -250,6 +355,64 @@ uint KPDFDocument::pages() const
return d->pdfdoc ? d->pdfdoc->getNumPages() : 0; return d->pdfdoc ? d->pdfdoc->getNumPages() : 0;
} }
QString KPDFDocument::author() const
{
return d->getDocumentInfo("Author");
}
QString KPDFDocument::creationDate() const
{
return d->getDocumentDate("CreationDate");
}
QString KPDFDocument::creator() const
{
return d->getDocumentInfo("Creator");
}
bool KPDFDocument::encrypted() const
{
if (d->pdfdoc) return d->pdfdoc->isEncrypted();
else return false;
}
QString KPDFDocument::keywords() const
{
return d->getDocumentInfo("Keywords");
}
QString KPDFDocument::modificationDate() const
{
return d->getDocumentDate("ModDate");
}
bool KPDFDocument::optimized() const
{
if (d->pdfdoc) return d->pdfdoc->isLinearized();
else return false;
}
float KPDFDocument::PDFversion() const
{
if (d->pdfdoc) return d->pdfdoc->getPDFVersion();
else return 0;
}
QString KPDFDocument::producer() const
{
return d->getDocumentInfo("Producer");
}
QString KPDFDocument::subject() const
{
return d->getDocumentInfo("Subject");
}
QString KPDFDocument::title() const
{
return d->getDocumentInfo("Title");
}
bool KPDFDocument::okToPrint() const bool KPDFDocument::okToPrint() const
{ {
return d->pdfdoc->okToPrint(); return d->pdfdoc->okToPrint();
......
...@@ -67,6 +67,17 @@ class KPDFDocument ...@@ -67,6 +67,17 @@ class KPDFDocument
// query methods (const ones) // query methods (const ones)
uint currentPage() const; uint currentPage() const;
uint pages() const; uint pages() const;
QString author() const;
QString creationDate() const;
QString creator() const;
bool encrypted() const;
QString keywords() const;
QString modificationDate() const;
bool optimized() const;
float PDFversion() const;
QString producer() const;
QString subject() const;
QString title() const;
bool okToPrint() const; bool okToPrint() const;
Outline * outline() const; Outline * outline() const;
const KPDFPage * page( uint page ) const; const KPDFPage * page( uint page ) const;
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#include "page.h" #include "page.h"
#include "toc.h" #include "toc.h"
#include "preferencesdialog.h" #include "preferencesdialog.h"
#include "propertiesdialog.h"
#include "settings.h" #include "settings.h"
typedef KParts::GenericFactory<KPDF::Part> KPDFPartFactory; typedef KParts::GenericFactory<KPDF::Part> KPDFPartFactory;
...@@ -171,6 +172,9 @@ Part::Part(QWidget *parentWidget, const char *widgetName, ...@@ -171,6 +172,9 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
KStdAction::saveAs( this, SLOT( slotSaveFileAs() ), ac, "save" ); KStdAction::saveAs( this, SLOT( slotSaveFileAs() ), ac, "save" );
KStdAction::preferences( this, SLOT( slotPreferences() ), ac, "preferences" ); KStdAction::preferences( this, SLOT( slotPreferences() ), ac, "preferences" );
KStdAction::printPreview( this, SLOT( slotPrintPreview() ), ac ); KStdAction::printPreview( this, SLOT( slotPrintPreview() ), ac );
m_showProperties = new KAction(i18n("Properties"), 0, this, SLOT(slotShowProperties()), ac, "properties");
m_showProperties->setEnabled( false );
// attach the actions of the 2 children widgets too // attach the actions of the 2 children widgets too
m_pageView->setupActions( ac ); m_pageView->setupActions( ac );
...@@ -240,6 +244,7 @@ bool Part::openFile() ...@@ -240,6 +244,7 @@ bool Part::openFile()
bool ok = m_document->openDocument( m_file ); bool ok = m_document->openDocument( m_file );
if ( ok && !m_watcher->contains(m_file)) m_watcher->addFile(m_file); if ( ok && !m_watcher->contains(m_file)) m_watcher->addFile(m_file);
m_find->setEnabled( ok ); m_find->setEnabled( ok );
m_showProperties->setEnabled( ok );
return ok; return ok;
} }
...@@ -569,6 +574,13 @@ void Part::slotShowMenu(const KPDFPage *page, const QPoint &point) ...@@ -569,6 +574,13 @@ void Part::slotShowMenu(const KPDFPage *page, const QPoint &point)
} }
void Part::slotShowProperties()
{
propertiesDialog *d = new propertiesDialog(widget(), m_document);
d->exec();
delete d;
}
void Part::slotPrint() void Part::slotPrint()
{ {
if (m_document->pages() == 0) return; if (m_document->pages() == 0) return;
......
...@@ -96,6 +96,7 @@ protected slots: ...@@ -96,6 +96,7 @@ protected slots:
void slotNewConfig(); void slotNewConfig();
void slotPrintPreview(); void slotPrintPreview();
void slotShowMenu(const KPDFPage *page, const QPoint &point); void slotShowMenu(const KPDFPage *page, const QPoint &point);
void slotShowProperties();
// can be connected to widget elements // can be connected to widget elements
void updateActions(); void updateActions();
void enableTOC(bool enable); void enableTOC(bool enable);
...@@ -136,6 +137,7 @@ private: ...@@ -136,6 +137,7 @@ private:
KAction *m_lastPage; KAction *m_lastPage;
KAction *m_find; KAction *m_find;
KAction *m_findNext; KAction *m_findNext;
KAction *m_showProperties;
KToggleAction* m_watchFile; KToggleAction* m_watchFile;
KToggleAction* m_showMenuBarAction; KToggleAction* m_showMenuBarAction;
bool m_showMenuBarActionSearched; bool m_showMenuBarActionSearched;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
<Action name="save" group="file_save"/> <Action name="save" group="file_save"/>
<Action name="file_print" group="file_print"/> <Action name="file_print" group="file_print"/>
<Action name="file_print_preview" group="file_print"/> <Action name="file_print_preview" group="file_print"/>
<Action name="properties" group="file_print"/>
</Menu> </Menu>
<Menu name="edit"><text>&amp;Edit</text> <Menu name="edit"><text>&amp;Edit</text>
<Action name="find"/> <Action name="find"/>
......
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>properties</class>
<widget class="QWidget">
<property name="name">
<cstring>properties</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>124</width>
<height>324</height>
</rect>
</property>
<property name="caption">
<string>Form2</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLabel" row="9" column="0">
<property name="name">
<cstring>textLabel1_3_2_3_6</cstring>
</property>
<property name="text">
<string>PDF version:</string>
</property>
</widget>
<widget class="QLabel" row="8" column="0">
<property name="name">
<cstring>textLabel1_3_2_3_5</cstring>
</property>
<property name="text">
<string>Security:</string>
</property>
</widget>
<widget class="QLabel" row="11" column="0">
<property name="name">
<cstring>textLabel1_3_2_3_8</cstring>
</property>
<property name="text">
<string>Optimized:</string>
</property>
</widget>
<spacer row="12" column="0">
<property name="name">
<cstring>spacer3</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
</spacer>
<spacer row="6" column="2">
<property name="name">
<cstring>spacer4</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
</spacer>
<widget class="QLabel" row="5" column="0">
<property name="name">
<cstring>textLabel1_3_2_3_2</cstring>
</property>
<property name="text">
<string>Producer:</string>
</property>
</widget>
<widget class="QLabel" row="2" column="0">
<property name="name">
<cstring>textLabel1_3_2</cstring>
</property>
<property name="text">
<string>Author:</string>
</property>
</widget>
<widget class="QLabel" row="6" column="1">
<property name="name">
<cstring>createdValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="9" column="1">
<property name="name">
<cstring>versionValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="2" column="1">
<property name="name">
<cstring>authorValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="6" column="0">
<property name="name">
<cstring>textLabel1_3_2_3_3</cstring>
</property>
<property name="text">
<string>Created:</string>
</property>
</widget>
<widget class="QLabel" row="3" column="0">
<property name="name">
<cstring>textLabel1_3_2_2</cstring>
</property>
<property name="text">
<string>Keywords:</string>
</property>
</widget>
<widget class="QLabel" row="5" column="1">
<property name="name">
<cstring>producerValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="3" column="1">
<property name="name">
<cstring>keywordsValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="7" column="1">
<property name="name">
<cstring>modifiedValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="4" column="1">
<property name="name">
<cstring>creatorValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="10" column="0">
<property name="name">
<cstring>textLabel1_3_2_3_7</cstring>
</property>
<property name="text">
<string>Pages:</string>
</property>
</widget>
<widget class="QLabel" row="11" column="1">
<property name="name">
<cstring>optimizedValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="10" column="1">
<property name="name">
<cstring>pagesValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="8" column="1">
<property name="name">
<cstring>securityValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="7" column="0">
<property name="name">
<cstring>textLabel1_3_2_3_4</cstring>
</property>
<property name="text">
<string>Modified:</string>
</property>
</widget>
<widget class="QLabel" row="4" column="0">
<property name="name">
<cstring>textLabel1_3_2_3</cstring>
</property>
<property name="text">
<string>Creator:</string>
</property>
</widget>
<widget class="QLabel" row="0" column="0">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>Title:</string>
</property>
</widget>
<widget class="QLabel" row="1" column="0">
<property name="name">
<cstring>textLabel1_3</cstring>
</property>
<property name="text">
<string>Subject:</string>
</property>
</widget>
<widget class="QLabel" row="1" column="1">
<property name="name">
<cstring>subjectValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="QLabel" row="0" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>titleValue</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
</grid>
</widget>
<layoutdefaults spacing="6" margin="11"/>
</UI>
/***************************************************************************
* Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es> *
* *
* 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 <klocale.h>
#include <qlabel.h>
#include "document.h"
#include "properties.h"
#include "propertiesdialog.h"
propertiesDialog::propertiesDialog(QWidget *parent, KPDFDocument *doc) : KDialogBase(parent, 0, true, i18n("PDF properties"), Ok)
{
properties *p = new properties(this);
setMainWidget(p);
p->pagesValue->setText(QString::number(doc->pages()));
p->authorValue->setText(doc->author());
p->titleValue->setText(doc->title());
p->subjectValue->setText(doc->subject());
p->keywordsValue->setText(doc->keywords());
p->producerValue->setText(doc->producer());
p->creatorValue->setText(doc->creator());
if (doc->optimized()) p->optimizedValue->setText(i18n("Yes"));
else p->optimizedValue->setText(i18n("No"));
if (doc->encrypted()) p->securityValue->setText(i18n("Encrypted"));
else p->securityValue->setText(i18n("No"));
p->versionValue->setText(QString::number(doc->PDFversion()));
p->createdValue->setText(doc->creationDate());
p->modifiedValue->setText(doc->modificationDate());
}
/***************************************************************************
* Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es> *
* *
* 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 _PROPERTIESDIALOG_H_
#define _PROPERTIESDIALOG_H_
#include <kdialogbase.h>
class