]> git.lyx.org Git - lyx.git/blob - src/lyx_cb.C
17dc46664a409d315259ec797e9b0fc23c3d19de
[lyx.git] / src / lyx_cb.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich,
7  *          Copyright 1995-1999 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #include <cctype>
14 #include <unistd.h>
15 #include <csignal>
16 #include <cstring>
17 #include <cstdlib>
18
19 #include "LString.h"
20 #include "support/lstrings.h"
21 #include "lyx_main.h"
22 #include FORMS_H_LOCATION
23 #include "lyx.h"
24 #include "layout_forms.h"
25 #include "bullet_forms.h"
26 #include "print_form.h"
27 #include "form1.h"
28 #include "spellchecker.h"
29 #include "version.h"
30 #include "lyx_cb.h"
31 #include "credits.h"
32 #include "insets/insetref.h"
33 #include "insets/insetquotes.h"
34 #if 0
35 #include "insets/insetlatex.h"
36 #endif
37 #include "insets/insetlabel.h"
38 #include "insets/insetinfo.h"
39 #include "insets/insetspecialchar.h"
40 #include "insets/figinset.h"
41 #include "lyxfunc.h"
42 #include "latexoptions.h"
43 #include "lyxfont.h"
44 #include "minibuffer.h"
45 #include "combox.h"
46 #include "bufferlist.h"
47 #include "support/filetools.h"
48 #include "support/path.h"
49 #include "filedlg.h"
50 #include "lyx_gui_misc.h"
51 #include "LyXView.h" // only because of form_main
52 #include "lastfiles.h"
53 #include "support/FileInfo.h"
54 #include "lyxscreen.h"
55 #include "debug.h"
56 #include "support/syscall.h"
57 #include "support/lyxlib.h"
58 #include "lyxserver.h"
59 #include "FontLoader.h"
60 #include "lyxrc.h"
61 #include "lyxtext.h"
62 #include "gettext.h"
63 #include "layout.h"
64
65 extern MiniBuffer * minibuffer;
66 extern Combox * combo_language;
67 extern BufferList bufferlist;
68 extern void show_symbols_form();
69 extern FD_form_main * fd_form_main;
70 extern FD_form_title * fd_form_title;
71 extern FD_form_paragraph * fd_form_paragraph;
72 extern FD_form_character * fd_form_character;
73 extern FD_form_document * fd_form_document;
74 extern FD_form_quotes * fd_form_quotes;
75 extern FD_form_preamble * fd_form_preamble;
76 extern FD_form_table * fd_form_table;
77 extern FD_form_print * fd_form_print;
78 extern FD_form_figure * fd_form_figure;
79 extern FD_form_screen * fd_form_screen;
80 extern FD_form_toc * fd_form_toc;
81 extern FD_form_ref * fd_form_ref;
82 extern FD_LaTeXOptions * fd_latex_options;
83 extern FD_form_bullet * fd_form_bullet;
84
85 extern BufferView * current_view; // called too many times in this file...
86
87 extern void DeleteSimpleCutBuffer(); /* for the cleanup when exiting */
88
89 extern bool send_fax(string const & fname, string const & sendcmd);
90
91 extern LyXServer * lyxserver;
92 extern FontLoader fontloader;
93
94 // this should be static, but I need it in buffer.C
95 bool quitting;  // flag, that we are quitting the program
96 extern bool finished; // all cleanup done just let it run through now.
97
98 char ascii_type; /* for selection notify callbacks */
99
100 bool scrolling = false;
101
102 char updatetimer = 0;
103
104 /* whether the work area should get callbacks */ 
105 bool input_prohibited = false;
106
107 /* the selection possible is needed, that only motion events are 
108 * used, where the bottom press event was on the drawing area too */
109 bool selection_possible = false;
110
111 // This is used to make the dreaded font toggle problem hopefully go
112 // away. Definitely not the best solution, but I think it sorta works.
113 bool toggleall = true;
114
115 void InsertCorrectQuote();
116
117
118 /* 
119    This is the inset locking stuff needed for mathed --------------------
120
121    an inset can simple call LockInset in it's edit call and *ONLY* in it's
122    edit call.
123    Inset::Edit() can only be called by the main lyx module.
124
125    Then the inset may modify the menu's and/or iconbars. 
126
127    Unlocking is either done by LyX or the inset itself with a UnlockInset-call
128
129    During the lock, all button and keyboard events will be modified
130    and send to the inset through the following inset-features. Note that
131    Inset::InsetUnlock will be called from inside UnlockInset. It is meant
132    to contain the code for restoring the menus and things like this.
133
134    
135    virtual void InsetButtonPress(int x, int y, int button);
136    virtual void InsetButtonRelease(int x, int y, int button);
137    virtual void InsetKeyPress(XKeyEvent *ev);
138    virtual void InsetMotionNotify(int x, int y, int state);
139    virtual void InsetUnlock();
140
141    If a inset wishes any redraw and/or update it just has to call
142    UpdateInset(this).
143    It's is completly irrelevant, where the inset is. UpdateInset will
144    find it in any paragraph in any buffer. 
145    Of course the_locking_inset and the insets in the current paragraph/buffer
146    are checked first, so no performance problem should occur.
147    
148    Hope that's ok for the beginning, Alejandro,
149    sorry that I needed so much time,
150
151                   Matthias
152    */
153
154 void UpdateInset(Inset * inset, bool mark_dirty = true);
155 /* these functions return 1 if an error occured, 
156    otherwise 0 */
157 // Now they work only for updatable insets. [Alejandro 080596]
158 int LockInset(UpdatableInset * inset);
159 void ToggleLockedInsetCursor(long x, long y, int asc, int desc);
160 void FitLockedInsetCursor(long x, long y, int asc, int desc);
161 int UnlockInset(UpdatableInset * inset);
162 void LockedInsetStoreUndo(Undo::undo_kind kind);
163
164 /* this is for asyncron updating. UpdateInsetUpdateList will be called
165    automatically from LyX. Just insert the Inset into the Updatelist */
166 void UpdateInsetUpdateList();
167 void PutInsetIntoInsetUpdateList(Inset * inset);
168
169 InsetUpdateStruct * InsetUpdateList = 0;
170
171
172 /*
173   -----------------------------------------------------------------------
174  */
175
176 /* some function prototypes */
177
178 void GotoNote();
179 void OpenStuff();
180 void ToggleFloat();
181 void MenuUndo();
182 void MenuRedo();
183 void HyphenationPoint();
184 void MenuSeparator();
185 void HFill();
186 void Newline();
187 void ProtectedBlank();
188 void CopyCB();
189 int RunLinuxDoc(int, string const &);
190 int RunDocBook(int, string const &);
191 void MenuWrite(Buffer * buf);
192 void MenuWriteAs(Buffer * buffer);
193 void MenuReload(Buffer * buf);
194 void MenuLayoutSave();
195
196 unsigned char GetCurrentTextClass()
197         // Who are we asking?
198         // Shouldn't this question be directed to the buffer?
199         // Indeed it should. Asger.
200 {
201         return current_view->buffer()->params.textclass;
202 }
203
204
205 // How should this actually work? Should it prohibit input in all BufferViews,
206 // or just in the current one? If "just the current one", then it should be
207 // placed in BufferView. If "all BufferViews" then LyXGUI (I think) should
208 // run "ProhibitInput" on all LyXViews which will run prohibitInput on all
209 // BufferViews. Or is it perhaps just the (input in) BufferViews in the
210 // current LyxView that should be prohibited (Lgb) (This applies to
211 // "AllowInput" as well.)
212 void ProhibitInput()
213 {
214         input_prohibited = true;
215         if (current_view->getScreen())
216                 current_view->getScreen()->HideCursor();
217
218         static Cursor cursor;
219         static bool cursor_undefined = true;
220    
221         if (cursor_undefined){
222                 cursor = XCreateFontCursor(fl_display, XC_watch);
223                 XFlush(fl_display);
224                 cursor_undefined = false;
225         }
226    
227         /* set the cursor to the watch for all forms and the canvas */ 
228         XDefineCursor(fl_display, fd_form_main->form_main->window, cursor);
229         if (fd_form_paragraph->form_paragraph->visible)
230                 XDefineCursor(fl_display,
231                               fd_form_paragraph->form_paragraph->window,
232                               cursor);
233         if (fd_form_character->form_character->visible)
234                 XDefineCursor(fl_display,
235                               fd_form_character->form_character->window,
236                               cursor);
237
238         XFlush(fl_display);
239         fl_deactivate_all_forms();
240 }
241
242
243 // Should find a way to move this into BufferView.C
244 void SetXtermCursor(Window win)
245 {
246         static Cursor cursor;
247         static bool cursor_undefined = true;
248         if (cursor_undefined){
249                 cursor = XCreateFontCursor(fl_display, XC_xterm);
250                 XFlush(fl_display);
251                 cursor_undefined = false;
252         }
253         XDefineCursor(fl_display, win, cursor);
254         XFlush(fl_display);
255 }
256
257
258 void AllowInput()
259 {
260         input_prohibited = false;
261
262         /* reset the cursor from the watch for all forms and the canvas */
263    
264         XUndefineCursor(fl_display, fd_form_main->form_main->window);
265         if (fd_form_paragraph->form_paragraph->visible)
266                 XUndefineCursor(fl_display,
267                                 fd_form_paragraph->form_paragraph->window);
268         if (fd_form_character->form_character->visible)
269                 XUndefineCursor(fl_display,
270                                 fd_form_character->form_character->window);
271         if (current_view->getWorkArea()->belowmouse)
272                 SetXtermCursor(fd_form_main->form_main->window);
273
274         XFlush(fl_display);
275         fl_activate_all_forms();
276 }
277
278
279 void FreeUpdateTimer()
280 {
281         /* a real free timer would be better but I don't know 
282          * how to do this with xforms */
283         updatetimer = 0;
284 }
285
286
287 void SetUpdateTimer(float time)
288 {
289         fl_set_timer(fd_form_main->timer_update, time);
290         updatetimer = 1;
291 }
292
293
294 void BeforeChange()
295 {
296         current_view->getScreen()->ToggleSelection();
297         current_view->buffer()->text->ClearSelection();
298         FreeUpdateTimer();
299 }
300
301
302 void SmallUpdate(signed char f)
303 {
304         current_view->getScreen()->SmallUpdate();
305         if (current_view->getScreen()->TopCursorVisible()
306             != current_view->getScreen()->first){
307                 current_view->buffer()->update(f);
308                 return;
309         }
310
311         current_view->fitCursor();
312         current_view->updateScrollbar();
313    
314         if (!current_view->buffer()->text->selection)
315                 current_view->buffer()->text->sel_cursor = 
316                         current_view->buffer()->text->cursor;
317
318         if (f == 1 || f == -1) {
319                 if (current_view->buffer()->isLyxClean()) {
320                         current_view->buffer()->markDirty();
321                         minibuffer->setTimer(4);
322                 }
323                 else {
324                         current_view->buffer()->markDirty();
325                 }
326         }
327 }
328
329
330 //
331 // Menu callbacks
332 //
333
334 //
335 // File menu
336 //
337
338 // should be moved to lyxfunc.C
339 void MenuWrite(Buffer * buf)
340 {
341         XFlush(fl_display);
342         if (!bufferlist.write(buf)) {
343                 string fname = buf->getFileName();
344                 string s = MakeAbsPath(fname);
345                 if (AskQuestion(_("Save failed. Rename and try again?"),
346                                  MakeDisplayPath(s, 50),
347                                  _("(If not, document is not saved.)"))) {
348                         MenuWriteAs(buf);
349                 }
350         } else {
351                 lastfiles->newFile(buf->getFileName());
352         }
353 }
354
355
356 // should be moved to BufferView.C
357 void MenuWriteAs(Buffer * buffer)
358 {
359         if (!buffer->text) return;
360
361         string fname = buffer->getFileName();
362         string oldname = fname;
363         LyXFileDlg fileDlg;
364
365         ProhibitInput();
366         fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
367         fileDlg.SetButton(1, _("Templates"), lyxrc->template_path);
368
369         if (!IsLyXFilename(fname))
370                 fname += ".lyx";
371
372         fname = fileDlg.Select(_("Enter Filename to Save Document as"), 
373                                OnlyPath(fname),
374                                "*.lyx", 
375                                OnlyFilename(fname));
376         AllowInput();
377
378         if (fname.empty()) {
379                 minibuffer->Set(_("Canceled."));
380                 return;
381         }
382
383         // Make sure the absolute filename ends with appropriate suffix
384         string s = MakeAbsPath(fname);
385         if (!IsLyXFilename(s))
386                 s += ".lyx";
387
388         // Same name as we have already?
389         if (s == oldname) {
390                 if (!AskQuestion(_("Same name as document already has:"),
391                                  MakeDisplayPath(s, 50),
392                                  _("Save anyway?")))
393                         return;
394                 // Falls through to name change and save
395         } 
396         // No, but do we have another file with this name open?
397         else if (bufferlist.exists(s)) {
398                 if (AskQuestion(_("Another document with same name open!"),
399                                 MakeDisplayPath(s, 50),
400                                 _("Replace with current document?")))
401                         {
402                                 bufferlist.close(bufferlist.getBuffer(s));
403
404                                 // Ok, change the name of the buffer, but don't save!
405                                 buffer->setFileName(s);
406                                 buffer->markDirty();
407
408                                 minibuffer->Set(_("Document renamed to '"),
409                                                 MakeDisplayPath(s),
410                                                 _("', but not saved..."));
411                         }
412                 return;
413         } // Check whether the file exists
414         else {
415                 FileInfo myfile(s);
416                 if (myfile.isOK() && !AskQuestion(_("Document already exists:"), 
417                                                   MakeDisplayPath(s, 50),
418                                                   _("Replace file?")))
419                         return;
420         }
421
422         // Ok, change the name of the buffer
423         buffer->setFileName(s);
424         buffer->markDirty();
425         // And save
426         // Small bug: If the save fails, we have irreversible changed the name
427         // of the document.
428         MenuWrite(buffer);
429 }    
430
431
432 int MenuRunLaTeX(Buffer * buffer)
433 {
434         int ret = 0;
435
436         if (buffer->isLinuxDoc())
437                 ret = RunLinuxDoc(1, buffer->getFileName());
438         else if (buffer->isLiterate())
439                 ret = buffer->runLiterate();
440         else if (buffer->isDocBook())
441                 ret = RunDocBook(1, buffer->getFileName());
442         else
443                 ret = buffer->runLaTeX();
444    
445         if (ret > 0) {
446                 string s;
447                 string t;
448                 if (ret == 1) {
449                         s = _("One error detected");
450                         t = _("You should try to fix it.");
451                 } else {
452                         s += tostr(ret);
453                         s += _(" errors detected.");
454                         t = _("You should try to fix them.");
455                 }
456                 WriteAlert(_("There were errors during the LaTeX run."), s, t);
457         }
458         return ret;
459 }
460
461
462 int MenuBuildProg(Buffer * buffer)
463 {
464         int ret = 0;
465         
466         if (buffer->isLiterate())
467                 ret = buffer->buildProgram();
468         else {
469                 string s = _("Wrong type of document");
470                 string t = _("The Build operation is not allowed in this document");
471                 WriteAlert(_("There were errors during the Build process."), s, t);
472                 return 1;
473         }
474         
475         if (ret > 0) {
476                 string s;
477                 string t;
478                 if (ret == 1) {
479                         s = _("One error detected");
480                         t = _("You should try to fix it.");
481                 } else {
482                         s += tostr(ret);
483                         s += _(" errors detected.");
484                         t = _("You should try to fix them.");
485                 }
486                 WriteAlert(_("There were errors during the Build process."), s, t);
487         }
488         return ret;
489 }
490
491
492 int MenuRunChktex(Buffer * buffer)
493 {
494         int ret;
495
496         if (buffer->isSGML()) {
497                 WriteAlert(_("Chktex does not work with SGML derived documents."));
498                 return 0;
499         } else 
500                 ret = buffer->runChktex();
501    
502         if (ret >= 0) {
503                 string s;
504                 string t;
505                 if (ret == 0) {
506                         s = _("No warnings found.");
507                 } else if (ret == 1) {
508                         s = _("One warning found.");
509                         t = _("Use 'Edit->Go to Error' to find it.");
510                 } else {
511                         s += tostr(ret);
512                         s += _(" warnings found.");
513                         t = _("Use 'Edit->Go to Error' to find them.");
514                 }
515                 WriteAlert(_("Chktex run successfully"), s, t);
516         } else {
517                 WriteAlert(_("Error!"), _("It seems chktex does not work."));
518         }
519         return ret;
520 }
521
522  
523 int MakeDVIOutput(Buffer * buffer)
524 {
525         if (!(buffer->text))
526                 return 1;
527
528         int ret = 0;
529
530         string path = OnlyPath(buffer->getFileName());
531         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)) {
532                 path = buffer->tmppath;
533         }
534         if (!buffer->isDviClean()) {
535                 Path p(path);
536                 ret = MenuRunLaTeX(buffer);
537         }
538         return ret;
539 }
540
541
542 /* wait == false means don't wait for termination */
543 /* wait == true means wait for termination       */
544 // The bool should be placed last on the argument line. (Lgb)
545 // Returns false if we fail.
546 bool RunScript(Buffer * buffer, bool wait,
547                string const & command,
548                string const & orgname = string(),
549                bool need_shell = true)
550 {
551         string path;
552         string cmd;
553         string name = orgname;
554         int result = 0;
555         
556         if (MakeDVIOutput(buffer) > 0)
557                 return false;
558         /* get DVI-Filename */
559         if (name.empty())
560                 name = ChangeExtension(buffer->getFileName(),
561                                        ".dvi", true);
562
563         path = OnlyPath(name);
564         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)) {
565                 path = buffer->tmppath;
566         }
567         Path p(path);
568
569         cmd = command + ' ' + SpaceLess(name);
570         Systemcalls one;
571
572         if (need_shell) {
573 #ifndef __EMX__
574                 if (!wait)
575                         cmd += " &";
576 #else
577                 // OS/2 cmd.exe has another use for '&'
578                 if (!wait) {
579                         // This is not NLS safe, but it's OK, I think.
580                         string sh = OnlyFilename(GetEnvPath("EMXSHELL"));
581                         if (sh.empty()) {
582                                 // COMSPEC is set, unless user unsets 
583                                 sh = OnlyFilename(GetEnvPath("COMSPEC"));
584                                 if (sh.empty())
585                                         sh = "cmd.exe";
586                         }
587                         sh = lowercase(sh);
588                         if (contains(sh, "cmd.exe")
589                             || contains(sh, "4os2.exe"))
590                                 cmd = "start /min/n " + cmd;
591                         else
592                                 cmd += " &";
593                 }
594 #endif
595                 // It seems that, if wait is false, we never get back
596                 // the return code of the command. This means that all
597                 // the code I added in PrintApplyCB is currently
598                 // useless...
599 #ifdef WITH_WARNINGS
600 #warning What should we do here?
601 #endif          
602                 minibuffer->Set(_("Executing command:"), cmd);
603                 result = one.startscript(Systemcalls::System, cmd);
604         } else {
605                 minibuffer->Set(_("Executing command:"), cmd);
606                 result = one.startscript(wait ? Systemcalls::Wait
607                                         : Systemcalls::DontWait, cmd);
608         }
609         return (result == 0);
610 }
611
612
613 // Returns false if we fail
614 bool MenuRunDvips(Buffer * buffer, bool wait = false)
615 {
616         if (!buffer->text)
617                 return false;
618
619         ProhibitInput();
620
621         // Generate dvi file
622         if (MakeDVIOutput(buffer) > 0) {
623                 AllowInput();
624                 return false;
625         }
626         // Generate postscript file
627         string ps = ChangeExtension (buffer->getFileName(),
628                                       ".ps_tmp", true);
629
630         string paper;
631         
632         char real_papersize = buffer->params.papersize;
633         if (real_papersize == BufferParams::PAPER_DEFAULT)
634                 real_papersize = lyxrc->default_papersize;
635
636         switch (real_papersize) {
637         case BufferParams::PAPER_USLETTER:
638                 paper = "letter";
639                 break;
640         case BufferParams::PAPER_A3PAPER:
641                 paper = "a3";
642                 break;
643         case BufferParams::PAPER_A4PAPER:
644                 paper = "a4";
645                 break;
646         case BufferParams::PAPER_A5PAPER:
647                 paper = "a5";
648                 break;
649         case BufferParams::PAPER_B5PAPER:
650                 paper = "b5";
651                 break;
652         case BufferParams::PAPER_EXECUTIVEPAPER:
653                 paper = "foolscap";
654                 break;
655         case BufferParams::PAPER_LEGALPAPER:
656                 paper = "legal";
657                 break;
658         default: /* If nothing else fits, keep an empty value... */
659                 break;
660         }
661
662         // Make postscript file.
663         string command = "dvips " + lyxrc->print_to_file + ' ';
664         command += SpaceLess(ps);
665         if (buffer->params.use_geometry
666             && buffer->params.papersize2 == BufferParams::VM_PAPER_CUSTOM
667             && !lyxrc->print_paper_dimension_flag.empty()
668             && !buffer->params.paperwidth.empty()
669             && !buffer->params.paperheight.empty()) {
670                 // using a custom papersize
671                 command += ' ';
672                 command += lyxrc->print_paper_dimension_flag + ' ';
673                 command += buffer->params.paperwidth + ',';
674                 command += buffer->params.paperheight;
675         } else if (!paper.empty()
676                    && (real_papersize != BufferParams::PAPER_USLETTER ||
677                        buffer->params.orientation == BufferParams::ORIENTATION_PORTRAIT)) {
678                 // dvips won't accept -t letter -t landscape.  In all other
679                 // cases, include the paper size explicitly.
680                 command += ' ';
681                 command += lyxrc->print_paper_flag + ' ' + paper;
682         }
683         if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE) {
684                 command += ' ';
685                 command += lyxrc->print_landscape_flag;
686         }
687         // push directorypath, if necessary 
688         string path = OnlyPath(buffer->getFileName());
689         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)){
690                 path = buffer->tmppath;
691         }
692         Path p(path);
693         bool ret = RunScript(buffer, wait, command);
694         AllowInput();
695         return ret;
696 }
697
698
699 // Returns false if we fail
700 bool MenuPreviewPS(Buffer * buffer)
701 {
702         if (!buffer->text)
703                 return false;
704
705         // Generate postscript file
706         if (!MenuRunDvips(buffer, true)) {
707                 return false;
708         }
709
710         // Start postscript viewer
711         ProhibitInput();
712         string ps = ChangeExtension (buffer->getFileName(),
713                                       ".ps_tmp", true);
714         // push directorypath, if necessary 
715         string path = OnlyPath(buffer->getFileName());
716         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)){
717                 path = buffer->tmppath;
718         }
719         Path p(path);
720         bool ret = RunScript(buffer, false, lyxrc->view_ps_command, ps);
721         AllowInput();
722         return ret;
723 }
724
725
726 void MenuFax(Buffer * buffer)
727 {
728         if (!buffer->text)
729                 return;
730
731         // Generate postscript file
732         if (!MenuRunDvips(buffer, true)) {
733                 return;
734         }
735
736         // Send fax
737         string ps = ChangeExtension (buffer->getFileName(), ".ps_tmp", true);
738         string path = OnlyPath (buffer->getFileName());
739         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)) {
740                 path = buffer->tmppath;
741         }
742         Path p(path);
743         if (!lyxrc->fax_program.empty()) {
744                 string help2 = subst(lyxrc->fax_program, "$$FName", ps);
745                 help2 += " &";
746                 Systemcalls one(Systemcalls::System, help2);
747         } else
748                 send_fax(ps, lyxrc->fax_command);
749 }
750
751
752 // Returns false if we fail
753 bool MenuPreview(Buffer * buffer)
754 {
755         if (!buffer->text)
756                 return false;
757    
758         string paper;
759         
760         char real_papersize = buffer->params.papersize;
761         if (real_papersize == BufferParams::PAPER_DEFAULT)
762                 real_papersize = lyxrc->default_papersize;
763    
764         switch (real_papersize) {
765         case BufferParams::PAPER_USLETTER:
766                 paper = "us";
767                 break;
768         case BufferParams::PAPER_A3PAPER:
769                 paper = "a3";
770                 break;
771         case BufferParams::PAPER_A4PAPER:
772                 paper = "a4";
773                 break;
774         case BufferParams::PAPER_A5PAPER:
775                 paper = "a5";
776                 break;
777         case BufferParams::PAPER_B5PAPER:
778                 paper = "b5";
779                 break;
780         case BufferParams::PAPER_EXECUTIVEPAPER:
781                 paper = "foolscap";
782                 break;
783         case BufferParams::PAPER_LEGALPAPER:
784                 paper = "legal";
785                 break;
786         default: /* If nothing else fits, keep the empty value */
787                 break;
788         }
789    
790         if (paper.empty()) {
791                 if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
792                         // we HAVE to give a size when the page is in
793                         // landscape, so use USletter.          
794                         paper = " -paper usr";
795         } else {
796                 paper = " -paper " + paper;
797                 if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
798                         paper+= 'r';
799         }
800
801         // push directorypath, if necessary 
802         string path = OnlyPath(buffer->getFileName());
803         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)){
804                 path = buffer->tmppath;
805         }
806         Path p(path);
807         // Run dvi-viewer
808         string command = lyxrc->view_dvi_command + paper ;
809         bool ret = RunScript(buffer, false, command);
810         return ret;
811 }
812
813
814 void MenuMakeLaTeX(Buffer * buffer)
815 {
816         if (buffer->text) {
817                 // Get LaTeX-Filename
818                 string s = SpaceLess(ChangeExtension(
819                                                 buffer->getFileName(),
820                                                 ".tex", false));
821
822                 FileInfo fi(s);
823                 if (fi.readable() &&
824                     !AskQuestion(_("File already exists:"), 
825                                 MakeDisplayPath(s, 50),
826                                 _("Do you want to overwrite the file?"))) {
827                         minibuffer->Set(_("Canceled"));
828                         return;
829                 }
830
831                 if (buffer->isDocBook())
832                         minibuffer->Set(_("DocBook does not have a latex backend"));
833                 else {
834                         if (buffer->isLinuxDoc())
835                                 RunLinuxDoc(0, buffer->getFileName());
836                         else
837                                 buffer->makeLaTeXFile(s, string(), true);
838                         minibuffer->Set(_("Nice LaTeX file saved as"),
839                                         MakeDisplayPath(s));
840                         buffer->markDviDirty();
841                 }
842         }
843 }
844
845
846 void MenuMakeLinuxDoc(Buffer * buffer)
847 {
848         if (buffer->text) {
849                 if (!buffer->isLinuxDoc()) {
850                         WriteAlert(_("Error!"), _("Document class must be linuxdoc."));
851                         return;
852                 }
853
854                 // Get LinuxDoc-Filename
855                 string s = ChangeExtension (buffer->getFileName(), 
856                                              ".sgml", false);
857
858                 FileInfo fi(s);
859                 if (fi.readable() &&
860                     !AskQuestion(_("File already exists:"), 
861                                 MakeDisplayPath(s, 50),
862                                 _("Do you want to overwrite the file?"))) {
863                         minibuffer->Set(_("Canceled"));
864                         return;
865                 }
866
867                 minibuffer->Set(_("Building LinuxDoc SGML file `"),
868                                 MakeDisplayPath(s), "'..."); 
869
870                 buffer->makeLinuxDocFile(s, 65);
871                 buffer->redraw();
872                 minibuffer->Set(_("LinuxDoc SGML file save as"),
873                                 MakeDisplayPath(s)); 
874         }
875 }
876
877
878 void MenuMakeDocBook(Buffer * buffer)
879 {
880         if (buffer->text) {
881                 if (!buffer->isDocBook()) {
882                         WriteAlert(_("Error!"),
883                                    _("Document class must be docbook."));
884                         return;
885                 }
886
887                 // Get DocBook-Filename
888                 string s = ChangeExtension (buffer->getFileName(), 
889                                              ".sgml", false);
890
891                 FileInfo fi(s);
892                 if (fi.readable() &&
893                     !AskQuestion(_("File already exists:"), 
894                                 MakeDisplayPath(s, 50),
895                                 _("Do you want to overwrite the file?"))) {
896                         minibuffer->Set(_("Canceled"));
897                         return;
898                 }
899
900                 minibuffer->Set(_("Building DocBook SGML file `"),
901                                 MakeDisplayPath(s), "'..."); 
902
903                 buffer->makeDocBookFile(s, 65);
904                 buffer->redraw();
905                 minibuffer->Set(_("DocBook SGML file save as"),
906                                 MakeDisplayPath(s)); 
907         }
908 }
909
910
911 void MenuMakeAscii(Buffer * buffer)
912 {
913         if (buffer->text) {
914                 /* get LaTeX-Filename */
915                 string s = ChangeExtension (buffer->getFileName(),
916                                              ".txt", false);
917
918                 FileInfo fi(s);
919                 if (fi.readable() &&
920                     !AskQuestion(_("File already exists:"), 
921                                 MakeDisplayPath(s, 50),
922                                 _("Do you want to overwrite the file?"))) {
923                         minibuffer->Set(_("Canceled"));
924                         return;
925                 }
926
927                 buffer->writeFileAscii(s, lyxrc->ascii_linelen);
928
929                 minibuffer->Set(_("Ascii file saved as"), MakeDisplayPath(s));
930         }
931 }
932
933
934 void MenuPrint(Buffer * buffer)
935 {
936         if (!buffer->text) 
937                 return;
938         
939         string input_file = ChangeExtension(buffer->getFileName(),
940                                      lyxrc->print_file_extension,
941                                      true);
942         fl_set_input(fd_form_print->input_file, input_file.c_str());
943         
944         if (fd_form_print->form_print->visible) {
945                 fl_raise_form(fd_form_print->form_print);
946         } 
947         else {
948                 fl_show_form(fd_form_print->form_print,
949                              FL_PLACE_MOUSE, FL_FULLBORDER,
950                              _("Print"));
951         }
952 }
953
954
955 void QuitLyX()
956 {
957         lyxerr.debug() << "Running QuitLyX." << endl;
958
959         if (!bufferlist.QwriteAll())
960                 return;
961
962         lastfiles->writeFile(lyxrc->lastfiles);
963
964         // Set a flag that we do quitting from the program,
965         // so no refreshes are necessary.
966         quitting = true;
967
968         // close buffers first
969         bufferlist.closeAll();
970
971         // do any other cleanup procedures now
972         lyxerr.debug() << "Deleting tmp dir " << system_tempdir << endl;
973
974         DestroyLyXTmpDir(system_tempdir);
975
976         finished = true;
977 }
978
979
980
981 void AutoSave()
982         // should probably be moved into BufferList (Lgb)
983         // Perfect target for a thread...
984 {
985         if (!current_view->getScreen() || !current_view->available())
986                 return;
987
988         if (current_view->buffer()->isBakClean()
989             || current_view->buffer()->isReadonly()) {
990                 // We don't save now, but we'll try again later
991                 current_view->owner()->resetAutosaveTimer();
992                 return;
993         }
994
995         minibuffer->Set(_("Autosaving current document..."));
996         
997         // create autosave filename
998         string fname =  OnlyPath(current_view->buffer()->getFileName());
999         fname += "#";
1000         fname += OnlyFilename(current_view->buffer()->getFileName());
1001         fname += "#";
1002         
1003         // tmp_ret will be located (usually) in /tmp
1004         // will that be a problem?
1005         string tmp_ret = tmpnam(0);
1006         
1007         pid_t pid = fork(); // If you want to debug the autosave
1008         // you should set pid to -1, and comment out the
1009         // fork.
1010         if (pid == 0 || pid == -1) {
1011                 // pid = -1 signifies that lyx was unable
1012                 // to fork. But we will do the save
1013                 // anyway.
1014                 bool failed = false;
1015                 if (!tmp_ret.empty()) {
1016                         current_view->buffer()->writeFile(tmp_ret, 1);
1017                         // assume successful write of tmp_ret
1018                         if (rename(tmp_ret.c_str(), fname.c_str()) == -1) {
1019                                 failed = true;
1020                                 // most likely couldn't move between filesystems
1021                                 // unless write of tmp_ret failed
1022                                 // so remove tmp file (if it exists)
1023                                 remove(tmp_ret.c_str());
1024                         }
1025                 } else {
1026                         failed = true;
1027                 }
1028                 
1029                 if (failed) {
1030                         // failed to write/rename tmp_ret so try writing direct
1031                         if (!current_view->buffer()->writeFile(fname, 1)) {
1032                                 // It is dangerous to do this in the child,
1033                                 // but safe in the parent, so...
1034                                 if (pid == -1)
1035                                         minibuffer->Set(_("Autosave Failed!"));
1036                         }
1037                 }
1038                 if (pid == 0) { // we are the child so...
1039                         _exit(0);
1040                 }
1041         }
1042         
1043         current_view->buffer()->markBakClean();
1044         current_view->owner()->resetAutosaveTimer();
1045 }
1046
1047
1048 //
1049 // (c) CHT Software Service GmbH
1050 // Uwe C. Schroeder
1051 //
1052 // create new file with template
1053 // SERVERCMD !
1054 //
1055 Buffer * NewLyxFile(string const & filename)
1056 {
1057         // Split argument by :
1058         string name;
1059         string tmpname = split(filename, name, ':');
1060 #ifdef __EMX__ // Fix me! lyx_cb.C may not be low level enough to allow this.
1061         if (name.length() == 1
1062             && isalpha(static_cast<unsigned char>(name[0]))
1063             && (prefixIs(tmpname, "/") || prefixIs(tmpname, "\\"))) {
1064                 name += ':';
1065                 name += token(tmpname, ':', 0);
1066                 tmpname = split(tmpname, ':');
1067         }
1068 #endif
1069         lyxerr.debug() << "Arg is " << filename
1070                        << "\nName is " << name
1071                        << "\nTemplate is " << tmpname << endl;
1072
1073         // find a free buffer 
1074         Buffer * tmpbuf = bufferlist.newFile(name, tmpname);
1075         if (tmpbuf)
1076                 lastfiles->newFile(tmpbuf->getFileName());
1077         return tmpbuf;
1078 }
1079
1080
1081 // Insert ascii file (if filename is empty, prompt for one)
1082 void InsertAsciiFile(string const & f, bool asParagraph)
1083 {
1084         string fname = f;
1085         LyXFileDlg fileDlg;
1086  
1087         if (!current_view->getScreen()) return;
1088      
1089         if (fname.empty()) {
1090                 ProhibitInput();
1091                 fname = fileDlg.Select(_("File to Insert"), 
1092                                        current_view->owner()->buffer()->filepath,
1093                                        "*");
1094                 AllowInput();
1095                 if (fname.empty()) return;
1096         }
1097
1098         FileInfo fi(fname);
1099
1100         if (!fi.readable()) {
1101                 WriteFSAlert(_("Error! Specified file is unreadable: "),
1102                              MakeDisplayPath(fname, 50));
1103                 return;
1104         }
1105
1106         FilePtr myfile(fname, FilePtr::read);
1107         if (!myfile()) {
1108                 WriteFSAlert(_("Error! Cannot open specified file: "),
1109                              MakeDisplayPath(fname, 50));
1110                 return;
1111         }
1112         LyXParagraph * tmppar = new LyXParagraph;
1113         tmppar->readSimpleWholeFile(myfile);
1114         
1115         // set the end of the string
1116 #ifdef WITH_WARNINGS
1117 #warning why do we do this?
1118 #endif
1119         // I don't think this is needed. Actually it might be plain wrong.
1120         tmppar->InsertChar(tmppar->text.size() - 1, '\0');
1121
1122         // insert the string
1123         current_view->getScreen()->HideCursor();
1124         
1125         // clear the selection
1126         BeforeChange();
1127         if (!asParagraph)
1128                 current_view->buffer()->text->InsertStringA(tmppar->text);
1129         else
1130                 current_view->buffer()->text->InsertStringB(tmppar->text);
1131         delete tmppar;
1132         current_view->buffer()->update(1);
1133 }
1134
1135
1136 void MenuShowTableOfContents()
1137 {
1138         static int ow = -1, oh;
1139
1140         TocUpdateCB(0, 0);
1141         if (fd_form_toc->form_toc->visible) {
1142                 fl_raise_form(fd_form_toc->form_toc);
1143         } else {
1144                 fl_show_form(fd_form_toc->form_toc,
1145                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
1146                              _("Table Of Contents"));
1147                 if (ow < 0) {
1148                         ow = fd_form_toc->form_toc->w;
1149                         oh = fd_form_toc->form_toc->h;
1150                 }
1151                 fl_set_form_minsize(fd_form_toc->form_toc, ow, oh);
1152         }
1153 }
1154
1155
1156 void MenuInsertLabel(char const * arg)
1157 {
1158         string label = arg;
1159         ProhibitInput();
1160         //string label = fl_show_input(_("Enter new label to insert:"), "");
1161         if (label.empty())
1162                 label = frontStrip(strip(askForText(_("Enter new label to insert:"))));
1163         if (!label.empty()) {
1164                 InsetLabel * new_inset = new InsetLabel;
1165                 new_inset->setContents(label);
1166                 current_view->buffer()->insertInset(new_inset);
1167         }
1168         AllowInput();
1169 }
1170
1171
1172 void MenuInsertRef()
1173 {
1174         static int ow = -1, oh;
1175
1176         RefUpdateCB(0, 0);
1177         if (fd_form_ref->form_ref->visible) {
1178                 fl_raise_form(fd_form_ref->form_ref);
1179         } else {
1180                 fl_show_form(fd_form_ref->form_ref,
1181                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
1182                              _("Insert Reference"));
1183                 if (ow < 0) {
1184                         ow = fd_form_ref->form_ref->w;
1185                         oh = fd_form_ref->form_ref->h;
1186                 }
1187                 fl_set_form_minsize(fd_form_ref->form_ref, ow, oh);
1188         }
1189 }
1190
1191
1192 void MenuPasteSelection(char at)
1193 {
1194         if (!current_view->getScreen())
1195                 return;
1196
1197         ascii_type = at;
1198   
1199         Atom data_prop = XInternAtom(fl_display, 
1200                                      "LyX_Primary",
1201                                      false);
1202         if (data_prop == None) 
1203                 return;
1204         XConvertSelection(fl_display,
1205                           XA_PRIMARY, XA_STRING, data_prop, 
1206                           fd_form_main->form_main->window, 0);
1207         XFlush(fl_display);
1208 }
1209
1210
1211 extern "C" void FootCB(FL_OBJECT *, long)
1212 {
1213         if (!current_view->available()) 
1214                 return;
1215         
1216         minibuffer->Set(_("Inserting Footnote..."));
1217         current_view->getScreen()->HideCursor();
1218         current_view->buffer()->update(-2);
1219         current_view->buffer()->text->InsertFootnoteEnvironment(LyXParagraph::FOOTNOTE);
1220         current_view->buffer()->update(1);
1221 }
1222
1223
1224 void LayoutsCB(int sel, void *)
1225 {
1226         string tmp = tostr(sel);
1227         current_view->owner()->getLyXFunc()->Dispatch(LFUN_LAYOUTNO,
1228                                                          tmp.c_str());
1229 }
1230
1231
1232 /*
1233  * SGML Linuxdoc support:
1234  * (flag == -1) import SGML file
1235  * (flag == 0) make TeX output
1236  * (flag == 1) make dvi output
1237  */
1238 int RunLinuxDoc(int flag, string const & filename)
1239 {
1240         string name;
1241         string s2;
1242         string path;
1243         string add_flags;
1244
1245         int errorcode = 0;
1246
1247         /* generate a path-less extension name */
1248         name = ChangeExtension (filename, ".sgml", true);
1249         path = OnlyPath (filename);
1250         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)) {
1251                 path = current_view->buffer()->tmppath;
1252         }
1253         Path p(path);
1254         
1255         if (flag != -1) {
1256                 if (!current_view->available())
1257                         return 0;
1258                 current_view->buffer()->makeLinuxDocFile(name, 0);
1259 #ifdef WITH_WARNINGS
1260 #warning remove this once we have a proper geometry class
1261 #endif
1262                 BufferParams::PAPER_SIZE ps = static_cast<BufferParams::PAPER_SIZE>(current_view->buffer()->params.papersize);
1263                 switch (ps) {
1264                 case BufferParams::PAPER_A4PAPER:
1265                         add_flags = "-p a4";
1266                         break;
1267                 case BufferParams::PAPER_USLETTER:
1268                         add_flags = "-p letter";
1269                         break;
1270                 default: /* nothing to be done yet ;-) */     break; 
1271                 }
1272         }
1273         
1274         ProhibitInput();
1275         
1276         Systemcalls one;
1277         switch (flag) {
1278         case -1: /* Import file */
1279                 minibuffer->Set(_("Importing LinuxDoc SGML file `"), 
1280                                 MakeDisplayPath(filename), "'...");
1281                 s2 = "sgml2lyx " + lyxrc->sgml_extra_options + ' ' 
1282                         + name;
1283                 if (one.startscript(Systemcalls::System, s2)) 
1284                         errorcode = 1;
1285                 break;
1286         case 0: /* TeX output asked */
1287                 minibuffer->Set(_("Converting LinuxDoc SGML to TeX file..."));
1288                 s2 = "sgml2latex " + add_flags + " -o tex "
1289                         + lyxrc->sgml_extra_options + ' ' + name;
1290                 if (one.startscript(Systemcalls::System, s2)) 
1291                         errorcode = 1;
1292                 break;
1293         case 1: /* dvi output asked */
1294                 minibuffer->Set(_("Converting LinuxDoc SGML to dvi file..."));
1295                 s2 = "sgml2latex " + add_flags + " -o dvi "
1296                         + lyxrc->sgml_extra_options + ' ' + name;
1297                 if (one.startscript(Systemcalls::System, s2)) {
1298                         errorcode = 1;
1299                 } else
1300                         current_view->buffer()->markDviClean();
1301                 break;
1302         default: /* unknown output */
1303                 break;
1304         }
1305         
1306         AllowInput();
1307
1308         current_view->buffer()->redraw();
1309         return errorcode;
1310 }
1311
1312
1313 /*
1314  * SGML DocBook support:
1315  * (flag == 1) make dvi output
1316  */
1317 int RunDocBook(int flag, string const & filename)
1318 {
1319         /* generate a path-less extension name */
1320         string name = ChangeExtension (filename, ".sgml", true);
1321         string path = OnlyPath (filename);
1322         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)) {
1323                 path = current_view->buffer()->tmppath;
1324         }
1325         Path p(path);
1326
1327         if (!current_view->available())
1328                 return 0;
1329         
1330         current_view->buffer()->makeDocBookFile(name, 0);
1331
1332         // Shall this code go or should it stay? (Lgb)
1333 //      string add_flags;
1334 //      LYX_PAPER_SIZE ps = (LYX_PAPER_SIZE) current_view->buffer()->params.papersize;
1335 //      switch (ps) {
1336 //      case BufferParams::PAPER_A4PAPER:  add_flags = "-p a4";     break;
1337 //      case BufferParams::PAPER_USLETTER: add_flags = "-p letter"; break;
1338 //      default: /* nothing to be done yet ;-) */     break; 
1339 //      }
1340         ProhibitInput();
1341         
1342         int errorcode = 0;
1343         Systemcalls one;
1344         switch (flag) {
1345         case 1: /* dvi output asked */
1346         {
1347                 minibuffer->Set(_("Converting DocBook SGML to dvi file..."));
1348                 string s2 = "sgmltools --backend dvi " + name;
1349                 if (one.startscript(Systemcalls::System, s2)) {
1350                         errorcode = 1;
1351                 } else
1352                         current_view->buffer()->markDviClean();
1353         }
1354         break;
1355         default: /* unknown output */
1356                 break;
1357         }
1358         
1359         AllowInput();
1360
1361         current_view->buffer()->redraw();
1362         return errorcode;
1363 }
1364
1365
1366 void AllFloats(char flag, char figmar)
1367 {
1368         if (!current_view->available())
1369                 return;
1370    
1371         LyXCursor cursor = current_view->buffer()->text->cursor;
1372
1373         if (!flag && cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE
1374             && ((figmar 
1375                  && cursor.par->footnotekind != LyXParagraph::FOOTNOTE 
1376                  && cursor.par->footnotekind != LyXParagraph::MARGIN)
1377                 || (!figmar
1378                     && cursor.par->footnotekind != LyXParagraph::FIG 
1379                     && cursor.par->footnotekind != LyXParagraph::TAB
1380                     && cursor.par->footnotekind != LyXParagraph::WIDE_FIG 
1381                     && cursor.par->footnotekind != LyXParagraph::WIDE_TAB
1382                     && cursor.par->footnotekind != LyXParagraph::ALGORITHM)))
1383                 ToggleFloat();
1384         else
1385                 BeforeChange();
1386
1387         LyXCursor tmpcursor = cursor;
1388         cursor.par = tmpcursor.par->ParFromPos(tmpcursor.pos);
1389         cursor.pos = tmpcursor.par->PositionInParFromPos(tmpcursor.pos);
1390
1391         LyXParagraph *par = current_view->buffer()->paragraph;
1392         while (par) {
1393                 if (flag) {
1394                         if (par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE
1395                             && ((figmar 
1396                                  && par->footnotekind != LyXParagraph::FOOTNOTE 
1397                                  && par->footnotekind !=  LyXParagraph::MARGIN)
1398                                 || (!figmar
1399                                     && par->footnotekind != LyXParagraph::FIG 
1400                                     && par->footnotekind != LyXParagraph::TAB
1401                                     && par->footnotekind != LyXParagraph::WIDE_FIG 
1402                                     && par->footnotekind != LyXParagraph::WIDE_TAB
1403                                     && par->footnotekind != LyXParagraph::ALGORITHM
1404                                         )
1405                                     )
1406                                 ) {
1407                                 if (par->previous
1408                                     && par->previous->footnoteflag != 
1409                                     LyXParagraph::CLOSED_FOOTNOTE){ /* should be */ 
1410                                         current_view->buffer()->text->SetCursorIntern(par->previous,
1411                                                                       0);
1412                                         current_view->buffer()->text->OpenFootnote();
1413                                 }
1414                         }
1415                 }
1416                 else  {
1417                         if (par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE
1418                             && (
1419                                     (figmar 
1420                                      &&
1421                                      par->footnotekind != LyXParagraph::FOOTNOTE 
1422                                      &&
1423                                      par->footnotekind !=  LyXParagraph::MARGIN
1424                                             )
1425                                     ||
1426                                     (!figmar
1427                                      &&
1428                                      par->footnotekind != LyXParagraph::FIG 
1429                                      &&
1430                                      par->footnotekind != LyXParagraph::TAB
1431                                      &&
1432                                      par->footnotekind != LyXParagraph::WIDE_FIG 
1433                                      &&
1434                                      par->footnotekind != LyXParagraph::WIDE_TAB
1435                                      &&
1436                                      par->footnotekind != LyXParagraph::ALGORITHM
1437                                             )
1438                                     )
1439                                 ){
1440                                 current_view->buffer()->text->SetCursorIntern(par, 0);
1441                                 current_view->buffer()->text->CloseFootnote();
1442                         }
1443                 }
1444                 par = par->next;
1445         }
1446
1447         current_view->buffer()->text->SetCursorIntern(cursor.par, cursor.pos);
1448         current_view->redraw();
1449         current_view->fitCursor();
1450         current_view->updateScrollbar();
1451 }
1452
1453
1454 void MenuLayoutCharacter()
1455 {
1456         static int ow = -1, oh;
1457
1458         if (fd_form_character->form_character->visible) {
1459                 fl_raise_form(fd_form_character->form_character);
1460         } else {
1461                 fl_show_form(fd_form_character->form_character,
1462                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
1463                              _("Character Style"));
1464                 if (ow < 0) {
1465                         ow = fd_form_character->form_character->w;
1466                         oh = fd_form_character->form_character->h;
1467                 }
1468                 fl_set_form_minsize(fd_form_character->form_character, ow, oh);
1469         }
1470 }
1471
1472
1473 inline void DeactivateParagraphButtons ()
1474 {
1475         fl_deactivate_object (fd_form_paragraph->button_ok);
1476         fl_deactivate_object (fd_form_paragraph->button_apply);
1477         fl_set_object_lcol (fd_form_paragraph->button_ok, FL_INACTIVE);
1478         fl_set_object_lcol (fd_form_paragraph->button_apply, FL_INACTIVE);
1479 }
1480
1481
1482 inline void ActivateParagraphButtons ()
1483 {
1484         fl_activate_object (fd_form_paragraph->button_ok);
1485         fl_activate_object (fd_form_paragraph->button_apply);
1486         fl_set_object_lcol (fd_form_paragraph->button_ok, FL_BLACK);
1487         fl_set_object_lcol (fd_form_paragraph->button_apply, FL_BLACK);
1488 }
1489
1490
1491 inline void DisableParagraphLayout ()
1492 {
1493         DeactivateParagraphButtons();
1494         fl_deactivate_object (fd_form_paragraph->input_labelwidth);
1495         fl_deactivate_object (fd_form_paragraph->check_lines_top);
1496         fl_deactivate_object (fd_form_paragraph->check_lines_bottom);
1497         fl_deactivate_object (fd_form_paragraph->check_pagebreaks_top);
1498         fl_deactivate_object (fd_form_paragraph->check_pagebreaks_bottom);
1499         fl_deactivate_object (fd_form_paragraph->check_noindent);
1500         fl_deactivate_object (fd_form_paragraph->group_radio_alignment);
1501         fl_deactivate_object (fd_form_paragraph->radio_align_right);
1502         fl_deactivate_object (fd_form_paragraph->radio_align_left);
1503         fl_deactivate_object (fd_form_paragraph->radio_align_block);
1504         fl_deactivate_object (fd_form_paragraph->radio_align_center);
1505         fl_deactivate_object (fd_form_paragraph->input_space_above);
1506         fl_deactivate_object (fd_form_paragraph->input_space_below);
1507         fl_deactivate_object (fd_form_paragraph->choice_space_above);
1508         fl_deactivate_object (fd_form_paragraph->choice_space_below);
1509         fl_deactivate_object (fd_form_paragraph->check_space_above);
1510         fl_deactivate_object (fd_form_paragraph->check_space_below);
1511 }
1512
1513
1514 inline void EnableParagraphLayout ()
1515 {
1516         ActivateParagraphButtons();
1517         fl_activate_object (fd_form_paragraph->input_labelwidth);
1518         fl_activate_object (fd_form_paragraph->check_lines_top);
1519         fl_activate_object (fd_form_paragraph->check_lines_bottom);
1520         fl_activate_object (fd_form_paragraph->check_pagebreaks_top);
1521         fl_activate_object (fd_form_paragraph->check_pagebreaks_bottom);
1522         fl_activate_object (fd_form_paragraph->check_noindent);
1523         fl_activate_object (fd_form_paragraph->group_radio_alignment);
1524         fl_activate_object (fd_form_paragraph->radio_align_right);
1525         fl_activate_object (fd_form_paragraph->radio_align_left);
1526         fl_activate_object (fd_form_paragraph->radio_align_block);
1527         fl_activate_object (fd_form_paragraph->radio_align_center);
1528         fl_activate_object (fd_form_paragraph->input_space_above);
1529         fl_activate_object (fd_form_paragraph->input_space_below);
1530         fl_activate_object (fd_form_paragraph->choice_space_above);
1531         fl_activate_object (fd_form_paragraph->choice_space_below);
1532         fl_activate_object (fd_form_paragraph->check_space_above);
1533         fl_activate_object (fd_form_paragraph->check_space_below);
1534 }
1535
1536
1537 bool UpdateLayoutParagraph()
1538 {
1539         if (!current_view->getScreen() || !current_view->available()) {
1540                 if (fd_form_paragraph->form_paragraph->visible) 
1541                         fl_hide_form(fd_form_paragraph->form_paragraph);
1542                 return false;
1543         }
1544
1545         Buffer * buf = current_view->buffer();
1546
1547         fl_set_input(fd_form_paragraph->input_labelwidth,
1548                      buf->text->cursor.par->GetLabelWidthString().c_str());
1549         fl_set_button(fd_form_paragraph->radio_align_right, 0);
1550         fl_set_button(fd_form_paragraph->radio_align_left, 0);
1551         fl_set_button(fd_form_paragraph->radio_align_center, 0);
1552         fl_set_button(fd_form_paragraph->radio_align_block, 0);
1553
1554         int align = buf->text->cursor.par->GetAlign();
1555         if (align == LYX_ALIGN_LAYOUT)
1556                 align = textclasslist.Style(buf->params.textclass,
1557                                   buf->text->cursor.par->GetLayout()).align;
1558          
1559         switch (align) {
1560         case LYX_ALIGN_RIGHT:
1561                 fl_set_button(fd_form_paragraph->radio_align_right, 1);
1562                 break;
1563         case LYX_ALIGN_LEFT:
1564                 fl_set_button(fd_form_paragraph->radio_align_left, 1);
1565                 break;
1566         case LYX_ALIGN_CENTER:
1567                 fl_set_button(fd_form_paragraph->radio_align_center, 1);
1568                 break;
1569         default:
1570                 fl_set_button(fd_form_paragraph->radio_align_block, 1);
1571                 break;
1572         }
1573          
1574         fl_set_button(fd_form_paragraph->check_lines_top,
1575                       buf->text->cursor.par->FirstPhysicalPar()->line_top);
1576         fl_set_button(fd_form_paragraph->check_lines_bottom,
1577                       buf->text->cursor.par->FirstPhysicalPar()->line_bottom);
1578         fl_set_button(fd_form_paragraph->check_pagebreaks_top,
1579                       buf->text->cursor.par->FirstPhysicalPar()->pagebreak_top);
1580         fl_set_button(fd_form_paragraph->check_pagebreaks_bottom,
1581                       buf->text->cursor.par->FirstPhysicalPar()->pagebreak_bottom);
1582         fl_set_button(fd_form_paragraph->check_noindent,
1583                       buf->text->cursor.par->FirstPhysicalPar()->noindent);
1584         fl_set_input (fd_form_paragraph->input_space_above, "");
1585         
1586         switch (buf->text->cursor.par->FirstPhysicalPar()->added_space_top.kind()) {
1587         case VSpace::NONE:
1588                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
1589                 break;
1590         case VSpace::DEFSKIP:
1591                 fl_set_choice (fd_form_paragraph->choice_space_above, 2);
1592                 break;
1593         case VSpace::SMALLSKIP:
1594                 fl_set_choice (fd_form_paragraph->choice_space_above, 3);
1595                 break;
1596         case VSpace::MEDSKIP:
1597                 fl_set_choice (fd_form_paragraph->choice_space_above, 4);
1598                 break;
1599         case VSpace::BIGSKIP:
1600                 fl_set_choice (fd_form_paragraph->choice_space_above, 5);
1601                 break;
1602         case VSpace::VFILL:
1603                 fl_set_choice (fd_form_paragraph->choice_space_above, 6);
1604                 break;
1605         case VSpace::LENGTH:
1606                 fl_set_choice (fd_form_paragraph->choice_space_above, 7); 
1607                 fl_set_input  (fd_form_paragraph->input_space_above, 
1608                                buf->text->cursor.par->FirstPhysicalPar()->added_space_top.length().asString().c_str());
1609                 break;
1610         }
1611         fl_set_button (fd_form_paragraph->check_space_above,
1612                        buf->text->cursor.par->FirstPhysicalPar()->added_space_top.keep());
1613         fl_set_input (fd_form_paragraph->input_space_below, "");
1614         switch (buf->text->cursor.par->FirstPhysicalPar()->added_space_bottom.kind()) {
1615         case VSpace::NONE:
1616                 fl_set_choice (fd_form_paragraph->choice_space_below,
1617                                1);
1618                 break;
1619         case VSpace::DEFSKIP:
1620                 fl_set_choice (fd_form_paragraph->choice_space_below,
1621                                2);
1622                 break;
1623         case VSpace::SMALLSKIP:
1624                 fl_set_choice (fd_form_paragraph->choice_space_below,
1625                                3);
1626                 break;
1627         case VSpace::MEDSKIP:
1628                 fl_set_choice (fd_form_paragraph->choice_space_below,
1629                                4);
1630                 break;
1631         case VSpace::BIGSKIP:
1632                 fl_set_choice (fd_form_paragraph->choice_space_below,
1633                                5);
1634                 break;
1635         case VSpace::VFILL:
1636                 fl_set_choice (fd_form_paragraph->choice_space_below,
1637                                6);
1638                 break;
1639         case VSpace::LENGTH:
1640                 fl_set_choice (fd_form_paragraph->choice_space_below,
1641                                7); 
1642                 fl_set_input  (fd_form_paragraph->input_space_below, 
1643                                buf->text->cursor.par->FirstPhysicalPar()->added_space_bottom.length().asString().c_str());
1644                 break;
1645         }
1646         fl_set_button (fd_form_paragraph->check_space_below,
1647                        buf->text->cursor.par->FirstPhysicalPar()->added_space_bottom.keep());
1648
1649         fl_set_button(fd_form_paragraph->check_noindent,
1650                       buf->text->cursor.par->FirstPhysicalPar()->noindent);
1651
1652         if (current_view->buffer()->isReadonly()) {
1653                 DisableParagraphLayout();
1654         } else {
1655                 EnableParagraphLayout();
1656         }
1657         return true;
1658 }
1659
1660
1661 void MenuLayoutParagraph()
1662 {
1663         if (UpdateLayoutParagraph()) {
1664                 if (fd_form_paragraph->form_paragraph->visible) {
1665                         fl_raise_form(fd_form_paragraph->form_paragraph);
1666                 } else {
1667                         fl_show_form(fd_form_paragraph->form_paragraph,
1668                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1669                                      _("Paragraph Environment"));
1670                 }
1671         }
1672 }
1673
1674
1675 inline
1676 void DeactivateDocumentButtons ()
1677 {
1678         fl_deactivate_object (fd_form_document->button_ok);
1679         fl_deactivate_object (fd_form_document->button_apply);
1680         fl_set_object_lcol (fd_form_document->button_ok, FL_INACTIVE);
1681         fl_set_object_lcol (fd_form_document->button_apply, FL_INACTIVE);
1682 }
1683
1684
1685 inline
1686 void ActivateDocumentButtons ()
1687 {
1688         fl_activate_object (fd_form_document->button_ok);
1689         fl_activate_object (fd_form_document->button_apply);
1690         fl_set_object_lcol (fd_form_document->button_ok, FL_BLACK);
1691         fl_set_object_lcol (fd_form_document->button_apply, FL_BLACK);
1692 }
1693
1694
1695 inline
1696 void DisableDocumentLayout ()
1697 {
1698         DeactivateDocumentButtons ();
1699         fl_deactivate_object (fd_form_document->group_radio_separation);
1700         fl_deactivate_object (fd_form_document->radio_indent);
1701         fl_deactivate_object (fd_form_document->radio_skip);
1702         fl_deactivate_object (fd_form_document->choice_class);
1703         fl_deactivate_object (fd_form_document->choice_pagestyle);
1704         fl_deactivate_object (fd_form_document->choice_fonts);
1705         fl_deactivate_object (fd_form_document->choice_fontsize);
1706         fl_deactivate_object (fd_form_document->input_float_placement);
1707         fl_deactivate_object (fd_form_document->choice_postscript_driver);
1708         fl_deactivate_object (fd_form_document->choice_inputenc);
1709         fl_deactivate_object (fd_form_document->group_radio_sides);
1710         fl_deactivate_object (fd_form_document->radio_sides_one);
1711         fl_deactivate_object (fd_form_document->radio_sides_two);
1712         fl_deactivate_object (fd_form_document->group_radio_columns);
1713         fl_deactivate_object (fd_form_document->radio_columns_one);
1714         fl_deactivate_object (fd_form_document->radio_columns_two);
1715         fl_deactivate_object (fd_form_document->input_extra);
1716         fl_deactivate_object (fd_form_document->choice_language);
1717         combo_language->deactivate();
1718         fl_deactivate_object (fd_form_document->input_default_skip);
1719         fl_deactivate_object (fd_form_document->choice_default_skip);
1720         fl_deactivate_object (fd_form_document->slider_secnumdepth);
1721         fl_deactivate_object (fd_form_document->slider_tocdepth);
1722         fl_deactivate_object (fd_form_document->choice_spacing);
1723         fl_deactivate_object (fd_form_document->input_spacing);
1724         fl_deactivate_object (fd_form_document->check_use_amsmath);
1725 }
1726
1727
1728 inline
1729 void EnableDocumentLayout ()
1730 {
1731         ActivateDocumentButtons ();
1732         fl_activate_object (fd_form_document->group_radio_separation);
1733         fl_activate_object (fd_form_document->radio_indent);
1734         fl_activate_object (fd_form_document->radio_skip);
1735         fl_activate_object (fd_form_document->choice_class);
1736         fl_activate_object (fd_form_document->choice_pagestyle);
1737         fl_activate_object (fd_form_document->choice_fonts);
1738         fl_activate_object (fd_form_document->choice_fontsize);
1739         fl_activate_object (fd_form_document->input_float_placement);
1740         fl_activate_object (fd_form_document->choice_postscript_driver);
1741         fl_activate_object (fd_form_document->choice_inputenc);
1742         fl_activate_object (fd_form_document->group_radio_sides);
1743         fl_activate_object (fd_form_document->radio_sides_one);
1744         fl_activate_object (fd_form_document->radio_sides_two);
1745         fl_activate_object (fd_form_document->group_radio_columns);
1746         fl_activate_object (fd_form_document->radio_columns_one);
1747         fl_activate_object (fd_form_document->radio_columns_two);
1748         fl_activate_object (fd_form_document->input_extra);
1749         fl_activate_object (fd_form_document->choice_language);
1750         combo_language->activate();
1751         fl_activate_object (fd_form_document->input_default_skip);
1752         fl_activate_object (fd_form_document->choice_default_skip);
1753         fl_activate_object (fd_form_document->slider_secnumdepth);
1754         fl_activate_object (fd_form_document->slider_tocdepth);
1755         fl_activate_object (fd_form_document->choice_spacing);
1756         fl_activate_object (fd_form_document->input_spacing);
1757         fl_activate_object (fd_form_document->check_use_amsmath);
1758 }
1759
1760
1761 bool UpdateLayoutDocument(BufferParams * params)
1762 {
1763         if (!current_view->getScreen() || !current_view->available()) {
1764                 if (fd_form_document->form_document->visible) 
1765                         fl_hide_form(fd_form_document->form_document);
1766                 return false;
1767         }               
1768
1769         if (params == 0)
1770                 params = &current_view->buffer()->params;
1771         LyXTextClass const & tclass = textclasslist.TextClass(params->textclass);
1772         
1773         fl_set_choice_text(fd_form_document->choice_class, 
1774                            textclasslist.DescOfClass(params->textclass).c_str());
1775         combo_language->select_text(params->language.c_str());
1776         
1777         fl_set_choice_text(fd_form_document->choice_fonts, 
1778                            params->fonts.c_str());
1779         fl_set_choice_text(fd_form_document->choice_inputenc, 
1780                            params->inputenc.c_str());
1781         fl_set_choice_text(fd_form_document->choice_postscript_driver, 
1782                            params->graphicsDriver.c_str());
1783
1784         // ale970405+lasgoutt970513
1785         fl_clear_choice(fd_form_document->choice_fontsize);
1786         fl_addto_choice(fd_form_document->choice_fontsize, "default");
1787         fl_addto_choice(fd_form_document->choice_fontsize, 
1788                         tclass.opt_fontsize().c_str());
1789         fl_set_choice(fd_form_document->choice_fontsize, 
1790                       tokenPos(tclass.opt_fontsize(), '|', params->fontsize) + 2);
1791
1792         // ale970405+lasgoutt970513
1793         fl_clear_choice(fd_form_document->choice_pagestyle);
1794         fl_addto_choice(fd_form_document->choice_pagestyle, "default");
1795         fl_addto_choice(fd_form_document->choice_pagestyle, 
1796                         tclass.opt_pagestyle().c_str());
1797     
1798         fl_set_choice(fd_form_document->choice_pagestyle,
1799                       tokenPos(tclass.opt_pagestyle(), '|', params->pagestyle) + 2);
1800
1801         fl_set_button(fd_form_document->radio_indent, 0);
1802         fl_set_button(fd_form_document->radio_skip, 0);
1803     
1804         
1805         fl_set_button(fd_form_document->check_use_amsmath, params->use_amsmath);
1806
1807         if (params->paragraph_separation == BufferParams::PARSEP_INDENT)
1808                 fl_set_button(fd_form_document->radio_indent, 1);
1809         else
1810                 fl_set_button(fd_form_document->radio_skip, 1);
1811
1812         switch (params->getDefSkip().kind()) {
1813         case VSpace::SMALLSKIP: 
1814                 fl_set_choice (fd_form_document->choice_default_skip, 1);
1815                 break;
1816         case VSpace::MEDSKIP: 
1817                 fl_set_choice (fd_form_document->choice_default_skip, 2);
1818                 break;
1819         case VSpace::BIGSKIP: 
1820                 fl_set_choice (fd_form_document->choice_default_skip, 3);
1821                 break;
1822         case VSpace::LENGTH: 
1823                 fl_set_choice (fd_form_document->choice_default_skip, 4);
1824                 fl_set_input (fd_form_document->input_default_skip,
1825                               params->getDefSkip().asLyXCommand().c_str());
1826                 break;
1827         default:
1828                 fl_set_choice (fd_form_document->choice_default_skip, 2);
1829                 break;
1830         }
1831    
1832         fl_set_button(fd_form_document->radio_sides_one, 0);
1833         fl_set_button(fd_form_document->radio_sides_two, 0);
1834    
1835         if (params->sides == 2)
1836                 fl_set_button(fd_form_document->radio_sides_two, 1);
1837         else
1838                 fl_set_button(fd_form_document->radio_sides_one, 1);
1839    
1840         fl_set_button(fd_form_document->radio_columns_one, 0);
1841         fl_set_button(fd_form_document->radio_columns_two, 0);
1842    
1843         if (params->columns == 2)
1844                 fl_set_button(fd_form_document->radio_columns_two, 1);
1845         else
1846                 fl_set_button(fd_form_document->radio_columns_one, 1);
1847    
1848         fl_set_input(fd_form_document->input_spacing, "");
1849         switch (params->spacing.getSpace()) {
1850         case Spacing::Single:
1851         {
1852                 // \singlespacing
1853                 fl_set_choice(fd_form_document->choice_spacing, 1);
1854                 break;
1855         }
1856         case Spacing::Onehalf:
1857         {
1858                 // \onehalfspacing
1859                 fl_set_choice(fd_form_document->choice_spacing, 2);
1860                 break;
1861         }
1862         case Spacing::Double:
1863         {
1864                 // \ doublespacing
1865                 fl_set_choice(fd_form_document->choice_spacing, 3);
1866                 break;
1867         }
1868         case Spacing::Other:
1869         {
1870                 fl_set_choice(fd_form_document->choice_spacing, 4);
1871                 char sval[20];
1872                 sprintf(sval, "%g", params->spacing.getValue()); 
1873                 fl_set_input(fd_form_document->input_spacing, sval);
1874                 break;
1875         }
1876         }
1877
1878
1879         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
1880                              params->secnumdepth);
1881         fl_set_counter_value(fd_form_document->slider_tocdepth, 
1882                              params->tocdepth);
1883         if (!params->float_placement.empty()) { // buffer local (Lgb)
1884                 fl_set_input(fd_form_document->input_float_placement,
1885                              params->float_placement.c_str());
1886         } else {
1887                 fl_set_input(fd_form_document->input_float_placement, "");
1888         }
1889         if (!params->options.empty())
1890                 fl_set_input(fd_form_document->input_extra,
1891                              params->options.c_str());
1892         else
1893                 fl_set_input(fd_form_document->input_extra, "");
1894
1895         if (current_view->buffer()->isSGML()) {
1896                 // bullets not used in SGML derived documents
1897                 fl_deactivate_object(fd_form_document->button_bullets);
1898                 fl_set_object_lcol(fd_form_document->button_bullets,
1899                                    FL_INACTIVE);
1900         } else {
1901                 fl_activate_object(fd_form_document->button_bullets);
1902                 fl_set_object_lcol(fd_form_document->button_bullets,
1903                                    FL_BLACK);
1904         }
1905
1906         if (current_view->buffer()->isReadonly()) {
1907                 DisableDocumentLayout();
1908         } else {
1909                 EnableDocumentLayout();
1910         }
1911
1912         return true;
1913 }
1914
1915
1916 void MenuLayoutDocument()
1917 {
1918         if (UpdateLayoutDocument()) {
1919                 if (fd_form_document->form_document->visible) {
1920                         fl_raise_form(fd_form_document->form_document);
1921                 } else {
1922                         fl_show_form(fd_form_document->form_document,
1923                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1924                                      _("Document Layout"));
1925                 }
1926         }
1927 }
1928
1929
1930 bool UpdateLayoutQuotes()
1931 {
1932         bool update = true;
1933         if (!current_view->getScreen()
1934             || !current_view->available()
1935             || current_view->buffer()->isReadonly())
1936                 update = false;
1937         
1938         if (update) {
1939                 fl_set_choice(fd_form_quotes->choice_quotes_language,
1940                       current_view->buffer()->params.quotes_language + 1);
1941                 fl_set_button(fd_form_quotes->radio_single, 0);
1942                 fl_set_button(fd_form_quotes->radio_double, 0);
1943         
1944                 if (current_view->buffer()->params.quotes_times == InsetQuotes::SingleQ)
1945                         fl_set_button(fd_form_quotes->radio_single, 1);
1946                 else
1947                         fl_set_button(fd_form_quotes->radio_double, 1);
1948         } else if (fd_form_quotes->form_quotes->visible) {
1949                 fl_hide_form(fd_form_quotes->form_quotes);
1950         }
1951         return update;
1952 }
1953
1954
1955 void MenuLayoutQuotes()
1956 {
1957         if (UpdateLayoutQuotes()) {
1958                 if (fd_form_quotes->form_quotes->visible) {
1959                         fl_raise_form(fd_form_quotes->form_quotes);
1960                 } else {
1961                         fl_show_form(fd_form_quotes->form_quotes,
1962                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1963                                      _("Quotes"));
1964                 }
1965         }
1966 }
1967
1968
1969 bool UpdateLayoutPreamble()
1970 {
1971         bool update = true;
1972         if (!current_view->getScreen() || ! current_view->available())
1973             update = false;
1974
1975         if (update) {
1976                 fl_set_input(fd_form_preamble->input_preamble,
1977                      current_view->buffer()->params.preamble.c_str());
1978
1979                 if (current_view->buffer()->isReadonly()) {
1980                   fl_deactivate_object(fd_form_preamble->input_preamble);
1981                   fl_deactivate_object(fd_form_preamble->button_ok);
1982                   fl_deactivate_object(fd_form_preamble->button_apply);
1983                   fl_set_object_lcol(fd_form_preamble->button_ok, FL_INACTIVE);
1984                   fl_set_object_lcol(fd_form_preamble->button_apply, FL_INACTIVE);
1985                 }
1986                 else {
1987                   fl_activate_object(fd_form_preamble->input_preamble);
1988                   fl_activate_object(fd_form_preamble->button_ok);
1989                   fl_activate_object(fd_form_preamble->button_apply);
1990                   fl_set_object_lcol(fd_form_preamble->button_ok, FL_BLACK);
1991                   fl_set_object_lcol(fd_form_preamble->button_apply, FL_BLACK);
1992                 }
1993         } else if (fd_form_preamble->form_preamble->visible) {
1994                 fl_hide_form(fd_form_preamble->form_preamble);
1995         }
1996         return update;
1997 }
1998
1999 void MenuLayoutPreamble()
2000 {
2001         static int ow = -1, oh;
2002
2003         if (UpdateLayoutPreamble()) {
2004                 if (fd_form_preamble->form_preamble->visible) {
2005                         fl_raise_form(fd_form_preamble->form_preamble);
2006                 } else {
2007                         fl_show_form(fd_form_preamble->form_preamble,
2008                                      FL_PLACE_MOUSE | FL_FREE_SIZE,
2009                                      FL_FULLBORDER,
2010                                      _("LaTeX Preamble"));
2011                         if (ow < 0) {
2012                                 ow = fd_form_preamble->form_preamble->w;
2013                                 oh = fd_form_preamble->form_preamble->h;
2014                         }
2015                         fl_set_form_minsize(fd_form_preamble->form_preamble,
2016                                             ow, oh);
2017                 }
2018         }
2019 }
2020
2021
2022 void MenuLayoutSave()
2023 {
2024         if (!current_view->getScreen() || ! current_view->available())
2025             return;
2026
2027         if (AskQuestion(_("Do you want to save the current settings"),
2028                         _("for Character, Document, Paper and Quotes"),
2029                         _("as default for new documents?")))
2030                 current_view->buffer()->saveParamsAsDefaults();
2031 }
2032
2033
2034 void NoteCB()
2035 {
2036         InsetInfo * new_inset = new InsetInfo();
2037         current_view->buffer()->insertInset(new_inset);
2038         new_inset->Edit(0, 0);
2039 }
2040
2041
2042 void OpenStuff()
2043 {
2044         if (current_view->available()) {
2045                 minibuffer->Set(_("Open/Close..."));
2046                 current_view->getScreen()->HideCursor();
2047                 BeforeChange();
2048                 current_view->buffer()->update(-2);
2049                 current_view->buffer()->text->OpenStuff();
2050                 current_view->buffer()->update(0);
2051         }
2052 }
2053
2054
2055 void ToggleFloat()
2056 {
2057         if (current_view->available()) {
2058                 minibuffer->Set(_("Open/Close..."));
2059                 current_view->getScreen()->HideCursor();
2060                 BeforeChange();
2061                 current_view->buffer()->update(-2);
2062                 current_view->buffer()->text->ToggleFootnote();
2063                 current_view->buffer()->update(0);
2064         }
2065 }
2066
2067
2068 void MenuUndo()
2069 {
2070 /*      if (current_view->buffer()->the_locking_inset) {
2071                 minibuffer->Set(_("Undo not yet supported in math mode"));
2072                 return;
2073         }*/
2074    
2075         if (current_view->available()) {
2076                 minibuffer->Set(_("Undo"));
2077                 current_view->getScreen()->HideCursor();
2078                 BeforeChange();
2079                 current_view->buffer()->update(-2);
2080                 if (!current_view->buffer()->text->TextUndo())
2081                         minibuffer->Set(_("No further undo information"));
2082                 else
2083                         current_view->buffer()->update(-1);
2084         }
2085 }
2086
2087
2088 void MenuRedo()
2089 {
2090         if (current_view->buffer()->the_locking_inset) {
2091                 minibuffer->Set(_("Redo not yet supported in math mode"));
2092                 return;
2093         }    
2094    
2095         if (current_view->available()) {
2096                 minibuffer->Set(_("Redo"));
2097                 current_view->getScreen()->HideCursor();
2098                 BeforeChange();
2099                 current_view->buffer()->update(-2);
2100                 if (!current_view->buffer()->text->TextRedo())
2101                         minibuffer->Set(_("No further redo information"));
2102                 else
2103                         current_view->buffer()->update(-1);
2104         }
2105 }
2106
2107
2108 void HyphenationPoint()
2109 {
2110         if (current_view->available())  {
2111                 current_view->getScreen()->HideCursor();
2112                 current_view->buffer()->update(-2);
2113                 InsetSpecialChar * new_inset = 
2114                         new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
2115                 current_view->buffer()->insertInset(new_inset);
2116         }
2117 }
2118
2119
2120 void Ldots()
2121 {
2122         if (current_view->available())  {
2123                 current_view->getScreen()->HideCursor();
2124                 current_view->buffer()->update(-2);
2125                 InsetSpecialChar * new_inset = 
2126                         new InsetSpecialChar(InsetSpecialChar::LDOTS);
2127                 current_view->buffer()->insertInset(new_inset);
2128         }
2129 }
2130
2131
2132 void EndOfSentenceDot()
2133 {
2134         if (current_view->available())  {
2135                 current_view->getScreen()->HideCursor();
2136                 current_view->buffer()->update(-2);
2137                 InsetSpecialChar * new_inset = 
2138                         new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
2139                 current_view->buffer()->insertInset(new_inset);
2140         }
2141 }
2142
2143
2144 void MenuSeparator()
2145 {
2146         if (current_view->available())  {
2147                 current_view->getScreen()->HideCursor();
2148                 current_view->buffer()->update(-2);
2149                 InsetSpecialChar * new_inset = 
2150                         new InsetSpecialChar(InsetSpecialChar::MENU_SEPARATOR);
2151                 current_view->buffer()->insertInset(new_inset);
2152         }
2153 }
2154
2155
2156 void Newline()
2157 {
2158         if (current_view->available())  {
2159                 current_view->getScreen()->HideCursor();
2160                 current_view->buffer()->update(-2);
2161                 current_view->buffer()->text->InsertChar(LyXParagraph::META_NEWLINE);
2162                 current_view->buffer()->update(-1);
2163         }
2164 }
2165
2166
2167 void ProtectedBlank()
2168 {
2169         if (current_view->available())  {
2170                 current_view->getScreen()->HideCursor();
2171                 current_view->buffer()->update(-2);
2172                 current_view->buffer()->text->InsertChar(LyXParagraph::META_PROTECTED_SEPARATOR);
2173                 current_view->buffer()->update(-1);
2174         }
2175 }
2176
2177
2178 void HFill()
2179 {
2180         if (current_view->available())  {
2181                 current_view->getScreen()->HideCursor();
2182                 current_view->buffer()->update(-2);
2183                 current_view->buffer()->text->InsertChar(LyXParagraph::META_HFILL);
2184                 current_view->buffer()->update(-1);
2185         }
2186 }
2187
2188
2189 /* -------> These CB's use ToggleFree() as the (one and only?) font-changer. 
2190                         They also show the current font state. */
2191
2192 static
2193 void ToggleAndShow(LyXFont const &);
2194
2195
2196 void FontSizeCB(string const & size)
2197 {
2198         LyXFont font(LyXFont::ALL_IGNORE);
2199         font.setGUISize(size);
2200         ToggleAndShow(font);
2201 }
2202
2203
2204 void EmphCB()
2205 {
2206         LyXFont font(LyXFont::ALL_IGNORE);
2207         font.setEmph(LyXFont::TOGGLE);
2208         ToggleAndShow(font);
2209 }
2210
2211
2212 void NounCB()
2213 {
2214         LyXFont font(LyXFont::ALL_IGNORE);
2215         font.setNoun(LyXFont::TOGGLE);
2216         ToggleAndShow(font);
2217 }
2218
2219
2220 void BoldCB()
2221 {
2222         LyXFont font(LyXFont::ALL_IGNORE);
2223         font.setSeries(LyXFont::BOLD_SERIES);
2224         ToggleAndShow(font);
2225 }
2226
2227
2228 void UnderlineCB()
2229 {
2230         LyXFont font(LyXFont::ALL_IGNORE);
2231         font.setUnderbar(LyXFont::TOGGLE);
2232         ToggleAndShow(font);
2233 }
2234
2235
2236 void CodeCB()
2237 {
2238         LyXFont font(LyXFont::ALL_IGNORE);
2239         font.setFamily(LyXFont::TYPEWRITER_FAMILY); // no good
2240         ToggleAndShow(font);
2241 }
2242
2243
2244 void SansCB()
2245 {
2246         LyXFont font(LyXFont::ALL_IGNORE);
2247         font.setFamily(LyXFont::SANS_FAMILY);
2248         ToggleAndShow(font);
2249 }
2250
2251
2252 void RomanCB()
2253 {
2254         LyXFont font(LyXFont::ALL_IGNORE);
2255         font.setFamily(LyXFont::ROMAN_FAMILY);
2256         ToggleAndShow(font);
2257 }
2258
2259
2260 void TexCB()
2261 {
2262         LyXFont font(LyXFont::ALL_IGNORE);
2263         font.setLatex (LyXFont::TOGGLE);
2264         ToggleAndShow(font);
2265 }
2266
2267
2268 void StyleResetCB()
2269 {
2270         LyXFont font(LyXFont::ALL_INHERIT);
2271         ToggleAndShow(font);
2272 }
2273
2274
2275 /* -------> Returns the current font and depth by printing a message. In the
2276  * future perhaps we could try to implement a callback to the button-bar.
2277  * That is, `light' the bold button when the font is currently bold, etc.
2278  */
2279 string CurrentState()
2280 {
2281         string state;
2282         if (current_view->available()) { 
2283                 // I think we should only show changes from the default
2284                 // font. (Asger)
2285                 Buffer * buffer = current_view->buffer();
2286                 LyXFont font = buffer->text->real_current_font;
2287                 LyXFont defaultfont = textclasslist.TextClass(buffer->
2288                                                          params.textclass).defaultfont();
2289                 font.reduce(defaultfont);
2290                 state = _("Font: ") + font.stateText();
2291
2292                 int depth = buffer->text->GetDepth();
2293                 if (depth>0) 
2294                         state += string(_(", Depth: ")) + tostr(depth);
2295         }
2296         return state;
2297 }
2298
2299
2300 /* -------> Does the actual toggle job of the XxxCB() calls above.
2301  * Also shows the current font state.
2302  */
2303 static
2304 void ToggleAndShow(LyXFont const & font)
2305 {
2306         if (current_view->available()) { 
2307                 current_view->getScreen()->HideCursor();
2308                 current_view->buffer()->update(-2);
2309                 current_view->buffer()->text->ToggleFree(font, toggleall);
2310                 current_view->buffer()->update(1);
2311         }
2312         // removed since it overrides the ToggleFree Message about the style
2313         // Since Styles are more "High Level" than raw fonts I think the user
2314         // prefers it like this               Matthias
2315         // FontStateShowCB( 0, 0 );
2316 }
2317
2318
2319 extern "C" void MarginCB(FL_OBJECT *, long)
2320 {
2321         if (current_view->available()) {
2322                 minibuffer->Set(_("Inserting margin note..."));
2323                 current_view->getScreen()->HideCursor();
2324                 current_view->buffer()->update(-2);
2325                 current_view->buffer()->text->InsertFootnoteEnvironment(LyXParagraph::MARGIN);
2326                 current_view->buffer()->update(1);
2327         }
2328 }
2329
2330
2331 extern "C" void FigureCB(FL_OBJECT *, long)
2332 {
2333         if (fd_form_figure->form_figure->visible) {
2334                 fl_raise_form(fd_form_figure->form_figure);
2335         } else {
2336                 fl_show_form(fd_form_figure->form_figure,
2337                              FL_PLACE_MOUSE, FL_FULLBORDER,
2338                              _("Insert Figure"));
2339         }
2340 }
2341
2342
2343 extern "C" void TableCB(FL_OBJECT *, long)
2344 {
2345         if (fd_form_table->form_table->visible) {
2346                 fl_raise_form(fd_form_table->form_table);
2347         } else {
2348                 fl_show_form(fd_form_table->form_table,
2349                              FL_PLACE_MOUSE, FL_FULLBORDER,
2350                              _("Insert Table"));
2351         }
2352 }
2353
2354
2355 void CopyEnvironmentCB()
2356 {
2357         if (current_view->available()) {
2358                 current_view->buffer()->text->copyEnvironmentType();
2359                 /* clear the selection, even if mark_set */ 
2360                 current_view->getScreen()->ToggleSelection();
2361                 current_view->buffer()->text->ClearSelection();
2362                 current_view->buffer()->update(-2);
2363                 minibuffer->Set(_("Paragraph environment type copied"));
2364         }
2365 }
2366
2367
2368 void PasteEnvironmentCB()
2369 {
2370         if (current_view->available()) {
2371                 current_view->buffer()->text->pasteEnvironmentType();
2372                 minibuffer->Set(_("Paragraph environment type set"));
2373                 current_view->buffer()->update(1);
2374         }
2375 }
2376
2377
2378 void CopyCB()
2379 {
2380         if (current_view->available()) {
2381                 current_view->buffer()->text->CopySelection();
2382                 /* clear the selection, even if mark_set */ 
2383                 current_view->getScreen()->ToggleSelection();
2384                 current_view->buffer()->text->ClearSelection();
2385                 current_view->buffer()->update(-2);
2386                 minibuffer->Set(_("Copy"));
2387         }
2388 }
2389
2390
2391 void CutCB()
2392 {
2393         if (current_view->available()) {
2394                 current_view->getScreen()->HideCursor();
2395                 current_view->buffer()->update(-2);
2396                 current_view->buffer()->text->CutSelection();
2397                 current_view->buffer()->update(1);
2398                 minibuffer->Set(_("Cut"));
2399         }
2400 }
2401
2402
2403 void PasteCB()
2404 {
2405         if (!current_view->available()) return;
2406         
2407         minibuffer->Set(_("Paste"));
2408         current_view->getScreen()->HideCursor();
2409         /* clear the selection */ 
2410         current_view->getScreen()->ToggleSelection();
2411         current_view->buffer()->text->ClearSelection();
2412         current_view->buffer()->update(-2);
2413         
2414         /* paste */ 
2415         current_view->buffer()->text->PasteSelection();
2416         current_view->buffer()->update(1);
2417         
2418         /* clear the selection */ 
2419         current_view->getScreen()->ToggleSelection();
2420         current_view->buffer()->text->ClearSelection();
2421         current_view->buffer()->update(-2);
2422 }
2423
2424
2425 extern "C" void MeltCB(FL_OBJECT *, long)
2426 {
2427         if (!current_view->available()) return;
2428         
2429         minibuffer->Set(_("Melt"));
2430         current_view->getScreen()->HideCursor();
2431         BeforeChange();
2432         current_view->buffer()->update(-2);
2433         current_view->buffer()->text->MeltFootnoteEnvironment();
2434         current_view->buffer()->update(1);
2435 }
2436
2437
2438 // Change environment depth.
2439 // if decInc == 0, depth change taking mouse button number into account
2440 // if decInc == 1, increment depth
2441 // if decInc == -1, decrement depth
2442 extern "C" void DepthCB(FL_OBJECT * ob, long decInc)
2443 {
2444         int button = 1;
2445
2446         /* When decInc != 0, fake a mouse button. This allows us to
2447            implement depth-plus and depth-min commands. RVDK_PATCH_5. */
2448         /* check out wether ob is defined, too (Matthias) */ 
2449         if ( decInc < 0 )
2450                 button = 0;
2451         else if (!decInc && ob) {
2452                 button = fl_get_button_numb(ob);
2453         }
2454   
2455         if (current_view->available()) {
2456                 current_view->getScreen()->HideCursor();
2457                 current_view->buffer()->update(-2);
2458                 if (button == 1)
2459                         current_view->buffer()->text->IncDepth();
2460                 else
2461                         current_view->buffer()->text->DecDepth();
2462                 current_view->buffer()->update(1);
2463                 minibuffer->Set(_("Changed environment depth"
2464                                   " (in possible range, maybe not)"));
2465         }
2466 }
2467
2468
2469 // This is both GUI and LyXFont dependent. Don't know where to put it. (Asger)
2470 // Well, it's mostly GUI dependent, so I guess it will stay here. (Asger)
2471 LyXFont UserFreeFont()
2472 {
2473         LyXFont font(LyXFont::ALL_IGNORE);
2474
2475         int pos = fl_get_choice(fd_form_character->choice_family);
2476         switch(pos) {
2477         case 1: font.setFamily(LyXFont::IGNORE_FAMILY); break;
2478         case 2: font.setFamily(LyXFont::ROMAN_FAMILY); break;
2479         case 3: font.setFamily(LyXFont::SANS_FAMILY); break;
2480         case 4: font.setFamily(LyXFont::TYPEWRITER_FAMILY); break;
2481         case 5: font.setFamily(LyXFont::INHERIT_FAMILY); break;
2482         }
2483
2484         pos = fl_get_choice(fd_form_character->choice_series);
2485         switch(pos) {
2486         case 1: font.setSeries(LyXFont::IGNORE_SERIES); break;
2487         case 2: font.setSeries(LyXFont::MEDIUM_SERIES); break;
2488         case 3: font.setSeries(LyXFont::BOLD_SERIES); break;
2489         case 4: font.setSeries(LyXFont::INHERIT_SERIES); break;
2490         }
2491
2492         pos = fl_get_choice(fd_form_character->choice_shape);
2493         switch(pos) {
2494         case 1: font.setShape(LyXFont::IGNORE_SHAPE); break;
2495         case 2: font.setShape(LyXFont::UP_SHAPE); break;
2496         case 3: font.setShape(LyXFont::ITALIC_SHAPE); break;
2497         case 4: font.setShape(LyXFont::SLANTED_SHAPE); break;
2498         case 5: font.setShape(LyXFont::SMALLCAPS_SHAPE); break;
2499         case 6: font.setShape(LyXFont::INHERIT_SHAPE); break;
2500         }
2501
2502         pos = fl_get_choice(fd_form_character->choice_size);
2503         switch(pos) {
2504         case 1: font.setSize(LyXFont::IGNORE_SIZE); break;
2505         case 2: font.setSize(LyXFont::SIZE_TINY); break;
2506         case 3: font.setSize(LyXFont::SIZE_SCRIPT); break;
2507         case 4: font.setSize(LyXFont::SIZE_FOOTNOTE); break;
2508         case 5: font.setSize(LyXFont::SIZE_SMALL); break;
2509         case 6: font.setSize(LyXFont::SIZE_NORMAL); break;
2510         case 7: font.setSize(LyXFont::SIZE_LARGE); break;
2511         case 8: font.setSize(LyXFont::SIZE_LARGER); break;
2512         case 9: font.setSize(LyXFont::SIZE_LARGEST); break;
2513         case 10: font.setSize(LyXFont::SIZE_HUGE); break;
2514         case 11: font.setSize(LyXFont::SIZE_HUGER); break;
2515         case 12: font.setSize(LyXFont::INCREASE_SIZE); break;
2516         case 13: font.setSize(LyXFont::DECREASE_SIZE); break;
2517         case 14: font.setSize(LyXFont::INHERIT_SIZE); break;
2518         }
2519
2520         pos = fl_get_choice(fd_form_character->choice_bar);
2521         switch(pos) {
2522         case 1: font.setEmph(LyXFont::IGNORE);
2523                 font.setUnderbar(LyXFont::IGNORE);
2524                 font.setNoun(LyXFont::IGNORE);
2525                 font.setLatex(LyXFont::IGNORE);
2526                 break;
2527         case 2: font.setEmph(LyXFont::TOGGLE); break;
2528         case 3: font.setUnderbar(LyXFont::TOGGLE); break;
2529         case 4: font.setNoun(LyXFont::TOGGLE); break;
2530         case 5: font.setLatex(LyXFont::TOGGLE); break;
2531         case 6: font.setEmph(LyXFont::INHERIT);
2532                 font.setUnderbar(LyXFont::INHERIT);
2533                 font.setNoun(LyXFont::INHERIT);
2534                 font.setLatex(LyXFont::INHERIT);
2535                 break;
2536         }
2537
2538         pos = fl_get_choice(fd_form_character->choice_color);
2539         switch(pos) {
2540         case 1: font.setColor(LyXFont::IGNORE_COLOR); break;
2541         case 2: font.setColor(LyXFont::NONE); break;
2542         case 3: font.setColor(LyXFont::BLACK); break;
2543         case 4: font.setColor(LyXFont::WHITE); break;
2544         case 5: font.setColor(LyXFont::RED); break;
2545         case 6: font.setColor(LyXFont::GREEN); break;
2546         case 7: font.setColor(LyXFont::BLUE); break;
2547         case 8: font.setColor(LyXFont::CYAN); break;
2548         case 9: font.setColor(LyXFont::MAGENTA); break;
2549         case 10: font.setColor(LyXFont::YELLOW); break;
2550         case 11: font.setColor(LyXFont::INHERIT_COLOR); break;
2551         }
2552
2553         return font; 
2554 }
2555
2556
2557 void FreeCB()
2558 {
2559         ToggleAndShow(UserFreeFont());
2560 }
2561
2562
2563 /* callbacks for form form_title */
2564 extern "C" void TimerCB(FL_OBJECT *, long)
2565 {
2566         // only if the form still exists
2567         if (fd_form_title->form_title != 0) {
2568                 if (fd_form_title->form_title->visible) {
2569                         fl_hide_form(fd_form_title->form_title);
2570                 }
2571                 fl_free_form(fd_form_title->form_title);
2572                 fd_form_title->form_title = 0;
2573         }
2574 }
2575
2576
2577 /* callbacks for form form_paragraph */
2578
2579 extern "C" void ParagraphVSpaceCB(FL_OBJECT * obj, long )
2580 {
2581         // "Synchronize" the choices and input fields, making it
2582         // impossible to commit senseless data.
2583
2584         FD_form_paragraph const * fp = fd_form_paragraph;
2585
2586         if (obj == fp->choice_space_above) {
2587                 if (fl_get_choice (fp->choice_space_above) != 7) {
2588                         fl_set_input (fp->input_space_above, "");
2589                         ActivateParagraphButtons();
2590                 }
2591         } else if (obj == fp->choice_space_below) {
2592                 if (fl_get_choice (fp->choice_space_below) != 7) {
2593                         fl_set_input (fp->input_space_below, "");
2594                         ActivateParagraphButtons();
2595                 }
2596         } else if (obj == fp->input_space_above) {
2597                 string input = fl_get_input (fp->input_space_above);
2598
2599                 if (input.empty()) {
2600                         fl_set_choice (fp->choice_space_above, 1);
2601                         ActivateParagraphButtons();
2602                 }
2603                 else if (isValidGlueLength (input)) {
2604                         fl_set_choice (fp->choice_space_above, 7);
2605                         ActivateParagraphButtons();
2606                 }
2607                 else {
2608                         fl_set_choice (fp->choice_space_above, 7);
2609                         DeactivateParagraphButtons();
2610                 }
2611         } else if (obj == fp->input_space_below) {
2612                 string input = fl_get_input (fp->input_space_below);
2613
2614                 if (input.empty()) {
2615                         fl_set_choice (fp->choice_space_below, 1);
2616                         ActivateParagraphButtons();
2617                 }
2618                 else if (isValidGlueLength (input)) {
2619                         fl_set_choice (fp->choice_space_below, 7);
2620                         ActivateParagraphButtons();
2621                 }
2622                 else {
2623                         fl_set_choice (fp->choice_space_below, 7);
2624                         DeactivateParagraphButtons();
2625                 }
2626         }
2627 }
2628
2629
2630 extern "C" void ParagraphApplyCB(FL_OBJECT *, long)
2631 {
2632         if (!current_view->available())
2633                 return;
2634         
2635         VSpace space_top, space_bottom;
2636         LyXAlignment align;
2637         string labelwidthstring;
2638         bool noindent;
2639
2640         // If a vspace kind is "Length" but there's no text in
2641         // the input field, reset the kind to "None". 
2642         if (fl_get_choice (fd_form_paragraph->choice_space_above) == 7
2643             && !*(fl_get_input (fd_form_paragraph->input_space_above))) {
2644                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
2645         }
2646         if (fl_get_choice (fd_form_paragraph->choice_space_below) == 7
2647             && !*(fl_get_input (fd_form_paragraph->input_space_below))) {
2648                 fl_set_choice (fd_form_paragraph->choice_space_below, 1);
2649         }
2650    
2651         bool line_top = fl_get_button(fd_form_paragraph->check_lines_top);
2652         bool line_bottom = fl_get_button(fd_form_paragraph->check_lines_bottom);
2653         bool pagebreak_top = fl_get_button(fd_form_paragraph->check_pagebreaks_top);
2654         bool pagebreak_bottom = fl_get_button(fd_form_paragraph->check_pagebreaks_bottom);
2655         switch (fl_get_choice (fd_form_paragraph->choice_space_above)) {
2656         case 1: space_top = VSpace(VSpace::NONE); break;
2657         case 2: space_top = VSpace(VSpace::DEFSKIP); break;
2658         case 3: space_top = VSpace(VSpace::SMALLSKIP); break;
2659         case 4: space_top = VSpace(VSpace::MEDSKIP); break;
2660         case 5: space_top = VSpace(VSpace::BIGSKIP); break;
2661         case 6: space_top = VSpace(VSpace::VFILL); break;
2662         case 7: space_top = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_above))); break;
2663         }
2664         if (fl_get_button (fd_form_paragraph->check_space_above))
2665           space_top.setKeep (true);
2666         switch (fl_get_choice (fd_form_paragraph->choice_space_below)) {
2667         case 1: space_bottom = VSpace(VSpace::NONE); break;
2668         case 2: space_bottom = VSpace(VSpace::DEFSKIP); break;
2669         case 3: space_bottom = VSpace(VSpace::SMALLSKIP); break;
2670         case 4: space_bottom = VSpace(VSpace::MEDSKIP); break;
2671         case 5: space_bottom = VSpace(VSpace::BIGSKIP); break;
2672         case 6: space_bottom = VSpace(VSpace::VFILL); break;
2673         case 7: space_bottom = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_below))); break;
2674         }
2675         if (fl_get_button (fd_form_paragraph->check_space_below))
2676           space_bottom.setKeep (true);
2677
2678         if (fl_get_button(fd_form_paragraph->radio_align_left))
2679                 align = LYX_ALIGN_LEFT;
2680         else if (fl_get_button(fd_form_paragraph->radio_align_right))
2681                 align = LYX_ALIGN_RIGHT;
2682         else if (fl_get_button(fd_form_paragraph->radio_align_center))
2683                 align = LYX_ALIGN_CENTER;
2684         else 
2685                 align = LYX_ALIGN_BLOCK;
2686    
2687         labelwidthstring = fl_get_input(fd_form_paragraph->input_labelwidth);
2688         noindent = fl_get_button(fd_form_paragraph->check_noindent);
2689    
2690         current_view->buffer()->text->SetParagraph(line_top,
2691                                                           line_bottom,
2692                                                           pagebreak_top,
2693                                                           pagebreak_bottom,
2694                                                           space_top,
2695                                                           space_bottom,
2696                                                           align, 
2697                                                           labelwidthstring,
2698                                                           noindent);
2699         current_view->buffer()->update(1);
2700         minibuffer->Set(_("Paragraph layout set"));
2701 }
2702
2703
2704 extern "C" void ParagraphCancelCB(FL_OBJECT *, long)
2705 {
2706         fl_hide_form(fd_form_paragraph->form_paragraph);
2707 }
2708
2709
2710 extern "C" void ParagraphOKCB(FL_OBJECT *ob, long data)
2711 {
2712         ParagraphApplyCB(ob, data);
2713         ParagraphCancelCB(ob, data);
2714 }
2715
2716
2717 /* callbacks for form form_character */
2718
2719 extern "C" void CharacterApplyCB(FL_OBJECT *, long)
2720 {
2721         // we set toggleall locally here, since it should be true for
2722         // all other uses of ToggleAndShow() (JMarc)
2723         toggleall = fl_get_button(fd_form_character->check_toggle_all);
2724         ToggleAndShow( UserFreeFont());
2725         toggleall = true;
2726 }
2727
2728
2729 extern "C" void CharacterCloseCB(FL_OBJECT *, long)
2730 {
2731         fl_hide_form(fd_form_character->form_character);
2732 }
2733
2734
2735 extern "C" void CharacterOKCB(FL_OBJECT *ob, long data)
2736 {
2737         CharacterApplyCB(ob, data);
2738         CharacterCloseCB(ob, data);
2739 }
2740
2741
2742 /* callbacks for form form_document */
2743
2744 void UpdateDocumentButtons(BufferParams const & params) 
2745 {
2746         fl_set_choice(fd_form_document->choice_pagestyle, 1);
2747         
2748         if (params.sides == 2)
2749                 fl_set_button(fd_form_document->radio_sides_two, 1);
2750         else
2751                 fl_set_button(fd_form_document->radio_sides_one, 1);
2752         
2753         if (params.columns == 2)
2754                 fl_set_button(fd_form_document->radio_columns_two, 1);
2755         else
2756                 fl_set_button(fd_form_document->radio_columns_one, 1);
2757         
2758         fl_set_input(fd_form_document->input_extra, params.options.c_str());
2759         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
2760                              params.secnumdepth);
2761         fl_set_counter_value(fd_form_document->slider_tocdepth, 
2762                              params.tocdepth);
2763         
2764 }
2765
2766 extern "C" void ChoiceClassCB(FL_OBJECT * ob, long)
2767 {
2768         ProhibitInput();
2769         if (textclasslist.Load(fl_get_choice(ob)-1)) {
2770                 if (AskQuestion(_("Should I set some parameters to"),
2771                                 fl_get_choice_text(ob),
2772                                 _("the defaults of this document class?"))) {
2773                         BufferParams params = BufferParams();
2774                         params.textclass = fl_get_choice(ob)-1;
2775                         params.useClassDefaults();
2776                         UpdateLayoutDocument(&params);
2777                         UpdateDocumentButtons(params);
2778                 }
2779         } else {
2780                 // unable to load new style
2781                 WriteAlert(_("Conversion Errors!"),
2782                            _("Unable to switch to new document class."),
2783                            _("Reverting to original document class."));
2784                 fl_set_choice(fd_form_document->choice_class, 
2785                               GetCurrentTextClass() + 1);
2786         }
2787         AllowInput();
2788 }
2789
2790
2791 extern "C" void DocumentDefskipCB(FL_OBJECT * obj, long)
2792 {
2793         // "Synchronize" the choice and the input field, so that it
2794         // is impossible to commit senseless data.
2795         FD_form_document const * fd = fd_form_document;
2796
2797         if (obj == fd->choice_default_skip) {
2798                 if (fl_get_choice (fd->choice_default_skip) != 4) {
2799                         fl_set_input (fd->input_default_skip, "");
2800                         ActivateDocumentButtons();
2801                 }
2802         } else if (obj == fd->input_default_skip) {
2803
2804                 char const * input = fl_get_input (fd->input_default_skip);
2805
2806                 if (!*input) {
2807                         fl_set_choice (fd->choice_default_skip, 2);
2808                         ActivateDocumentButtons();
2809                 } else if (isValidGlueLength (input)) {
2810                         fl_set_choice (fd->choice_default_skip, 4);
2811                         ActivateDocumentButtons();
2812                 } else {
2813                         fl_set_choice (fd->choice_default_skip, 4);
2814                         DeactivateDocumentButtons();
2815                 }
2816         }
2817 }
2818
2819
2820 extern "C" void DocumentSpacingCB(FL_OBJECT * obj, long)
2821 {
2822         // "Synchronize" the choice and the input field, so that it
2823         // is impossible to commit senseless data.
2824         FD_form_document const * fd = fd_form_document;
2825
2826         if (obj == fd->choice_spacing
2827             && fl_get_choice (fd->choice_spacing) != 4) {
2828                 fl_set_input(fd->input_spacing, "");
2829         } else if (obj == fd->input_spacing) {
2830
2831                 const char* input = fl_get_input (fd->input_spacing);
2832
2833                 if (!*input) {
2834                         fl_set_choice (fd->choice_spacing, 1);
2835                 } else {
2836                         fl_set_choice (fd->choice_spacing, 4);
2837                 }
2838         }
2839 }
2840
2841
2842 extern "C" void DocumentApplyCB(FL_OBJECT *, long)
2843 {
2844         bool redo = false;
2845         BufferParams *params = &(current_view->buffer()->params);
2846         current_view->buffer()->params.language = 
2847                 combo_language->getline();
2848
2849         // If default skip is a "Length" but there's no text in the
2850         // input field, reset the kind to "Medskip", which is the default.
2851         if (fl_get_choice (fd_form_document->choice_default_skip) == 4
2852             && !*(fl_get_input (fd_form_document->input_default_skip))) {
2853                 fl_set_choice (fd_form_document->choice_default_skip, 2);
2854         }
2855
2856         /* this shouldn't be done automatically IMO. For example I write german
2857          * documents with an american keyboard very often. Matthias */
2858    
2859         /* ChangeKeymap(buffer->parameters.language, TRUE, false,
2860            fl_get_choice(fd_form_document->choice_language)); */
2861         params->fonts = 
2862                 fl_get_choice_text(fd_form_document->choice_fonts);
2863         params->inputenc = 
2864                 fl_get_choice_text(fd_form_document->choice_inputenc);
2865         params->fontsize = 
2866                 fl_get_choice_text(fd_form_document->choice_fontsize);
2867         params->pagestyle = 
2868                 fl_get_choice_text(fd_form_document->choice_pagestyle);
2869         params->graphicsDriver = 
2870                 fl_get_choice_text(fd_form_document->choice_postscript_driver);
2871         params->use_amsmath = 
2872                 fl_get_button(fd_form_document->check_use_amsmath);
2873    
2874         if (!current_view->available())
2875                 return;
2876
2877         LyXTextClassList::ClassList::size_type new_class = fl_get_choice(fd_form_document->choice_class) - 1;
2878         if (params->textclass != new_class) {
2879                 // try to load new_class
2880                 if (textclasslist.Load(new_class)) {
2881                         // successfully loaded
2882                         redo = true;
2883                         minibuffer->Set(_("Converting document to new document class..."));
2884                         int ret = current_view->buffer()->
2885                                 text->
2886                                 SwitchLayoutsBetweenClasses(current_view->buffer()->
2887                                                             params.textclass,
2888                                                             new_class,
2889                                                             current_view->buffer()->
2890                                                             paragraph);
2891
2892                         if (ret){
2893                                 string s;
2894                                 if (ret == 1)
2895                                         s = _("One paragraph couldn't be converted");
2896                                 else {
2897                                         s += tostr(ret);
2898                                         s += _(" paragraphs couldn't be converted");
2899                                 }
2900                                 WriteAlert(_("Conversion Errors!"), s,
2901                                            _("into chosen document class"));
2902                         }
2903
2904                         params->textclass = new_class;
2905                 } else {
2906                         // problem changing class -- warn user and retain old style
2907                         WriteAlert(_("Conversion Errors!"),
2908                                    _("Unable to switch to new document class."),
2909                                    _("Reverting to original document class."));
2910                         fl_set_choice(fd_form_document->choice_class, params->textclass + 1);
2911                 }
2912         }
2913
2914         char tmpsep = params->paragraph_separation;
2915         if (fl_get_button(fd_form_document->radio_indent))
2916                 params->paragraph_separation = BufferParams::PARSEP_INDENT;
2917         else
2918                 params->paragraph_separation = BufferParams::PARSEP_SKIP;
2919         if (tmpsep != params->paragraph_separation)
2920                 redo = true;
2921    
2922         VSpace tmpdefskip = params->getDefSkip();
2923         switch (fl_get_choice (fd_form_document->choice_default_skip)) {
2924         case 1: params->setDefSkip(VSpace(VSpace::SMALLSKIP)); break;
2925         case 2: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2926         case 3: params->setDefSkip(VSpace(VSpace::BIGSKIP)); break;
2927         case 4: params->setDefSkip( 
2928                 VSpace (LyXGlueLength (fl_get_input 
2929                                        (fd_form_document->input_default_skip))));
2930         break;
2931         // DocumentDefskipCB assures that this never happens
2932         default: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2933         }
2934         if (!(tmpdefskip == params->getDefSkip()))
2935                 redo = true;
2936
2937         if (fl_get_button(fd_form_document->radio_columns_two))
2938                 params->columns = 2;
2939         else
2940                 params->columns = 1;
2941         if (fl_get_button(fd_form_document->radio_sides_two))
2942                 params->sides = LyXTextClass::TwoSides;
2943         else
2944                 params->sides = LyXTextClass::OneSide;
2945
2946         Spacing tmpSpacing = params->spacing;
2947         switch(fl_get_choice(fd_form_document->choice_spacing)) {
2948         case 1:
2949                 lyxerr.debug() << "Spacing: SINGLE" << endl;
2950                 params->spacing.set(Spacing::Single);
2951                 break;
2952         case 2:
2953                 lyxerr.debug() << "Spacing: ONEHALF" << endl;
2954                 params->spacing.set(Spacing::Onehalf);
2955                 break;
2956         case 3:
2957                 lyxerr.debug() << "Spacing: DOUBLE" << endl;
2958                 params->spacing.set(Spacing::Double);
2959                 break;
2960         case 4:
2961                 lyxerr.debug() << "Spacing: OTHER" << endl;
2962                 params->spacing.set(Spacing::Other, 
2963                                     fl_get_input(fd_form_document->input_spacing));
2964                 break;
2965         }
2966         if (tmpSpacing != params->spacing)
2967                 redo = true;
2968         
2969         signed char tmpchar =  
2970                 static_cast<signed char>(fl_get_counter_value(fd_form_document->slider_secnumdepth));
2971         if (params->secnumdepth != tmpchar)
2972                 redo = true;
2973         params->secnumdepth = tmpchar;
2974    
2975         params->tocdepth =  
2976                 static_cast<int>(fl_get_counter_value(fd_form_document->slider_tocdepth));
2977
2978         params->float_placement = 
2979                 fl_get_input(fd_form_document->input_float_placement);
2980
2981         // More checking should be done to ensure the string doesn't have
2982         // spaces or illegal placement characters in it. (thornley)
2983
2984         if (redo)
2985                 current_view->redoCurrentBuffer();
2986    
2987         minibuffer->Set(_("Document layout set"));
2988         current_view->buffer()->markDirty();
2989
2990         params->options = 
2991                 fl_get_input(fd_form_document->input_extra);
2992    
2993 }
2994
2995
2996 extern "C" void DocumentCancelCB(FL_OBJECT *, long)
2997 {
2998         fl_hide_form(fd_form_document->form_document);
2999 }
3000
3001
3002 extern "C" void DocumentOKCB(FL_OBJECT * ob, long data)
3003 {
3004         DocumentCancelCB(ob, data);
3005         DocumentApplyCB(ob, data);
3006 }
3007
3008
3009 extern "C" void DocumentBulletsCB(FL_OBJECT *, long)
3010 {
3011         bulletForm();
3012         // bullet callbacks etc. in bullet_panel.C -- ARRae
3013 }
3014
3015
3016 void GotoNote()
3017 {
3018         if (!current_view->getScreen())
3019                 return;
3020    
3021         current_view->getScreen()->HideCursor();
3022         BeforeChange();
3023         current_view->buffer()->update(-2);
3024         LyXCursor tmp;
3025    
3026         if (!current_view->buffer()->text->GotoNextNote()) {
3027                 if (current_view->buffer()->text->cursor.pos 
3028                     || current_view->buffer()->text->cursor.par != 
3029                     current_view->buffer()->text->FirstParagraph())
3030                         {
3031                                 tmp = current_view->buffer()->text->cursor;
3032                                 current_view->buffer()->text->cursor.par = 
3033                                         current_view->buffer()->text->FirstParagraph();
3034                                 current_view->buffer()->text->cursor.pos = 0;
3035                                 if (!current_view->buffer()->text->GotoNextNote()) {
3036                                         current_view->buffer()->text->cursor = tmp;
3037                                         minibuffer->Set(_("No more notes"));
3038                                         LyXBell();
3039                                 }
3040                         } else {
3041                                 minibuffer->Set(_("No more notes"));
3042                                 LyXBell();
3043                         }
3044         }
3045         current_view->buffer()->update(0);
3046         current_view->buffer()->text->sel_cursor = 
3047                 current_view->buffer()->text->cursor;
3048 }
3049
3050
3051 void InsertCorrectQuote()
3052 {
3053         Buffer * cbuffer = current_view->buffer();
3054         char c;
3055
3056         if  (cbuffer->text->cursor.pos )
3057                 c = cbuffer->text->cursor.par->GetChar(cbuffer->text->cursor.pos - 1);
3058         else 
3059                 c = ' ';
3060
3061         cbuffer->insertInset(new InsetQuotes(c, cbuffer->params));
3062 }
3063
3064
3065 /* callbacks for form form_quotes */
3066
3067 extern "C" void QuotesApplyCB(FL_OBJECT *, long)
3068 {
3069         if (!current_view->available())
3070                 return;
3071         
3072         minibuffer->Set(_("Quotes type set"));
3073         //current_view->buffer()->params.quotes_language = 
3074         //      fl_get_choice(fd_form_quotes->choice_quotes_language) - 1;
3075         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
3076         switch(fl_get_choice(fd_form_quotes->choice_quotes_language) - 1) {
3077         case 0:
3078                 lga = InsetQuotes::EnglishQ;
3079                 break;
3080         case 1:
3081                 lga = InsetQuotes::SwedishQ;
3082                 break;
3083         case 2:
3084                 lga = InsetQuotes::GermanQ;
3085                 break;
3086         case 3:
3087                 lga = InsetQuotes::PolishQ;
3088                 break;
3089         case 4:
3090                 lga = InsetQuotes::FrenchQ;
3091                 break;
3092         case 5:
3093                 lga = InsetQuotes::DanishQ;
3094                 break;
3095         }
3096         current_view->buffer()->params.quotes_language = lga;
3097         if (fl_get_button(fd_form_quotes->radio_single))   
3098                 current_view->buffer()->
3099                         params.quotes_times = InsetQuotes::SingleQ;
3100         else
3101                 current_view->buffer()->
3102                         params.quotes_times = InsetQuotes::DoubleQ;
3103 }
3104
3105
3106 extern "C" void QuotesCancelCB(FL_OBJECT *, long)
3107 {
3108         fl_hide_form(fd_form_quotes->form_quotes);
3109 }
3110
3111
3112 extern "C" void QuotesOKCB(FL_OBJECT * ob, long data)
3113 {
3114         QuotesApplyCB(ob, data);
3115         QuotesCancelCB(ob, data);
3116 }
3117
3118
3119
3120 /* callbacks for form form_preamble */
3121
3122 extern "C" void PreambleCancelCB(FL_OBJECT *, long)
3123 {
3124         fl_hide_form(fd_form_preamble->form_preamble);
3125 }
3126
3127
3128 extern "C" void PreambleApplyCB(FL_OBJECT *, long)
3129 {
3130         if (!current_view->available())
3131                 return;
3132         
3133         current_view->buffer()->params.preamble = 
3134                 fl_get_input(fd_form_preamble->input_preamble);
3135         current_view->buffer()->markDirty();
3136         minibuffer->Set(_("LaTeX preamble set"));
3137 }
3138
3139    
3140 extern "C" void PreambleOKCB(FL_OBJECT * ob, long data)
3141 {
3142         PreambleApplyCB(ob, data);
3143         PreambleCancelCB(ob, data);
3144 }
3145
3146
3147 /* callbacks for form form_table */
3148
3149 extern "C" void TableApplyCB(FL_OBJECT *, long)
3150 {
3151         if (!current_view->getScreen())
3152                 return;
3153    
3154         // check for tables in tables
3155         if (current_view->buffer()->text->cursor.par->table){
3156                 WriteAlert(_("Impossible Operation!"),
3157                            _("Cannot insert table in table."),
3158                            _("Sorry."));
3159                 return;
3160         }
3161  
3162         minibuffer->Set(_("Inserting table..."));
3163
3164         int ysize = int(fl_get_slider_value(fd_form_table->slider_columns) + 0.5);
3165         int xsize = int(fl_get_slider_value(fd_form_table->slider_rows) + 0.5);
3166    
3167    
3168         current_view->getScreen()->HideCursor();
3169         BeforeChange();
3170         current_view->buffer()->update(-2);
3171    
3172         current_view->buffer()->text->SetCursorParUndo(); 
3173         current_view->buffer()->text->FreezeUndo();
3174
3175         current_view->buffer()->text->BreakParagraph();
3176         current_view->buffer()->update(-1);
3177    
3178         if (current_view->buffer()->text->cursor.par->Last()) {
3179                 current_view->buffer()->text->CursorLeft();
3180       
3181                 current_view->buffer()->text->BreakParagraph();
3182                 current_view->buffer()->update(-1);
3183         }
3184
3185         current_view->buffer()->text->current_font.setLatex(LyXFont::OFF);
3186         //if (!fl_get_button(fd_form_table->check_latex)){
3187         // insert the new wysiwy table
3188         current_view->buffer()->text->SetLayout(0); // standard layout
3189         if (current_view->buffer()->text->cursor.par->footnoteflag == 
3190             LyXParagraph::NO_FOOTNOTE) {
3191                 current_view->buffer()->
3192                         text->SetParagraph(0, 0,
3193                                            0, 0,
3194                                            VSpace (0.3 * current_view->buffer()->
3195                                                    params.spacing.getValue(),
3196                                                    LyXLength::CM),
3197                                            VSpace (0.3 * current_view->buffer()->
3198                                                    params.spacing.getValue(),
3199                                                    LyXLength::CM),
3200                                            LYX_ALIGN_CENTER,
3201                                            string(),
3202                                            0);
3203         }
3204         else
3205                 current_view->buffer()->
3206                         text->SetParagraph(0, 0,
3207                                            0, 0,
3208                                            VSpace(VSpace::NONE),
3209                                            VSpace(VSpace::NONE),
3210                                            LYX_ALIGN_CENTER, 
3211                                            string(),
3212                                            0);
3213
3214         current_view->buffer()->text->cursor.par->table =
3215                 new LyXTable(xsize, ysize);
3216
3217         for (int i = 0; i < xsize * ysize - 1; ++i)
3218                 current_view->buffer()->text->cursor.par->InsertChar(0, LyXParagraph::META_NEWLINE);
3219         current_view->buffer()->text->RedoParagraph();
3220    
3221         current_view->buffer()->text->UnFreezeUndo();
3222      
3223         current_view->buffer()->update(1);
3224         minibuffer->Set(_("Table inserted"));
3225 }
3226
3227
3228 extern "C" void TableCancelCB(FL_OBJECT *, long)
3229 {
3230         fl_hide_form(fd_form_table->form_table);
3231 }
3232
3233
3234 extern "C" void TableOKCB(FL_OBJECT * ob, long data)
3235 {
3236         TableApplyCB(ob, data);
3237         TableCancelCB(ob, data);
3238 }
3239
3240
3241 /* callbacks for form form_print */
3242
3243 extern "C" void PrintCancelCB(FL_OBJECT *, long)
3244 {
3245         fl_hide_form(fd_form_print->form_print);
3246 }
3247
3248 static bool stringOnlyContains (string const & LStr, char const * cset)
3249 {
3250         char const * cstr = LStr.c_str() ;
3251
3252         return strspn(cstr, cset) == strlen(cstr) ;
3253 }
3254
3255 extern "C" void PrintApplyCB(FL_OBJECT *, long)
3256 {
3257         if (!current_view->available())
3258                 return;
3259         Buffer * buffer = current_view->buffer();
3260         string path = OnlyPath(buffer->getFileName());
3261
3262         string pageflag;
3263         if (fl_get_button(fd_form_print->radio_even_pages))
3264                 pageflag = lyxrc->print_evenpage_flag + ' ';
3265         else if (fl_get_button(fd_form_print->radio_odd_pages))
3266                 pageflag = lyxrc->print_oddpage_flag + ' ';
3267
3268 // Changes by Stephan Witt (stephan.witt@beusen.de), 19-Jan-99
3269 // User may give a page (range) list
3270 // User may print multiple (unsorted) copies
3271         string pages = subst(fl_get_input(fd_form_print->input_pages), ';',',');
3272         pages = subst(pages, '+',',');
3273         pages = frontStrip(strip(pages)) ;
3274         while (!pages.empty()) { // a page range was given
3275                 string piece ;
3276                 pages = split (pages, piece, ',') ;
3277                 piece = strip(piece) ;
3278                 piece = frontStrip(piece) ;
3279                 if ( !stringOnlyContains (piece, "0123456789-") ) {
3280                         WriteAlert(_("ERROR!  Unable to print!"),
3281                                 _("Check 'range of pages'!"));
3282                         return;
3283                 }
3284                 if (piece.find('-') == string::npos) { // not found
3285                         pageflag += lyxrc->print_pagerange_flag + piece + '-' + piece + ' ' ;
3286                 } else if (suffixIs(piece, "-") ) { // missing last page
3287                         pageflag += lyxrc->print_pagerange_flag + piece + "1000 ";
3288                 } else if (prefixIs(piece, "-") ) { // missing first page
3289                         pageflag += lyxrc->print_pagerange_flag + '1' + piece + ' ' ;
3290                 } else {
3291                         pageflag += lyxrc->print_pagerange_flag + piece + ' ' ;
3292                 }
3293         }
3294    
3295         string copies = frontStrip(strip(fl_get_input(fd_form_print->input_copies)));
3296         if (!copies.empty()) { // a number of copies was given
3297                 if ( !stringOnlyContains (copies, "0123456789") ) {
3298                         WriteAlert(_("ERROR!  Unable to print!"),
3299                                 _("Check 'number of copies'!"));
3300                         return;
3301                 }
3302                 if (fl_get_button(fd_form_print->do_unsorted))
3303                         pageflag += lyxrc->print_copies_flag;
3304                 else
3305                         pageflag += lyxrc->print_collcopies_flag;
3306                 pageflag += " " + copies + ' ' ;
3307         }
3308
3309         string reverseflag;
3310         if (fl_get_button(fd_form_print->radio_order_reverse))
3311                 reverseflag = lyxrc->print_reverse_flag + ' ';
3312    
3313         string orientationflag;
3314         if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
3315                 orientationflag = lyxrc->print_landscape_flag + ' ';
3316    
3317         string ps_file = SpaceLess(fl_get_input(fd_form_print->input_file));
3318         string printer = strip(fl_get_input(fd_form_print->input_printer));
3319
3320         string printerflag;
3321         if (lyxrc->print_adapt_output // printer name should be passed to dvips
3322             && ! printer.empty()) // a printer name has been given
3323                 printerflag = lyxrc->print_to_printer + printer + ' ';
3324      
3325         string extraflags;
3326         if (!lyxrc->print_extra_options.empty())
3327                 extraflags = lyxrc->print_extra_options + ' ';
3328
3329         string command = lyxrc->print_command + ' ' 
3330                 + printerflag + pageflag + reverseflag 
3331                 + orientationflag + extraflags;
3332  
3333         char real_papersize = buffer->params.papersize;
3334         if (real_papersize == BufferParams::PAPER_DEFAULT)
3335                 real_papersize = lyxrc->default_papersize;
3336         
3337         string paper;
3338         switch (real_papersize) {
3339         case BufferParams::PAPER_USLETTER:
3340                 paper = "letter";
3341                 break;
3342         case BufferParams::PAPER_A3PAPER:
3343                 paper = "a3";
3344                 break;
3345         case BufferParams::PAPER_A4PAPER:
3346                 paper = "a4";
3347                 break;
3348         case BufferParams::PAPER_A5PAPER:
3349                 paper = "a5";
3350                 break;
3351         case BufferParams::PAPER_B5PAPER:
3352                 paper = "b5";
3353                 break;
3354         case BufferParams::PAPER_EXECUTIVEPAPER:
3355                 paper = "foolscap";
3356                 break;
3357         case BufferParams::PAPER_LEGALPAPER:
3358                 paper = "legal";
3359                 break;
3360         default: /* If nothing else fits, keep an empty value... */
3361                 break;
3362         }
3363
3364         if (buffer->params.use_geometry
3365             && buffer->params.papersize2 == BufferParams::VM_PAPER_CUSTOM
3366             && !lyxrc->print_paper_dimension_flag.empty()
3367             && !buffer->params.paperwidth.empty()
3368             && !buffer->params.paperheight.empty()) {
3369                 // using a custom papersize
3370                 command += ' ';
3371                 command += lyxrc->print_paper_dimension_flag + ' ';
3372                 command += buffer->params.paperwidth + ',';
3373                 command += buffer->params.paperheight + ' ';
3374         } else if (!lyxrc->print_paper_flag.empty()
3375                    && !paper.empty()
3376                    && (real_papersize != BufferParams::PAPER_USLETTER ||
3377                        buffer->params.orientation == BufferParams::ORIENTATION_PORTRAIT)) {
3378                 command += " " + lyxrc->print_paper_flag + " " + paper + " ";
3379         }
3380         if (fl_get_button(fd_form_print->radio_file))
3381                 command += lyxrc->print_to_file + '\"'
3382                         + MakeAbsPath(ps_file, path)
3383                         + '\"';
3384         else if (!lyxrc->print_spool_command.empty())
3385                 command += lyxrc->print_to_file 
3386                         + '\"' + ps_file + '\"';
3387         
3388         // push directorypath, if necessary 
3389         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)){
3390                 path = buffer->tmppath;
3391         }
3392         Path p(path);
3393
3394         bool result;
3395         if (!lyxrc->print_spool_command.empty() && 
3396             !fl_get_button(fd_form_print->radio_file)) {
3397                 string command2 = lyxrc->print_spool_command + ' ';
3398                 if (!printer.empty())
3399                         command2 += lyxrc->print_spool_printerprefix 
3400                                     + printer;
3401                 // First run dvips and, if succesful, then spool command
3402                 if ((result = RunScript(buffer, true, command))) {
3403                         result = RunScript(buffer, false, command2, ps_file);
3404                 }
3405         } else
3406                 result = RunScript(buffer, false, command);
3407
3408         if (!result)
3409                 WriteAlert(_("Error:"),
3410                            _("Unable to print"),
3411                            _("Check that your parameters are correct"));
3412 }
3413
3414
3415 extern "C" void PrintOKCB(FL_OBJECT * ob, long data)
3416 {
3417         PrintCancelCB(ob, data);  
3418         PrintApplyCB(ob, data);
3419 }
3420
3421
3422 /* callbacks for form form_figure */
3423
3424 extern "C" void FigureApplyCB(FL_OBJECT *, long)
3425 {
3426         if (!current_view->available())
3427                 return;
3428
3429         Buffer * buffer = current_view->buffer();
3430         if(buffer->isReadonly()) // paranoia
3431                 return;
3432         
3433         minibuffer->Set(_("Inserting figure..."));
3434         if (fl_get_button(fd_form_figure->radio_inline)
3435             || buffer->text->cursor.par->table) {
3436                 InsetFig * new_inset = new InsetFig(100, 20, buffer);
3437                 buffer->insertInset(new_inset);
3438                 minibuffer->Set(_("Figure inserted"));
3439                 new_inset->Edit(0, 0);
3440                 return;
3441         }
3442         
3443         current_view->getScreen()->HideCursor();
3444         buffer->update(-2);
3445         BeforeChange();
3446       
3447         buffer->text->SetCursorParUndo(); 
3448         buffer->text->FreezeUndo();
3449
3450         buffer->text->BreakParagraph();
3451         buffer->update(-1);
3452       
3453         if (buffer->text->cursor.par->Last()) {
3454                 buffer->text->CursorLeft();
3455          
3456                 buffer->text->BreakParagraph();
3457                 buffer->update(-1);
3458         }
3459
3460         // The standard layout should always be numer 0;
3461         buffer->text->SetLayout(0);
3462         
3463         if (buffer->text->cursor.par->footnoteflag == 
3464             LyXParagraph::NO_FOOTNOTE) {
3465                 buffer->text->
3466                         SetParagraph(0, 0,
3467                                      0, 0,
3468                                      VSpace (0.3 * buffer->params.spacing.getValue(),
3469                                              LyXLength::CM),
3470                                      VSpace (0.3 *
3471                                              buffer->params.spacing.getValue(),
3472                                              LyXLength::CM),
3473                                      LYX_ALIGN_CENTER, string(), 0);
3474         } else
3475                 buffer->text->SetParagraph(0, 0,
3476                                            0, 0,
3477                                            VSpace(VSpace::NONE),
3478                                            VSpace(VSpace::NONE),
3479                                            LYX_ALIGN_CENTER, 
3480                                            string(),
3481                                            0);
3482         
3483         buffer->update(-1);
3484       
3485         Inset * new_inset = new InsetFig(100, 100, buffer);
3486         buffer->insertInset(new_inset);
3487         new_inset->Edit(0, 0);
3488         buffer->update(0);
3489         minibuffer->Set(_("Figure inserted"));
3490         buffer->text->UnFreezeUndo();
3491 }
3492
3493    
3494 extern "C" void FigureCancelCB(FL_OBJECT *, long)
3495 {
3496         fl_hide_form(fd_form_figure->form_figure);
3497 }
3498
3499
3500 extern "C" void FigureOKCB(FL_OBJECT * ob, long data)
3501 {
3502         FigureApplyCB(ob, data);
3503         FigureCancelCB(ob, data);
3504 }
3505
3506
3507 extern "C" void ScreenApplyCB(FL_OBJECT *, long)
3508 {
3509         lyxrc->roman_font_name = fl_get_input(fd_form_screen->input_roman);
3510         lyxrc->sans_font_name = fl_get_input(fd_form_screen->input_sans);
3511         lyxrc->typewriter_font_name = fl_get_input(fd_form_screen->input_typewriter);
3512         lyxrc->font_norm = fl_get_input(fd_form_screen->input_font_norm);
3513         lyxrc->zoom = atoi(fl_get_input(fd_form_screen->intinput_size));
3514         fontloader.update();
3515    
3516         // All buffers will need resize
3517         bufferlist.resize();
3518
3519         minibuffer->Set(_("Screen options set"));
3520 }
3521
3522
3523 extern "C" void ScreenCancelCB(FL_OBJECT *, long)
3524 {
3525         fl_hide_form(fd_form_screen->form_screen);
3526 }
3527
3528
3529 extern "C" void ScreenOKCB(FL_OBJECT * ob, long data)
3530 {
3531         ScreenCancelCB(ob, data);
3532         ScreenApplyCB(ob, data);
3533 }
3534
3535
3536 void LaTeXOptions()
3537 {
3538         if (!current_view->available())
3539                 return;
3540
3541         fl_set_button(fd_latex_options->accents,
3542                       (int)current_view->buffer()->params.allowAccents);
3543         
3544         if (fd_latex_options->LaTeXOptions->visible) {
3545                 fl_raise_form(fd_latex_options->LaTeXOptions);
3546         } else {
3547                 fl_show_form(fd_latex_options->LaTeXOptions,
3548                              FL_PLACE_MOUSE, FL_FULLBORDER,
3549                              _("LaTeX Options"));
3550         }
3551 }
3552
3553
3554 // This function runs "configure" and then rereads lyx.defaults to
3555 // reconfigure the automatic settings.
3556 void Reconfigure()
3557 {
3558         minibuffer->Set(_("Running configure..."));
3559
3560         // Run configure in user lyx directory
3561         Path p(user_lyxdir);
3562         Systemcalls one(Systemcalls::System, 
3563                           AddName(system_lyxdir, "configure"));
3564         p.pop();
3565         minibuffer->Set(_("Reloading configuration..."));
3566         lyxrc->read(LibFileSearch(string(), "lyxrc.defaults"));
3567         WriteAlert(_("The system has been reconfigured."), 
3568                    _("You need to restart LyX to make use of any"),
3569                    _("updated document class specifications."));
3570 }
3571
3572
3573 /* these functions are for the spellchecker */ 
3574 char * NextWord(float & value)
3575 {
3576         if (!current_view->available()){
3577                 value = 1;
3578                 return 0;
3579         }
3580    
3581         char * string =  current_view->buffer()->text->SelectNextWord(value);
3582
3583         return string;
3584 }
3585
3586   
3587 void SelectLastWord()
3588 {
3589         if (!current_view->available())
3590                 return;
3591    
3592         current_view->getScreen()->HideCursor();
3593         BeforeChange(); 
3594         current_view->buffer()->text->SelectSelectedWord();
3595         current_view->getScreen()->ToggleSelection(false);
3596         current_view->buffer()->update(0);
3597 }
3598
3599
3600 void EndOfSpellCheck()
3601 {
3602         if (!current_view->available())
3603                 return;
3604    
3605         current_view->getScreen()->HideCursor();
3606         BeforeChange(); 
3607         current_view->buffer()->text->SelectSelectedWord();
3608         current_view->buffer()->text->ClearSelection();
3609         current_view->buffer()->update(0);
3610 }
3611
3612
3613 void ReplaceWord(string const & replacestring)
3614 {
3615         if (!current_view->getScreen())
3616                 return;
3617
3618         current_view->getScreen()->HideCursor();
3619         current_view->buffer()->update(-2);
3620    
3621         /* clear the selection (if there is any) */ 
3622         current_view->getScreen()->ToggleSelection(false);
3623         current_view->buffer()->text->
3624                 ReplaceSelectionWithString(replacestring.c_str());
3625    
3626         current_view->buffer()->text->SetSelectionOverString(replacestring.c_str());
3627
3628         // Go back so that replacement string is also spellchecked
3629         for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
3630                 current_view->buffer()->text->CursorLeftIntern();
3631         }
3632         current_view->buffer()->update(1);
3633 }
3634 // End of spellchecker stuff
3635
3636
3637
3638 //
3639 // Table of Contents
3640 //
3641
3642 struct TocList {
3643         int counter[6];
3644         bool appendix;
3645         TocList * next;
3646 };
3647
3648
3649 static TocList * toclist = 0;
3650
3651
3652 extern "C" void TocSelectCB(FL_OBJECT * ob, long)
3653 {
3654         if (!current_view->available())
3655                 return;
3656    
3657         TocList * tmptoclist = toclist;
3658         int i = fl_get_browser(ob);
3659         for (int a = 1; a < i && tmptoclist->next; ++a) {
3660                 tmptoclist = tmptoclist->next;
3661         }
3662
3663         if (!tmptoclist)
3664                 return;
3665      
3666
3667         LyXParagraph * par = current_view->buffer()->paragraph;
3668         while (par && (par->GetFirstCounter(0) != tmptoclist->counter[0] ||
3669                        par->GetFirstCounter(1) != tmptoclist->counter[1] ||
3670                        par->GetFirstCounter(2) != tmptoclist->counter[2] ||
3671                        par->GetFirstCounter(3) != tmptoclist->counter[3] ||
3672                        par->GetFirstCounter(4) != tmptoclist->counter[4] ||
3673                        par->GetFirstCounter(5) != tmptoclist->counter[5] ||
3674                        par->appendix != tmptoclist->appendix)) {
3675                 par = par->LastPhysicalPar()->Next();
3676         }
3677    
3678         if (par) {
3679                 BeforeChange();
3680                 current_view->buffer()->text->SetCursor(par, 0);
3681                 current_view->buffer()->text->sel_cursor = 
3682                         current_view->buffer()->text->cursor;
3683                 current_view->buffer()->update(0);
3684         }
3685         else {
3686                 WriteAlert(_("Error"), 
3687                            _("Couldn't find this label"), 
3688                            _("in current document."));
3689         }
3690           
3691 }
3692
3693
3694 extern "C" void TocCancelCB(FL_OBJECT *, long)
3695 {
3696         fl_hide_form(fd_form_toc->form_toc);
3697 }
3698
3699
3700 extern "C" void TocUpdateCB(FL_OBJECT *, long)
3701 {
3702         static LyXParagraph * stapar = 0;
3703         TocList * tmptoclist = 0;
3704    
3705         /* deleted the toclist */ 
3706         if (toclist){
3707                 while (toclist){
3708                         tmptoclist = toclist->next;
3709                         delete toclist;
3710                         toclist = tmptoclist;
3711                 }
3712         }
3713         toclist = 0;
3714         tmptoclist = toclist;
3715
3716
3717         fl_clear_browser(fd_form_toc->browser_toc);
3718         if (!current_view->available()) {
3719                 fl_add_browser_line(fd_form_toc->browser_toc,
3720                                     _("*** No Document ***"));
3721                 return;
3722         }
3723         fl_hide_object(fd_form_toc->browser_toc);
3724         /* get the table of contents */ 
3725         LyXParagraph * par = current_view->buffer()->paragraph;
3726         char labeltype;
3727         char * line = new char[200];
3728         int pos = 0;
3729         unsigned char c;
3730         int topline = 0;
3731    
3732         if (stapar == par)
3733                 topline = fl_get_browser_topline(fd_form_toc->browser_toc);
3734         stapar = par;
3735    
3736         while (par) {
3737                 labeltype = textclasslist.Style(current_view->buffer()->params.textclass, 
3738                                            par->GetLayout()).labeltype;
3739       
3740                 if (labeltype >= LABEL_COUNTER_CHAPTER
3741                     && labeltype <= LABEL_COUNTER_CHAPTER +
3742                     current_view->buffer()->params.tocdepth) {
3743                         /* insert this into the table of contents */ 
3744                         /* first indent a little bit */ 
3745                         
3746                         for (pos = 0; 
3747                              pos < (labeltype - 
3748                                     textclasslist.TextClass(current_view->buffer()->
3749                                                        params.textclass).maxcounter()) * 4 + 2;
3750                              pos++)
3751                                 line[pos] = ' ';
3752                         
3753                         // Then the labestring
3754                         if (!par->labelstring.empty()) {
3755                                 string::size_type i = 0;
3756                                 while (pos < 199 && i < par->labelstring.length()) {
3757                                         line[pos] = par->labelstring[i];
3758                                         i++;
3759                                         pos++;
3760                                 }
3761                         }
3762          
3763                         line[pos] = ' ';
3764                         pos++;
3765                         
3766                         /* now the contents */
3767                         LyXParagraph::size_type i = 0;
3768                         while (pos < 199 && i < par->size()) {
3769                                 c = par->GetChar(i);
3770                                 if (isprint(c) || c >= 128) {
3771                                         line[pos] = c;
3772                                         pos++;
3773                                 }
3774                                 i++;
3775                         }
3776                         line[pos] = '\0';
3777                         fl_add_browser_line(fd_form_toc->browser_toc, line);
3778                         
3779                         /* make a toclist entry */
3780                         if (!tmptoclist){
3781                                 tmptoclist = new TocList;
3782                                 toclist = tmptoclist;
3783                         } else {
3784                                 tmptoclist->next = new TocList;
3785                                 tmptoclist = tmptoclist->next;
3786                         }
3787                         
3788                         tmptoclist->next = 0;
3789                         int a = 0;
3790                         for (a = 0; a<6; a++){
3791                                 tmptoclist->counter[a] = par->GetFirstCounter(a);
3792                         }
3793                         tmptoclist->appendix = par->appendix;
3794                 }
3795                 par = par->LastPhysicalPar()->Next();
3796                 
3797         }
3798         delete[] line;
3799         fl_set_browser_topline(fd_form_toc->browser_toc, topline);
3800         fl_show_object(fd_form_toc->browser_toc);
3801 }
3802
3803
3804 /* callbacks for form form_ref */
3805 extern "C" void RefSelectCB(FL_OBJECT *, long data)
3806 {
3807         if (!current_view->available())
3808                 return;
3809
3810         string s = 
3811                 fl_get_browser_line(fd_form_ref->browser_ref,
3812                                     fl_get_browser(fd_form_ref->browser_ref));
3813         string u = frontStrip(strip(fl_get_input(fd_form_ref->ref_name)));
3814
3815         if (s.empty())
3816                 return;
3817
3818         if (data == 2) {
3819                 current_view->owner()->getLyXFunc()->Dispatch(LFUN_REFGOTO, s.c_str());
3820                 return;
3821         }
3822             
3823         string t;
3824         if (data == 0)
3825                 t += "\\ref";
3826         else
3827                 t += "\\pageref";
3828
3829         if(current_view->buffer()->isSGML())
3830                 t += "[" + u + "]" + "{" + s + "}";
3831         else
3832                 t += "{" + s + "}";
3833
3834         Inset * new_inset = 
3835                 new InsetRef(t, current_view->buffer());
3836         current_view->buffer()->insertInset(new_inset);
3837 }
3838
3839
3840 extern "C" void RefUpdateCB(FL_OBJECT *, long)
3841 {
3842         if (!current_view->available()) {
3843                 fl_clear_browser(fd_form_ref->browser_ref);
3844                 return;
3845         }
3846
3847         FL_OBJECT * brow = fd_form_ref->browser_ref;
3848
3849         // Get the current line, in order to restore it later
3850         char const * const btmp = fl_get_browser_line(brow,
3851                                                      fl_get_browser(brow));
3852         string currentstr = btmp ? btmp : "";
3853         //string currentstr = fl_get_browser_line(brow,
3854         //                                      fl_get_browser(brow));
3855
3856         fl_clear_browser(brow);
3857
3858         string refs = current_view->buffer()->getReferenceList('\n');
3859         int topline = 1;
3860
3861 #if FL_REVISION > 85
3862         fl_addto_browser_chars(brow, refs.c_str());
3863         int total_lines = fl_get_browser_maxline(brow);
3864         for (int i = 1; i <= total_lines ; i++) {
3865                 if (fl_get_browser_line(brow, i) == currentstr) {
3866                         topline = i;
3867                         break;
3868                 }
3869         }
3870         fl_set_browser_topline(brow, topline);
3871 #else
3872         // Keep the old ugly code for xforms 0.81 compatibility
3873         string curr_ref;
3874         int ref_num = 0;
3875                                        
3876         while(true) {
3877                 curr_ref = refs.token('\n', ref_num);
3878                 if (curr_ref.empty())
3879                         break;
3880                 fl_add_browser_line(brow, curr_ref.c_str());
3881                 ref_num++;
3882         }
3883 #endif
3884
3885         if (!fl_get_browser_maxline(brow)) {
3886                 fl_add_browser_line(brow, 
3887                                     _("*** No labels found in document ***"));
3888                 fl_deactivate_object(brow);
3889         } else {
3890                 fl_select_browser_line(brow, topline);
3891                 fl_activate_object(brow);
3892         }
3893         if (current_view->buffer()->isReadonly()) {
3894                 // would be better to de/activate insert buttons
3895                 // but that's more work... besides this works. ARRae
3896                 fl_hide_form(fd_form_ref->form_ref);
3897         }
3898         if (!current_view->buffer()->isSGML()) {
3899                 fl_deactivate_object(fd_form_ref->ref_name);
3900                 fl_set_object_lcol(fd_form_ref->ref_name, FL_INACTIVE);
3901         }
3902         else {
3903                 fl_activate_object(fd_form_ref->ref_name);
3904                 fl_set_object_lcol(fd_form_ref->ref_name, FL_BLACK);
3905         }
3906 }
3907
3908
3909 extern "C" void RefHideCB(FL_OBJECT *, long)
3910 {
3911         fl_hide_form(fd_form_ref->form_ref);
3912 }
3913
3914
3915 void UpdateInset(Inset * inset, bool mark_dirty)
3916 {
3917         if (!inset)
3918                 return;
3919
3920         /* very first check for locking insets*/
3921         if (current_view->buffer()->the_locking_inset == inset){
3922                 if (current_view->buffer()->text->UpdateInset(inset)){
3923                         current_view->update();
3924                         if (mark_dirty){
3925                                 if (current_view->buffer()->isLyxClean())
3926                                         minibuffer->setTimer(4);
3927                                 current_view->buffer()->markDirty();
3928                         }
3929                         current_view->updateScrollbar();
3930                         return;
3931                 }
3932         }
3933   
3934         /* first check the current buffer */
3935         if (current_view->available()){
3936                 current_view->getScreen()->HideCursor();
3937                 current_view->buffer()->update(-3);
3938                 if (current_view->buffer()->text->UpdateInset(inset)){
3939                         if (mark_dirty)
3940                                 current_view->buffer()->update(1);
3941                         else 
3942                                 current_view->buffer()->update(3);
3943                         return;
3944                 }
3945         }
3946   
3947         // check all buffers
3948         bufferlist.updateInset(inset, mark_dirty);
3949
3950 }
3951
3952
3953 /* these functions return 1 if an error occured, 
3954    otherwise 0 */
3955 int LockInset(UpdatableInset * inset)
3956 {
3957         if (!current_view->buffer()->the_locking_inset && inset){
3958                 current_view->buffer()->the_locking_inset = inset;
3959                 return 0;
3960         }
3961         return 1;
3962 }
3963
3964
3965 void ShowLockedInsetCursor(long x, long y, int asc, int desc)
3966 {
3967         if (current_view->buffer()->the_locking_inset &&
3968             current_view->getScreen()){
3969                 y += current_view->buffer()->text->cursor.y;
3970                 current_view->getScreen()->ShowManualCursor(x, y,
3971                                                             asc, desc);
3972         }
3973 }
3974
3975
3976 void HideLockedInsetCursor(long x, long y, int asc, int desc)
3977 {
3978         if (current_view->buffer()->the_locking_inset &&
3979             current_view->getScreen()){
3980                 y += current_view->buffer()->text->cursor.y;
3981                 current_view->getScreen()->HideManualCursor(x, y,
3982                                                             asc, desc);
3983         }
3984 }
3985
3986
3987 void FitLockedInsetCursor(long x, long y, int asc, int desc)
3988 {
3989         if (current_view->buffer()->the_locking_inset &&
3990             current_view->getScreen()){
3991                 y += current_view->buffer()->text->cursor.y;
3992                 if (current_view->getScreen()->FitManualCursor(x, y, asc, desc))
3993                         current_view->updateScrollbar();
3994         }
3995 }
3996
3997
3998 int UnlockInset(UpdatableInset * inset)
3999 {
4000         if (inset &&
4001             current_view->buffer()->the_locking_inset == inset){
4002                 inset->InsetUnlock();
4003                 current_view->buffer()->the_locking_inset = 0;
4004                 current_view->buffer()->text->FinishUndo();
4005                 return 0;
4006         }
4007         return bufferlist.unlockInset(inset);
4008 }
4009
4010
4011 void LockedInsetStoreUndo(Undo::undo_kind kind)
4012 {
4013         if (!current_view->buffer()->the_locking_inset)
4014                 return; // shouldn't happen
4015         if (kind == Undo::EDIT) // in this case insets would not be stored!
4016                 kind = Undo::FINISH;
4017         current_view->buffer()->text->SetUndo(kind,
4018                               current_view->buffer()->text->cursor.par->
4019                               ParFromPos(current_view->buffer()->text->cursor.pos)->previous, 
4020                               current_view->buffer()->text->cursor.par->
4021                               ParFromPos(current_view->buffer()->text->cursor.pos)->next); 
4022 }
4023
4024
4025 void PutInsetIntoInsetUpdateList(Inset * inset)
4026 {
4027         if (inset) {
4028                 InsetUpdateStruct * tmp = new InsetUpdateStruct();
4029                 tmp->inset = inset;
4030                 tmp->next = InsetUpdateList;
4031                 InsetUpdateList = tmp;
4032         }
4033 }
4034
4035
4036 void UpdateInsetUpdateList()
4037 {
4038         InsetUpdateStruct * tmp = InsetUpdateList;
4039         while (tmp) {
4040                 UpdateInset(tmp->inset, false); // "false" because no document change
4041                 tmp = tmp->next;
4042         }
4043   
4044         // delete the update list
4045         while (InsetUpdateList) {
4046                 tmp = InsetUpdateList;
4047                 InsetUpdateList = InsetUpdateList->next;
4048                 delete tmp;
4049         }
4050         InsetUpdateList = 0;
4051 }
4052
4053
4054 #ifdef WITH_WARNINGS
4055 #warning UGLY!!
4056 #endif
4057 // I know we shouldn't put anything in here but this seems the fastest
4058 // way to do this (and the cleanest for now). This function just inserts
4059 // a newline in the string and the inserts 'depth'-spaces so that the
4060 // code is indented in the right way!!!
4061 void addNewlineAndDepth(string & file, int const depth)
4062 {
4063        file += '\n';
4064        file.append(depth, ' ');
4065 }