diff --git a/TODO b/TODO index 1ae0d9819..dc2e47fa1 100644 --- a/TODO +++ b/TODO @@ -7,21 +7,11 @@ o implement SaveAs o Fonts should be free when file is reloaded and the fonts are no longer needed -o Optionrequester: changes (e.g. PostScript on/off) are not applied until restart of the program. - -o Optionrequester: Hypertext on/off, Warnings on/off - -o Proper Error handling with throw/catch - o Update the Manual. o Document the technical specs. -o Bugfixing - -o psgs should use and remove tmp-files - -o kvieshell should change pageno when clicking on internal hyperlinks +o kviewshell should change pageno when clicking on internal hyperlinks HIGHLY DESIRABLE @@ -42,7 +32,7 @@ NOT SO URGENT o Document info dialog o Better online help o Internal printing using QPrinter -o Redirect error messages to a window (partly done) +o Redirect error messages to a window o More background processing to keep the UI responsive o Magnifier window o Two page view @@ -50,3 +40,4 @@ o Support for even more TeX specials o Popup-Window to inform the user when Fonts are generated o Search option o dynamical storage allocation for hyperlinks (see dviwin.h) +o more robust Error handling with throw/catch; no need to abort just because a PK-file is bad. \ No newline at end of file diff --git a/dvi_init.cpp b/dvi_init.cpp index b3b84b564..64b6aa717 100644 --- a/dvi_init.cpp +++ b/dvi_init.cpp @@ -241,6 +241,7 @@ static void process_preamble() if (one(dvi_file) != PRE) dvi_oops("DVI file doesn't start with preamble"); + // @@@ throw("DVI file doesn't start with preamble"); if (one(dvi_file) != 2) dvi_oops("Wrong version of DVI output for this program"); diff --git a/dviwin.cpp b/dviwin.cpp index f57b8288b..d2cbd1405 100644 --- a/dviwin.cpp +++ b/dviwin.cpp @@ -88,7 +88,6 @@ extern int total_pages; extern Display * DISP; extern Screen * SCRN; Window mainwin; -int useAlpha; void draw_page(void); extern "C" void kpse_set_progname(const char*); @@ -165,6 +164,8 @@ dviWindow::~dviWindow() void dviWindow::setShowPS( int flag ) { + kdDebug() << "setShowPS" << endl; + if ( _postscript == flag ) return; _postscript = flag; @@ -176,27 +177,27 @@ int dviWindow::showPS() return _postscript; } -void dviWindow::setAntiAlias( int flag ) +void dviWindow::setShowHyperLinks( int flag ) { - if ( !useAlpha == !flag ) + if ( _showHyperLinks == flag ) return; - useAlpha = flag; - //@@@ psp_destroy(); + _showHyperLinks = flag; + drawPage(); } -int dviWindow::antiAlias() +int dviWindow::showHyperLinks() { - return useAlpha; + return _showHyperLinks; } void dviWindow::setMakePK( int flag ) { - if (!ChangesPossible) - KMessageBox::sorry( this, + if (!ChangesPossible) + KMessageBox::sorry( this, i18n("The change in font generation will be effective\n" - "only after you start kdvi again!") ); - makepk = flag; + "only after you start kdvi again!") ); + makepk = flag; } int dviWindow::makePK() @@ -283,11 +284,11 @@ void dviWindow::initDVI() void dviWindow::drawPage() { - //@@@ psp_interrupt(); if (filename.isEmpty()) { // must call setFile first resize(0, 0); return; } + if (!dvi_name) { // dvi file not initialized yet QApplication::setOverrideCursor( waitCursor ); dvi_name = const_cast(filename.ascii()); @@ -297,8 +298,11 @@ void dviWindow::drawPage() dvi_time.setTime_t(0); // force init_dvi_file QApplication::restoreOverrideCursor(); KMessageBox::error( this, - i18n("What's this? DVI problem!\n") - + dvi_oops_msg); + i18n("File corruption!\n\n") + + dvi_oops_msg + + i18n("\n\nMost likely this means that the DVI file\n") + + filename + + i18n("\nis broken, or that it is not a DVI file.")); return; } check_dvi_file(); @@ -308,13 +312,6 @@ void dviWindow::drawPage() return; } - /*@@@ - min_x = 0; - min_y = 0; - max_x = page_w; - max_y = page_h; - */ - if ( !pixmap ) return; @@ -327,8 +324,11 @@ void dviWindow::drawPage() QApplication::restoreOverrideCursor(); foreGroundPaint.end(); KMessageBox::error( this, - i18n("What's this? DVI problem!\n") - + dvi_oops_msg); + i18n("File corruption!\n\n") + + dvi_oops_msg + + i18n("\n\nMost likely this means that the DVI file\n") + + filename + + i18n("\nis broken, or that it is not a DVI file.")); return; } else { check_dvi_file(); diff --git a/dviwin.h b/dviwin.h index 5e1d1d0a5..0efb466d1 100644 --- a/dviwin.h +++ b/dviwin.h @@ -44,8 +44,8 @@ public: void setShowPS( int flag ); int showPS(); - void setAntiAlias( int flag ); - int antiAlias(); + void setShowHyperLinks( int flag ); + int showHyperLinks(); void setMakePK( int flag ); int makePK(); void setResolution( int basedpi ); @@ -121,6 +121,9 @@ private: // drawn. unsigned char _postscript; + // TRUE, if Hyperlinks should be shown. + unsigned char _showHyperLinks; + // For each page, this vector contains the PostScript needed to // render that page. All entries point to valid QString which migt, // however, be empty. diff --git a/dviwin_draw.cpp b/dviwin_draw.cpp index 94aa4a975..47074a09d 100644 --- a/dviwin_draw.cpp +++ b/dviwin_draw.cpp @@ -150,18 +150,8 @@ static void xskip(long offset) } -static void tell_oops(const char *message, ...) +static void tell_oops(QString message) { - /* @@@ - kdError() << prog << ": " << endl; - va_start(args, message); - (void) vfprintf(stderr, message, args); - va_end(args); - if (currinf._virtual) - kdError() << " in virtual font " << currinf._virtual->fontname << endl; - else - kdError() << ", offset " << xtell(currinf.pos - 1) << "d" << endl; - */ dvi_oops_msg = (message), longjmp(dvi_env, 1); /* dvi_oops */ exit(1); } @@ -181,7 +171,7 @@ static void change_font(unsigned long n) { currinf.fontp = currinf.fonttable[n]; if (currinf.fontp == NULL) - tell_oops("non-existent font #%d", n); + tell_oops(QString("non-existent font #%1").arg(n) ); currinf.set_char_p = currinf.fontp->set_char_p; } @@ -210,7 +200,7 @@ void dviWindow::set_char(unsigned int cmd, unsigned int ch) // Draw the character. foreGroundPaint.drawPixmap(x, y, pix); // Mark hyperlinks in blue. - if (HTML_href != NULL) { + if (HTML_href != NULL && _showHyperLinks != 0) { int width = (int)(basedpi*0.05/(2.54*shrink_factor) + 0.5); // Line width 0.5 mm width = (width < 1) ? 1 : width; // but at least one pt. foreGroundPaint.fillRect(x, PXL_V, pix.width(), width, Qt::blue); @@ -419,7 +409,6 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case EOP: if (current_frame != minframe) tell_oops("stack not empty at EOP"); - //@@@ psp.endpage(); return; case PUSH: @@ -520,11 +509,11 @@ void dviWindow::draw_part(struct frame *minframe, double current_dimconv) case PRE: case POST: case POSTPOST: - tell_oops("shouldn't happen: %s encountered", dvi_table2[ch - (FNTNUM0 + 64)]); + tell_oops(QString("shouldn't happen: %1 encountered").arg(dvi_table2[ch - (FNTNUM0 + 64)])); break; default: - tell_oops("unknown op-code %d", ch); + tell_oops(QString("unknown op-code %1").arg(ch)); } /* end switch*/ } /* end else (ch not a SETCHAR or FNTNUM) */ } /* end for */ diff --git a/examples/BrokenDVI1.dvi b/examples/BrokenDVI1.dvi new file mode 100644 index 000000000..4f189853d Binary files /dev/null and b/examples/BrokenDVI1.dvi differ diff --git a/font.cpp b/font.cpp index e1fdc819a..df4d368ad 100644 --- a/font.cpp +++ b/font.cpp @@ -20,7 +20,7 @@ extern "C" { #include "oconfig.h" extern FILE *xfopen(const char *filename, const char *type); -extern void oops(const char *message, ...); +extern void oops(QString message); /** We try for a VF first because that's what dvips does. Also, it's * easier to avoid running MakeTeXPK if we have a VF this way. */ @@ -156,12 +156,12 @@ unsigned char font::load_font(void) read_PK_index(); else if (magic == GF_MAGIC) - oops("The GF format for font file %s is no longer supported", filename); + oops(QString("The GF format for font file %1 is no longer supported").arg(filename) ); else if (magic == VF_MAGIC) read_VF_index(); else - oops("Cannot recognize format for font file %s", filename); + oops(QString("Cannot recognize format for font file %1").arg(filename) ); return False; } @@ -211,7 +211,7 @@ struct glyph *font::glyphptr(unsigned int ch) { if (file == NULL) { file = xfopen(filename, OPEN_MODE); if (file == NULL) { - oops("Font file disappeared: %s", filename); + oops(QString("Font file disappeared: %1").arg(filename) ); return NULL; } } diff --git a/kdvi_multipage.cpp b/kdvi_multipage.cpp index d76a43f40..b2a47e120 100644 --- a/kdvi_multipage.cpp +++ b/kdvi_multipage.cpp @@ -201,10 +201,13 @@ void KDVIMultiPage::doSettings() void KDVIMultiPage::preferencesChanged() { + kdDebug() << "preferencesChanged" << endl; + KConfig *config = instance()->config(); QString s; + config->reparseConfiguration(); config->setGroup( "kdvi" ); s = config->readEntry( "FontPath" ); @@ -230,8 +233,10 @@ void KDVIMultiPage::preferencesChanged() int showPS = config->readNumEntry( "ShowPS" ); if (showPS != window->showPS()) window->setShowPS(showPS); - - window->setAntiAlias( config->readNumEntry( "PS Anti Alias", 1 ) ); + + int showHyperLinks = config->readNumEntry( "ShowHyperLinks" ); + if (showHyperLinks != window->showHyperLinks()) + window->setShowHyperLinks(showHyperLinks); } diff --git a/optiondialog.cpp b/optiondialog.cpp index 8821f9194..4c12b7ea8 100644 --- a/optiondialog.cpp +++ b/optiondialog.cpp @@ -76,7 +76,7 @@ void OptionDialog::slotApply() config->writeEntry( "FontPath", mFont.fontPathEdit->text() ); config->writeEntry( "ShowPS", mRender.showSpecialCheck->isChecked() ); - config->writeEntry( "PS Anti Alias", mRender.antialiasCheck->isChecked() ); + config->writeEntry( "ShowHyperLinks", mRender.showHyperLinksCheck->isChecked() ); config->sync(); @@ -98,7 +98,7 @@ void OptionDialog::setup() // Rendering page mRender.showSpecialCheck->setChecked( config->readNumEntry( "ShowPS", 0 ) ); - mRender.antialiasCheck->setChecked(config->readNumEntry("PS Anti Alias", 1)); + mRender.showHyperLinksCheck->setChecked(config->readNumEntry("ShowHyperLinks", 1)); } @@ -144,10 +144,10 @@ void OptionDialog::makeRenderingPage() mRender.showSpecialCheck = new QCheckBox( i18n("Show PostScript specials"), page ); - mRender.antialiasCheck = - new QCheckBox( i18n("Antialiased PostScript"), page ); + mRender.showHyperLinksCheck = + new QCheckBox( i18n("Show Hyperlinks"), page ); topLayout->addWidget( mRender.showSpecialCheck ); - topLayout->addWidget( mRender.antialiasCheck ); + topLayout->addWidget( mRender.showHyperLinksCheck ); topLayout->addStretch(1); } diff --git a/optiondialog.h b/optiondialog.h index 5dfa9b6d1..395537a77 100644 --- a/optiondialog.h +++ b/optiondialog.h @@ -49,7 +49,7 @@ class OptionDialog : public KDialogBase { int pageIndex; QCheckBox *showSpecialCheck; - QCheckBox *antialiasCheck; + QCheckBox *showHyperLinksCheck; }; public: diff --git a/pk.cpp b/pk.cpp index dada1dcdc..55c0d7cef 100644 --- a/pk.cpp +++ b/pk.cpp @@ -60,7 +60,7 @@ #include "glyph.h" #include "oconfig.h" extern char *xmalloc (unsigned, const char *); -extern void oops(const char *message, ...); +extern void oops(QString message); extern void alloc_bitmap(bitmap *bitmap); BMUNIT bit_masks[33] = { @@ -174,7 +174,7 @@ void font::PK_skip_specials(void) case PK_NOOP : break; default : - oops("Unexpected %d in PK file %s", PK_flag_byte, filename); + oops(QString("Unexpected %1 in PK file %2").arg(PK_flag_byte).arg(filename) ); break; } } @@ -238,7 +238,7 @@ void font::read_PK_char(unsigned int ch) w = num(fp, n); h = num(fp, n); if (w > 0x7fff || h > 0x7fff) - oops("Character %d too large in file %s", ch, fontname); + oops(QString("Character %1 too large in file %2").arg(ch).arg(fontname)); g->bitmap.w = w; g->bitmap.h = h; } @@ -346,9 +346,9 @@ void font::read_PK_char(unsigned int ch) paint_switch = 1 - paint_switch; } if (cp != ((BMUNIT *) (g->bitmap.bits + bytes_wide * g->bitmap.h))) - oops("Wrong number of bits stored: char. %d, font %s", ch, fontname); + oops(QString("Wrong number of bits stored: char. %1, font %2").arg(ch).arg(fontname)); if (rows_left != 0 || h_bit != g->bitmap.w) - oops("Bad pk file (%s), too many bits", fontname); + oops(QString("Bad pk file (%1), too many bits").arg(fontname)); } } diff --git a/psgs.cpp b/psgs.cpp index 0ab126da3..91ae94e5e 100644 --- a/psgs.cpp +++ b/psgs.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "dviwin.h" @@ -15,15 +16,19 @@ QString PostScriptHeaderString; void dviWindow::renderPostScript(QString *PostScript) { // Step 1: Write the PostScriptString to a File - FILE *f = fopen("/tmp/t","w"); + KTempFile PSfile(QString::null,".ps"); + FILE *f = PSfile.fstream(); fputs("%!PS-Adobe-2.0\n",f); fputs("%%Creator: kdvi\n",f); - fputs("%%Title: test.dvi\n",f); + fprintf(f,"%%Title: %s\n", filename.latin1()); fputs("%%Pages: 1\n",f); fputs("%%PageOrder: Ascend\n",f); - fputs("%%BoundingBox: 0 0 596 842\n",f); //@@@ + fprintf(f,"%%BoundingBox: 0 0 %ld %ld\n", (long)(72*unshrunk_paper_w) / basedpi, + (long)(72*unshrunk_paper_h) / basedpi); // HSize and VSize in 1/72 inch + fputs("",f); //@@@ fputs("%%EndComments\n",f); + fputs("%!\n",f); fputs("(/usr/share/texmf/dvips/base/texc.pro) run\n",f); fputs("(/usr/share/texmf/dvips/base/special.pro) run\n",f); @@ -38,26 +43,30 @@ void dviWindow::renderPostScript(QString *PostScript) { fputs("TeXDict begin\n",f); fputs("1 0 bop 0 0 a \n",f); // Start page - // fputs("@beginspecial 0 @llx 0 @lly 100 @urx 100 @ury @setspecial\n",f); if (PostScriptHeaderString.latin1() != NULL) fputs(PostScriptHeaderString.latin1(),f); if (PostScript->latin1() != NULL) fputs(PostScript->latin1(),f); - // fputs("@endspecial\n",f); fputs("end\n",f); fputs("showpage \n",f); - fclose(f); + PSfile.close(); // Step 2: Call GS with the File + KTempFile PNGfile(QString::null,".png"); + PNGfile.close(); // we are just interested in the filename, not the file + KProcess proc; proc << "gs"; - proc << "-dNOPAUSE" << "-dBATCH" << "-sDEVICE=png16m" << "-sOutputFile=/tmp/s"; + proc << "-dNOPAUSE" << "-dBATCH" << "-sDEVICE=png16m"; + proc << QString("-sOutputFile=%1").arg(PNGfile.name()); proc << QString("-g%1x%2").arg(page_w).arg(page_h); // page size in pixels proc << QString("-r%1").arg(basedpi/currwin.shrinkfactor); // resolution in dpi - proc << "/tmp/t"; + proc << PSfile.name(); proc.start(KProcess::Block); + PSfile.unlink(); // Step 3: write the generated output to the pixmap - QPixmap tmp("/tmp/s"); + QPixmap tmp(PNGfile.name()); foreGroundPaint.drawPixmap(0, 0, tmp); + PNGfile.unlink(); } diff --git a/util.cpp b/util.cpp index 18f19d374..cc545db6d 100644 --- a/util.cpp +++ b/util.cpp @@ -50,6 +50,8 @@ */ #include +#include +#include #include "dviwin.h" extern "C" { @@ -64,13 +66,6 @@ extern "C" { #include "glyph.h" -#ifdef Mips -extern int errno; -#endif - -#ifdef VMS -#include -#endif /* VMS */ /* @@ -81,24 +76,21 @@ extern int errno; * Print error message and quit. */ -void oops(const char *message, ...) +void oops(QString message) { -#if !NeedVarargsPrototypes - const char *message; -#endif - va_list args; - - //@@@ Fprintf(stderr, "%s: ", prog); -#if NeedVarargsPrototypes - va_start(args, message); -#else - va_start(args); - message = va_arg(args, const char *); -#endif - (void) vfprintf(stderr, message, args); - va_end(args); - Putc('\n', stderr); - exit(1); + kdError() << "Fatal Error! " << message << endl; + + KMessageBox::error( NULL, + i18n("Fatal Error!\n\n") + + message + + i18n("\n\n\ +This probably means that either you found bug in KDVI,\n\ +or that the DVI file, or auxiliary files (such as font files, \n\ +or virtual font files) were really badly broken.\n\ +KDVI will abort after this message. If you believe that you \n\ +found a bug, or that KDVI should behave better in this situtation\n\ +please report the problem.")); + exit(1); } /** Either allocate storage or fail with explanation. */ @@ -114,7 +106,7 @@ char * xmalloc(unsigned size, const char *why) char *mem = (char *)malloc(size ? size : 1); if (mem == NULL) - oops("! Cannot allocate %u bytes for %s.\n", size, why); + oops(QString("Cannot allocate %1 bytes for %2.").arg(size).arg(why) ); return mem; } @@ -179,27 +171,6 @@ FILE *xfopen(const char *filename, const char *type) } #undef TYPE - -/* - * Create a pipe, closing a file if necessary. This is (so far) used only - * in psgs.c. - */ - -int xpipe(int *fd) -{ - int retval; - - for (;;) { - retval = pipe(fd); - if (retval == 0 || (errno != EMFILE && errno != ENFILE)) break; - n_files_left = 0; - close_a_file(); - } - return retval; -} - - - /* * * Read size bytes from the FILE fp, constructing them into a diff --git a/vf.cpp b/vf.cpp index fc59394de..561ae2298 100644 --- a/vf.cpp +++ b/vf.cpp @@ -33,7 +33,7 @@ extern char *xmalloc (unsigned, const char *); extern font *define_font(FILE *file, unsigned int cmnd, font *vfparent, QIntDict *TeXNumberTable); -extern void oops(const char *message, ...); +extern void oops(QString message); /*** *** VF font reading routines. @@ -138,7 +138,7 @@ void font::read_VF_index(void) } } if (cmnd != POST) - oops("Wrong command byte found in VF macro list: %d", cmnd); + oops(QString("Wrong command byte found in VF macro list: %1").arg(cmnd)); Fclose (VF_file); n_files_left++;