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