X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Ffiginset.C;h=9bf32f5e6b47ba5a17f68a63a033ffbcb43e9815;hb=4a5b7a5952ad2381fcdf4830511293e184c7c5a1;hp=201443e639e3cc5e0a9a2a5e8aae656c1ca0b810;hpb=132fe5e1322fbc86a32692df51eba78d6b4e479c;p=lyx.git diff --git a/src/insets/figinset.C b/src/insets/figinset.C index 201443e639..9bf32f5e6b 100644 --- a/src/insets/figinset.C +++ b/src/insets/figinset.C @@ -2,8 +2,6 @@ * figinset.C - part of LyX project */ -extern long int background_pixels; - /* Rework of path-handling (Matthias 04.07.1996 ) * ------------------------------------------------ * figinsets keep an absolute path to the eps-file. @@ -30,56 +28,84 @@ extern long int background_pixels; #include +#include "figinset.h" + +#include "lyx_main.h" +#include "buffer.h" +#include "LyXView.h" // just because of form_main +#include "debug.h" +#include "LaTeXFeatures.h" +#include "lyxrc.h" +#include "gettext.h" +#include "lyx_gui_misc.h" // CancelCloseBoxCB +#include "Painter.h" +#include "font.h" +#include "bufferview_funcs.h" +#include "ColorHandler.h" +#include "converter.h" +#include "BufferView.h" + +#include "frontends/FileDialog.h" +#include "frontends/Alert.h" +#include "frontends/Dialogs.h" // redrawGUI + +#include "support/FileInfo.h" +#include "support/lyxlib.h" +#include "support/os.h" +#include "support/filetools.h" + +#include +#include +#include +#include +#include +#include + #include #include #include - -#include FORMS_H_LOCATION #include #include #include -#include -#include -#include -#include +#include + +using std::ostream; +using std::istream; using std::ofstream; using std::ifstream; using std::queue; using std::list; +using std::vector; using std::find; using std::flush; +using std::endl; +using std::copy; +using std::pair; +using std::make_pair; +using std::ios; +using std::ostream_iterator; + +#ifndef CXX_GLOBAL_CSTD +using std::memcpy; +using std::sin; +using std::cos; +using std::fabs; +#endif + -#include "figinset.h" -#include "lyx.h" -#include "lyx_main.h" -#include "buffer.h" -#include "filedlg.h" -#include "support/filetools.h" -#include "LyXView.h" // just because of form_main -#include "debug.h" -#include "LaTeXFeatures.h" -#include "lyxrc.h" -#include "gettext.h" -#include "lyx_gui_misc.h" // CancelCloseBoxCB -#include "support/FileInfo.h" -#include "support/lyxlib.h" -#include "Painter.h" extern BufferView * current_view; extern FL_OBJECT * figinset_canvas; extern char ** environ; // is this only redundtant on linux systems? Lgb. -extern void ProhibitInput(); -extern void AllowInput(); +// xforms doesn't define this (but it should be in ). +extern "C" +FL_APPEVENT_CB fl_set_preemptive_callback(Window, FL_APPEVENT_CB, void *); -static float const DEG2PI = 57.295779513; -static int const figallocchunk = 32; +namespace { -static int figinsref = 0; /* number of figures */ -static int figarrsize = 0; /* current max number of figures */ -static int bmpinsref = 0; /* number of bitmaps */ -static int bmparrsize = 0; /* current max number of bitmaps */ +float const DEG2PI = 57.295779513; struct queue_element { float rx, ry; // resolution x and y @@ -87,49 +113,42 @@ struct queue_element { figdata * data; // we are doing it for this data }; -static int const MAXGS = 3; /* maximum 3 gs's at a time */ - -static Figref ** figures; /* all the figures */ -static figdata ** bitmaps; /* all the bitmaps */ +int const MAXGS = 3; /* maximum 3 gs's at a time */ -static queue gsqueue; // queue for ghostscripting +typedef vector figures_type; +typedef vector bitmaps_type; +figures_type figures; // all figures +bitmaps_type bitmaps; // all bitmaps -static int gsrunning = 0; /* currently so many gs's are running */ -static bool bitmap_waiting = false; /* bitmaps are waiting finished */ -static char bittable[256]; /* bit reversion table */ +queue gsqueue; // queue for ghostscripting -static bool gs_color; // do we allocate colors for gs? -static bool color_visual; // is the visual color? -static bool gs_xcolor = false; // allocated extended colors -static unsigned long gs_pixels[128]; // allocated pixels -static int gs_num_pixels; // number of pixels allocated -static int gs_spc; // shades per color -static bool gs_gray; // is grayscale? -static int gs_allcolors; // number of all colors +int gsrunning = 0; /* currently so many gs's are running */ +bool bitmap_waiting = false; /* bitmaps are waiting finished */ -static list pidwaitlist; // pid wait list +bool gs_color; // do we allocate colors for gs? +bool color_visual; // is the visual color? +bool gs_xcolor = false; // allocated extended colors +unsigned long gs_pixels[128]; // allocated pixels +int gs_spc; // shades per color +int gs_allcolors; // number of all colors -//extern Colormap color_map; +list pidwaitlist; // pid wait list - - -static GC createGC() { XGCValues val; - val.foreground = BlackPixel(fl_display, - DefaultScreen(fl_display)); + val.foreground = BlackPixel(fl_get_display(), + DefaultScreen(fl_get_display())); val.function=GXcopy; val.graphics_exposures = false; val.line_style = LineSolid; val.line_width = 0; - return XCreateGC(fl_display, RootWindow(fl_display, 0), + return XCreateGC(fl_get_display(), RootWindow(fl_get_display(), 0), GCForeground | GCFunction | GCGraphicsExposures | GCLineWidth | GCLineStyle , &val); } -static GC local_gc_copy; @@ -140,33 +159,52 @@ void addpidwait(int pid) if (lyxerr.debugging()) { lyxerr << "Pids to wait for: \n"; - for (list::const_iterator cit = pidwaitlist.begin(); - cit != pidwaitlist.end(); ++cit) { - lyxerr << (*cit) << '\n'; - } + copy(pidwaitlist.begin(), pidwaitlist.end(), + ostream_iterator(lyxerr, "\n")); lyxerr << flush; } } -extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, - XEvent * ev, void *) +string make_tmp(int pid) +{ + return system_tempdir + "/~lyxgs" + tostr(pid) + ".ps"; +} + + +void kill_gs(int pid, int sig) +{ + if (lyxerr.debugging()) + lyxerr << "Killing gs " << pid << endl; + lyx::kill(pid, sig); + lyx::unlink(make_tmp(pid)); +} + + +extern "C" { + +static +int GhostscriptMsg(XEvent * ev, void *) { - char tmp[128]; + // bin all events not of interest + if (ev->type != ClientMessage) + return FL_PREEMPT; XClientMessageEvent * e = reinterpret_cast(ev); - if(lyxerr.debugging()) { + if (lyxerr.debugging()) { lyxerr << "ClientMessage, win:[xx] gs:[" << e->data.l[0] << "] pm:[" << e->data.l[1] << "]" << endl; } // just kill gs, that way it will work for sure // This loop looks like S**T so it probably is... - for (int i = 0; i < bmpinsref; ++i) - if ((long)bitmaps[i]->bitmap == (long)e->data.l[1]) { + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) + if (static_cast((*it)->bitmap) == + static_cast(e->data.l[1])) { // found the one - figdata * p = bitmaps[i]; + figdata * p = (*it); p->gsdone = true; // first update p->bitmap, if necessary @@ -174,24 +212,22 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, && p->flags > (1|8) && gs_color && p->wid) { // query current colormap and re-render // the pixmap with proper colors - //XColor * cmap; XWindowAttributes wa; register XImage * im; int i; int y; - int wid1; - int spc1 = gs_spc-1; + int spc1 = gs_spc - 1; int spc2 = gs_spc * gs_spc; int wid = p->wid; int forkstat; Display * tmpdisp; GC gc = local_gc_copy; - XGetWindowAttributes(fl_display, + XGetWindowAttributes(fl_get_display(), fl_get_canvas_id( figinset_canvas), &wa); - XFlush(fl_display); + XFlush(fl_get_display()); if (lyxerr.debugging()) { lyxerr << "Starting image translation " << p->bitmap << " " @@ -203,10 +239,10 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, // now fork rendering process forkstat = fork(); if (forkstat == -1) { - lyxerr.debug() + lyxerr[Debug::INFO] << "Cannot fork, using slow " "method for pixmap translation." << endl; - tmpdisp = fl_display; + tmpdisp = fl_get_display(); } else if (forkstat > 0) { // parent // register child if (lyxerr.debugging()) { @@ -216,7 +252,7 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, addpidwait(forkstat); break; } else { // child - tmpdisp = XOpenDisplay(XDisplayName(0)); + tmpdisp = XOpenDisplay(DisplayString(fl_get_display())); XFlush(tmpdisp); } im = XGetImage(tmpdisp, p->bitmap, 0, 0, @@ -240,7 +276,6 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, .colormap, cmap, gs_allcolors); XFlush(tmpdisp); - wid1 = p->wid - 1; // now we process all the image for (y = 0; y < p->hgh; ++y) { for (int x = 0; x < wid; ++x) { @@ -271,39 +306,22 @@ extern "C" int GhostscriptMsg(FL_OBJECT *, Window, int, int, } } noim: - if (lyxerr.debugging()) { - lyxerr << "Killing gs " - << p->gspid << endl; - } - lyx::kill(p->gspid, SIGHUP); - - sprintf(tmp, "%s/~lyxgs%d.ps", - system_tempdir.c_str(), - p->gspid); - unlink(tmp); + kill_gs(p->gspid, SIGHUP); if (forkstat == 0) { XCloseDisplay(tmpdisp); _exit(0); } } else { - if (lyxerr.debugging()) { - lyxerr << "Killing gs " - << p->gspid << endl; - } - lyx::kill(p->gspid, SIGHUP); - - sprintf(tmp, "%s/~lyxgs%d.ps", - system_tempdir.c_str(), - p->gspid); - unlink(tmp); + kill_gs(p->gspid, SIGHUP); } break; } - return 0; + return FL_PREEMPT; +} + } -static void AllocColors(int num) // allocate color cube numxnumxnum, if possible { @@ -320,16 +338,16 @@ void AllocColors(int num) if (num > 5) num = 5; XColor xcol; for (int i = 0; i < num * num * num; ++i) { - xcol.red = 65535 * (i / (num * num)) / (num - 1); - xcol.green = 65535 * ((i / num) % num) / (num - 1); - xcol.blue = 65535 * (i % num) / (num - 1); + xcol.red = short(65535 * (i / (num * num)) / (num - 1)); + xcol.green = short(65535 * ((i / num) % num) / (num - 1)); + xcol.blue = short(65535 * (i % num) / (num - 1)); xcol.flags = DoRed | DoGreen | DoBlue; - if (!XAllocColor(fl_display, + if (!XAllocColor(fl_get_display(), fl_state[fl_get_vclass()].colormap, &xcol)) { - if (i) XFreeColors(fl_display, + if (i) XFreeColors(fl_get_display(), fl_state[fl_get_vclass()].colormap, gs_pixels, i, 0); - if(lyxerr.debugging()) { + if (lyxerr.debugging()) { lyxerr << "Cannot allocate color cube " << num << endl;; } @@ -339,14 +357,11 @@ void AllocColors(int num) gs_pixels[i] = xcol.pixel; } gs_color = true; - gs_gray = false; gs_spc = num; - gs_num_pixels = num * num * num; } // allocate grayscale ramp -static void AllocGrays(int num) { if (lyxerr.debugging()) { @@ -362,11 +377,11 @@ void AllocGrays(int num) if (num > 128) num = 128; XColor xcol; for (int i = 0; i < num; ++i) { - xcol.red = xcol.green = xcol.blue = 65535 * i / (num - 1); + xcol.red = xcol.green = xcol.blue = short(65535 * i / (num - 1)); xcol.flags = DoRed | DoGreen | DoBlue; - if (!XAllocColor(fl_display, + if (!XAllocColor(fl_get_display(), fl_state[fl_get_vclass()].colormap, &xcol)) { - if (i) XFreeColors(fl_display, + if (i) XFreeColors(fl_get_display(), fl_state[fl_get_vclass()].colormap, gs_pixels, i, 0); if (lyxerr.debugging()) { @@ -379,86 +394,63 @@ void AllocGrays(int num) gs_pixels[i] = xcol.pixel; } gs_color = true; - gs_gray = false; - gs_num_pixels = num; } void InitFigures() { - bmparrsize = figarrsize = figallocchunk; - typedef Figref * Figref_p; - figures = new Figref_p[figallocchunk]; - typedef figdata * figdata_p; - bitmaps = new figdata_p[figallocchunk]; - - unsigned int k; - for (unsigned int i = 0; i < 256; ++i) { - k = 0; - for (unsigned int j = 0; j < 8; ++j) - if (i & (1 << (7-j))) k |= 1 << j; - bittable[i] = char(~k); - } - - fl_add_canvas_handler(figinset_canvas, ClientMessage, - GhostscriptMsg, current_view->owner()->getMainForm()); + // if bitmaps and figures are not empty we will leak mem + figures.clear(); + bitmaps.clear(); // allocate color cube on pseudo-color display // first get visual gs_color = false; - local_gc_copy = createGC(); + if (lyxrc.use_gui) { + /* we want to capture every event, in order to work around an + * xforms bug. + */ + fl_set_preemptive_callback(fl_get_canvas_id(figinset_canvas), GhostscriptMsg, 0); - Visual * vi = DefaultVisual(fl_display, DefaultScreen(fl_display)); - if (lyxerr.debugging()) { - printf("Visual ID: %ld, class: %d, bprgb: %d, mapsz: %d\n", - vi->visualid, vi->c_class, - vi->bits_per_rgb, vi->map_entries); - } - color_visual = ( (vi->c_class == StaticColor) || - (vi->c_class == PseudoColor) || - (vi->c_class == TrueColor) || - (vi->c_class == DirectColor) ); - if ((vi->c_class & 1) == 0) return; - // now allocate colors - if (vi->c_class == GrayScale) { - // allocate grayscale - AllocGrays(vi->map_entries/2); - } else { - // allocate normal color - int i = 5; - while (i * i * i * 2 > vi->map_entries) --i; - AllocColors(i); + local_gc_copy = createGC(); + + Visual * vi = DefaultVisual(fl_get_display(), + DefaultScreen(fl_get_display())); + if (lyxerr.debugging()) { + printf("Visual ID: %ld, class: %d, bprgb: %d, mapsz: %d\n", + vi->visualid, vi->c_class, + vi->bits_per_rgb, vi->map_entries); + } + color_visual = ((vi->c_class == StaticColor) || + (vi->c_class == PseudoColor) || + (vi->c_class == TrueColor) || + (vi->c_class == DirectColor)); + if ((vi->c_class & 1) == 0) return; + // now allocate colors + if (vi->c_class == GrayScale) { + // allocate grayscale + AllocGrays(vi->map_entries/2); + } else { + // allocate normal color + int i = 5; + while (i * i * i * 2 > vi->map_entries) --i; + AllocColors(i); + } + gs_allcolors = vi->map_entries; } - gs_allcolors = vi->map_entries; } void DoneFigures() { - delete[] figures; - delete[] bitmaps; - figarrsize = 0; - bmparrsize = 0; - - lyxerr.debug() << "Unregistering figures..." << endl; - - fl_remove_canvas_handler(figinset_canvas, ClientMessage, - GhostscriptMsg); -} - - -int FindBmpIndex(figdata * tmpdata) -{ - int i = 0; - while (i < bmpinsref) { - if (bitmaps[i] == tmpdata) return i; - ++i; - } - return i; + // if bitmaps and figures are not empty we will leak mem + bitmaps.clear(); + figures.clear(); + + lyxerr[Debug::INFO] << "Unregistering figures..." << endl; } -static void freefigdata(figdata * tmpdata) { tmpdata->ref--; @@ -466,28 +458,23 @@ void freefigdata(figdata * tmpdata) if (tmpdata->gspid > 0) { int pid = tmpdata->gspid; - char buf[128]; // kill ghostscript and unlink it's files tmpdata->gspid = -1; - lyx::kill(pid, SIGKILL); - sprintf(buf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), pid); - unlink(buf); + kill_gs(pid, SIGKILL); } - if (tmpdata->bitmap) XFreePixmap(fl_display, tmpdata->bitmap); + if (tmpdata->bitmap) XFreePixmap(fl_get_display(), tmpdata->bitmap); + bitmaps.erase(find(bitmaps.begin(), bitmaps.end(), tmpdata)); delete tmpdata; - int i = FindBmpIndex(tmpdata); - --bmpinsref; - while (i < bmpinsref) { - bitmaps[i] = bitmaps[i + 1]; - ++i; - } } -static void runqueue() { + // This _have_ to be set before the fork! + unsigned long background_pixel = + lyxColorHandler->colorPixel(LColor::graphicsbg); + // run queued requests for ghostscript, if any if (!gsrunning && gs_color && !gs_xcolor) { // here alloc all colors, so that gs will use only @@ -497,7 +484,7 @@ void runqueue() } while (gsrunning < MAXGS) { - char tbuf[384], tbuf2[80]; + //char tbuf[384]; //, tbuf2[80]; Atom * prop; int nprop, i; @@ -515,7 +502,7 @@ void runqueue() continue; } - int pid = fork(); + int pid = ::fork(); if (pid == -1) { if (lyxerr.debugging()) { @@ -527,15 +514,13 @@ void runqueue() return; } if (pid == 0) { // child - char ** env, rbuf[80], gbuf[40]; + char ** env; int ne = 0; - Display * tempdisp = XOpenDisplay(XDisplayName(0)); + Display * tempdisp = XOpenDisplay(DisplayString(fl_get_display())); // create translation file - sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), - int(getpid())); - - ofstream ofs(tbuf); + ofstream ofs; + ofs.open(make_tmp(getpid()).c_str(), ios::binary); ofs << "gsave clippath pathbbox grestore\n" << "4 dict begin\n" << "/ury exch def /urx exch def /lly exch def " @@ -552,29 +537,35 @@ void runqueue() ofs.close(); // Don't remove this. // gs process - set ghostview environment first - sprintf(tbuf2, "GHOSTVIEW=%ld %ld", fl_get_canvas_id( - figinset_canvas), p->data->bitmap); - + ostringstream t2; + t2 << "GHOSTVIEW=" << fl_get_canvas_id(figinset_canvas) + << ' ' << p->data->bitmap; // now set up ghostview property on a window - sprintf(tbuf, "0 0 0 0 %d %d 72 72 0 0 0 0", - p->data->wid, p->data->hgh); + // #ifdef WITH_WARNINGS // #warning BUG seems that the only bug here // might be the hardcoded dpi.. Bummer! + // #endif + ostringstream t1; + t1 << "0 0 0 0 " << p->data->wid << ' ' + << p->data->hgh << " 72 72 0 0 0 0"; if (lyxerr.debugging()) { lyxerr << "Will set GHOSTVIEW property to [" - << tbuf << "]" << endl; + << t1.str() << "]" << endl; } // wait until property is deleted if executing multiple // ghostscripts + XGrabServer(tempdisp); for (;;) { // grab server to prevent other child // interfering with setting GHOSTVIEW property + // The grabbing goes on for too long, is it + // really needed? (Lgb) + // I moved most of the grabs... (Lgb) if (lyxerr.debugging()) { lyxerr << "Grabbing the server" << endl; } - XGrabServer(tempdisp); prop = XListProperties(tempdisp, fl_get_canvas_id( figinset_canvas), &nprop); @@ -584,17 +575,16 @@ void runqueue() for (i = 0; i < nprop; ++i) { char * p = XGetAtomName(tempdisp, prop[i]); - if (strcmp(p, "GHOSTVIEW") == 0) { + if (compare(p, "GHOSTVIEW") == 0) { err = false; + // We free it when we leave so we don't leak. + XFree(p); break; } XFree(p); } XFree(reinterpret_cast(prop)); // jc: if (err) break; - // release the server - XUngrabServer(tempdisp); - XFlush(tempdisp); // ok, property found, we must wait until // ghostscript deletes it if (lyxerr.debugging()) { @@ -603,90 +593,102 @@ void runqueue() << "] GHOSTVIEW property" " found. Waiting." << endl; } - - sleep(1); + XUngrabServer(tempdisp); + XFlush(tempdisp); + ::sleep(1); + XGrabServer(tempdisp); } - XChangeProperty(tempdisp, fl_get_canvas_id(figinset_canvas), XInternAtom(tempdisp, "GHOSTVIEW", false), XInternAtom(tempdisp, "STRING", false), 8, PropModeAppend, - reinterpret_cast(tbuf), - strlen(tbuf)); - + reinterpret_cast(const_cast(t1.str().c_str())), + int(t1.str().size())); + XUngrabServer(tempdisp); + XFlush(tempdisp); + + ostringstream t3; + switch (p->data->flags & 3) { - case 0: tbuf[0] = 'H'; break; // Hidden - case 1: tbuf[0] = 'M'; break; // Mono - case 2: tbuf[0] = 'G'; break; // Gray + case 0: t3 << 'H'; break; // Hidden + case 1: t3 << 'M'; break; // Mono + case 2: t3 << 'G'; break; // Gray case 3: if (color_visual) - tbuf[0] = 'C'; // Color + t3 << 'C'; // Color else - tbuf[0] = 'G'; // Gray + t3 << 'G'; // Gray break; } + + t3 << ' ' << BlackPixelOfScreen(DefaultScreenOfDisplay(tempdisp)) + << ' ' << background_pixel; - sprintf(tbuf+1, " %ld %ld", BlackPixelOfScreen( - DefaultScreenOfDisplay(fl_display)), - fl_get_pixel(FL_WHITE)); - + XGrabServer(tempdisp); XChangeProperty(tempdisp, fl_get_canvas_id(figinset_canvas), XInternAtom(tempdisp, "GHOSTVIEW_COLORS", false), XInternAtom(tempdisp, "STRING", false), 8, PropModeReplace, - reinterpret_cast(tbuf), - strlen(tbuf)); + reinterpret_cast(const_cast(t3.str().c_str())), + int(t3.str().size())); XUngrabServer(tempdisp); XFlush(tempdisp); + if (lyxerr.debugging()) { lyxerr << "Releasing the server" << endl; } XCloseDisplay(tempdisp); // set up environment - while (environ[ne]) ++ne; + while (environ[ne]) + ++ne; typedef char * char_p; env = new char_p[ne + 2]; - env[0] = tbuf2; - memcpy(&env[1], environ, sizeof(char*) * (ne + 1)); + string tmp = t2.str().c_str(); + env[0] = new char[tmp.size() + 1]; + copy(tmp.begin(), tmp.end(), env[0]); + env[0][tmp.size()] = '\0'; + memcpy(&env[1], environ, + sizeof(char*) * (ne + 1)); environ = env; // now make gs command // close(0); // close(1); do NOT close. If GS writes out // errors it would hang. (Matthias 290596) - sprintf(rbuf, "-r%gx%g", p->rx, p->ry); - sprintf(gbuf, "-g%dx%d", p->data->wid, p->data->hgh); + + string rbuf = "-r" + tostr(p->rx) + "x" + tostr(p->ry); + string gbuf = "-g" + tostr(p->data->wid) + "x" + tostr(p->data->hgh); + // now chdir into dir with .eps file, to be on the safe // side - chdir(OnlyPath(p->data->fname).c_str()); + lyx::chdir(OnlyPath(p->data->fname)); // make temp file name - sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), - int(getpid())); + string tmpf = make_tmp(getpid()); if (lyxerr.debugging()) { - lyxerr << "starting gs " << tbuf << " " + lyxerr << "starting gs " << tmpf << " " << p->data->fname << ", pid: " << getpid() << endl; } - int err = execlp(lyxrc->ps_command.c_str(), - lyxrc->ps_command.c_str(), + int err = ::execlp(lyxrc.ps_command.c_str(), + lyxrc.ps_command.c_str(), "-sDEVICE=x11", "-dNOPAUSE", "-dQUIET", "-dSAFER", - rbuf, gbuf, tbuf, + rbuf.c_str(), gbuf.c_str(), tmpf.c_str(), p->data->fname.c_str(), "showpage.ps", "quit.ps", "-", 0); // if we are still there, an error occurred. lyxerr << "Error executing ghostscript. " << "Code: " << err << endl; - lyxerr.debug() << "Cmd: " - << lyxrc->ps_command + lyxerr[Debug::INFO] << "Cmd: " + << lyxrc.ps_command << " -sDEVICE=x11 " - << tbuf << ' ' + << tmpf << ' ' << p->data->fname << endl; _exit(0); // no gs? } @@ -702,7 +704,6 @@ void runqueue() } -static void addwait(int psx, int psy, int pswid, int pshgh, figdata * data) { // recompute the stuff and put in the queue @@ -721,39 +722,25 @@ void addwait(int psx, int psy, int pswid, int pshgh, figdata * data) } -static figdata * getfigdata(int wid, int hgh, string const & fname, - int psx, int psy, int pswid, int pshgh, - int raw_wid, int raw_hgh, float angle, char flags) + int psx, int psy, int pswid, int pshgh, + int raw_wid, int raw_hgh, float angle, char flags) { /* first search for an exact match with fname and width/height */ - if (fname.empty()) return 0; + if (fname.empty() || !IsFileReadable(fname)) + return 0; - int i = 0; - while (i < bmpinsref) { - if (bitmaps[i]->wid == wid && bitmaps[i]->hgh == hgh && - bitmaps[i]->flags == flags && bitmaps[i]->fname == fname && - bitmaps[i]->angle == angle) { - bitmaps[i]->ref++; - return bitmaps[i]; + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) { + if ((*it)->wid == wid && (*it)->hgh == hgh && + (*it)->flags == flags && (*it)->fname == fname && + (*it)->angle == angle) { + (*it)->ref++; + return (*it); } - ++i; - } - /* not found -> create new record or return 0 if no record */ - ++bmpinsref; - if (bmpinsref > bmparrsize) { - // allocate more space - bmparrsize += figallocchunk; - typedef figdata * figdata_p; - figdata ** tmp = new figdata_p[bmparrsize]; - memcpy(tmp, bitmaps, - sizeof(figdata*) * (bmparrsize - figallocchunk)); - delete[] bitmaps; - bitmaps = tmp; } figdata * p = new figdata; - bitmaps[bmpinsref-1] = p; p->wid = wid; p->hgh = hgh; p->raw_wid = raw_wid; @@ -761,13 +748,14 @@ figdata * getfigdata(int wid, int hgh, string const & fname, p->angle = angle; p->fname = fname; p->flags = flags; + bitmaps.push_back(p); XWindowAttributes wa; - XGetWindowAttributes(fl_display, fl_get_canvas_id( + XGetWindowAttributes(fl_get_display(), fl_get_canvas_id( figinset_canvas), &wa); if (lyxerr.debugging()) { - lyxerr << "Create pixmap disp:" << fl_display - << " scr:" << DefaultScreen(fl_display) + lyxerr << "Create pixmap disp:" << fl_get_display() + << " scr:" << DefaultScreen(fl_get_display()) << " w:" << wid << " h:" << hgh << " depth:" << wa.depth << endl; @@ -778,7 +766,7 @@ figdata * getfigdata(int wid, int hgh, string const & fname, p->broken = false; p->gspid = -1; if (flags) { - p->bitmap = XCreatePixmap(fl_display, fl_get_canvas_id( + p->bitmap = XCreatePixmap(fl_get_display(), fl_get_canvas_id( figinset_canvas), wid, hgh, wa.depth); p->gsdone = false; // initialize reading of .eps file with correct sizes and stuff @@ -793,42 +781,45 @@ figdata * getfigdata(int wid, int hgh, string const & fname, } -static void getbitmap(figdata * p) { p->gspid = -1; } -static void makeupdatelist(figdata * p) { - for (int i = 0; i < figinsref; ++i) - if (figures[i]->data == p) { + for (figures_type::iterator it = figures.begin(); + it != figures.end(); ++it) + if ((*it)->data == p) { if (lyxerr.debugging()) { lyxerr << "Updating inset " - << figures[i]->inset + << (*it)->inset << endl; } // add inset figures[i]->inset into to_update list - current_view->pushIntoUpdateList(figures[i]->inset); + current_view->pushIntoUpdateList((*it)->inset); } } +} // namespace anon + +// this func is only "called" in spellchecker.C void sigchldchecker(pid_t pid, int * status) { - lyxerr.debug() << "Got pid = " << pid << endl; + lyxerr[Debug::INFO] << "Got pid = " << pid << endl; bool pid_handled = false; - for (int i = bmpinsref - 1; i >= 0; --i) { - if (bitmaps[i]->reading && pid == bitmaps[i]->gspid) { - lyxerr.debug() << "Found pid in bitmaps" << endl; + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) { + if ((*it)->reading && pid == (*it)->gspid) { + lyxerr[Debug::INFO] << "Found pid in bitmaps" << endl; // now read the file and remove it from disk - figdata * p = bitmaps[i]; + figdata * p = (*it); p->reading = false; - if (bitmaps[i]->gsdone) *status = 0; + if ((*it)->gsdone) *status = 0; if (*status == 0) { - lyxerr.debug() << "GS [" << pid + lyxerr[Debug::INFO] << "GS [" << pid << "] exit OK." << endl; } else { lyxerr << "GS [" << pid << "] error " @@ -843,33 +834,29 @@ void sigchldchecker(pid_t pid, int * status) p->broken = false; } else { // remove temporary files - char tmp[128]; - sprintf(tmp, "%s/~lyxgs%d.ps", - system_tempdir.c_str(), - p->gspid); - unlink(tmp); + lyx::unlink(make_tmp(p->gspid)); p->gspid = -1; p->broken = true; } - makeupdatelist(bitmaps[i]); + makeupdatelist((*it)); --gsrunning; runqueue(); pid_handled = true; } } if (!pid_handled) { - lyxerr.debug() << "Checking pid in pidwait" << endl; + lyxerr[Debug::INFO] << "Checking pid in pidwait" << endl; list::iterator it = find(pidwaitlist.begin(), pidwaitlist.end(), pid); if (it != pidwaitlist.end()) { - lyxerr.debug() << "Found pid in pidwait\n" + lyxerr[Debug::INFO] << "Found pid in pidwait\n" << "Caught child pid of recompute " "routine" << pid << endl; pidwaitlist.erase(it); } } if (pid == -1) { - lyxerr.debug() << "waitpid error" << endl; + lyxerr[Debug::INFO] << "waitpid error" << endl; switch (errno) { case ECHILD: lyxerr << "The process or process group specified by " @@ -893,64 +880,45 @@ void sigchldchecker(pid_t pid, int * status) } else if (pid == 0) { lyxerr << "waitpid nohang" << endl;; } else { - lyxerr.debug() << "normal exit from childhandler" << endl; + lyxerr[Debug::INFO] << "normal exit from childhandler" << endl; } } -static +namespace { + void getbitmaps() { bitmap_waiting = false; - for (int i = 0; i < bmpinsref; ++i) - if (bitmaps[i]->gspid > 0 && !bitmaps[i]->reading) - getbitmap(bitmaps[i]); + for (bitmaps_type::iterator it = bitmaps.begin(); + it != bitmaps.end(); ++it) + if ((*it)->gspid > 0 && !(*it)->reading) + getbitmap((*it)); } -static void RegisterFigure(InsetFig * fi) { - if (figinsref == 0) InitFigures(); + if (figures.empty()) InitFigures(); fi->form = 0; - ++figinsref; - if (figinsref > figarrsize) { - // allocate more space - figarrsize += figallocchunk; - typedef Figref * Figref_p; - Figref ** tmp = new Figref_p[figarrsize]; - memcpy(tmp, figures, - sizeof(Figref*) * (figarrsize-figallocchunk)); - delete[] figures; - figures = tmp; - } Figref * tmpfig = new Figref; tmpfig->data = 0; tmpfig->inset = fi; - figures[figinsref-1] = tmpfig; + figures.push_back(tmpfig); fi->figure = tmpfig; - if (lyxerr.debugging()) { + if (lyxerr.debugging() && current_view) { lyxerr << "Register Figure: buffer:[" << current_view->buffer() << "]" << endl; } } -int FindFigIndex(Figref * tmpfig) -{ - int i = 0; - while (i < figinsref) { - if (figures[i] == tmpfig) return i; - ++i; - } - return i; -} - - -static void UnregisterFigure(InsetFig * fi) { + if (!lyxrc.use_gui) + return; + Figref * tmpfig = fi->figure; if (tmpfig->data) freefigdata(tmpfig->data); @@ -961,43 +929,24 @@ void UnregisterFigure(InsetFig * fi) fl_hide_form(tmpfig->inset->form->Figure); } #if FL_REVISION == 89 -#warning Reactivate this free_form calls + // CHECK Reactivate this free_form calls #else fl_free_form(tmpfig->inset->form->Figure); free(tmpfig->inset->form); // Why free? tmpfig->inset->form = 0; #endif } - int i = FindFigIndex(tmpfig); - --figinsref; - while (i < figinsref) { - figures[i] = figures[i+1]; - ++i; - } + figures.erase(find(figures.begin(), figures.end(), tmpfig)); delete tmpfig; - if (figinsref == 0) DoneFigures(); + if (figures.empty()) DoneFigures(); } +} // namespace anon -static -string NextToken(istream & is) -{ - string token; - char c; - if (!is.eof()) { - do { - is.get(c); - token += c; - } while (!is.eof() && !isspace(c)); - token.erase(token.length() - 1); // remove the isspace - } - return token; -} - -InsetFig::InsetFig(int tmpx, int tmpy, Buffer * o) - : owner(o) +InsetFig::InsetFig(int tmpx, int tmpy, Buffer const & o) + : owner(&o) { wid = tmpx; hgh = tmpy; @@ -1012,6 +961,7 @@ InsetFig::InsetFig(int tmpx, int tmpy, Buffer * o) raw_wid = raw_hgh = 0; changedfname = false; RegisterFigure(this); + r_ = Dialogs::redrawGUI.connect(SigC::slot(this, &InsetFig::redraw)); } @@ -1021,31 +971,40 @@ InsetFig::~InsetFig() lyxerr << "Figure destructor called" << endl; } UnregisterFigure(this); + r_.disconnect(); } -int InsetFig::ascent(Painter &, LyXFont const &) const +void InsetFig::redraw() +{ + if (form && form->Figure->visible) + fl_redraw_form(form->Figure); +} + + +int InsetFig::ascent(BufferView *, LyXFont const &) const { return hgh + 3; } -int InsetFig::descent(Painter &, LyXFont const &) const +int InsetFig::descent(BufferView *, LyXFont const &) const { return 1; } -int InsetFig::width(Painter &, LyXFont const &) const +int InsetFig::width(BufferView *, LyXFont const &) const { return wid + 2; } -void InsetFig::draw(Painter & pain, LyXFont const & f, - int baseline, float & x) const +void InsetFig::draw(BufferView * bv, LyXFont const & f, + int baseline, float & x, bool) const { LyXFont font(f); + Painter & pain = bv->painter(); if (bitmap_waiting) getbitmaps(); @@ -1064,36 +1023,45 @@ void InsetFig::draw(Painter & pain, LyXFont const & f, wid + 1, hgh + 1); } else { - char * msg = 0; + //char const * msg = 0; + string msg; + string lfname = fname; + if (!fname.empty() && GetExtension(fname).empty()) + lfname += ".eps"; // draw frame - pain.rectangle(x, baseline - hgh - 1, wid + 1, hgh + 1); + pain.rectangle(int(x), baseline - hgh - 1, wid + 1, hgh + 1); if (figure && figure->data) { if (figure->data->broken) msg = _("[render error]"); else if (figure->data->reading) msg = _("[rendering ... ]"); - } else - if (fname.empty()) msg = _("[no file]"); - else if ((flags & 3) == 0) msg = _("[not displayed]"); - else if (lyxrc->ps_command.empty()) msg = _("[no ghostscript]"); + } + else if (fname.empty()) + msg = _("[no file]"); + else if (!IsFileReadable(lfname)) + msg = _("[bad file name]"); + else if ((flags & 3) == 0) + msg = _("[not displayed]"); + else if (lyxrc.ps_command.empty()) + msg = _("[no ghostscript]"); - if (!msg) msg = _("[unknown error]"); + if (msg.empty()) msg = _("[unknown error]"); font.setFamily(LyXFont::SANS_FAMILY); font.setSize(LyXFont::SIZE_FOOTNOTE); - string justname = OnlyFilename (fname); - pain.text(int(x + 8), baseline - font.maxAscent() - 4, + string const justname = OnlyFilename (fname); + pain.text(int(x + 8), baseline - lyxfont::maxAscent(font) - 4, justname, font); font.setSize(LyXFont::SIZE_TINY); - pain.text(int(x + 8), baseline - 4, msg, strlen(msg), font); + pain.text(int(x + 8), baseline - 4, msg, font); } - x += width(pain, font); // ? + x += width(bv, font); // ? } -void InsetFig::Write(ostream & os) const +void InsetFig::write(Buffer const *, ostream & os) const { - Regenerate(); + regenerate(); os << "Figure size " << wid << " " << hgh << "\n"; if (!fname.empty()) { string buf1 = OnlyPath(owner->fileName()); @@ -1110,16 +1078,16 @@ void InsetFig::Write(ostream & os) const } -void InsetFig::Read(LyXLex & lex) +void InsetFig::read(Buffer const *, LyXLex & lex) { string buf; bool finished = false; - while (lex.IsOK() && !finished) { + while (lex.isOK() && !finished) { lex.next(); - string const token = lex.GetString(); - lyxerr.debug() << "Token: " << token << endl; + string const token = lex.getString(); + lyxerr[Debug::INFO] << "Token: " << token << endl; if (token.empty()) continue; @@ -1127,8 +1095,8 @@ void InsetFig::Read(LyXLex & lex) finished = true; } else if (token == "file") { if (lex.next()) { - buf = lex.GetString(); - string buf1 = OnlyPath(owner->fileName()); + buf = lex.getString(); + string const buf1(OnlyPath(owner->fileName())); fname = MakeAbsPath(buf, buf1); changedfname = true; } @@ -1136,30 +1104,30 @@ void InsetFig::Read(LyXLex & lex) if (lex.next()); // kept for backwards compability. Delete in 0.13.x } else if (token == "subcaption") { - if (lex.EatLine()) - subcaption = lex.GetString(); + if (lex.eatLine()) + subcaption = lex.getString(); } else if (token == "label") { if (lex.next()); // kept for backwards compability. Delete in 0.13.x } else if (token == "angle") { if (lex.next()) - angle = lex.GetFloat(); + angle = lex.getFloat(); } else if (token == "size") { if (lex.next()) - wid = lex.GetInteger(); + wid = lex.getInteger(); if (lex.next()) - hgh = lex.GetInteger(); + hgh = lex.getInteger(); } else if (token == "flags") { if (lex.next()) - flags = pflags = lex.GetInteger(); + flags = pflags = lex.getInteger(); } else if (token == "subfigure") { subfigure = psubfigure = true; } else if (token == "width") { int typ = 0; if (lex.next()) - typ = lex.GetInteger(); + typ = lex.getInteger(); if (lex.next()) - xwid = lex.GetFloat(); + xwid = lex.getFloat(); switch (typ) { case DEF: wtype = DEF; break; case CM: wtype = CM; break; @@ -1167,117 +1135,97 @@ void InsetFig::Read(LyXLex & lex) case PER_PAGE: wtype = PER_PAGE; break; case PER_COL: wtype = PER_COL; break; default: - lyxerr.debug() << "Unknown type!" << endl; + lyxerr[Debug::INFO] << "Unknown type!" << endl; break; } twtype = wtype; } else if (token == "height") { int typ = 0; if (lex.next()) - typ = lex.GetInteger(); + typ = lex.getInteger(); if (lex.next()) - xhgh = lex.GetFloat(); + xhgh = lex.getFloat(); switch (typ) { case DEF: htype = DEF; break; case CM: htype = CM; break; case IN: htype = IN; break; case PER_PAGE: htype = PER_PAGE; break; default: - lyxerr.debug() << "Unknown type!" << endl; + lyxerr[Debug::INFO] << "Unknown type!" << endl; break; } thtype = htype; } } - Regenerate(); - Recompute(); + regenerate(); + recompute(); } -int InsetFig::Latex(ostream & os, signed char /* fragile*/, bool /* fs*/) const +int InsetFig::latex(Buffer const *, ostream & os, + bool /* fragile*/, bool /* fs*/) const { - Regenerate(); + regenerate(); if (!cmd.empty()) os << cmd << " "; return 0; } -#ifndef USE_OSTREAM_ONLY -int InsetFig::Latex(string & file, signed char /* fragile*/, bool/* fs*/) const +int InsetFig::ascii(Buffer const *, ostream &, int) const { - Regenerate(); - file += cmd + ' '; return 0; } -int InsetFig::Linuxdoc(string &/*file*/) const +int InsetFig::linuxdoc(Buffer const *, ostream &) const { return 0; } -int InsetFig::DocBook(string & file) const +int InsetFig::docbook(Buffer const *, ostream & os) const { - string figurename = fname; + string const buf1 = OnlyPath(owner->fileName()); + string figurename = MakeRelPath(fname, buf1); - if(suffixIs(figurename, ".eps")) - figurename.erase(fname.length() - 5); - - file += "@"; - return 0; -} - -#else + if (suffixIs(figurename, ".eps")) + figurename.erase(figurename.length() - 4); -int InsetFig::Linuxdoc(ostream &) const -{ + os << ""; return 0; -} +} -int InsetFig::DocBook(ostream & os) const +void InsetFig::validate(LaTeXFeatures & features) const { - string figurename = fname; - - if(suffixIs(figurename, ".eps")) - figurename.erase(fname.length() - 5); - - os << "@"; - return 0; + features.require("graphics"); + if (subfigure) + features.require("subfigure"); } -#endif -void InsetFig::Validate(LaTeXFeatures & features) const +Inset::EDITABLE InsetFig::editable() const { - features.graphics = true; - if (subfigure) features.subfigure = true; + return IS_EDITABLE; } -Inset::EDITABLE InsetFig::Editable() const +bool InsetFig::deletable() const { - return IS_EDITABLE; + return false; } -bool InsetFig::Deletable() const +string const InsetFig::editMessage() const { - return false; + return _("Opened figure"); } -void InsetFig::Edit(BufferView * bv, int, int, unsigned int) +void InsetFig::edit(BufferView *, int, int, unsigned int) { - lyxerr.debug() << "Editing InsetFig." << endl; - Regenerate(); - - // We should have RO-versions of the form instead. - // The actual prevention of altering a readonly doc - // is done in CallbackFig() - if(bv->buffer()->isReadonly()) - WarnReadonly(bv->buffer()->fileName()); + lyxerr[Debug::INFO] << "Editing InsetFig." << endl; + regenerate(); if (!form) { form = create_form_Figure(); @@ -1286,23 +1234,30 @@ void InsetFig::Edit(BufferView * bv, int, int, unsigned int) fl_set_object_return(form->Width, FL_RETURN_ALWAYS); fl_set_object_return(form->Height, FL_RETURN_ALWAYS); } - RestoreForm(); + restoreForm(); if (form->Figure->visible) { fl_raise_form(form->Figure); } else { - fl_show_form(form->Figure, FL_PLACE_MOUSE | FL_PLACE_SIZE, - FL_FULLBORDER, _("Figure")); + fl_show_form(form->Figure, + FL_PLACE_MOUSE | FL_FREE_SIZE, FL_TRANSIENT, + _("Figure")); } } -Inset * InsetFig::Clone() const +void InsetFig::edit(BufferView * bv, bool) +{ + edit(bv, 0, 0, 0); +} + + +Inset * InsetFig::clone(Buffer const & buffer, bool) const { - InsetFig * tmp = new InsetFig(100, 100, owner); + InsetFig * tmp = new InsetFig(100, 100, buffer); if (lyxerr.debugging()) { lyxerr << "Clone Figure: buffer:[" - << current_view->buffer() + << &buffer << "], cbuffer:[xx]" << endl; } @@ -1324,32 +1279,67 @@ Inset * InsetFig::Clone() const tmp->pswid = pswid; tmp->pshgh = pshgh; tmp->fname = fname; - if (!fname.empty() && (flags & 3) && !lyxrc->ps_command.empty()) { + string lfname = fname; + if (!fname.empty() && GetExtension(fname).empty()) + lfname += ".eps"; + if (!fname.empty() && IsFileReadable(lfname) + && (flags & 3) && !lyxrc.ps_command.empty() + && lyxrc.use_gui) { // do not display if there is // "do not display" chosen (Matthias 260696) - tmp->figure->data = getfigdata(wid, hgh, fname, psx, psy, + tmp->figure->data = getfigdata(wid, hgh, lfname, psx, psy, pswid, pshgh, raw_wid, raw_hgh, angle, flags & (3|8)); } else tmp->figure->data = 0; tmp->subcaption = subcaption; tmp->changedfname = false; tmp->owner = owner; - tmp->Regenerate(); + tmp->regenerate(); return tmp; } -Inset::Code InsetFig::LyxCode() const +Inset::Code InsetFig::lyxCode() const { return Inset::GRAPHICS_CODE; } -void InsetFig::Regenerate() const +namespace { + +string const stringify(InsetFig::HWTYPE hw, float f, string suffix) +{ + string res; + switch (hw) { + case InsetFig::DEF: + break; + case InsetFig::CM:// \resizebox*{h-length}{v-length}{text} + res = tostr(f) + "cm"; + break; + case InsetFig::IN: + res = tostr(f) + "in"; + break; + case InsetFig::PER_PAGE: + res = tostr(f/100) + "\\text" + suffix; + break; + case InsetFig::PER_COL: + // Doesn't occur for htype... + res = tostr(f/100) + "\\column" + suffix; + break; + } + return res; +} + +} // namespace anon + + +void InsetFig::regenerate() const { string cmdbuf; - string resizeW, resizeH; - string rotate, recmd; + string resizeW; + string resizeH; + string rotate; + string recmd; if (fname.empty()) { cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}"; @@ -1362,69 +1352,8 @@ void InsetFig::Regenerate() const string fname2 = MakeRelPath(fname, buf1); string gcmd = "\\includegraphics{" + fname2 + '}'; - - switch (wtype) { - case DEF: - break; - case CM:{// \resizebox*{h-length}{v-length}{text} - char buf[10]; - sprintf(buf, "%g", xwid); // should find better - resizeW = buf; - resizeW += "cm"; - break; - } - case IN: { - char buf[10]; - sprintf(buf, "%g", xwid); - resizeW = buf; - resizeW += "in"; - break; - } - case PER_PAGE:{ - char buf[10]; - sprintf(buf, "%g", xwid/100); - resizeW = buf; - resizeW += "\\textwidth"; - break; - } - case PER_COL:{ - char buf[10]; - sprintf(buf, "%g", xwid/100); - resizeW = buf; - resizeW += "\\columnwidth"; - break; - } - } - - switch (htype) { - case DEF: - break; - case CM: { - char buf[10]; - sprintf(buf, "%g", xhgh); - resizeH = buf; - resizeH += "cm"; - break; - } - case IN:{ - char buf[10]; - sprintf(buf, "%g", xhgh); - resizeH = buf; - resizeH += "in"; - break; - } - case PER_PAGE: { - char buf[10]; - sprintf(buf, "%g", xhgh/100); - resizeH = buf; - resizeH += "\\textheight"; - break; - } - case PER_COL: { - // Doesn't occur; case exists to suppress compiler warnings. - break; - } - } + resizeW = stringify(wtype, xwid, "width"); + resizeH = stringify(htype, xhgh, "height"); if (!resizeW.empty() || !resizeH.empty()) { recmd = "\\resizebox*{"; @@ -1442,12 +1371,8 @@ void InsetFig::Regenerate() const if (angle != 0) { - char buf[10]; - sprintf(buf, "%g", angle); // \rotatebox{angle}{text} - rotate = "\\rotatebox{"; - rotate += buf; - rotate += "}{"; + rotate = "\\rotatebox{" + tostr(angle) + "}{"; } cmdbuf = recmd; @@ -1467,11 +1392,13 @@ void InsetFig::Regenerate() const } -void InsetFig::TempRegenerate() +void InsetFig::tempRegenerate() { string cmdbuf; - string resizeW, resizeH; - string rotate, recmd; + string resizeW; + string resizeH; + string rotate; + string recmd; char const * tfname = fl_get_input(form->EpsFile); string tsubcap = fl_get_input(form->Subcaption); @@ -1480,8 +1407,8 @@ void InsetFig::TempRegenerate() float txhgh = atof(fl_get_input(form->Height)); if (!tfname || !*tfname) { - cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}"; - cmd += _("empty figure path"); + cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}"; + cmd += _("empty figure path"); cmd += '}'; return; } @@ -1490,69 +1417,9 @@ void InsetFig::TempRegenerate() string fname2 = MakeRelPath(tfname, buf1); // \includegraphics*[][]{file} string gcmd = "\\includegraphics{" + fname2 + '}'; - - switch (twtype) { - case DEF: - break; - case CM: {// \resizebox*{h-length}{v-length}{text} - char buf[10]; - sprintf(buf, "%g", txwid); // should find better - resizeW = buf; - resizeW += "cm"; - break; - } - case IN: { - char buf[10]; - sprintf(buf, "%g", txwid); - resizeW = buf; - resizeW += "in"; - break; - } - case PER_PAGE: { - char buf[10]; - sprintf(buf, "%g", txwid/100); - resizeW = buf; - resizeW += "\\textwidth"; - break; - } - case PER_COL: { - char buf[10]; - sprintf(buf, "%g", txwid/100); - resizeW = buf; - resizeW += "\\columnwidth"; - break; - } - } - switch (thtype) { - case DEF: - break; - case CM: { - char buf[10]; - sprintf(buf, "%g", txhgh); - resizeH = buf; - resizeH += "cm"; - break; - } - case IN: { - char buf[10]; - sprintf(buf, "%g", txhgh); - resizeH = buf; - resizeH += "in"; - break; - } - case PER_PAGE: { - char buf[10]; - sprintf(buf, "%g", txhgh/100); - resizeH = buf; - resizeH += "\\textheight"; - break; - } - case PER_COL: { - // Doesn't occur; case exists to suppress compiler warnings. - break; - } - } + resizeW = stringify(twtype, txwid, "width"); + resizeH = stringify(thtype, txhgh, "height"); // \resizebox*{h-length}{v-length}{text} if (!resizeW.empty() || !resizeH.empty()) { @@ -1570,17 +1437,11 @@ void InsetFig::TempRegenerate() } if (tangle != 0) { - char buf[10]; - sprintf(buf, "%g", tangle); // \rotatebox{angle}{text} - rotate = "\\rotatebox{"; - rotate += buf; - rotate += "}{"; + rotate = "\\rotatebox{" + tostr(tangle) + "}{"; } - cmdbuf = recmd; - cmdbuf += rotate; - cmdbuf += gcmd; + cmdbuf = recmd + rotate + gcmd; if (!rotate.empty()) cmdbuf += '}'; if (!recmd.empty()) cmdbuf += '}'; if (psubfigure && !tsubcap.empty()) { @@ -1590,22 +1451,29 @@ void InsetFig::TempRegenerate() } -void InsetFig::Recompute() +void InsetFig::recompute() { + if (!lyxrc.use_gui) + return; + bool changed = changedfname; int newx, newy, nraw_x, nraw_y; - if (changed) GetPSSizes(); + if (changed) getPSSizes(); - float sin_a = sin (angle / DEG2PI); /* rotation; H. Zeller 021296 */ - float cos_a = cos (angle / DEG2PI); + float sin_a = sin(angle / DEG2PI); /* rotation; H. Zeller 021296 */ + float cos_a = cos(angle / DEG2PI); int frame_wid = int(ceil(fabs(cos_a * pswid) + fabs(sin_a * pshgh))); int frame_hgh= int(ceil(fabs(cos_a * pshgh) + fabs(sin_a * pswid))); + string lfname = fname; + if (GetExtension(fname).empty()) + lfname += ".eps"; + /* now recompute wid and hgh, and if that is changed, set changed */ /* this depends on chosen size of the picture and its bbox */ // This will be redone in 0.13 ... (hen) - if (!fname.empty()) { + if (!lfname.empty() && IsFileReadable(lfname)) { // say, total width is 595 pts, as A4 in TeX, thats in 1/72" */ newx = frame_wid; @@ -1684,11 +1552,11 @@ void InsetFig::Recompute() figdata * pf = figure->data; // get new data - if (!fname.empty() && (flags & 3) - && !lyxrc->ps_command.empty()) { + if (!lfname.empty() && IsFileReadable(lfname) && (flags & 3) + && !lyxrc.ps_command.empty()) { // do not display if there is "do not display" // chosen (Matthias 260696) - figure->data = getfigdata(wid, hgh, fname, + figure->data = getfigdata(wid, hgh, lfname, psx, psy, pswid, pshgh, raw_wid, raw_hgh, angle, flags & (3|8)); @@ -1702,7 +1570,7 @@ void InsetFig::Recompute() } -void InsetFig::GetPSSizes() +void InsetFig::getPSSizes() { /* get %%BoundingBox: from postscript file */ @@ -1716,7 +1584,10 @@ void InsetFig::GetPSSizes() if (fname.empty()) return; string p; - ifstream ifs(fname.c_str()); + string lfname = fname; + if (GetExtension(fname).empty()) + lfname += ".eps"; + ifstream ifs(lfname.c_str()); if (!ifs) return; // file not found !!!! @@ -1730,17 +1601,14 @@ void InsetFig::GetPSSizes() for (;;) { char c = 0; ifs.get(c); if (ifs.eof()) { - lyxerr.debug() << "End of (E)PS file reached and" + lyxerr[Debug::INFO] << "End of (E)PS file reached and" " no BoundingBox!" << endl; break; } if (c == '%' && lastchar == '%') { - p = NextToken(ifs); + ifs >> p; if (p.empty()) break; - // we should not use this, with it we cannot - // discover bounding box and end of file. - //if (strcmp(p, "EndComments") == 0) break; - lyxerr.debug() << "Token: `" << p << "'" << endl; + lyxerr[Debug::INFO] << "Token: `" << p << "'" << endl; if (p == "BoundingBox:") { float fpsx, fpsy, fpswid, fpshgh; if (ifs >> fpsx >> fpsy >> fpswid >> fpshgh) { @@ -1768,7 +1636,7 @@ void InsetFig::GetPSSizes() } -void InsetFig::CallbackFig(long arg) +void InsetFig::callbackFig(long arg) { bool regen = false; char const * p; @@ -1810,7 +1678,7 @@ void InsetFig::CallbackFig(long arg) fl_activate_object(form->Width); break; default: - lyxerr.debug() << "Unknown type!" << endl; + lyxerr[Debug::INFO] << "Unknown type!" << endl; break; } regen = true; @@ -1841,7 +1709,7 @@ void InsetFig::CallbackFig(long arg) fl_activate_object(form->Height); break; default: - lyxerr.debug() << "Unknown type!" << endl; + lyxerr[Debug::INFO] << "Unknown type!" << endl; break; } regen = true; @@ -1871,16 +1739,16 @@ void InsetFig::CallbackFig(long arg) regen = true; /* regenerate command */ break; case 0: /* browse file */ - BrowseFile(); + browseFile(); regen = true; break; case 1: /* preview */ p = fl_get_input(form->EpsFile); - Preview(p); + preview(p); break; case 7: /* apply */ case 8: /* ok (apply and close) */ - if(!current_view->buffer()->isReadonly()) { + if (!current_view->buffer()->isReadonly()) { wtype = twtype; htype = thtype; xwid = atof(fl_get_input(form->Width)); @@ -1894,13 +1762,13 @@ void InsetFig::CallbackFig(long arg) } else { if (!fname.empty()) { changedfname = true; - fname.clear(); + fname.erase(); } } subcaption = fl_get_input(form->Subcaption); - Regenerate(); - Recompute(); + regenerate(); + recompute(); /* now update inset */ if (lyxerr.debugging()) { lyxerr << "Update: [" @@ -1911,7 +1779,7 @@ void InsetFig::CallbackFig(long arg) fl_set_focus_object(form->Figure, form->OkBtn); fl_hide_form(form->Figure); #if FL_REVISION == 89 -#warning Reactivate this free_form calls + // CHECK Reactivate this free_form calls #else fl_free_form(form->Figure); free(form); // Why free? @@ -1921,15 +1789,15 @@ void InsetFig::CallbackFig(long arg) break; } //if not readonly // The user has already been informed about RO in ::Edit - if(arg == 7) // if 'Apply' + if (arg == 7) // if 'Apply' break; // fall through case 9: /* cancel = restore and close */ fl_set_focus_object(form->Figure, form->OkBtn); fl_hide_form(form->Figure); #if FL_REVISION == 89 -#warning Reactivate this free_form calls -#warning Jug, is this still a problem? + // CHECK Reactivate this free_form calls + // Jug, is this still a problem? #else fl_free_form(form->Figure); free(form); // Why free? @@ -1938,7 +1806,7 @@ void InsetFig::CallbackFig(long arg) break; } - if (regen) TempRegenerate(); + if (regen) tempRegenerate(); } @@ -2016,10 +1884,8 @@ void EnableFigurePanel(FD_Figure * const form) } -void InsetFig::RestoreForm() +void InsetFig::restoreForm() { - char buf[32]; - EnableFigurePanel(form); twtype = wtype; @@ -2047,66 +1913,49 @@ void InsetFig::RestoreForm() fl_activate_object(form->Height); } - int pflags = flags & 3; - fl_set_button(form->Wysiwyg0, (pflags == 0)); - fl_set_button(form->Wysiwyg1, (pflags == 1)); - fl_set_button(form->Wysiwyg2, (pflags == 2)); - fl_set_button(form->Wysiwyg3, (pflags == 3)); + int piflags = flags & 3; + fl_set_button(form->Wysiwyg0, (piflags == 0)); + fl_set_button(form->Wysiwyg1, (piflags == 1)); + fl_set_button(form->Wysiwyg2, (piflags == 2)); + fl_set_button(form->Wysiwyg3, (piflags == 3)); fl_set_button(form->Frame, ((flags & 4) != 0)); fl_set_button(form->Translations, ((flags & 8) != 0)); fl_set_button(form->Subfigure, (subfigure != 0)); pflags = flags; psubfigure = subfigure; - sprintf(buf, "%g", xwid); - fl_set_input(form->Width, buf); - sprintf(buf, "%g", xhgh); - fl_set_input(form->Height, buf); - sprintf(buf, "%g", angle); - fl_set_input(form->Angle, buf); - if (!fname.empty()){ + fl_set_input(form->Width, tostr(xwid).c_str()); + fl_set_input(form->Height, tostr(xhgh).c_str()); + fl_set_input(form->Angle, tostr(angle).c_str()); + if (!fname.empty()) { string buf1 = OnlyPath(owner->fileName()); string fname2 = MakeRelPath(fname, buf1); fl_set_input(form->EpsFile, fname2.c_str()); } else fl_set_input(form->EpsFile, ""); fl_set_input(form->Subcaption, subcaption.c_str()); - if(current_view->buffer()->isReadonly()) + if (current_view->buffer()->isReadonly()) DisableFigurePanel(form); - TempRegenerate(); + tempRegenerate(); } -void InsetFig::Preview(char const * p) +void InsetFig::preview(string const & p) { - int pid = fork(); - - if (pid == -1) { - lyxerr << "Cannot fork process!" << endl; - return; // error - } - if (pid > 0) { - addpidwait(pid); - return; // parent process - } - + string tfname = p; + if (GetExtension(tfname).empty()) + tfname += ".eps"; string buf1 = OnlyPath(owner->fileName()); - string buf2 = MakeAbsPath(p, buf1); - - lyxerr << "Error during rendering " - << execlp(lyxrc->view_pspic_command.c_str(), - lyxrc->view_pspic_command.c_str(), - buf2.c_str(), 0) - << endl; - _exit(0); + string buf2 = os::external_path(MakeAbsPath(tfname, buf1)); + if (!formats.view(owner, buf2, "eps")) + lyxerr << "Can't view " << buf2 << endl; } -void InsetFig::BrowseFile() +void InsetFig::browseFile() { static string current_figure_path; - static int once = 0; - LyXFileDlg fileDlg; + static int once; if (lyxerr.debugging()) { lyxerr << "Filename: " @@ -2120,7 +1969,7 @@ void InsetFig::BrowseFile() buf = MakeAbsPath(p, buf2); buf = OnlyPath(buf); } else { - buf = OnlyPath(owner->fileName().c_str()); + buf = OnlyPath(owner->fileName()); } // Does user clipart directory exist? @@ -2131,37 +1980,34 @@ void InsetFig::BrowseFile() bufclip = AddName (system_lyxdir, "clipart"); - fileDlg.SetButton(0, _("Clipart"), bufclip); - fileDlg.SetButton(1, _("Document"), buf); + FileDialog fileDlg(current_view->owner(), _("Select an EPS figure"), + LFUN_SELECT_FILE_SYNC, + make_pair(string(_("Clip art|#C#c")), string(bufclip)), + make_pair(string(_("Documents|#o#O")), string(buf))); bool error = false; do { - ProhibitInput(); - if (once) { - p = fileDlg.Select(_("EPS Figure"), - current_figure_path, - "*ps", string()); - } else { - p = fileDlg.Select(_("EPS Figure"), buf, - "*ps", string()); - } - AllowInput(); + string const path = (once) ? current_figure_path : buf; - if (p.empty()) return; + FileDialog::Result result = fileDlg.Select(path, _("*ps| PostScript documents")); + + string const p = result.second; + + if (p.empty()) + return; buf = MakeRelPath(p, buf2); current_figure_path = OnlyPath(p); once = 1; if (contains(p, "#") || contains(p, "~") || contains(p, "$") - || contains(p, "%") || contains(p, " ")) - { - WriteAlert(_("Filename can't contain any " - "of these characters:"), - // xgettext:no-c-format - _("space, '#', '~', '$' or '%'.")); - error = true; - } + || contains(p, "%") || contains(p, " ")) { + Alert::alert(_("Filename can't contain any " + "of these characters:"), + // xgettext:no-c-format + _("space, '#', '~', '$' or '%'.")); + error = true; + } } while (error); if (form) fl_set_input(form->EpsFile, buf.c_str()); @@ -2177,14 +2023,15 @@ void GraphicsCB(FL_OBJECT * obj, long arg) } /* find inset we were reacting to */ - for (int i = 0; i < figinsref; ++i) - if (figures[i]->inset->form && figures[i]->inset->form->Figure + for (figures_type::iterator it = figures.begin(); + it != figures.end(); ++it) + if ((*it)->inset->form && (*it)->inset->form->Figure == obj->form) { - if (lyxerr.debugging()) { - lyxerr << "Calling back figure " << i << endl; + lyxerr << "Calling back figure " + << (*it) << endl; } - figures[i]->inset->CallbackFig(arg); + (*it)->inset->callbackFig(arg); return; } } @@ -2192,13 +2039,14 @@ void GraphicsCB(FL_OBJECT * obj, long arg) void HideFiguresPopups() { - for (int i = 0; i < figinsref; ++i) - if (figures[i]->inset->form - && figures[i]->inset->form->Figure->visible) { + for (figures_type::iterator it = figures.begin(); + it != figures.end(); ++it) + if ((*it)->inset->form + && (*it)->inset->form->Figure->visible) { if (lyxerr.debugging()) { - lyxerr << "Hiding figure " << i << endl; + lyxerr << "Hiding figure " << (*it) << endl; } // hide and free the form - figures[i]->inset->CallbackFig(9); + (*it)->inset->callbackFig(9); } }