mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-28 19:28:38 +00:00
fixes issue #112446
svn path=/trunk/KDE/kdegraphics/kdvi/; revision=461082
This commit is contained in:
parent
46bb5ad692
commit
3d2b6db73e
3 changed files with 131 additions and 4 deletions
69
dviFile.cpp
69
dviFile.cpp
|
@ -52,6 +52,7 @@
|
|||
|
||||
#include <kdebug.h>
|
||||
#include <klocale.h>
|
||||
#include <ktempfile.h>
|
||||
#include <qdir.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -75,6 +76,7 @@ dvifile::dvifile(const dvifile *old, fontPool *fp)
|
|||
numberOfExternalPSFiles = 0;
|
||||
numberOfExternalNONPSFiles = 0;
|
||||
sourceSpecialMarker = old->sourceSpecialMarker;
|
||||
have_complainedAboutMissingPDF2PS = false;
|
||||
|
||||
dviData = old->dviData.copy();
|
||||
|
||||
|
@ -278,6 +280,7 @@ dvifile::dvifile(QString fname, fontPool *pool)
|
|||
numberOfExternalNONPSFiles = 0;
|
||||
font_pool = pool;
|
||||
sourceSpecialMarker = true;
|
||||
have_complainedAboutMissingPDF2PS = false;
|
||||
|
||||
QFile file(fname);
|
||||
filename = file.name();
|
||||
|
@ -315,6 +318,13 @@ dvifile::~dvifile()
|
|||
kdDebug(4300) << "destroy dvi-file" << endl;
|
||||
#endif
|
||||
|
||||
// Delete converted PDF files
|
||||
QMapIterator<QString, QString> i(convertedFiles);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
QFile::remove(i.value());
|
||||
}
|
||||
|
||||
if (suggestedPageSize != 0)
|
||||
delete suggestedPageSize;
|
||||
if (font_pool != 0)
|
||||
|
@ -351,6 +361,65 @@ void dvifile::renumber()
|
|||
}
|
||||
|
||||
|
||||
QString dvifile::convertPDFtoPS(const QString &PDFFilename, QString *converrorms)
|
||||
{
|
||||
// Check if the PDFFile is known
|
||||
QMap<QString, QString>::Iterator it = convertedFiles.find(PDFFilename);
|
||||
if (it != convertedFiles.end()) {
|
||||
// PDF-File is known. Good.
|
||||
return it.data();
|
||||
}
|
||||
|
||||
// Get the name of a temporary file
|
||||
KTempFile tmpfile(QString::null, ".ps");
|
||||
QString convertedFileName = tmpfile.name();
|
||||
tmpfile.close();
|
||||
tmpfile.unlink();
|
||||
|
||||
// Use pdf2ps to do the conversion
|
||||
KProcIO proc;
|
||||
proc << "pdf2ps" << PDFFilename << convertedFileName;
|
||||
if (proc.start(KProcess::Block, true) == false) {
|
||||
convertedFiles[PDFFilename] = QString::null; // Indicates that conversion failed, won't try again.
|
||||
if ((converrorms != 0) && (have_complainedAboutMissingPDF2PS == false)) {
|
||||
*converrorms = i18n("<qt><p>The external program <strong>pdf2ps</strong> could not be started. As a result, "
|
||||
"the PDF-file %1 could not be converted to PostScript. Some graphic elements in your "
|
||||
"document will therefore not be displayed.</p>"
|
||||
"<p><b>Possible reason:</b> The program <strong>pdf2ps</strong> is perhaps not installed "
|
||||
"on your system, or it cannot be found in the current search path.</p>"
|
||||
"<p><b>What you can do:</b> The program <strong>pdf2ps</strong> program is normally "
|
||||
"contained in distributions of the ghostscript PostScript interpreter system. If "
|
||||
"ghostscipt is not installed on your system, you could install it now. "
|
||||
"If you are sure that ghostscript is installed, please try to use <strong>pdf2ps</strong> "
|
||||
"from the command line to check if it really works.</p><p><b>PATH:</b> %2</p></qt>").arg(PDFFilename).arg(getenv("PATH"));
|
||||
have_complainedAboutMissingPDF2PS = true;
|
||||
}
|
||||
return QString::null;
|
||||
}
|
||||
if ( !QFile::exists(convertedFileName) || !proc.normalExit() || (proc.exitStatus() != 0) ) {
|
||||
convertedFiles[PDFFilename] = QString::null; // Indicates that conversion failed, won't try again.
|
||||
if (converrorms != 0) {
|
||||
QString outp, outl;
|
||||
while(proc.readln(outl) != -1)
|
||||
outp += outl;
|
||||
|
||||
*converrorms = i18n("<qt><p>The PDF-file %1 could not be converted to PostScript. Some graphic elements in your "
|
||||
"document will therefore not be displayed.</p>"
|
||||
"<p><b>Possible reason:</b> The file %1 might be broken, or might not be a PDF-file at all. "
|
||||
"This is the output of the <strong>pdf2ps</strong> program that KDVI used:</p>"
|
||||
"<p><strong>%2</strong></p></qt>").arg(PDFFilename).arg(outp);
|
||||
}
|
||||
return QString::null;
|
||||
}
|
||||
// Save name of converted file to buffer, so PDF file won't be
|
||||
// converted again, and files can be deleted when *this is
|
||||
// deconstructed.
|
||||
convertedFiles[PDFFilename] = convertedFileName;
|
||||
|
||||
return convertedFileName;
|
||||
}
|
||||
|
||||
|
||||
bool dvifile::saveAs(const QString &filename)
|
||||
{
|
||||
if (dvi_Data() == 0)
|
||||
|
|
36
dviFile.h
36
dviFile.h
|
@ -5,7 +5,7 @@
|
|||
// Class that represents a DVI file. Part of KDVI - A DVI previewing
|
||||
// plugin for kviewshell.
|
||||
//
|
||||
// (C) 2004 Stefan Kebekus. Distributed under the GPL.
|
||||
// (C) 2004-2005 Stefan Kebekus. Distributed under the GPL.
|
||||
//
|
||||
|
||||
#ifndef _DVIFILE_H
|
||||
|
@ -18,6 +18,7 @@
|
|||
#include <qstring.h>
|
||||
//Added by qt3to4:
|
||||
#include <Q3MemArray>
|
||||
#include <qmap.h>
|
||||
|
||||
#include "bigEndianByteReader.h"
|
||||
|
||||
|
@ -99,6 +100,26 @@ class dvifile : public bigEndianByteReader
|
|||
renumbers the pages. */
|
||||
void renumber();
|
||||
|
||||
/** PDF to PS file conversion
|
||||
|
||||
This utility method takes the name of a PDF-file, and attempts to
|
||||
convert it to a PS file. The dvifile internally keeps a list of
|
||||
converted files, to do two thigs:
|
||||
|
||||
- convert files only once.
|
||||
|
||||
- delete all converted files on destruction
|
||||
|
||||
@warning The internal buffer can lead to difficulties if filenames
|
||||
of PDF-files are not unique: if the content of a PDF file is
|
||||
changed and this method is called a second time with the same file
|
||||
name, the method will then NOT convert the file, but simply return
|
||||
the name from the buffer
|
||||
|
||||
@returns The name of the PS file, or QString::null on failure.
|
||||
*/
|
||||
QString convertPDFtoPS(const QString &PDFFilename, QString *converrorms=0);
|
||||
|
||||
private:
|
||||
/** process_preamble reads the information in the preamble and
|
||||
stores it into global variables for later use. */
|
||||
|
@ -118,6 +139,19 @@ class dvifile : public bigEndianByteReader
|
|||
double cmPerDVIunit;
|
||||
|
||||
Q3MemArray<Q_UINT8> dviData;
|
||||
|
||||
/** Map of filenames for converted PDF files
|
||||
|
||||
This map contains names of PDF files that were converted to
|
||||
PostScript. The key is the name of the PDF file, the data the name
|
||||
of the associated PS file, or QString::null, if the file could not
|
||||
be converted. The PS files are deleted when the DVI-file is
|
||||
destructed. */
|
||||
QMap<QString, QString> convertedFiles;
|
||||
|
||||
/** Flag, used so that KDVI complains only once about a missing
|
||||
"PDF2PS" utility. Set to "false" in the constructor. */
|
||||
bool have_complainedAboutMissingPDF2PS;
|
||||
};
|
||||
|
||||
#endif //ifndef _DVIFILE_H
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <kdebug.h>
|
||||
#include <klocale.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kmimetype.h>
|
||||
#include <kprocess.h>
|
||||
#include <kprocio.h>
|
||||
|
@ -85,6 +86,10 @@ void dviRenderer::prescan_embedPS(char *cp, Q_UINT8 *beginningOfSpecialCommand)
|
|||
// Now locate the Gfx file on the hard disk...
|
||||
EPSfilename = ghostscript_interface::locateEPSfile(EPSfilename, dviFile);
|
||||
|
||||
// If the EPSfilename really points to a PDF file, convert that file now.
|
||||
if (ending == "pdf")
|
||||
EPSfilename = dviFile->convertPDFtoPS(EPSfilename);
|
||||
|
||||
if (!QFile::exists(EPSfilename)) {
|
||||
// Find the number of the page
|
||||
Q_UINT32 currentOffset = beginningOfSpecialCommand - dviFile->dvi_Data();
|
||||
|
@ -92,6 +97,9 @@ void dviRenderer::prescan_embedPS(char *cp, Q_UINT8 *beginningOfSpecialCommand)
|
|||
for(page=0; page < dviFile->total_pages; page++)
|
||||
if ((dviFile->page_offset[page] <= currentOffset) && (currentOffset <= dviFile->page_offset[page+1]))
|
||||
break;
|
||||
if (ending == "pdf")
|
||||
errorMsg += i18n("Page %1: The PDF file <strong>%2</strong> could not be converted to PostScript.<br>").arg(page+1).arg(originalFName);
|
||||
else
|
||||
errorMsg += i18n("Page %1: The PostScript file <strong>%2</strong> could not be found.<br>").arg(page+1).arg(originalFName);
|
||||
embedPS_progress->progressBar()->advance(1);
|
||||
qApp->processEvents();
|
||||
|
@ -409,6 +417,22 @@ void dviRenderer::prescan_ParsePSFileSpecial(QString cp)
|
|||
// Now locate the Gfx file on the hard disk...
|
||||
EPSfilename = ghostscript_interface::locateEPSfile(EPSfilename, dviFile);
|
||||
|
||||
// If the EPSfilename really points to a PDF file, convert that file now.
|
||||
if (ending == "pdf") {
|
||||
QString convErrorMsg;
|
||||
QString oEPSfilename = EPSfilename;
|
||||
emit setStatusBarText( i18n("Converting PDF-file %1...").arg(EPSfilename) );
|
||||
EPSfilename = dviFile->convertPDFtoPS(EPSfilename, &convErrorMsg);
|
||||
emit setStatusBarText( QString::null );
|
||||
if (convErrorMsg.isEmpty() != true) {
|
||||
KMessageBox::detailedError(parentWidget,
|
||||
i18n("<qt><strong>File conversion error!</strong> KDVI was not able to convert the external "
|
||||
"PDF-file <strong>%1</strong> into PostScript. Expect missing graphics or graphic errors.</qt>").arg(oEPSfilename),
|
||||
convErrorMsg, i18n("PDF/PS conversion error"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Now parse the arguments.
|
||||
int llx = 0;
|
||||
int lly = 0;
|
||||
|
|
Loading…
Reference in a new issue