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