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