Patch by Luigi Toscano <luigi.toscano@tiscali.it> to mplemented printing support for DVI backend.

CCMAIL: luigi.toscano@tiscali.it

He says:
"Thanks for the infrastructure work to John Layt and apologies for my (non-existent) reply to your mail..."
CCMAIL: john@layt.net

svn path=/trunk/KDE/kdegraphics/okular/; revision=754729
This commit is contained in:
Pino Toscano 2007-12-30 16:41:10 +00:00
parent 0b65d8ef2b
commit 59f19fe8aa
7 changed files with 113 additions and 78 deletions

View File

@ -4,7 +4,7 @@ include_directories(
)
add_definitions (-DQT3_SUPPORT -DQT3_SUPPORT_WARNINGS)
#add_definitions(-DDEBUG_DVIRENDERER -DDEBUG_RENDER -DDEBUG_PRESCAN)
#add_definitions(-DDEBUG_DVIRENDERER -DDEBUG_RENDER -DDEBUG_PRESCAN -DDEBUG_PSGS -DDEBUG_FONTPOOL)
if (FREETYPE_FOUND)
add_definitions(-DHAVE_FREETYPE)
@ -44,6 +44,7 @@ set(okularGenerator_dvi_SRCS
fontpool.cpp
fontprogress.cpp
dvisourcesplitter.cpp
dviexport.cpp
)

View File

@ -31,9 +31,9 @@
#include <kstandarddirs.h>
#include <kvbox.h>
#include <q3ptrstack.h>
#include <QApplication>
#include <QCheckBox>
#include <QEventLoop>
#include <QFileInfo>
#include <QHBoxLayout>
#include <QLabel>
@ -41,7 +41,6 @@
#include <QProgressBar>
#include <QRegExp>
//#define DEBUG_DVIRENDERER
QPainter *foreGroundPainter; // QPainter used for text
@ -66,7 +65,8 @@ dviRenderer::dviRenderer()
current_page(0),
penWidth_in_mInch(0),
number_of_elements_in_path(0),
currentlyDrawnPage(0)
currentlyDrawnPage(0),
m_eventLoop(0)
{
#ifdef DEBUG_DVIRENDERER
//kDebug(kvs::dvi) << "dviRenderer( parent=" << par << " )";
@ -768,14 +768,9 @@ void dviRenderer::exportPDF()
void dviRenderer::exportPS(const QString& fname, const QStringList& options, QPrinter* printer)
{
Q_UNUSED( fname );
Q_UNUSED( options );
Q_UNUSED( printer );
/*
KSharedPtr<DVIExport> exporter(new DVIExportToPS(*this, parentWidget, fname, options, printer));
if (exporter->started())
all_exports_[exporter.data()] = exporter;
*/
}
/*
@ -793,7 +788,6 @@ void dviRenderer::editor_finished(const DVISourceEditor*)
}
*/
/*
void dviRenderer::export_finished(const DVIExport* key)
{
typedef QMap<const DVIExport*, KSharedPtr<DVIExport> > ExportMap;
@ -801,6 +795,16 @@ void dviRenderer::export_finished(const DVIExport* key)
if (it != all_exports_.end())
all_exports_.remove(key);
}
*/
void dviRenderer::setEventLoop(QEventLoop *el)
{
if (el == NULL)
{
delete m_eventLoop;
m_eventLoop = NULL;
}
else
m_eventLoop = el;
}
#include "dviRenderer.moc"

View File

@ -12,7 +12,7 @@
#include "bigEndianByteReader.h"
//#include "documentRenderer.h"
//#include "dviexport.h"
#include "dviexport.h"
//#include "dvisourceeditor.h"
#include "fontpool.h"
#include "dviPageInfo.h"
@ -36,6 +36,7 @@ class dvifile;
class dviRenderer;
class ghostscript_interface;
//class infoDialog;
class QEventLoop;
class QPrinter;
class KProgressDialog;
class PreBookmark;
@ -123,6 +124,10 @@ public:
virtual PageNumber totalPages() const;
void setParentWidget(QWidget *parent) {parentWidget = parent;}
void setEventLoop(QEventLoop *el);
#if 0
/** Called by the exporter or editor in order to update the
* contents of the global info dialog with @c text.
@ -145,7 +150,7 @@ public:
void html_href_special(const QString& msg);
void html_anchor_end();
void draw_page();
//void export_finished(const DVIExport*);
void export_finished(const DVIExport*);
//void editor_finished(const DVISourceEditor*);
public slots:
@ -177,8 +182,9 @@ private slots:
// void showThatSourceInformationIsPresent();
private:
// friend class DVIExportToPS;
friend class DVISourceEditor;
friend class DVIExportToPS;
friend class DVIExport;
// friend class DVISourceEditor;
/** URL to the DVI file
This field is initialized by the setFile() method. See the
@ -306,7 +312,7 @@ private:
drawinf currinf;
RenderedDocumentPagePixmap* currentlyDrawnPage;
//QMap<const DVIExport*, KSharedPtr<DVIExport> > all_exports_;
QMap<const DVIExport*, KSharedPtr<DVIExport> > all_exports_;
//KSharedPtr<DVISourceEditor> editor_;
/** Flag if document is modified
@ -326,6 +332,15 @@ private:
QVector<SimplePageSize> pageSizes;
QMap<QString, Anchor> anchorList;
/** pointer to the parent widget
This pointer can be used by implementations e.g. to display error
messages. This pointer can well be zero.
*/
QWidget* parentWidget;
QEventLoop* m_eventLoop;
};
#endif

