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