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