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