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 generatorString;
FILE * file;
int total_pages;
unsigned int total_pages;
long * page_offset;
/** Numerator and denominator of the TeX units, as explained in

@ -26,10 +26,13 @@
#include <kdebug.h>
#include <kfiledialog.h>
#include <kio/job.h>
#include <kio/netaccess.h>
#include <klocale.h>
#include <kprinter.h>
#include <kprocess.h>
#include "dviwin.h"
#include "fontpool.h"
#include "fontprogress.h"
@ -137,6 +140,7 @@ dviWindow::dviWindow(double zoom, int mkpk, QWidget *parent, const char *name )
progress = 0;
export_printer = 0;
export_fileName = "";
export_tmpFileName = "";
// Calculate the horizontal resolution of the display device. @@@
// 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
// knows?
if (proc != 0) {
KMessageBox::sorry(0, i18n("Another export command is currently running"));
KMessageBox::sorry(this, i18n("Another export command is currently running"));
return;
}
// That sould also not happen.
if (dviFile == NULL)
return;
QString fileName;
if (fname.isEmpty()) {
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)));
}
// 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();
if (proc == 0) {
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
if (options.isEmpty() == false)
*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->closeStdin();
if (proc->start(KProcess::NotifyOnExit, KProcess::Stderr) == false) {
@ -376,6 +441,11 @@ void dviWindow::abortExternalProgramm(void)
proc = 0;
}
if (export_tmpFileName.isEmpty() != true) {
unlink(export_tmpFileName.latin1()); // That should delete the file.
export_tmpFileName = "";
}
if (progress != 0) {
progress->hideDialog();
delete progress;
@ -681,7 +751,7 @@ bool dviWindow::setFile( const QString & fname )
//------ handling pages ----------
void dviWindow::gotoPage(int new_page)
void dviWindow::gotoPage(unsigned int new_page)
{
if (dviFile == NULL)
return;
@ -834,12 +904,20 @@ void dviWindow::mousePressEvent ( QMouseEvent * e )
if (cp[i].isDigit() == false)
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);
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(TeXfile),
i18n( "Could not find file" ));
return;
if (QFile::exists(cp.mid(i+1)))
TeXfile = cp.mid(i+1);
else {
TeXfile = cp.mid(i);
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",
"Use KDE's editor kate for now");
if (r == KMessageBox::Continue)
command = "xkate %f";
command = "kate %f";
else
return;
}

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

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

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

Loading…
Cancel
Save