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