/* Rework of path-handling (Matthias 04.07.1996 ) * ------------------------------------------------ * figinsets keep an absolute path to the eps-file. * For the user alway a relative path appears * (in lyx-file, latex-file and edit-popup). * To calculate this relative path the path to the * document where the figinset is in is needed. * This is done by a reference to the buffer, called * figinset::cbuffer. To be up to date the cbuffer * is sometimes set to the current buffer * bufferlist.current(), when it can be assumed that * this operation happens in the current buffer. * This is true for InsetFig::Edit(...), * InsetFig::InsetFig(...), InsetFig::Read(...), * InsetFig::Write and InsetFig::Latex(...). * Therefore the bufferlist has to make sure that * during these operations bufferlist.current() * returns the buffer where the figinsets are in. * This made few changes in buffer.C necessary. * * The above is not totally valid anymore. (Lgb)
*/
externchar **environ; // is this only redundtant on linux systems? Lgb. externvoid UpdateInset(Inset* inset, bool mark_dirty = true); // better for asyncron updating: void PutInsetIntoInsetUpdateList(Inset* inset); externvoid ProhibitInput(); externvoid AllowInput();
staticint figinsref = 0; /* number of figures */ staticint figarrsize = 0; /* current max number of figures */ staticint bmpinsref = 0; /* number of bitmaps */ staticint bmparrsize = 0; /* current max number of bitmaps */
struct queue { float rx, ry; /* resolution x and y */ int ofsx, ofsy; /* x and y translation */
figdata *data; /* we are doing it for this data */
queue *next; /* next item in queue */
};
struct pidwait { int pid; /* pid to wait for */
pidwait *next; /* next */
};
#define MAXGS 3 /* maximum 3 gs's at a time */
static Figref **figures; /* all the figures */ static figdata **bitmaps; /* all the bitmaps */ static queue *gsqueue = NULL; /* queue for ghostscripting */ staticint gsrunning = 0; /* currently so many gs's are running */ staticbool bitmap_waiting = false; /* bitmaps are waiting finished */ staticchar bittable[256]; /* bit reversion table */
staticbool gs_color; // do we allocate colors for gs? staticbool gs_xcolor = false; // allocated extended colors staticunsignedlong gs_pixels[128]; // allocated pixels staticint gs_num_pixels; // number of pixels allocated staticint gs_spc; // shades per color staticbool gs_gray; // is grayscale? staticint gs_allcolors; // number of all colors
// just kill gs, that way it will work for sure for (i = 0; i < bmpinsref; ++i) if ((long)bitmaps[i]->bitmap == (long)e->data.l[1]) { // found the one
figdata *p = bitmaps[i];
p->gsdone = true;
// first update p->bitmap, if necessary if (p->bitmap != None && 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, y, wid1, spc1 = gs_spc-1,
spc2 = gs_spc*gs_spc, wid = p->wid,
forkstat;
Display *tmpdisp;
GC gc = getGC(gc_copy);
XGetWindowAttributes(fl_display, fl_get_canvas_id(
figinset_canvas), &wa);
XFlush(fl_display); if (lyxerr.debugging()) {
fprintf(stderr, "Starting image translation %ld %d %dx%d %d %d\n",
p->bitmap, p->flags, p->wid, p->hgh, wa.depth,
XYPixmap);
} // now fork rendering process
forkstat = fork(); if (forkstat == -1) {
lyxerr.debug("Cannot fork, using slow " "method for pixmap translation.");
tmpdisp = fl_display;
} elseif (forkstat > 0) { // register child if (lyxerr.debugging()) {
lyxerr.print(
LString("Spawned child ")
+ int(forkstat));
}
addpidwait(forkstat); break; // in parent process
} else {
tmpdisp = XOpenDisplay(XDisplayName(NULL));
XFlush(tmpdisp);
}
im = XGetImage(tmpdisp, p->bitmap, 0, 0,
p->wid, p->hgh, (1<<wa.depth)-1, XYPixmap);
XFlush(tmpdisp); if (lyxerr.debugging()) {
lyxerr.print("Got the image");
} if (!im) { if (lyxerr.debugging()) {
lyxerr.print("Error getting the image");
} goto noim;
} // query current colormap
cmap = (XColor *) malloc(gs_allcolors*sizeof(XColor)); for (i = 0; i < gs_allcolors; ++i) cmap[i].pixel = i;
XQueryColors(tmpdisp, color_map, cmap, gs_allcolors);
XFlush(tmpdisp);
wid1 = p->wid - 1; // now we process all the image for (y = 0; y < p->hgh; ++y) { registerint x; for (x = 0; x < wid; ++x) { register XColor* pc;
pc = cmap + XGetPixel(im, x, y);
XFlush(tmpdisp);
XPutPixel(im, x, y, gs_pixels[((pc->red+6553)*
spc1/65535)*spc2+((pc->green+6553)*
spc1/65535)*gs_spc+((pc->blue+6553)*
spc1/65535)]);
XFlush(tmpdisp);
}
} if (lyxerr.debugging()) {
lyxerr.print("Putting image back");
}
XPutImage(tmpdisp, p->bitmap, gc, im, 0, 0,
0, 0, p->wid, p->hgh);
XDestroyImage(im); if (lyxerr.debugging()) {
lyxerr.print("Done translation");
}
noim: if (lyxerr.debugging()) {
lyxerr.print(LString("Killing gs ")
+ int(p->gspid));
}
kill(p->gspid, SIGHUP);
// now we have to init color_map if (!color_map) color_map = DefaultColormap(fl_display,
DefaultScreen(fl_display)); // allocate color cube on pseudo-color display // first get visual
gs_color = false;
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);
} 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;
}
if (gs_color) {
lyxerr.debug("Freeing up the colors...");
XFreeColors(fl_display, color_map, gs_pixels,
gs_num_pixels, 0); /******????????????????? what's planes in this case ??????***/
}
}
int FindBmpIndex(figdata *tmpdata)
{ int i = 0; while (i < bmpinsref) { if (bitmaps[i] == tmpdata) return i;
++i;
} return i;
}
// here read the pixmap and change all colors to those we // have allocated
XCloseDisplay(tempdisp);
}
staticvoid freefigdata(figdata *tmpdata)
{ int i;
tmpdata->ref--; if (tmpdata->ref) return;
if (tmpdata->gspid > 0) { int pid = tmpdata->gspid; char buf[128]; // change Pixmap according to our allocated colormap
chpixmap(tmpdata->bitmap, tmpdata->wid, tmpdata->hgh); // kill ghostscript and unlink it's files
tmpdata->gspid = -1;
kill(pid, SIGKILL);
sprintf(buf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), pid);
unlink(buf);
}
if (tmpdata->bitmap) XFreePixmap(fl_display, tmpdata->bitmap); delete tmpdata;
i = FindBmpIndex(tmpdata);
--bmpinsref; while (i < bmpinsref) {
bitmaps[i] = bitmaps[i+1];
++i;
}
}
staticvoid runqueue()
{ // run queued requests for ghostscript, if any if (!gsrunning && gs_color && !gs_xcolor) { // here alloc all colors, so that gs will use only // those we allocated for it // *****
gs_xcolor = true;
}
while (gsrunning < MAXGS) {
queue *p; int pid; char tbuf[384], tbuf2[80];
Atom *prop; int nprop, i;
if (!gsqueue) { if (!gsrunning && gs_xcolor) { // de-allocate rest of colors // *****
gs_xcolor = false;
} return;
}
p = gsqueue;
if (!p->data) { delete p; continue;
}
pid = fork();
if (pid == -1) { if (lyxerr.debugging()) {
lyxerr.print("GS start error! Cannot fork.");
}
p->data->broken = true;
p->data->reading = false; return;
} if (pid == 0) { // child char **env, rbuf[80], gbuf[40]; int ne = 0;
Display* tempdisp = XOpenDisplay(XDisplayName(NULL));
// DON'T EVER remove this!!
f.close(); // was this all? (Lgb)
// gs process - set ghostview environment first
sprintf(tbuf2, "GHOSTVIEW=%ld %ld", 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); //#warning BUG seems that the only bug here might be the hardcoded dpi.. Bummer!
if (lyxerr.debugging()) {
lyxerr.print(LString("Will set GHOSTVIEW" " property to [") +
tbuf + "]");
} // wait until property is deleted if executing multiple // ghostscripts for (;;) { // grab server to prevent other child interfering // with setting GHOSTVIEW property if (lyxerr.debugging()) {
lyxerr.print("Grabbing the server");
}
XGrabServer(tempdisp);
prop = XListProperties(tempdisp, fl_get_canvas_id(
figinset_canvas), &nprop); if (!prop) break;
bool err = true; for (i = 0; i < nprop; ++i) { char *p = XGetAtomName(tempdisp, prop[i]); if (strcmp(p, "GHOSTVIEW") == 0) {
err = false; break;
}
XFree(p);
}
XFree((char *)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()) {
lyxerr.print("Releasing the server");
lyxerr.print(LString('[') + int(getpid()) + "] GHOSTVIEW property" " found. Waiting.");
} #ifdef WITH_WARNINGS #warning What is this doing? (wouldn't a sleep(1); work too?') #endif
alarm(1);
alarmed = false;
signal(SIGALRM, waitalarm); while (!alarmed) pause();
}
// set up environment while (environ[ne]) ++ne;
env = (char **) malloc(sizeof(char*)*(ne+2));
env[0] = tbuf2;
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); // now chdir into dir with .eps file, to be on the safe // side
chdir(OnlyPath(p->data->fname).c_str()); // make temp file name
sprintf(tbuf, "%s/~lyxgs%d.ps", system_tempdir.c_str(), int(getpid())); if (lyxerr.debugging()) {
printf("starting gs %s %s, pid: %d\n", tbuf,
p->data->fname.c_str(), int(getpid()));
}
int err = execlp(lyxrc->ps_command.c_str(),
lyxrc->ps_command.c_str(), "-sDEVICE=x11", "-dNOPAUSE", "-dQUIET", "-dSAFER",
rbuf, gbuf, tbuf,
p->data->fname.c_str(), "showpage.ps", "quit.ps", "-", NULL); // if we are still there, an error occurred.
lyxerr.print(LString("Error executing ghostscript. ")
+"Code: "+err);
lyxerr.debug("Cmd: "
+ lyxrc->ps_command
+" -sDEVICE=x11 "
+ tbuf + LString(' ')
+ p->data->fname);
_exit(0); // no gs?
} // normal process (parent) if (lyxerr.debugging()) {
lyxerr.print(LString("GS [") + int(pid) + "] started");
}
gsqueue = gsqueue->next;
gsrunning++;
p->data->gspid = pid; delete p;
}
}
staticvoid addwait(int psx, int psy, int pswid, int pshgh, figdata *data)
{ // recompute the stuff and put in the queue
queue *p, *p2;
p = new queue;
p->ofsx = psx;
p->ofsy = psy;
p->rx = ((float)data->raw_wid*72)/pswid;
p->ry = ((float)data->raw_hgh*72)/pshgh;
p->data = data;
p->next = NULL;
// now put into queue
p2 = gsqueue; if (!gsqueue) gsqueue = p; else { while (p2->next) p2 = p2->next;
p2->next = p;
}
// if possible, run the queue
runqueue();
}
static figdata *getfigdata(int wid, int hgh, LString const & fname, 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 */ int i = 0;
figdata *p;
XWindowAttributes wa;
if (fname.empty()) return NULL;
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];
}
++i;
} /* not found -> create new record or return NULL if no record */
++bmpinsref; if (bmpinsref > bmparrsize) { // allocate more space
bmparrsize += figallocchunk;
figdata **tmp = (figdata**) malloc(sizeof(figdata*)*bmparrsize);
memcpy(tmp, bitmaps, sizeof(figdata*)*(bmparrsize-figallocchunk));
free(bitmaps);
bitmaps = tmp;
}
p = new figdata;
bitmaps[bmpinsref-1] = p;
p->wid = wid;
p->hgh = hgh;
p->raw_wid = raw_wid;
p->raw_hgh = raw_hgh;
p->angle = angle;
p->fname = fname;
p->flags = flags;
XGetWindowAttributes(fl_display, fl_get_canvas_id(
figinset_canvas), &wa);
for (i = 0; i < figinsref; ++i) if (figures[i]->data == p) { if (lyxerr.debugging()) {
printf("Updating inset %d\n",
PTR_AS_INT(figures[i]->inset));
} //UpdateInset(figures[i]->inset); // add inset figures[i]->inset into to_update list
PutInsetIntoInsetUpdateList(figures[i]->inset);
}
}
void sigchldchecker(pid_t pid, int *status)
{ int i;
figdata *p;
bool pid_handled = false;
lyxerr.debug(LString("Got pid = ") + long (pid));
pid_handled = false; for (i = bmpinsref - 1; i >= 0; --i) { if (bitmaps[i]->reading && pid == bitmaps[i]->gspid) {
lyxerr.debug("Found pid in bitmaps"); // now read the file and remove it from disk
p = bitmaps[i];
p->reading = false; if (bitmaps[i]->gsdone) *status = 0; if (*status == 0) {
lyxerr.debug(LString("GS [") + int(pid) + "] exit OK.");
} else {
fprintf(stderr, "GS [%ld] error %d E:%d %d S:%d %d\n", long(pid),
*status, WIFEXITED(*status), WEXITSTATUS(*status),
WIFSIGNALED(*status), WTERMSIG(*status));
} if (*status == 0) {
bitmap_waiting = true;
p->broken = false;
} else { // remove temporary files char tmp[128];
sprintf(tmp, "%s/~lyxgs%d.ps",
system_tempdir.c_str(),
p->gspid);
unlink(tmp);
p->gspid = -1;
p->broken = true;
}
makeupdatelist(bitmaps[i]);
gsrunning--;
runqueue();
pid_handled = true;
}
} if (!pid_handled) {
lyxerr.debug("Checking pid in pidwait");
pidwait *p = pw, *prev = NULL; while (p) { if (pid == p->pid) {
lyxerr.debug("Found pid in pidwait");
lyxerr.debug(LString("Caught child pid of recompute routine ") + int(pid)); if (prev)
prev->next = p->next; else
pw = p->next;
free(p); break;
}
prev = p;
p = p->next;
}
}
if (pid == -1) {
lyxerr.debug("waitpid error"); switch (errno) { case ECHILD:
lyxerr.print( "The process or process group specified by pid " "does not exist or is not a child of the cal-" "ling process or can never be in the states " "specified by options."); break; case EINTR:
lyxerr.print( "waitpid() was interrupted due to the receipt " "of a signal sent by the calling process."); break; case EINVAL:
lyxerr.print( "An invalid value was specified for options."); break; default:
lyxerr.print("Unknown error from waitpid"); break;
}
} elseif (pid == 0) {
lyxerr.print("waitpid nohang");
} else {
lyxerr.debug("normal exit from childhandler");
}
}
staticvoid getbitmaps()
{ int i;
bitmap_waiting = false; for (i = 0; i < bmpinsref; ++i) if (bitmaps[i]->gspid > 0 && !bitmaps[i]->reading)
getbitmap(bitmaps[i]);
}
int InsetFig::Ascent(LyXFont const&) const
{ return hgh + 3;
}
int InsetFig::Descent(LyXFont const&) const
{ return 1;
}
int InsetFig::Width(LyXFont const&) const
{ return wid + 2;
}
void InsetFig::Draw(LyXFont font, LyXScreen &scr, int baseline, float &x)
{ if (bitmap_waiting) getbitmaps();
// I wish that I didn't have to use this // but the figinset code is so complicated so // I don't want to fiddle with it now. unsignedlong pm = scr.getForeground();
// We should have RO-versions of the form instead. // The actual prevention of altering a readonly doc // is done in CallbackFig() if(current_view->currentBuffer()->isReadonly())
WarnReadonly();
if (!form) {
form = create_form_Figure();
fl_set_form_atclose(form->Figure, CancelCloseBoxCB, NULL);
fl_set_object_return(form->Angle,FL_RETURN_ALWAYS);
fl_set_object_return(form->Width,FL_RETURN_ALWAYS);
fl_set_object_return(form->Height,FL_RETURN_ALWAYS);
}
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"));
}
}
Inset *InsetFig::Clone()
{
InsetFig *tmp = new InsetFig(100, 100, owner);
if (lyxerr.debugging()) {
fprintf(stderr, "Clone Figure: buffer:[%d], cbuffer:[xx]\n",
PTR_AS_INT(current_view->currentBuffer()));
}
/* 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()) { // say, total width is 595 pts, as A4 in TeX, thats in 1/72" */
newx = frame_wid;
newy = frame_hgh; switch (wtype) { case DEF: break; case CM: /* cm */
newx = (int) (28.346*xwid); break; case IN: /* in */
newx = (int) (72*xwid); break; case PER_PAGE: /* % of page */
newx = (int) (5.95*xwid); break; case PER_COL: /* % of col */
newx = (int) (2.975*xwid); break;
}
if (wtype && frame_wid) newy = newx*frame_hgh/frame_wid;
switch (htype) { case DEF: //fprintf(stderr, "This should not happen!\n"); break; case CM: /* cm */
newy = (int) (28.346*xhgh); break; case IN: /* in */
newy = (int) (72*xhgh); break; case PER_PAGE: /* % of page */
newy = (int) (8.42*xhgh); break; case PER_COL: // Doesn't occur; case exists to suppress // compiler warnings. break;
} if (htype && !wtype && frame_hgh) newx = newy*frame_wid/frame_hgh;
} else {
newx = wid;
newy = hgh;
}
// get new data if (!fname.empty() && (flags & 3) && !lyxrc->ps_command.empty()) { // do not display if there is "do not display" // chosen (Matthias 260696)
figure->data = getfigdata(wid, hgh, fname,
psx, psy, pswid, pshgh,
raw_wid, raw_hgh,
angle, flags & (3|8));
} else figure->data = NULL;
// free the old data if (pf) freefigdata(pf);
}
changedfname = false;
}
void InsetFig::GetPSSizes()
{ /* get %%BoundingBox: from postscript file */ int lastchar, c; char *p = NULL;
/* defaults to associated size * ..just in case the PS-file is not readable (Henner,24-Aug-97)
*/
psx = 0;
psy = 0;
pswid = wid;
pshgh = hgh;
if (lyxerr.debugging()) {
printf("Figure callback, arg %ld\n", arg);
}
switch (arg) { case 10: case 11: case 12: /* width type */ case 13: case 14: switch (arg - 10) { case DEF:
twtype = DEF; // put disable here
fl_deactivate_object(form->Width); break; case CM:
twtype = CM; // put enable here
fl_activate_object(form->Width); break; case IN:
twtype = IN; // put enable here
fl_activate_object(form->Width); break; case PER_PAGE:
twtype = PER_PAGE; // put enable here
fl_activate_object(form->Width); break; case PER_COL:
twtype = PER_COL; // put enable here
fl_activate_object(form->Width); break; default:
lyxerr.debug("Unknown type!"); break;
}
regen = true; break; case 20: case 21: case 22: /* height type */ case 23: switch (arg - 20) { case DEF:
thtype = DEF; // put disable here
fl_deactivate_object(form->Height); break; case CM:
thtype = CM; // put enable here
fl_activate_object(form->Height); break; case IN:
thtype = IN; // put enable here
fl_activate_object(form->Height); break; case PER_PAGE:
thtype = PER_PAGE; // put enable here
fl_activate_object(form->Height); break; default:
lyxerr.debug("Unknown type!"); break;
}
regen = true; break; case 3:
pflags = pflags & ~3; /* wysiwyg0 */ break; case 33:
pflags = (pflags & ~3) | 1; /* wysiwyg1 */ break; case 43:
pflags = (pflags & ~3) | 2; /* wysiwyg2 */ break; case 63:
pflags = (pflags & ~3) | 3; /* wysiwyg3 */ break; case 53:
pflags ^= 4; /* frame */ break; case 54:
pflags ^= 8; /* do translations */ break; case 70:
psubfigure = !psubfigure; /* This is a subfigure */ break; case 2:
regen = true; /* regenerate command */ break; case 0: /* browse file */
BrowseFile();
regen = true; break; case 1: /* preview */
p = fl_get_input(form->EpsFile);
Preview(p); break; case 7: /* apply */ case 8: /* ok (apply and close) */ if(!current_view->currentBuffer()->isReadonly())
{
wtype = twtype;
htype = thtype;
xwid = atof(fl_get_input(form->Width));
xhgh = atof(fl_get_input(form->Height));
angle = atof(fl_get_input(form->Angle));
p = fl_get_input(form->EpsFile); if (p && *p) {
LString buf1 = OnlyPath(owner->getFileName());
fname = MakeAbsPath(p, buf1);
changedfname = true;
} else { if (!fname.empty()) {
changedfname = true;
fname.clean();
}
}
subcaption = fl_get_input(form->Subcaption);
Regenerate();
Recompute(); /* now update inset */ if (lyxerr.debugging()) {
fprintf(stderr, "Update: [%dx%d]\n", wid, hgh);
}
UpdateInset(this); if (arg == 8) {
fl_hide_form(form->Figure);
fl_free_form(form->Figure);
free(form);
form = NULL;
} break;
} //if not readonly // The user has already been informed about RO in ::Edit if(arg == 7) // if 'Apply' break; // fall through case 9: /* cancel = restore and close */
fl_hide_form(form->Figure);
fl_free_form(form->Figure);
free(form);
form = NULL; break;
}
// Does user clipart directory exist?
bufclip = AddName (user_lyxdir, "clipart");
FileInfo fileInfo(bufclip); if (!(fileInfo.isOK() && fileInfo.isDir())) // No - bail out to system clipart directory
bufclip = AddName (system_lyxdir, "clipart");
bool error = false; do {
ProhibitInput(); if (once) {
p =fileDlg.Select(_("EPS Figure"), current_figure_path, "*ps", LString());
} else {
p = fileDlg.Select(_("EPS Figure"), buf, "*ps", LString());
}
AllowInput();
if (p.empty()) return;
buf = MakeRelPath(p, buf2);
current_figure_path = OnlyPath(p);
once = 1;
if (p.contains("#") || p.contains("~") || p.contains("$")
|| p.contains("%") || p.contains(" "))
{
WriteAlert(_("Filename can't contain any of these characters:"),
_("space, '#', '~', '$' or '%'."));
error = true;
}
} while (error);
if (form) fl_set_input(form->EpsFile, buf.c_str());
}
void GraphicsCB(FL_OBJECT *obj, long arg)
{ /* obj->form contains the form */
if (lyxerr.debugging()) {
lyxerr.print(LString("GraphicsCB callback: ") + 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
== obj->form) {
if (lyxerr.debugging()) {
lyxerr.print(LString("Calling back figure ")
+int(i));
}
figures[i]->inset->CallbackFig(arg); return;
}
}
void HideFiguresPopups()
{ for (int i = 0; i < figinsref; ++i) if (figures[i]->inset->form
&& figures[i]->inset->form->Figure->visible) { if (lyxerr.debugging()) {
lyxerr.print(LString("Hiding figure ")
+int(i));
} // hide and free the form
figures[i]->inset->CallbackFig(9);
}
}
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.