diff --git a/dvi_init.h b/dvi_init.h index 6c50369c2..d316b5e36 100644 --- a/dvi_init.h +++ b/dvi_init.h @@ -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 diff --git a/dviwin.cpp b/dviwin.cpp index 54e6c5afb..51e80b137 100644 --- a/dviwin.cpp +++ b/dviwin.cpp @@ -26,10 +26,13 @@ #include #include #include +#include #include #include #include + + #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 %1 to the temporary file %2. " + "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 " - "%1 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 " + "%1 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; } diff --git a/dviwin.h b/dviwin.h index 8b46bd203..57889ef13 100644 --- a/dviwin.h +++ b/dviwin.h @@ -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; }; diff --git a/kdvi_multipage.cpp b/kdvi_multipage.cpp index cada68169..9686b84dd 100644 --- a/kdvi_multipage.cpp +++ b/kdvi_multipage.cpp @@ -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; } diff --git a/optiondialog.cpp b/optiondialog.cpp index 6529103a6..c2c372ff4 100644 --- a/optiondialog.cpp +++ b/optiondialog.cpp @@ -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();