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