fixes printing bug

svn path=/trunk/kdegraphics/kdvi/; revision=112245
remotes/origin/kdvi-3.0
Stefan Kebekus 25 years ago
parent 32af7f65d7
commit 971f7d6fd0
  1. 2
      dvi_init.h
  2. 98
      dviwin.cpp
  3. 5
      dviwin.h
  4. 4
      kdvi_multipage.cpp
  5. 1
      optiondialog.cpp

@ -16,7 +16,7 @@ class dvifile {
QString filename; QString filename;
QString generatorString; QString generatorString;
FILE * file; FILE * file;
int total_pages; unsigned int total_pages;
long * page_offset; long * page_offset;
/** Numerator and denominator of the TeX units, as explained in /** Numerator and denominator of the TeX units, as explained in

@ -26,10 +26,13 @@
#include <kdebug.h> #include <kdebug.h>
#include <kfiledialog.h> #include <kfiledialog.h>
#include <kio/job.h> #include <kio/job.h>
#include <kio/netaccess.h>
#include <klocale.h> #include <klocale.h>
#include <kprinter.h> #include <kprinter.h>
#include <kprocess.h> #include <kprocess.h>
#include "dviwin.h" #include "dviwin.h"
#include "fontpool.h" #include "fontpool.h"
#include "fontprogress.h" #include "fontprogress.h"
@ -137,6 +140,7 @@ dviWindow::dviWindow(double zoom, int mkpk, QWidget *parent, const char *name )
progress = 0; progress = 0;
export_printer = 0; export_printer = 0;
export_fileName = ""; export_fileName = "";
export_tmpFileName = "";
// Calculate the horizontal resolution of the display device. @@@ // Calculate the horizontal resolution of the display device. @@@
// We assume implicitly that the horizontal and vertical resolutions // We assume implicitly that the horizontal and vertical resolutions
@ -296,14 +300,14 @@ void dviWindow::exportPS(QString fname, QString options, KPrinter *printer)
// Should not happen since the progressDialog is modal... but who // Should not happen since the progressDialog is modal... but who
// knows? // knows?
if (proc != 0) { if (proc != 0) {
KMessageBox::sorry(0, i18n("Another export command is currently running")); KMessageBox::sorry(this, i18n("Another export command is currently running"));
return; return;
} }
// That sould also not happen. // That sould also not happen.
if (dviFile == NULL) if (dviFile == NULL)
return; return;
QString fileName; QString fileName;
if (fname.isEmpty()) { if (fname.isEmpty()) {
fileName = KFileDialog::getSaveFileName(QString::null, "*.ps|PostScript (*.ps)", this, i18n("Export File As")); fileName = KFileDialog::getSaveFileName(QString::null, "*.ps|PostScript (*.ps)", this, i18n("Export File As"));
@ -337,6 +341,67 @@ void dviWindow::exportPS(QString fname, QString options, KPrinter *printer)
qApp->connect(progress, SIGNAL(finished(void)), this, SLOT(abortExternalProgramm(void))); qApp->connect(progress, SIGNAL(finished(void)), this, SLOT(abortExternalProgramm(void)));
} }
// There is a major problem with dvips, at least 5.86 and lower: the
// arguments of the option "-pp" refer to TeX-pages, not to
// sequentially numbered pages. For instance "-pp 7" may refer to 3
// or more pages: one page "VII" in the table of contents, a page
// "7" in the text body, and any number of pages "7" in various
// appendices, indices, bibliographies, and so forth. KDVI currently
// uses the following disgusting workaround: if the "options"
// variable is used, the DVI-file is copied to a temporary file, and
// all the page numbers are changed into a sequential ordering
// (using UNIX files, and taking manually care of CPU byte
// ordering). Finally, dvips is then called with the new file, and
// the file is afterwards deleted. Isn't that great?
// Sourcefile is the name of the DVI which is used by dvips, either
// the original file, or a temporary file with a new numbering.
QString sourceFileName = dviFile->filename;
if (options.isEmpty() == false) {
// Get a name for a temporary file.
KTempFile export_tmpFile;
export_tmpFileName = export_tmpFile.name();
export_tmpFile.unlink();
sourceFileName = export_tmpFileName;
if (KIO::NetAccess::copy(dviFile->filename, sourceFileName)) {
int wordSize;
bool bigEndian;
qSysInfo (&wordSize, &bigEndian);
// Proper error handling? We don't care.
FILE *f = fopen(sourceFileName.latin1(),"r+");
for(Q_UINT32 i=0; i<=dviFile->total_pages; i++) {
fseek(f,dviFile->page_offset[i-1]+1, SEEK_SET);
// Write the page number to the file, taking good care of byte
// orderings. Hopefully QT will implement random access QFiles
// soon.
if (bigEndian) {
fwrite(&i, sizeof(Q_INT32), 1, f);
fwrite(&i, sizeof(Q_INT32), 1, f);
fwrite(&i, sizeof(Q_INT32), 1, f);
fwrite(&i, sizeof(Q_INT32), 1, f);
} else {
Q_UINT8 anum[4];
Q_UINT8 *bnum = (Q_UINT8 *)&i;
anum[0] = bnum[3];
anum[1] = bnum[2];
anum[2] = bnum[1];
anum[3] = bnum[0];
fwrite(anum, sizeof(Q_INT32), 1, f);
fwrite(anum, sizeof(Q_INT32), 1, f);
fwrite(anum, sizeof(Q_INT32), 1, f);
fwrite(anum, sizeof(Q_INT32), 1, f);
}
}
fclose(f);
} else {
KMessageBox::error(this, i18n("Failed to copy the DVI-file <strong>%1</strong> to the temporary file <strong>%2</strong>. "
"The export or print command is aborted.").arg(dviFile->filename).arg(sourceFileName));
return;
}
}
// Allocate and initialize the shell process.
proc = new KShellProcess(); proc = new KShellProcess();
if (proc == 0) { if (proc == 0) {
kdError(4300) << "Could not allocate ShellProcess for the dvips command." << endl; kdError(4300) << "Could not allocate ShellProcess for the dvips command." << endl;
@ -358,7 +423,7 @@ void dviWindow::exportPS(QString fname, QString options, KPrinter *printer)
*proc << "-z"; // export Hyperlinks *proc << "-z"; // export Hyperlinks
if (options.isEmpty() == false) if (options.isEmpty() == false)
*proc << options; *proc << options;
*proc << QString("%1").arg(KShellProcess::quote(dviFile->filename)); *proc << QString("%1").arg(KShellProcess::quote(sourceFileName));
*proc << QString("-o %1").arg(KShellProcess::quote(fileName)); *proc << QString("-o %1").arg(KShellProcess::quote(fileName));
proc->closeStdin(); proc->closeStdin();
if (proc->start(KProcess::NotifyOnExit, KProcess::Stderr) == false) { if (proc->start(KProcess::NotifyOnExit, KProcess::Stderr) == false) {
@ -376,6 +441,11 @@ void dviWindow::abortExternalProgramm(void)
proc = 0; proc = 0;
} }
if (export_tmpFileName.isEmpty() != true) {
unlink(export_tmpFileName.latin1()); // That should delete the file.
export_tmpFileName = "";
}
if (progress != 0) { if (progress != 0) {
progress->hideDialog(); progress->hideDialog();
delete progress; delete progress;
@ -681,7 +751,7 @@ bool dviWindow::setFile( const QString & fname )
//------ handling pages ---------- //------ handling pages ----------
void dviWindow::gotoPage(int new_page) void dviWindow::gotoPage(unsigned int new_page)
{ {
if (dviFile == NULL) if (dviFile == NULL)
return; return;
@ -834,12 +904,20 @@ void dviWindow::mousePressEvent ( QMouseEvent * e )
if (cp[i].isDigit() == false) if (cp[i].isDigit() == false)
break; break;
// The macro-package srcltx gives a special like "src:99 test.tex"
// while MikTeX gives "src:99test.tex". KDVI tries
// to understand both.
QString TeXfile = cp.mid(i); QString TeXfile = cp.mid(i);
if (!QFile::exists(TeXfile)) { if (QFile::exists(cp.mid(i+1)))
KMessageBox::sorry(this, i18n("The DVI-file refers to the TeX-file " TeXfile = cp.mid(i+1);
"<strong>%1</strong> which could not be found.").arg(TeXfile), else {
i18n( "Could not find file" )); TeXfile = cp.mid(i);
return; if (!QFile::exists(TeXfile)) {
KMessageBox::sorry(this, i18n("The DVI-file refers to the TeX-file "
"<strong>%1</strong> which could not be found.").arg(KShellProcess::quote(TeXfile)),
i18n( "Could not find file" ));
return;
}
} }
@ -852,7 +930,7 @@ void dviWindow::mousePressEvent ( QMouseEvent * e )
"Need to specify editor", "Need to specify editor",
"Use KDE's editor kate for now"); "Use KDE's editor kate for now");
if (r == KMessageBox::Continue) if (r == KMessageBox::Continue)
command = "xkate %f"; command = "kate %f";
else else
return; return;
} }

@ -126,7 +126,7 @@ public slots:
bool setFile(const QString & fname); bool setFile(const QString & fname);
/** Displays the page of the first argument */ /** Displays the page of the first argument */
void gotoPage(int page); void gotoPage(unsigned int page);
/** Displays the page of the first argument, and blinks the display /** Displays the page of the first argument, and blinks the display
at the vertical offset vflashOffset. This is used when the user at the vertical offset vflashOffset. This is used when the user
@ -232,7 +232,7 @@ private:
unsigned int MetafontMode; unsigned int MetafontMode;
QString paper_type; QString paper_type;
int ChangesPossible; int ChangesPossible;
int current_page; unsigned int current_page;
// Indicates if the current page is already drawn (=1) or not (=0). // Indicates if the current page is already drawn (=1) or not (=0).
char is_current_page_drawn; char is_current_page_drawn;
double _zoom; double _zoom;
@ -242,6 +242,7 @@ private:
KShellProcess *proc; KShellProcess *proc;
KPrinter *export_printer; KPrinter *export_printer;
QString export_fileName; QString export_fileName;
QString export_tmpFileName;
}; };

@ -415,7 +415,6 @@ bool KDVIMultiPage::print(const QStringList &pages, int current)
commaflag = 1; commaflag = 1;
dvips_options += QString("%1").arg(*it); dvips_options += QString("%1").arg(*it);
} }
kdDebug() << "dvips_options " << dvips_options << "\n";
// Now print. For that, export the DVI-File to PostScript. Note that // Now print. For that, export the DVI-File to PostScript. Note that
// dvips will run concurrently to keep the GUI responsive, keep log // dvips will run concurrently to keep the GUI responsive, keep log
@ -423,12 +422,11 @@ bool KDVIMultiPage::print(const QStringList &pages, int current)
// means that the dvi-widget will print the file when dvips // means that the dvi-widget will print the file when dvips
// terminates, and then delete the output file. // terminates, and then delete the output file.
KTempFile tf; KTempFile tf;
kdDebug() << "TMP " << tf.name() << "\n";
window->exportPS(tf.name(), dvips_options, printer); window->exportPS(tf.name(), dvips_options, printer);
// "True" may be a bit euphemistic. However, since dvips runs // "True" may be a bit euphemistic. However, since dvips runs
// concurrently, there is no way of telling the result of the // concurrently, there is no way of telling the result of the
// printing command now. // printing command at this stage.
return true; return true;
} }

@ -125,6 +125,7 @@ void OptionDialog::slotApply()
config->writeEntry( "MakePK", mFont.fontPathCheck->isChecked() ); config->writeEntry( "MakePK", mFont.fontPathCheck->isChecked() );
config->writeEntry( "ShowPS", mRender.showSpecialCheck->isChecked() ); config->writeEntry( "ShowPS", mRender.showSpecialCheck->isChecked() );
config->writeEntry( "ShowHyperLinks", mRender.showHyperLinksCheck->isChecked() ); config->writeEntry( "ShowHyperLinks", mRender.showHyperLinksCheck->isChecked() );
config->writeEntry( "EditorCommand", EditorCommand );
config->sync(); config->sync();

Loading…
Cancel
Save