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