home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / insetfig.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  27KB  |  1,183 lines

  1. #include <config.h>
  2.  
  3. #include <unistd.h>
  4. #include <math.h>
  5. #include <ctype.h>
  6.  
  7. #include "insetfig.h"
  8. #include "error.h"
  9. #include "lyxrc.h"
  10. #include "filetools.h"
  11. #include "lyx_gui_misc.h"
  12. #include "FileInfo.h"
  13. #include "filedlg.h"
  14. #include "lyx_main.h"
  15. #include "procMgr.h"
  16.  
  17. extern LyXRC *lyxrc;
  18. extern BufferView *current_view;
  19. //extern void sigchldhandler(int sig);
  20. extern void UpdateInset(Inset* inset, bool mark_dirty = true);
  21. extern void ProhibitInput();
  22. extern void AllowInput();
  23.  
  24. static char* NextToken(FILE *myfile);
  25.  
  26. const float DEG2PI = 57.295779513;
  27.  
  28. InsetFig::InsetFig(int tmpx, int tmpy, Buffer *o)
  29.     : owner(o)
  30. {
  31.     wid = tmpx;
  32.     hgh = tmpy;
  33.     wtype = DEF;
  34.     htype = DEF;
  35.     twtype = DEF;
  36.     thtype = DEF;
  37.     pflags = flags = 9;
  38.     psubfigure = subfigure = false;
  39.     xwid = xhgh = angle = 0;
  40.     raw_wid = raw_hgh = 0;
  41.     changedfname = false;
  42.     figL.RegisterFigure(this);
  43. }
  44.  
  45. InsetFig::~InsetFig()
  46. {
  47.     if (lyxerr.debugging()) {
  48.         printf("Figure destructor called\n");
  49.     }
  50.     figL.UnregisterFigure(this);
  51. }
  52.  
  53.  
  54. int InsetFig::Ascent(LyXFont const&) const
  55. {
  56.     return hgh + 3;
  57. }
  58.  
  59.  
  60. int InsetFig::Descent(LyXFont const&) const
  61. {
  62.     return 1;
  63. }
  64.  
  65.  
  66. int InsetFig::Width(LyXFont const&) const
  67. {
  68.     return wid + 2;
  69. }
  70.  
  71.  
  72. void InsetFig::Draw(LyXFont font, LyXScreen &scr, int baseline, float &x)
  73. {
  74.     if (figL.bitmap_waiting) figL.getbitmaps();
  75.  
  76.     // I wish that I didn't have to use this
  77.     // but the figinset code is so complicated so
  78.     // I don't want to fiddle with it now.
  79.     unsigned long pm = scr.getForeground();
  80.     
  81.     if (figure && figure->data && figure->data->bitmap &&
  82.         !figure->data->reading && !figure->data->broken) {
  83.         // draw the bitmap
  84.         XCopyArea(fl_display, figure->data->bitmap, pm, getGC(gc_copy),
  85.               0, 0, wid, hgh, int(x+1), baseline-hgh);
  86.         XFlush(fl_display);
  87.         if (flags & 4) XDrawRectangle(fl_display, pm, getGC(gc_copy),
  88.                           int(x), baseline - hgh - 1,
  89.                           wid+1, hgh+1);
  90.     } else {
  91.         LString msg;
  92.         // draw frame
  93.         XDrawRectangle(fl_display, pm, getGC(gc_copy),
  94.                    (int) x,
  95.                    baseline - hgh - 1, wid+1, hgh+1);
  96.         if (figure && figure->data) {
  97.           if (figure->data->broken)
  98.               msg = _("[render error]");
  99.           else if (figure->data->reading)
  100.               msg = _("[rendering ... ]");
  101.         } else 
  102.           if (fname.empty())
  103.               msg = _("[no file]");
  104.           else if ((flags & 3) == 0)
  105.               msg = _("[not displayed]");
  106.           else if (lyxrc->ps_command.empty())
  107.               msg = _("[no ghostscript]");
  108.  
  109.         if (msg.empty()) msg = _("[unknown error]");
  110.         
  111.         font.setFamily (LyXFont::SANS_FAMILY);
  112.         font.setSize (LyXFont::SIZE_FOOTNOTE);
  113.         LString justname = OnlyFilename (fname);
  114.         font.drawString(justname,pm,
  115.                    baseline - font.maxAscent() - 4,
  116.                    int(x + 8));
  117.         font.setSize (LyXFont::SIZE_TINY);
  118.         font.drawString(msg,pm,
  119.                    baseline - 4,
  120.                    int(x + 8));
  121.  
  122.     }
  123.     x += Width(font);    // ?
  124. }
  125.  
  126.  
  127. void InsetFig::Write(FILE *file)
  128. {
  129.     Regenerate();
  130.     fprintf(file, "Figure size %d %d\n", wid, hgh);
  131.     if (!fname.empty()) {
  132.       LString buf1 = OnlyPath(owner->getFileName());
  133.       LString fname2 = MakeRelPath(fname, buf1);
  134.       fprintf(file, "file %s\n", fname2.c_str());
  135.     }
  136.     if (!subcaption.empty())
  137.       fprintf(file, "subcaption %s\n", subcaption.c_str());
  138.     if (wtype) fprintf(file, "width %d %g\n", wtype, xwid);
  139.     if (htype) fprintf(file, "height %d %g\n", htype, xhgh);
  140.     if (angle != 0) fprintf(file, "angle %g\n", angle);
  141.     fprintf(file, "flags %d\n", flags);
  142.     if (subfigure) fprintf(file, "subfigure\n");
  143. }
  144.  
  145.  
  146. void InsetFig::Read(LyXLex &lex)
  147. {
  148.     LString buf;
  149.     //int i;
  150.     bool finished = false;
  151.     
  152.     while (lex.IsOK() && !finished) {
  153.         lex.next();
  154.  
  155.         LString const token = lex.GetString();
  156.         lyxerr.debug("Token: " + token);
  157.         
  158.         if (token.empty())
  159.             continue;
  160.         else if (token == "\\end_inset") {
  161.             finished = true;
  162.         } else if (token == "file") {
  163.             if (lex.next()) {
  164.                 buf = lex.GetString();
  165.                 LString buf1 = OnlyPath(owner->getFileName());
  166.                 fname = MakeAbsPath(buf, buf1);
  167.                 changedfname = true;
  168.             }
  169.             //} else if (token == "extra") {
  170.             //if (lex.next());
  171.             // kept for backwards compability. Delete in 0.13.x
  172.         } else if (token == "subcaption") {
  173.             if (lex.EatLine())
  174.                 subcaption = lex.GetString();
  175.             //} else if (token == "label") {
  176.             //if (lex.next());
  177.             // kept for backwards compability. Delete in 0.13.x
  178.         } else if (token == "angle") {
  179.             if (lex.next())
  180.                 angle = lex.GetFloat();
  181.         } else if (token == "size") {
  182.             if (lex.next())
  183.                 wid = lex.GetInteger();
  184.             if (lex.next())
  185.                 hgh = lex.GetInteger();
  186.         } else if (token == "flags") {
  187.             if (lex.next())
  188.                 flags = pflags = lex.GetInteger();
  189.         } else if (token == "subfigure") {
  190.             subfigure = psubfigure = true;
  191.         } else if (token == "width") {
  192.             int typ = 0;
  193.             if (lex.next())
  194.                 typ = lex.GetInteger();
  195.             if (lex.next())
  196.                 xwid = lex.GetFloat();
  197.             switch (typ) {
  198.             case DEF: wtype = DEF; break;
  199.             case CM: wtype = CM; break;
  200.             case IN: wtype = IN; break;
  201.             case PER_PAGE: wtype = PER_PAGE; break;
  202.             case PER_COL: wtype = PER_COL; break;
  203.             default:
  204.                 lyxerr.debug("Unknown type!");
  205.                 break;
  206.             }
  207.             twtype = wtype;
  208.         } else if (token == "height") {
  209.             int typ = 0;
  210.             if (lex.next())
  211.                 typ = lex.GetInteger();
  212.             if (lex.next())
  213.                 xhgh = lex.GetFloat();
  214.             switch (typ) {
  215.             case DEF: htype = DEF; break;
  216.             case CM: htype = CM; break;
  217.             case IN: htype = IN; break;
  218.             case PER_PAGE: htype = PER_PAGE; break;
  219.             default:
  220.                 lyxerr.debug("Unknown type!");
  221.                 break;
  222.             }
  223.             thtype = htype;
  224.         }
  225.     }
  226.     Regenerate();
  227.     Recompute();
  228. }
  229.  
  230.  
  231. int InsetFig::Latex(FILE *file, signed char /* fragile*/ )
  232. {
  233.     Regenerate();
  234.     if (!cmd.empty()) fprintf(file, "%s ", cmd.c_str());
  235.     return 0;
  236. }
  237.  
  238.  
  239. int InsetFig::Latex(LString &file, signed char /* fragile*/ )
  240. {
  241.     Regenerate();
  242.     file += cmd + ' ';
  243.     return 0;
  244. }
  245.  
  246.  
  247. void InsetFig::Validate(LaTeXFeatures &features) const
  248. {
  249.     features.graphics = true;
  250.     if (subfigure) features.subfigure = true;
  251. }
  252.  
  253.  
  254. unsigned char InsetFig::Editable() const
  255. {
  256.     return 1;
  257. }
  258.  
  259.  
  260. bool InsetFig::Deletable() const
  261. {
  262.     return false;
  263. }
  264.  
  265.  
  266. void InsetFig::Edit(int, int)
  267. {
  268.     if (lyxerr.debugging()) {
  269.         printf("Editing InsetFig\n");
  270.     }
  271.     Regenerate();
  272.  
  273.     // We should have RO-versions of the form instead.
  274.     // The actual prevention of altering a readonly doc is done in CallbackFig()
  275.     if(current_view->currentBuffer()->isReadonly()) 
  276.         WarnReadonly();
  277.  
  278.     if (!form) {
  279.         form = create_form_Figure();
  280.         fl_set_form_atclose(form->Figure, CancelCloseBoxCB, NULL);
  281.         fl_set_object_return(form->Angle,FL_RETURN_ALWAYS);
  282.         fl_set_object_return(form->Width,FL_RETURN_ALWAYS);
  283.         fl_set_object_return(form->Height,FL_RETURN_ALWAYS);
  284.     }
  285.     RestoreForm();
  286.     if (form->Figure->visible) {
  287.         fl_raise_form(form->Figure);
  288.     } else {
  289.         fl_show_form(form->Figure, FL_PLACE_MOUSE | FL_PLACE_SIZE,
  290.                  FL_FULLBORDER, _("Figure"));
  291.     }
  292. }
  293.  
  294.  
  295. Inset *InsetFig::Clone()
  296. {
  297.     InsetFig *tmp = new InsetFig(100, 100, owner);
  298.  
  299.     if (lyxerr.debugging()) {
  300.         printf("Clone Figure: buffer:[%d], cbuffer:[xx]\n",
  301.                PTR_AS_INT(current_view->currentBuffer()));
  302.     }
  303.  
  304.     tmp->wid = wid;
  305.     tmp->hgh = hgh;
  306.     tmp->raw_wid = raw_wid;
  307.     tmp->raw_hgh = raw_hgh;
  308.     tmp->angle = angle;
  309.     tmp->xwid = xwid;
  310.     tmp->xhgh = xhgh;
  311.     tmp->flags = flags;
  312.     tmp->pflags = pflags;
  313.     tmp->subfigure = subfigure;
  314.     tmp->psubfigure = psubfigure;
  315.     tmp->wtype = wtype;
  316.     tmp->htype = htype;
  317.     tmp->psx = psx;
  318.     tmp->psy = psy;
  319.     tmp->pswid = pswid;
  320.     tmp->pshgh = pshgh;
  321.     tmp->fname = fname;
  322.     if (!fname.empty() && (flags & 3) && !lyxrc->ps_command.empty()) { 
  323.       // do not display if there is "do not display" chosen (Matthias 260696)
  324.         tmp->figure->data =
  325.             figL.getfigdata(wid, hgh, fname, psx, psy,
  326.                     pswid, pshgh, raw_wid, raw_hgh,
  327.                     angle, flags & (3|8));
  328.     } else tmp->figure->data = NULL;
  329.     tmp->subcaption = subcaption;
  330.     tmp->changedfname = false;
  331.     tmp->owner = owner;
  332.     tmp->Regenerate();
  333.     return tmp;
  334. }
  335.  
  336.  
  337. Inset::Code InsetFig::LyxCode() const
  338. {
  339.     return Inset::GRAPHICS_CODE;
  340. }
  341.  
  342.  
  343. void InsetFig::Regenerate()
  344. {
  345.     LString cmdbuf;
  346.     LString gcmd;
  347.     LString resizeW, resizeH;
  348.     LString rotate, recmd;
  349.  
  350.     if (fname.empty()) {
  351.         cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}";
  352.             cmd += _("empty figure path");
  353.         cmd += '}';
  354.         //if (form) fl_set_object_label(form->cmd, "");
  355.         return;
  356.     }
  357.  
  358.     LString buf1 = OnlyPath(owner->getFileName());
  359.     LString fname2 = MakeRelPath(fname, buf1);
  360.  
  361.     gcmd = "\\includegraphics{" + fname2 + '}';
  362.     
  363.     switch (wtype) {
  364.     case DEF:
  365.         break;
  366.     case CM:{// \resizebox*{h-length}{v-length}{text}
  367.         char buf[10];
  368.         sprintf(buf, "%g", xwid); // should find better
  369.         resizeW = buf;
  370.         resizeW += "cm";
  371.         break;
  372.     }
  373.     case IN: {
  374.         char buf[10];
  375.         sprintf(buf, "%g", xwid);
  376.         resizeW = buf;
  377.         resizeW += "in";
  378.         break;
  379.     }
  380.     case PER_PAGE:{
  381.         char buf[10];
  382.         sprintf(buf, "%g", xwid/100);
  383.         resizeW = buf;
  384.         resizeW += "\\textwidth";
  385.         break;
  386.     }
  387.     case PER_COL:{
  388.         char buf[10];
  389.         sprintf(buf, "%g", xwid/100);
  390.         resizeW = buf;
  391.         resizeW += "\\columnwidth";
  392.         break;
  393.     }
  394.     }
  395.  
  396.     switch (htype) {
  397.     case DEF:
  398.         break;
  399.     case CM: {
  400.         char buf[10];
  401.         sprintf(buf, "%g", xhgh);
  402.         resizeH = buf;
  403.         resizeH += "cm";
  404.         break;
  405.     }
  406.     case IN:{
  407.         char buf[10];
  408.         sprintf(buf, "%g", xhgh);
  409.         resizeH = buf;
  410.         resizeH += "in";
  411.         break;
  412.     }
  413.     case PER_PAGE: {
  414.         char buf[10];
  415.         sprintf(buf, "%g", xhgh/100);
  416.         resizeH = buf;
  417.         resizeH += "\\textheight";
  418.         break;
  419.     }
  420.     case PER_COL: {
  421.                 // Doesn't occur; case exists to suppress compiler warnings.
  422.             break;
  423.     }
  424.     }
  425.  
  426.     if (!resizeW.empty() || !resizeH.empty()) {
  427.         recmd = "\\resizebox*{";
  428.         if (!resizeW.empty())
  429.             recmd += resizeW;
  430.         else
  431.             recmd += '!';
  432.         recmd += "}{";
  433.         if (!resizeH.empty())
  434.             recmd += resizeH;
  435.         else
  436.             recmd += '!';
  437.         recmd += "}{";
  438.     }
  439.     
  440.     
  441.     if (angle != 0) {
  442.         char buf[10];
  443.         sprintf(buf, "%g", angle);
  444.         // \rotatebox{angle}{text}
  445.         rotate = "\\rotatebox{";
  446.         rotate += buf;
  447.         rotate += "}{";
  448.     }
  449.  
  450.     cmdbuf = recmd;
  451.     cmdbuf += rotate;
  452.     cmdbuf += gcmd;
  453.     if (!rotate.empty()) cmdbuf += '}';
  454.     if (!recmd.empty()) cmdbuf += '}';
  455.     if (subfigure) {
  456.         if (!subcaption.empty())
  457.             cmdbuf = "\\subfigure[" + subcaption +
  458.               "]{" + cmdbuf + "}";
  459.         else
  460.             cmdbuf = "\\subfigure{" + cmdbuf + "}";
  461.     }
  462.     
  463.     cmd = cmdbuf;
  464. }
  465.  
  466.  
  467. void InsetFig::TempRegenerate()
  468. {
  469.     LString gcmd;
  470.     LString cmdbuf;
  471.     LString resizeW, resizeH;
  472.     LString rotate, recmd;
  473.     LString tsubcap;
  474.     
  475.     char const *tfname; // *textra;
  476.     float tangle, txwid, txhgh;
  477.  
  478.     tfname = fl_get_input(form->EpsFile);
  479.     tsubcap = fl_get_input(form->Subcaption);
  480.     tangle = atof(fl_get_input(form->Angle));
  481.     txwid = atof(fl_get_input(form->Width));
  482.     txhgh = atof(fl_get_input(form->Height));
  483.  
  484.     if (!tfname || !*tfname) {
  485.             cmd = "\\fbox{\\rule[-0.5in]{0pt}{1in}";
  486.             cmd += _("empty figure path");
  487.         cmd += '}';
  488.         return;
  489.     }
  490.  
  491.     LString buf1 = OnlyPath(owner->getFileName());
  492.     LString fname2 = MakeRelPath(tfname, buf1);
  493.     // \includegraphics*[<llx,lly>][<urx,ury>]{file}
  494.     gcmd = "\\includegraphics{" + fname2 + '}';
  495.     
  496.     switch (twtype) {
  497.     case DEF:
  498.         break;
  499.     case CM: {// \resizebox*{h-length}{v-length}{text}
  500.         char buf[10];
  501.         sprintf(buf, "%g", txwid); // should find better
  502.         resizeW = buf;
  503.         resizeW += "cm";
  504.         break;
  505.     }
  506.     case IN: {
  507.         char buf[10];
  508.         sprintf(buf, "%g", txwid);
  509.         resizeW = buf;
  510.         resizeW += "in";
  511.         break;
  512.     }
  513.     case PER_PAGE: {
  514.         char buf[10];
  515.         sprintf(buf, "%g", txwid/100);
  516.         resizeW = buf;
  517.         resizeW += "\\textwidth";
  518.         break;
  519.     }
  520.     case PER_COL: {
  521.         char buf[10];
  522.         sprintf(buf, "%g", txwid/100);
  523.         resizeW = buf;
  524.         resizeW += "\\columnwidth";
  525.         break;
  526.     }
  527.     }
  528.  
  529.     switch (thtype) {
  530.     case DEF:
  531.         break;
  532.     case CM: {
  533.         char buf[10];
  534.         sprintf(buf, "%g", txhgh);
  535.         resizeH = buf;
  536.         resizeH += "cm";
  537.         break;
  538.     }
  539.     case IN: {
  540.         char buf[10];
  541.         sprintf(buf, "%g", txhgh);
  542.         resizeH = buf;
  543.         resizeH += "in";
  544.         break;
  545.     }
  546.     case PER_PAGE: {
  547.         char buf[10];
  548.         sprintf(buf, "%g", txhgh/100);
  549.         resizeH = buf;
  550.         resizeH += "\\textheight";
  551.         break;
  552.     }
  553.     case PER_COL: {
  554.                 // Doesn't occur; case exists to suppress compiler warnings.
  555.             break;
  556.     }
  557.     }
  558.  
  559.     // \resizebox*{h-length}{v-length}{text}
  560.     if (!resizeW.empty() || !resizeH.empty()) {
  561.         recmd = "\\resizebox*{";
  562.         if (!resizeW.empty())
  563.             recmd += resizeW;
  564.         else
  565.             recmd += '!';
  566.         recmd += "}{";
  567.         if (!resizeH.empty())
  568.             recmd += resizeH;
  569.         else
  570.             recmd += '!';
  571.         recmd += "}{";
  572.     }
  573.     
  574.     if (tangle != 0) {
  575.         char buf[10];
  576.         sprintf(buf, "%g", tangle);
  577.         // \rotatebox{angle}{text}
  578.         rotate = "\\rotatebox{";
  579.         rotate += buf;
  580.         rotate += "}{";
  581.     }
  582.  
  583.     cmdbuf = recmd;
  584.     cmdbuf += rotate;
  585.     cmdbuf += gcmd;
  586.     if (!rotate.empty()) cmdbuf += '}';
  587.     if (!recmd.empty()) cmdbuf += '}';
  588.     if (psubfigure && !tsubcap.empty()) {
  589.         cmdbuf = LString("\\subfigure{") + tsubcap
  590.           + LString("}{") + cmdbuf + "}";
  591.     }
  592. }
  593.  
  594.  
  595. void InsetFig::Recompute()
  596. {
  597.     bool changed = changedfname;
  598.     int newx, newy, nraw_x, nraw_y, frame_wid, frame_hgh;
  599.     float sin_a, cos_a;
  600.  
  601.     if (changed) GetPSSizes();
  602.  
  603.     sin_a = sin (angle / DEG2PI);        /* rotation; H. Zeller 021296 */
  604.     cos_a = cos (angle / DEG2PI);
  605.     frame_wid = (int) ceil (fabs(cos_a * pswid) + fabs(sin_a * pshgh));
  606.     frame_hgh= (int) ceil (fabs(cos_a * pshgh) + fabs(sin_a * pswid));
  607.  
  608.     /* now recompute wid and hgh, and if that is changed, set changed */
  609.     /* this depends on chosen size of the picture and its bbox */
  610.     // This will be redone in 0.13 ... (hen)
  611.     if (!fname.empty()) {
  612.         // say, total width is 595 pts, as A4 in TeX, thats in 1/72" */
  613.  
  614.         newx = frame_wid;
  615.         newy = frame_hgh;
  616.         switch (wtype) {
  617.         case DEF:
  618.             break;
  619.         case CM:    /* cm */
  620.             newx = (int) (28.346*xwid);
  621.             break;
  622.         case IN: /* in */
  623.             newx = (int) (72*xwid);
  624.             break;
  625.         case PER_PAGE:    /* % of page */
  626.             newx = (int) (5.95*xwid);
  627.             break;
  628.         case PER_COL:    /* % of col */
  629.             newx = (int) (2.975*xwid);
  630.             break;
  631.         }
  632.         
  633.         if (wtype && frame_wid) newy = newx*frame_hgh/frame_wid;
  634.         
  635.         switch (htype) {
  636.         case DEF:
  637.             //fprintf(stderr, "This should not happen!\n");
  638.             break;
  639.         case CM:    /* cm */
  640.             newy = (int) (28.346*xhgh);
  641.             break;
  642.         case IN: /* in */
  643.             newy = (int) (72*xhgh);
  644.             break;
  645.         case PER_PAGE:    /* % of page */
  646.             newy = (int) (8.42*xhgh);
  647.             break;
  648.              case PER_COL: 
  649.                         // Doesn't occur; case exists to suppress
  650.             // compiler warnings.  
  651.                         break;
  652.         }
  653.         if (htype && !wtype && frame_hgh) newx = newy*frame_wid/frame_hgh;
  654.     } else {
  655.         newx = wid;
  656.         newy = hgh;
  657.     }
  658.  
  659.     nraw_x = int((1.0 * pswid * newx)/frame_wid);
  660.     nraw_y = int((1.0 * pshgh * newy)/frame_hgh);
  661.  
  662.     // cannot be zero, actually, set it to some minimum, so its clickable
  663.     if (newx < 5) newx = 5;
  664.     if (newy < 5) newy = 5;
  665.  
  666.     if (newx   != wid     || newy   != hgh     || 
  667.         nraw_x != raw_wid || nraw_y != raw_hgh ||
  668.         flags  != pflags  || subfigure != psubfigure) 
  669.         changed = true;
  670.        
  671.     raw_wid = nraw_x;
  672.     raw_hgh = nraw_y;
  673.     wid = newx;
  674.     hgh = newy;
  675.     flags = pflags;
  676.     subfigure = psubfigure;
  677.  
  678.     if (changed) {
  679.         figdata *pf = figure->data;
  680.  
  681.         // get new data
  682.         if (!fname.empty() && (flags & 3) && !lyxrc->ps_command.empty()) {
  683.             // do not display if there is "do not display"
  684.             // chosen (Matthias 260696)
  685.             figure->data = figL.getfigdata(wid, hgh, fname,
  686.                                psx, psy, pswid, pshgh,
  687.                                raw_wid, raw_hgh,
  688.                                angle, flags & (3|8));
  689.         } else figure->data = NULL;
  690.  
  691.         // free the old data
  692.         if (pf) figL.freefigdata(pf);
  693.     }
  694.  
  695.     changedfname = false;
  696. }
  697.  
  698.  
  699. void InsetFig::GetPSSizes()
  700. {
  701.     /* get %%BoundingBox: from postscript file */
  702.     int lastchar, c;
  703.     char *p = NULL;
  704.     
  705.     /* defaults to associated size
  706.      * ..just in case the PS-file is not readable (Henner,24-Aug-97) 
  707.      */
  708.     psx = 0;
  709.     psy = 0;
  710.     pswid = wid;
  711.     pshgh = hgh;
  712.  
  713.     if (fname.empty()) return;
  714.     
  715.     FilePtr f(fname, FilePtr::read);
  716.  
  717.     if (!f()) return;    // file not found !!!!
  718.  
  719.     /* defaults to A4 page */
  720.     psx = 0;
  721.     psy = 0;
  722.     pswid = 595;
  723.     pshgh = 842;
  724.  
  725.     lastchar = fgetc(f);
  726.     for (;;) {
  727.         c = fgetc(f);
  728.         if (c == EOF) {
  729.             lyxerr.debug("End of (E)PS file reached and"
  730.                       " no BoundingBox!");
  731.             break;
  732.         }
  733.         if (c == '%' && lastchar == '%') {
  734.             p = NextToken(f);
  735.             if (!p) break;
  736.             if (strcmp(p, "EndComments") == 0) break;
  737.             if (strcmp(p, "BoundingBox:") == 0) {
  738.                 fscanf(f, "%d %d %d %d", &psx, &psy,
  739.                        &pswid, &pshgh);
  740.                 if (lyxerr.debugging()) {
  741.                     fprintf(stderr, "%%%%BoundingBox:"
  742.                         " %d %d %d %d\n",
  743.                         psx, psy, pswid, pshgh);
  744.                     break;
  745.                 }
  746.             }
  747.             c = 0;
  748.             delete[] p;
  749.             p = NULL;
  750.         }
  751.         lastchar = c;
  752.     }
  753.     if (p) delete[] p;
  754.     pswid -= psx;
  755.     pshgh -= psy;
  756.  
  757. }
  758.  
  759.  
  760. void InsetFig::CallbackFig(long arg)
  761. {
  762.     bool regen = false;
  763.     char const *p;
  764.  
  765.     if (lyxerr.debugging()) {
  766.         printf("Figure callback, arg %ld\n", arg);
  767.     }
  768.  
  769.     switch (arg) {
  770.     case 10:
  771.     case 11:
  772.     case 12:    /* width type */
  773.     case 13:
  774.     case 14:
  775.         switch (arg - 10) {
  776.         case DEF:
  777.             twtype = DEF;
  778.             // put disable here
  779.             fl_deactivate_object(form->Width);
  780.             break;
  781.         case CM:
  782.             twtype = CM;
  783.             // put enable here
  784.             fl_activate_object(form->Width);
  785.             break;
  786.         case IN:
  787.             twtype = IN;
  788.             // put enable here
  789.             fl_activate_object(form->Width);
  790.             break;
  791.         case PER_PAGE:
  792.             twtype = PER_PAGE;
  793.             // put enable here
  794.             fl_activate_object(form->Width);
  795.             break;
  796.         case PER_COL:
  797.             twtype = PER_COL;
  798.             // put enable here
  799.             fl_activate_object(form->Width);
  800.             break;
  801.         default:
  802.             lyxerr.debug("Unknown type!");
  803.             break;
  804.         }
  805.         regen = true;
  806.         break;
  807.     case 20:
  808.     case 21:
  809.     case 22:    /* height type */
  810.     case 23:
  811.         switch (arg - 20) {
  812.         case DEF:
  813.             thtype = DEF;
  814.             // put disable here
  815.             fl_deactivate_object(form->Height);
  816.             break;
  817.         case CM:
  818.             thtype = CM;
  819.             // put enable here
  820.             fl_activate_object(form->Height);
  821.             break;
  822.         case IN:
  823.             thtype = IN;
  824.             // put enable here
  825.             fl_activate_object(form->Height);
  826.             break;
  827.         case PER_PAGE:
  828.             thtype = PER_PAGE;
  829.             // put enable here
  830.             fl_activate_object(form->Height);
  831.             break;
  832.         default:
  833.             lyxerr.debug("Unknown type!");
  834.             break;
  835.         }
  836.         regen = true;
  837.         break;
  838.     case 3:
  839.         pflags = pflags & ~3;        /* wysiwyg0 */
  840.         break;
  841.     case 33:
  842.         pflags = (pflags & ~3) | 1;    /* wysiwyg1 */
  843.         break;
  844.     case 43:
  845.         pflags = (pflags & ~3) | 2;    /* wysiwyg2 */
  846.         break;
  847.     case 63:
  848.         pflags = (pflags & ~3) | 3;    /* wysiwyg3 */
  849.         break;
  850.     case 53:
  851.         pflags ^= 4;    /* frame */
  852.         break;
  853.     case 54:
  854.         pflags ^= 8;    /* do translations */
  855.         break;
  856.     case 70:
  857.         psubfigure = !psubfigure;    /* This is a subfigure */
  858.         break;
  859.     case 2:
  860.         regen = true;        /* regenerate command */
  861.         break;
  862.     case 0:                /* browse file */
  863.         BrowseFile();
  864.         regen = true;
  865.         break;
  866.     case 1:                /* preview */
  867.         p = fl_get_input(form->EpsFile);
  868.         Preview(p);
  869.         break;
  870.     case 7:                /* apply */
  871.     case 8:                /* ok (apply and close) */
  872.         if(!current_view->currentBuffer()->isReadonly())
  873.         {
  874.             wtype = twtype;
  875.             htype = thtype;
  876.             xwid = atof(fl_get_input(form->Width));
  877.             xhgh = atof(fl_get_input(form->Height));
  878.             angle = atof(fl_get_input(form->Angle));
  879.             p = fl_get_input(form->EpsFile);
  880.             if (p && *p) {
  881.                 LString buf1 = OnlyPath(owner->getFileName());
  882.                 fname = MakeAbsPath(p, buf1);
  883.                 changedfname = true;
  884.             } else {
  885.                 if (!fname.empty()) {
  886.                     changedfname = true;
  887.                     fname.erase();
  888.                 }
  889.             }
  890.             subcaption = fl_get_input(form->Subcaption);
  891.     
  892.             Regenerate();
  893.             Recompute();
  894.             /* now update inset */
  895.             if (lyxerr.debugging()) {
  896.                 printf("Update: [%dx%d]\n", wid, hgh);
  897.             }
  898.             UpdateInset(this);
  899.             if (arg == 8) {
  900.                 fl_hide_form(form->Figure);
  901.                 fl_free_form(form->Figure);
  902.                 free(form);
  903.                 form = NULL;
  904.             }
  905.             break;
  906.         } //if not readonly
  907.         //  The user has already been informed about RO in ::Edit
  908.         if(arg == 7) // if 'Apply'
  909.             break;
  910.         // fall through
  911.     case 9:                /* cancel = restore and close */
  912.         fl_hide_form(form->Figure);
  913.         fl_free_form(form->Figure);
  914.         free(form);
  915.         form = NULL;
  916.         break;
  917.     }
  918.  
  919.     if (regen) TempRegenerate();
  920. }
  921.  
  922. inline void DisableFigurePanel(FD_Figure * const form)
  923. {
  924.         fl_deactivate_object(form->EpsFile);
  925.     fl_deactivate_object(form->Browse);
  926.     fl_deactivate_object(form->Width);
  927.     fl_deactivate_object(form->Height);
  928.     fl_deactivate_object(form->Frame);
  929.     fl_deactivate_object(form->Translations);
  930.     fl_deactivate_object(form->Angle);
  931.     fl_deactivate_object(form->HeightGrp);
  932.     fl_deactivate_object(form->page2);
  933.     fl_deactivate_object(form->Default2);
  934.     fl_deactivate_object(form->cm2);
  935.     fl_deactivate_object(form->in2);
  936.     fl_deactivate_object(form->HeightLabel);
  937.     fl_deactivate_object(form->WidthLabel);
  938.     fl_deactivate_object(form->DisplayGrp);
  939.     fl_deactivate_object(form->Wysiwyg3);
  940.     fl_deactivate_object(form->Wysiwyg0);
  941.     fl_deactivate_object(form->Wysiwyg2);
  942.     fl_deactivate_object(form->Wysiwyg1);
  943.     fl_deactivate_object(form->WidthGrp);
  944.     fl_deactivate_object(form->Default1);
  945.     fl_deactivate_object(form->cm1);
  946.     fl_deactivate_object(form->in1);
  947.     fl_deactivate_object(form->page1);
  948.     fl_deactivate_object(form->column1);
  949.     fl_deactivate_object(form->Subcaption);
  950.     fl_deactivate_object(form->Subfigure);
  951.     fl_deactivate_object (form->OkBtn);
  952.     fl_deactivate_object (form->ApplyBtn);
  953.     fl_set_object_lcol (form->OkBtn, FL_INACTIVE);
  954.     fl_set_object_lcol (form->ApplyBtn, FL_INACTIVE);
  955. }
  956.  
  957. inline void EnableFigurePanel(FD_Figure * const form)
  958. {
  959.         fl_activate_object(form->EpsFile);
  960.     fl_activate_object(form->Browse);
  961.     fl_activate_object(form->Width);
  962.     fl_activate_object(form->Height);
  963.     fl_activate_object(form->Frame);
  964.     fl_activate_object(form->Translations);
  965.     fl_activate_object(form->Angle);
  966.     fl_activate_object(form->HeightGrp);
  967.     fl_activate_object(form->page2);
  968.     fl_activate_object(form->Default2);
  969.     fl_activate_object(form->cm2);
  970.     fl_activate_object(form->in2);
  971.     fl_activate_object(form->HeightLabel);
  972.     fl_activate_object(form->WidthLabel);
  973.     fl_activate_object(form->DisplayGrp);
  974.     fl_activate_object(form->Wysiwyg3);
  975.     fl_activate_object(form->Wysiwyg0);
  976.     fl_activate_object(form->Wysiwyg2);
  977.     fl_activate_object(form->Wysiwyg1);
  978.     fl_activate_object(form->WidthGrp);
  979.     fl_activate_object(form->Default1);
  980.     fl_activate_object(form->cm1);
  981.     fl_activate_object(form->in1);
  982.     fl_activate_object(form->page1);
  983.     fl_activate_object(form->column1);
  984.     fl_activate_object(form->Subcaption);
  985.     fl_activate_object(form->Subfigure);
  986.     fl_activate_object (form->OkBtn);
  987.     fl_activate_object (form->ApplyBtn);
  988.     fl_set_object_lcol (form->OkBtn, FL_BLACK);
  989.     fl_set_object_lcol (form->ApplyBtn, FL_BLACK);
  990. }
  991.  
  992. void InsetFig::RestoreForm()
  993. {
  994.     char buf[32];
  995.     int pflags;
  996.  
  997.     EnableFigurePanel(form);
  998.  
  999.     twtype = wtype;
  1000.     fl_set_button(form->Default1, (wtype == 0));
  1001.     fl_set_button(form->cm1, (wtype == 1));
  1002.     fl_set_button(form->in1, (wtype == 2));
  1003.     fl_set_button(form->page1, (wtype == 3));
  1004.     fl_set_button(form->column1, (wtype == 4));
  1005.     if (wtype == 0) {
  1006.         fl_deactivate_object(form->Width);
  1007.     } else {
  1008.         fl_activate_object(form->Width);
  1009.     }
  1010.         
  1011.     // enable and disable should be put here.
  1012.     thtype = htype;
  1013.     fl_set_button(form->Default2, (htype == 0));
  1014.     fl_set_button(form->cm2, (htype == 1));
  1015.     fl_set_button(form->in2, (htype == 2));
  1016.     fl_set_button(form->page2, (htype == 3));
  1017.     // enable and disable should be put here.
  1018.     if (htype == 0) {
  1019.         fl_deactivate_object(form->Height);
  1020.     } else {
  1021.         fl_activate_object(form->Height);
  1022.     }
  1023.  
  1024.     pflags = flags & 3;
  1025.     fl_set_button(form->Wysiwyg0, (pflags == 0));
  1026.     fl_set_button(form->Wysiwyg1, (pflags == 1));
  1027.     fl_set_button(form->Wysiwyg2, (pflags == 2));
  1028.     fl_set_button(form->Wysiwyg3, (pflags == 3));
  1029.     fl_set_button(form->Frame, ((flags & 4) != 0));
  1030.     fl_set_button(form->Translations, ((flags & 8) != 0));
  1031.     fl_set_button(form->Subfigure, (subfigure != 0));
  1032.     pflags = flags;
  1033.     psubfigure = subfigure;
  1034.     sprintf(buf, "%g", xwid);
  1035.     fl_set_input(form->Width, buf);
  1036.     sprintf(buf, "%g", xhgh);
  1037.     fl_set_input(form->Height, buf);
  1038.     sprintf(buf, "%g", angle);
  1039.     fl_set_input(form->Angle, buf);
  1040.     if (!fname.empty()){
  1041.         LString buf1 = OnlyPath(owner->getFileName());
  1042.         LString fname2 = MakeRelPath(fname, buf1);
  1043.         fl_set_input(form->EpsFile, fname2.c_str());
  1044.     }
  1045.     else fl_set_input(form->EpsFile, "");
  1046.     fl_set_input(form->Subcaption, subcaption.c_str());
  1047.     if(current_view->currentBuffer()->isReadonly()) 
  1048.             DisableFigurePanel(form);
  1049.  
  1050.     TempRegenerate();
  1051. }
  1052.  
  1053.  
  1054. void InsetFig::Preview(char const *p)
  1055. {
  1056.     int pid;
  1057.  
  1058.      pid = fork();
  1059.  
  1060.       if (pid == -1) {
  1061.           lyxerr.print("Cannot fork process!");
  1062.           return;        // error
  1063.       }
  1064.       if (pid > 0) {
  1065.           procMgr.addpidwait(pid);
  1066.           return;        // parent process
  1067.       }
  1068.  
  1069.     LString buf1 = OnlyPath(owner->getFileName());
  1070.     LString buf2 = MakeAbsPath(p, buf1);
  1071.     
  1072.     lyxerr.print(LString("Error during rendering ") +
  1073.               int(execlp(lyxrc->view_pspic_command.c_str(),
  1074.                  lyxrc->view_pspic_command.c_str(),
  1075.                  buf2.c_str(), 
  1076.                  NULL)));
  1077.     _exit(0);
  1078. }
  1079.  
  1080.  
  1081. void InsetFig::BrowseFile()
  1082. {
  1083.     LString buf, buf2, bufclip;
  1084.     static LString current_figure_path;
  1085.     static int once = 0;
  1086.     LyXFileDlg fileDlg;
  1087.  
  1088.     if (lyxerr.debugging()) {
  1089.         printf("Filename: %s\n", owner->getFileName().c_str());
  1090.     }
  1091.     LString p = fl_get_input(form->EpsFile);
  1092.  
  1093.     buf = MakeAbsPath(owner->getFileName());
  1094.     buf2 = OnlyPath(buf);
  1095.     if (!p.empty()) {
  1096.         buf = MakeAbsPath(p, buf2);
  1097.         buf = OnlyPath(buf);
  1098.     } else {
  1099.       buf = OnlyPath(owner->getFileName().c_str());
  1100.     }
  1101.     
  1102.     // Does user clipart directory exist?
  1103.     bufclip = AddName (user_lyxdir, "clipart");    
  1104.     FileInfo fileInfo(bufclip);
  1105.     if (!(fileInfo.isOK() && fileInfo.isDir()))
  1106.       // No - bail out to system clipart directory
  1107.       bufclip = AddName (system_lyxdir, "clipart");    
  1108.  
  1109.  
  1110.     fileDlg.SetButton(0, _("Clipart"), bufclip); 
  1111.     fileDlg.SetButton(1, _("Document"), buf); 
  1112.  
  1113.     bool error = false;
  1114.     do {
  1115.  
  1116.         ProhibitInput();
  1117.         if (once) {
  1118.             p =fileDlg.Select(_("EPS Figure"), current_figure_path,
  1119.                        "*ps", LString());
  1120.         } else {
  1121.             p = fileDlg.Select(_("EPS Figure"), buf,
  1122.                        "*ps", LString());
  1123.         }
  1124.         AllowInput();
  1125.  
  1126.         if (p.empty()) return;
  1127.  
  1128.         buf = MakeRelPath(p, buf2);
  1129.         current_figure_path = OnlyPath(p);
  1130.         once = 1;
  1131.         
  1132.         if (p.contains("#") || p.contains("~") || p.contains("$")
  1133.             || p.contains("%") || p.contains(" ")) 
  1134.         {
  1135.             WriteAlert(_("Filename can't contain any of these characters:"),
  1136.                    _("space, '#', '~', '$' or '%'."));
  1137.             error = true;
  1138.         }
  1139.     } while (error);
  1140.  
  1141.     if (form) fl_set_input(form->EpsFile, buf.c_str());
  1142. }
  1143.  
  1144.  
  1145. void GraphicsCB(FL_OBJECT *obj, long arg)
  1146. {
  1147.     /* obj->form contains the form */
  1148.  
  1149.     if (lyxerr.debugging()) {
  1150.         printf("GraphicsCB callback: %ld\n", arg);
  1151.     }
  1152.  
  1153.     /* find inset we were reacting to */
  1154.     for (int i = 0; i < figL.figinsref; ++i)
  1155.         if (figL.figures[i]->inset->form && figL.figures[i]->inset->form->Figure
  1156.             == obj->form) {
  1157.         
  1158.             if (lyxerr.debugging()) {
  1159.                 printf("Calling back figure %d\n", i);
  1160.             }
  1161.             figL.figures[i]->inset->CallbackFig(arg);
  1162.             return;
  1163.         }
  1164. }
  1165.  
  1166. static char* NextToken(FILE *myfile)
  1167. {
  1168.     char* token = NULL;
  1169.     char c;
  1170.     int i = 0;
  1171.    
  1172.     if (!feof(myfile)) {
  1173.         token = new char[256];
  1174.         do {
  1175.             c = fgetc(myfile);
  1176.             token[i++]=c;
  1177.         } while (!feof(myfile) && !isspace(c));
  1178.       
  1179.         token[i-1]='\0';         /* just the end of a command  */
  1180.     }
  1181.     return token;
  1182. }
  1183.