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