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