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