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