diff --git a/Makefile.am b/Makefile.am index c623bdf12..b97812c94 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,9 +13,8 @@ noinst_PROGRAMS = squeeze METASOURCES = AUTO libkdvi_la_SOURCES = kdvi_multipage.cpp \ - dviwin.cpp bigEndianByteReader.cpp \ - optiondialog.cpp infodialog.cpp\ - psheader.c dviwin_draw.cpp dviwin_textsearch.cpp dvi_init.cpp\ + dviwin.cpp bigEndianByteReader.cpp optiondialog.cpp infodialog.cpp\ + psheader.c dviwin_draw.cpp dviwin_export.cpp dviwin_textsearch.cpp dvi_init.cpp\ font.cpp fontpool.cpp fontprogress.cpp pk.cpp psgs.cpp\ special.cpp util.cpp vf.cpp glyph.cpp selection.cpp history.cpp diff --git a/dviwin.cpp b/dviwin.cpp index 58ac245ff..f92f10e25 100644 --- a/dviwin.cpp +++ b/dviwin.cpp @@ -177,6 +177,7 @@ dviWindow::~dviWindow() export_printer = 0; } + void dviWindow::showInfo(void) { if (info == 0) @@ -191,406 +192,6 @@ void dviWindow::showInfo(void) } -void dviWindow::exportText(void) -{ - // That sould also not happen. - if (dviFile == NULL) - return; - if (dviFile->dvi_Data == 0 ) - return; - if (pixmap->paintingActive()) - return; - - if (KMessageBox::warningContinueCancel( this, - i18n("This function exports the DVI file to a plain text. Unfortunately, this version of " - "KDVI treats only plain ASCII characters properly. Symbols, ligatures, mathematical " - "formulae, accented characters, and non-english text, such as Russian or Korean, will " - "most likely be messed up completely."), - i18n("Function may not work as expected"), - i18n("Continue anyway"), - "warning_export_to_text_may_not_work") == KMessageBox::Cancel) - return; - - QString fileName = KFileDialog::getSaveFileName(QString::null, "*.txt|Plain Text (Latin 1) (*.txt)", this, i18n("Export File As")); - if (fileName.isEmpty()) - return; - QFileInfo finfo(fileName); - if (finfo.exists()) { - int r = KMessageBox::warningYesNo (this, QString(i18n("The file %1\nexists. Shall I overwrite that file?")).arg(fileName), - i18n("Overwrite file")); - if (r == KMessageBox::No) - return; - } - - QFile textFile(fileName); - textFile.open( IO_WriteOnly ); - QTextStream stream( &textFile ); - - bool _postscript_sav = _postscript; - int current_page_sav = current_page; - _postscript = FALSE; // Switch off postscript to speed up things... - QProgressDialog progress( i18n("Exporting to text..."), i18n("Abort"), dviFile->total_pages, this, "export_text_progress", TRUE ); - progress.setMinimumDuration(300); - QPixmap pixie(1,1); - for(current_page=0; current_page < dviFile->total_pages; current_page++) { - progress.setProgress( current_page ); - // Funny. The manual to QT tells us that we need to call - // qApp->processEvents() regularly to keep the application from - // freezing. However, the application crashes immediately if we - // uncomment the following line and works just fine as it is. Wild - // guess: Could that be related to the fact that we are linking - // agains qt-mt? - - // qApp->processEvents(); - - if ( progress.wasCancelled() ) - break; - - foreGroundPaint.begin( &pixie ); - draw_page(); // We gracefully ingore any errors (bad dvi-file, etc.) which may occur during draw_page() - foreGroundPaint.end(); - - for(int i=0; itotal_pages ); - // Restore the PostScript setting - _postscript = _postscript_sav; - - // Restore the current page. - current_page = current_page_sav; - foreGroundPaint.begin( &pixie ); - draw_page(); // We gracefully ingore any errors (bad dvi-file, etc.) which may occur during draw_page() - foreGroundPaint.end(); - - return; -} - - -void dviWindow::exportPDF(void) -{ - // It could perhaps happen that a kShellProcess, which runs an - // editor for inverse search, is still running. In that case, we - // ingore any further output of the editor by detaching the - // appropriate slots. The sigal "processExited", however, remains - // attached to the slow "exportCommand_terminated", which is smart - // enough to ignore the exit status of the editor if another command - // has been called meanwhile. See also the exportPS method. - if (proc != 0) { - // Make sure all further output of the programm is ignored - qApp->disconnect(proc, SIGNAL(receivedStderr(KProcess *, char *, int)), 0, 0); - qApp->disconnect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)), 0, 0); - proc = 0; - } - - // That sould also not happen. - if (dviFile == NULL) - return; - - // Is the dvipdfm-Programm available ?? - QStringList texList = QStringList::split(":", QString::fromLocal8Bit(getenv("PATH"))); - bool found = false; - for (QStringList::Iterator it=texList.begin(); it!=texList.end(); ++it) { - QString temp = (*it) + "/" + "dvipdfm"; - if (QFile::exists(temp)) { - found = true; - break; - } - } - if (found == false) { - KMessageBox::sorry(0, i18n("KDVI could not locate the program 'dvipdfm' on your computer. That program is\n" - "absolutely needed by the export function. You can, however, convert\n" - "the DVI-file to PDF using the print function of KDVI, but that will often\n" - "produce which print ok, but are of inferior quality if viewed in the \n" - "Acrobat Reader. It may be wise to upgrade to a more recent version of your\n" - "TeX distribution which includes the 'dvipdfm' program.\n\n" - "Hint to the perplexed system administrator: KDVI uses the shell's PATH variable\n" - "when looking for programs.")); - return; - } - - QString fileName = KFileDialog::getSaveFileName(QString::null, "*.pdf|Portable Document Format (*.pdf)", this, i18n("Export File As")); - if (fileName.isEmpty()) - return; - QFileInfo finfo(fileName); - if (finfo.exists()) { - int r = KMessageBox::warningYesNo (this, QString(i18n("The file %1\nexists. Shall I overwrite that file?")).arg(fileName), - i18n("Overwrite file")); - if (r == KMessageBox::No) - return; - } - - // Initialize the progress dialog - progress = new fontProgressDialog( QString::null, - i18n("Using dvipdfm to export the file to PDF"), - QString::null, - i18n("KDVI is currently using the external program 'dvipdfm' to " - "convert your DVI-file to PDF. Sometimes that can take " - "a while because dvipdfm needs to generate its own bitmap fonts " - "Please be patient."), - i18n("Waiting for dvipdfm to finish..."), - this, "dvipdfm progress dialog", false ); - if (progress != 0) { - progress->TextLabel2->setText( i18n("Please be patient") ); - progress->setTotalSteps( dviFile->total_pages ); - qApp->connect(progress, SIGNAL(finished(void)), this, SLOT(abortExternalProgramm(void))); - } - - proc = new KShellProcess(); - if (proc == 0) { - kdError(4300) << "Could not allocate ShellProcess for the dvipdfm command." << endl; - return; - } - qApp->disconnect( this, SIGNAL(mySignal()), 0, 0 ); - - qApp->connect(proc, SIGNAL(receivedStderr(KProcess *, char *, int)), this, SLOT(dvips_output_receiver(KProcess *, char *, int))); - qApp->connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)), this, SLOT(dvips_output_receiver(KProcess *, char *, int))); - qApp->connect(proc, SIGNAL(processExited(KProcess *)), this, SLOT(dvips_terminated(KProcess *))); - - export_errorString = i18n("The external program 'dvipdf', which was used to export the file, reported an error. " - "You might wish to look at the document info dialog which you will " - "find in the File-Menu for a precise error report.") ; - - - if (info) - info->clear(QString(i18n("Export: %1 to PDF")).arg(KShellProcess::quote(dviFile->filename))); - - proc->clearArguments(); - finfo.setFile(dviFile->filename); - *proc << QString("cd %1; dvipdfm").arg(KShellProcess::quote(finfo.dirPath(true))); - *proc << QString("-o %1").arg(KShellProcess::quote(fileName)); - *proc << KShellProcess::quote(dviFile->filename); - proc->closeStdin(); - if (proc->start(KProcess::NotifyOnExit, KProcess::AllOutput) == false) { - kdError(4300) << "dvipdfm failed to start" << endl; - return; - } - return; -} - - -void dviWindow::exportPS(QString fname, QString options, KPrinter *printer) -{ - // Safety check. - if (dviFile->page_offset == 0) - return; - - // It could perhaps happen that a kShellProcess, which runs an - // editor for inverse search, is still running. In that case, we - // ingore any further output of the editor by detaching the - // appropriate slots. The sigal "processExited", however, remains - // attached to the slow "exportCommand_terminated", which is smart - // enough to ignore the exit status of the editor if another command - // has been called meanwhile. See also the exportPDF method. - if (proc != 0) { - qApp->disconnect(proc, SIGNAL(receivedStderr(KProcess *, char *, int)), 0, 0); - qApp->disconnect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)), 0, 0); - proc = 0; - } - - // 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")); - if (fileName.isEmpty()) - return; - QFileInfo finfo(fileName); - if (finfo.exists()) { - int r = KMessageBox::warningYesNo (this, QString(i18n("The file %1\nexists. Shall I overwrite that file?")).arg(fileName), - i18n("Overwrite file")); - if (r == KMessageBox::No) - return; - } - } else - fileName = fname; - export_fileName = fileName; - export_printer = printer; - - // Initialize the progress dialog - progress = new fontProgressDialog( QString::null, - i18n("Using dvips to export the file to PostScript"), - QString::null, - i18n("KDVI is currently using the external program 'dvips' to " - "convert your DVI-file to PostScript. Sometimes that can take " - "a while because dvips needs to generate its own bitmap fonts " - "Please be patient."), - i18n("Waiting for dvips to finish..."), - this, "dvips progress dialog", false ); - if (progress != 0) { - progress->TextLabel2->setText( i18n("Please be patient") ); - progress->setTotalSteps( dviFile->total_pages ); - 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(QFile::encodeName(sourceFileName),"r+"); - for(Q_UINT32 i=1; 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; - return; - } - - qApp->connect(proc, SIGNAL(receivedStderr(KProcess *, char *, int)), this, SLOT(dvips_output_receiver(KProcess *, char *, int))); - qApp->connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)), this, SLOT(dvips_output_receiver(KProcess *, char *, int))); - qApp->connect(proc, SIGNAL(processExited(KProcess *)), this, SLOT(dvips_terminated(KProcess *))); - export_errorString = i18n("The external program 'dvips', which was used to export the file, reported an error. " - "You might wish to look at the document info dialog which you will " - "find in the File-Menu for a precise error report.") ; - if (info) - info->clear(QString(i18n("Export: %1 to PostScript")).arg(KShellProcess::quote(dviFile->filename))); - - proc->clearArguments(); - QFileInfo finfo(dviFile->filename); - *proc << QString("cd %1; dvips").arg(KShellProcess::quote(finfo.dirPath(true))); - if (printer == 0) - *proc << "-z"; // export Hyperlinks - if (options.isEmpty() == false) - *proc << options; - *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) { - kdError(4300) << "dvips failed to start" << endl; - return; - } - return; -} - -void dviWindow::dvips_output_receiver(KProcess *, char *buffer, int buflen) -{ - // Paranoia. - if (buflen < 0) - return; - QString op = QString::fromLocal8Bit(buffer, buflen); - - if (info != 0) - info->outputReceiver(op); - if (progress != 0) - progress->show(); -} - -void dviWindow::dvips_terminated(KProcess *sproc) -{ - // Give an error message from the message string. However, if the - // sproc is not the "current external process of interest", i.e. not - // the LAST external program that was started by the user, then the - // export_errorString, does not correspond to sproc. In that case, - // we ingore the return status silently. - if ((proc == sproc) && (sproc->normalExit() == true) && (sproc->exitStatus() != 0)) - KMessageBox::error( this, export_errorString ); - - if (export_printer != 0) - export_printer->printFiles( QStringList(export_fileName), true ); - // Kill and delete the remaining process, reset the printer, etc. - abortExternalProgramm(); -} - -void dviWindow::editorCommand_terminated(KProcess *sproc) -{ - // Give an error message from the message string. However, if the - // sproc is not the "current external process of interest", i.e. not - // the LAST external program that was started by the user, then the - // export_errorString, does not correspond to sproc. In that case, - // we ingore the return status silently. - if ((proc == sproc) && (sproc->normalExit() == true) && (sproc->exitStatus() != 0)) - KMessageBox::error( this, export_errorString ); - - // Let's hope that this is not all too nasty... killing a - // KShellProcess from a slot that was called from the KShellProcess - // itself. Until now, there weren't any problems. - - // Perhaps it was a bad idea, after all. - //@@@@ delete sproc; -} - - - -void dviWindow::abortExternalProgramm(void) -{ - if (proc != 0) { - delete proc; // Deleting the KProcess kills the child. - proc = 0; - } - - if (export_tmpFileName.isEmpty() != true) { - unlink(QFile::encodeName(export_tmpFileName)); // That should delete the file. - export_tmpFileName = ""; - } - - if (progress != 0) { - progress->hideDialog(); - delete progress; - progress = 0; - } - - export_printer = 0; - export_fileName = ""; -} - void dviWindow::selectAll(void) { QString selectedText(""); @@ -823,7 +424,7 @@ void dviWindow::changePageSize() //------ setup the dvi interpreter (should do more here ?) ---------- -bool dviWindow::setFile(QString fname, QString ref, bool sourceMarker=true) +bool dviWindow::setFile(QString fname, QString ref, bool sourceMarker) { DVIselection.clear(); reference = QString::null; @@ -970,7 +571,7 @@ void dviWindow::all_fonts_loaded(void) for(i=0;i= sourceLineNumber)) { - page = current_page; - y = sourceHyperLinkList[i].box.top(); - } + if (fileName.stripWhiteSpace() == sourceFileName.stripWhiteSpace()) + if (refLineNumber >= sourceLineNumber) { + page = current_page; + y = sourceHyperLinkList[i].box.top(); + } else + break; } } progress.setProgress( dviFile->total_pages ); // Switch off the progress dialog, etc. diff --git a/kdvi_multipage.cpp b/kdvi_multipage.cpp index c56bfcd16..afbfd46e4 100644 --- a/kdvi_multipage.cpp +++ b/kdvi_multipage.cpp @@ -122,6 +122,8 @@ bool KDVIMultiPage::openFile() emit setStatusBarText(QString(i18n("Loading file %1")).arg(m_file)); bool r = window->setFile(m_file,url().ref()); + if (!r) + emit setStatusBarText(QString::null); window->changePageSize(); // This also calles drawPage(); emit numberOfPages(window->totalPages()); enableActions(r);