View File

@ -17,6 +17,7 @@
*/
#include <config.h>
#include <okular/core/fileprinter.h>
#include "dviexport.h"
@ -29,15 +30,15 @@
#include <klocale.h>
#include <kmessagebox.h>
#include <kprocess.h>
#include <ktemporaryfile.h>
#include <QEventLoop>
#include <QFileInfo>
#include <QLabel>
#include <QTemporaryFile>
#include <QtGui/QPrinter>
#include <cassert>
//#define DVIEXPORT_USE_QPROCESS
DVIExport::DVIExport(dviRenderer& parent, QWidget* parent_widget)
: started_(false),
@ -72,7 +73,7 @@ void DVIExport::initialise_progress_dialog(int total_steps,
if (progress_) {
progress_->TextLabel2->setText(i18n("Please be patient"));
progress_->setTotalSteps(total_steps);
connect(progress_, SIGNAL(finished()), this, SLOT(abort_process()));
//connect(progress_, SIGNAL(finished()), this, SLOT(abort_process()));
}
}
@ -84,34 +85,27 @@ void DVIExport::start(const QString& command,
{
assert(!process_);
#ifndef DVIEXPORT_USE_QPROCESS
process_ = new KProcess;
connect(process_, SIGNAL(receivedStderr(KProcess* , char* , int)), this, SLOT(output_receiver(KProcess* , char* , int)));
connect(process_, SIGNAL(receivedStdout(KProcess* , char* , int)), this, SLOT(output_receiver(KProcess* , char* , int)));
connect(process_, SIGNAL(processExited(KProcess* )), this, SLOT(finished(KProcess*)));
*process_ << command << args;
#else
process_ = new QProcess;
process_->setReadChannelMode(QProcess::MergedChannels);
process_->setOutputChannelMode(KProcess::MergedChannels);
process_->setNextOpenMode(QIODevice::Text);
connect(process_, SIGNAL(readyReadStandardOutput()), this, SLOT(output_receiver()));
connect(process_, SIGNAL(finished(int)), this, SLOT(finished(int)));
#endif
*process_ << command << args;
if (!working_directory.isEmpty())
process_->setWorkingDirectory(working_directory);
error_message_ = error_message;
#ifndef DVIEXPORT_USE_QPROCESS
if (!process_->start(KProcess::NotifyOnExit, KProcess::AllOutput))
#else
process_->start(command, args, QIODevice::ReadOnly);
process_->start();
if (!process_->waitForStarted(-1))
#endif
kError(kvs::dvi) << command << " failed to start" << endl;
else
started_ = true;
if (parent_->m_eventLoop)
parent_->m_eventLoop->exec();
}
@ -133,46 +127,28 @@ void DVIExport::abort_process_impl()
}
#ifndef DVIEXPORT_USE_QPROCESS
void DVIExport::finished_impl()
#else
void DVIExport::finished_impl(int exit_code)
#endif
{
if (progress_) {
// Explicitly disconnect to prevent a recursive call of abort_process.
disconnect(progress_, SIGNAL(finished()), 0, 0);
//disconnect(progress_, SIGNAL(finished()), 0, 0);
if (progress_->isVisible())
progress_->hide();
}
#ifndef DVIEXPORT_USE_QPROCESS
if (process_ && process_->normalExit() && process_->exitStatus() != 0)
#else
if (process_ && exit_code != 0)
#endif
KMessageBox::error(parent_widget_, error_message_);
// Remove this from the store of all export processes.
parent_->m_eventLoop->exit( exit_code );
parent_->export_finished(this);
}
#ifndef DVIEXPORT_USE_QPROCESS
void DVIExport::output_receiver(KProcess* , char* buffer, int buflen)
#else
void DVIExport::output_receiver()
#endif
{
#ifndef DVIEXPORT_USE_QPROCESS
// Paranoia.
if (buflen <= 0)
return;
#endif
if (process_) {
#ifndef DVIEXPORT_USE_QPROCESS
parent_->update_info_dialog(QString::fromLocal8Bit(buffer, buflen));
#else
QString out = process_->readAllStandardOutput();
#if 0
parent_->update_info_dialog(process_->readAll());
#endif
if (progress_)
@ -278,7 +254,7 @@ DVIExportToPDF::DVIExportToPDF(dviRenderer& parent, QWidget* parent_widget)
KMessageBox::warningContinueCancel(parent_widget,
i18n("The file %1\nexists. Do you want to overwrite that file?", output_name),
i18n("Overwrite File"),
i18n("Overwrite"));
KGuiItem( i18n("Overwrite") ));
if (result == KMessageBox::Cancel)
return;
}
@ -291,8 +267,10 @@ DVIExportToPDF::DVIExportToPDF(dviRenderer& parent, QWidget* parent_widget)
"Please be patient."),
i18n("Waiting for dvipdfm to finish...") );
#if 0
parent.update_info_dialog(i18n("Export: %1 to PDF", dvi.filename),
true);
#endif
start("dvipdfm",
QStringList() << "-o"
@ -363,7 +341,7 @@ DVIExportToPS::DVIExportToPS(dviRenderer& parent,
KMessageBox::warningContinueCancel(parent_widget,
i18n("The file %1\nexists. Do you want to overwrite that file?", output_name_),
i18n("Overwrite File"),
i18n("Overwrite"));
KGuiItem( i18n("Overwrite") ));
if (result == KMessageBox::Cancel)
return;
}
@ -394,7 +372,8 @@ DVIExportToPS::DVIExportToPS(dviRenderer& parent,
if (!options.isEmpty() || dvi.suggestedPageSize != 0) {
// Get a name for a temporary file.
// Must open the QTemporaryFile to access the name.
QTemporaryFile tmpfile;
KTemporaryFile tmpfile;
tmpfile.setAutoRemove(false);
tmpfile.open();
tmpfile_name_ = tmpfile.fileName();
tmpfile.close();
@ -446,8 +425,10 @@ DVIExportToPS::DVIExportToPS(dviRenderer& parent,
"Please be patient."),
i18n("Waiting for dvips to finish...") );
#if 0
parent.update_info_dialog(i18n("Export: %1 to PostScript", dvi.filename),
true);
#endif
QStringList args;
if (!printer)
@ -470,28 +451,26 @@ DVIExportToPS::DVIExportToPS(dviRenderer& parent,
}
#ifndef DVIEXPORT_USE_QPROCESS
void DVIExportToPS::finished_impl()
#else
void DVIExportToPS::finished_impl(int exit_code)
#endif
{
if (printer_ && !output_name_.isEmpty()) {
const QFileInfo output(output_name_);
if (output.exists() && output.isReadable()) {
// I'm not 100% sure on this, think we still need to select pages in export to ps above
FilePrinter::printFile( printer_, output_name_,
FilePrinter::ApplicationDeletesFiles,
FilePrinter::ApplicationSelectsPages,
Okular::FilePrinter::printFile( (*printer_), output_name_,
Okular::FilePrinter::ApplicationDeletesFiles,
Okular::FilePrinter::ApplicationSelectsPages,
QString() );
}
}
#ifndef DVIEXPORT_USE_QPROCESS
DVIExport::finished_impl();
#else
if (!tmpfile_name_.isEmpty()) {
// Delete the file.
QFile(tmpfile_name_).remove();
tmpfile_name_.clear();
}
DVIExport::finished_impl(exit_code);
#endif
}

View File

@ -78,20 +78,17 @@ protected:
* when the external process finishes.
* @param exit_code the exit code retuned by the external process.
*/
//virtual void finished_impl(int exit_code);
virtual void finished_impl();
virtual void finished_impl(int exit_code);
private slots:
/// Calls an impl() inline so that derived classes don't need slots.
void abort_process() { abort_process_impl(); }
//void finished(int exit_code) { finished_impl(exit_code); }
void finished(KProcess*) { finished_impl(); }
void finished(int exit_code) { finished_impl(exit_code); }
/** This slot receives all output from the child process's stdin
* and stdout streams.
*/
//void output_receiver();
void output_receiver(KProcess *, char *, int);
void output_receiver();
private:
QString error_message_;
@ -136,8 +133,7 @@ public:
private:
virtual void abort_process_impl();
//virtual void finished_impl(int exit_code);
virtual void finished_impl();
virtual void finished_impl(int exit_code);
QPrinter* printer_;
QString output_name_;

View File

@ -9,6 +9,7 @@
#include <okular/core/action.h>
#include <okular/core/document.h>
#include <okular/core/fileprinter.h>
#include <okular/core/page.h>
#include <okular/core/sourcereference.h>
#include <okular/core/textpage.h>
@ -19,6 +20,7 @@
#include "dviPageInfo.h"
#include "dviRenderer.h"
#include "pageSize.h"
#include "dviexport.h"
#include <qapplication.h>
#include <qstring.h>
@ -29,6 +31,7 @@
#include <kaboutdata.h>
#include <kdebug.h>
#include <klocale.h>
#include <ktemporaryfile.h>
static KAboutData createAboutData()
{
@ -51,6 +54,7 @@ DviGenerator::DviGenerator( QObject *parent, const QVariantList &args ) : Okular
m_docInfo( 0 ), m_docSynopsis( 0 ), ready( false ), m_dviRenderer( 0 )
{
setFeature( TextExtraction );
setFeature( PrintPostscript );
}
bool DviGenerator::loadDocument( const QString & fileName, QVector< Okular::Page * > &pagesVector )
@ -62,6 +66,8 @@ bool DviGenerator::loadDocument( const QString & fileName, QVector< Okular::Page
if ( ! m_dviRenderer->setFile( fileName, base ) )
return false;
m_dviRenderer->setParentWidget( document()->widget() );
kDebug() << "# of pages: " << m_dviRenderer->dviFile->total_pages;
m_resolution = Okular::Utils::dpiY();
@ -386,4 +392,36 @@ void DviGenerator::loadPages( QVector< Okular::Page * > &pagesVector )
pagesVector[i]->setSourceReferences( refRects.at(i) );
}
bool DviGenerator::print( QPrinter& printer )
{
// Create tempfile to write to
KTemporaryFile tf;
tf.setSuffix( ".ps" );
if ( !tf.open() )
return false;
QList<int> pageList = Okular::FilePrinter::pageList( printer,
m_dviRenderer->totalPages(),
document()->bookmarkedPageList() );
QString pages;
QStringList printOptions;
// List of pages to print.
foreach ( int p, pageList )
{
pages += QString(",%1").arg(p);
}
if ( !pages.isEmpty() )
printOptions << "-pp" << pages.mid(1);
QEventLoop el;
m_dviRenderer->setEventLoop( &el );
m_dviRenderer->exportPS( tf.fileName(), printOptions, &printer );
tf.close();
// Error messages are handled by the generator - ugly, but it works.
return true;
}
#include "generator_dvi.moc"

View File

@ -37,6 +37,8 @@ class DviGenerator : public Okular::Generator
// table of contents
const Okular::DocumentSynopsis *generateDocumentSynopsis();
bool print( QPrinter &printer );
protected:
bool doCloseDocument();
Okular::TextPage* textPage( Okular::Page *page );