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