]> git.lyx.org Git - lyx.git/blob - src/lyx_cb.C
2a54f1128f6e0d7b307d8c7963285df6b4063d01
[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()
207 {
208         input_prohibited = true;
209         current_view->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, current_view->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()
253 {
254         input_prohibited = false;
255
256         /* reset the cursor from the watch for all forms and the canvas */
257    
258         XUndefineCursor(fl_display, current_view->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 (current_view->belowMouse())
268                 SetXtermCursor(current_view->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();
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();
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();
591
592         // Generate dvi file
593         if (MakeLaTeXOutput(buffer) > 0) {
594                 AllowInput();
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();
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();
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();
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()
1100         // should probably be moved into BufferList (Lgb)
1101         // Perfect target for a thread...
1102 {
1103         if (!current_view->available())
1104                 return;
1105
1106         if (current_view->buffer()->isBakClean()
1107             || current_view->buffer()->isReadonly()) {
1108                 // We don't save now, but we'll try again later
1109                 current_view->owner()->resetAutosaveTimer();
1110                 return;
1111         }
1112
1113         current_view->owner()->getMiniBuffer()->Set(_("Autosaving current document..."));
1114         
1115         // create autosave filename
1116         string fname =  OnlyPath(current_view->buffer()->fileName());
1117         fname += "#";
1118         fname += OnlyFilename(current_view->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                         current_view->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 (!current_view->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                                         current_view->owner()->getMiniBuffer()->Set(_("Autosave Failed!"));
1154                         }
1155                 }
1156                 if (pid == 0) { // we are the child so...
1157                         _exit(0);
1158                 }
1159         }
1160         
1161         current_view->buffer()->markBakClean();
1162         current_view->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();
1209                 fname = fileDlg.Select(_("File to Insert"), 
1210                                        bv->owner()->buffer()->filepath,
1211                                        "*");
1212                 AllowInput();
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();
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();
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 = static_cast<BufferParams::PAPER_SIZE>(bv->buffer()->params.papersize);
1382         switch (ps) {
1383         case BufferParams::PAPER_A4PAPER:
1384                 add_flags = "-p a4";
1385                 break;
1386         case BufferParams::PAPER_USLETTER:
1387                 add_flags = "-p letter";
1388                 break;
1389         default: /* nothing to be done yet ;-) */     break; 
1390         }
1391         
1392         ProhibitInput();
1393         
1394         Systemcalls one;
1395         switch (flag) {
1396         case 0: /* TeX output asked */
1397               bv->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to TeX file..."));
1398                 s2 = lyxrc.linuxdoc_to_latex_command + ' ' + add_flags + " -o tex " + ' ' + name;
1399                 if (one.startscript(Systemcalls::System, s2)) 
1400                         errorcode = 1;
1401                 break;
1402         case 1: /* dvi output asked */
1403                 bv->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to dvi file..."));
1404                 s2 = lyxrc.linuxdoc_to_latex_command + ' ' + add_flags + " -o dvi " + ' ' + name;
1405                 if (one.startscript(Systemcalls::System, s2)) {
1406                         errorcode = 1;
1407                 } else
1408                         bv->buffer()->markDviClean();
1409                 break;
1410         default: /* unknown output */
1411                 break;
1412         }
1413         
1414         AllowInput();
1415
1416         bv->buffer()->redraw();
1417         return errorcode;
1418 }
1419
1420
1421 /*
1422  * SGML DocBook support:
1423  * (flag == 1) make dvi output
1424  */
1425 int RunDocBook(int flag, string const & filename)
1426 {
1427         /* generate a path-less extension name */
1428         string name = ChangeExtension (filename, ".sgml", true);
1429         string path = OnlyPath (filename);
1430         if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)) {
1431                 path = current_view->buffer()->tmppath;
1432         }
1433         Path p(path);
1434
1435         if (!current_view->available())
1436                 return 0;
1437         
1438         current_view->buffer()->makeDocBookFile(name, 0);
1439
1440         // Shall this code go or should it stay? (Lgb)
1441         // This code is a placeholder for future implementation. (Jose')
1442 //      string add_flags;
1443 //      LYX_PAPER_SIZE ps = (LYX_PAPER_SIZE) current_view->buffer()->params.papersize;
1444 //      switch (ps) {
1445 //      case BufferParams::PAPER_A4PAPER:  add_flags = "-p a4";     break;
1446 //      case BufferParams::PAPER_USLETTER: add_flags = "-p letter"; break;
1447 //      default: /* nothing to be done yet ;-) */     break; 
1448 //      }
1449         ProhibitInput();
1450         
1451         int errorcode = 0;
1452         Systemcalls one;
1453         switch (flag) {
1454         case 1: /* dvi output asked */
1455         {
1456                 current_view->owner()->getMiniBuffer()->Set(_("Converting DocBook SGML to dvi file..."));
1457                 string s2 = lyxrc.docbook_to_dvi_command + ' ' + name;
1458                 if (one.startscript(Systemcalls::System, s2)) {
1459                         errorcode = 1;
1460                 } else
1461                         current_view->buffer()->markDviClean();
1462         }
1463         break;
1464         default: /* unknown output */
1465                 break;
1466         }
1467         
1468         AllowInput();
1469
1470         current_view->buffer()->redraw();
1471         return errorcode;
1472 }
1473
1474
1475 void MenuLayoutCharacter()
1476 {
1477         static int ow = -1, oh;
1478
1479         if (fd_form_character->form_character->visible) {
1480                 fl_raise_form(fd_form_character->form_character);
1481         } else {
1482                 fl_show_form(fd_form_character->form_character,
1483                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
1484                              _("Character Style"));
1485                 if (ow < 0) {
1486                         ow = fd_form_character->form_character->w;
1487                         oh = fd_form_character->form_character->h;
1488                 }
1489                 fl_set_form_minsize(fd_form_character->form_character, ow, oh);
1490         }
1491 }
1492
1493
1494 inline
1495 void DeactivateParagraphButtons ()
1496 {
1497         fl_deactivate_object (fd_form_paragraph->button_ok);
1498         fl_deactivate_object (fd_form_paragraph->button_apply);
1499         fl_set_object_lcol (fd_form_paragraph->button_ok, FL_INACTIVE);
1500         fl_set_object_lcol (fd_form_paragraph->button_apply, FL_INACTIVE);
1501 }
1502
1503
1504 inline
1505 void ActivateParagraphButtons ()
1506 {
1507         fl_activate_object (fd_form_paragraph->button_ok);
1508         fl_activate_object (fd_form_paragraph->button_apply);
1509         fl_set_object_lcol (fd_form_paragraph->button_ok, FL_BLACK);
1510         fl_set_object_lcol (fd_form_paragraph->button_apply, FL_BLACK);
1511 }
1512
1513
1514 inline
1515 void DisableParagraphLayout ()
1516 {
1517         DeactivateParagraphButtons();
1518         fl_deactivate_object (fd_form_paragraph->input_labelwidth);
1519         fl_deactivate_object (fd_form_paragraph->check_lines_top);
1520         fl_deactivate_object (fd_form_paragraph->check_lines_bottom);
1521         fl_deactivate_object (fd_form_paragraph->check_pagebreaks_top);
1522         fl_deactivate_object (fd_form_paragraph->check_pagebreaks_bottom);
1523         fl_deactivate_object (fd_form_paragraph->check_noindent);
1524         fl_deactivate_object (fd_form_paragraph->group_radio_alignment);
1525         fl_deactivate_object (fd_form_paragraph->radio_align_right);
1526         fl_deactivate_object (fd_form_paragraph->radio_align_left);
1527         fl_deactivate_object (fd_form_paragraph->radio_align_block);
1528         fl_deactivate_object (fd_form_paragraph->radio_align_center);
1529         fl_deactivate_object (fd_form_paragraph->input_space_above);
1530         fl_deactivate_object (fd_form_paragraph->input_space_below);
1531         fl_deactivate_object (fd_form_paragraph->choice_space_above);
1532         fl_deactivate_object (fd_form_paragraph->choice_space_below);
1533         fl_deactivate_object (fd_form_paragraph->check_space_above);
1534         fl_deactivate_object (fd_form_paragraph->check_space_below);
1535 }
1536
1537
1538 inline
1539 void EnableParagraphLayout ()
1540 {
1541         ActivateParagraphButtons();
1542         fl_activate_object (fd_form_paragraph->input_labelwidth);
1543         fl_activate_object (fd_form_paragraph->check_lines_top);
1544         fl_activate_object (fd_form_paragraph->check_lines_bottom);
1545         fl_activate_object (fd_form_paragraph->check_pagebreaks_top);
1546         fl_activate_object (fd_form_paragraph->check_pagebreaks_bottom);
1547         fl_activate_object (fd_form_paragraph->check_noindent);
1548         fl_activate_object (fd_form_paragraph->group_radio_alignment);
1549         fl_activate_object (fd_form_paragraph->radio_align_right);
1550         fl_activate_object (fd_form_paragraph->radio_align_left);
1551         fl_activate_object (fd_form_paragraph->radio_align_block);
1552         fl_activate_object (fd_form_paragraph->radio_align_center);
1553         fl_activate_object (fd_form_paragraph->input_space_above);
1554         fl_activate_object (fd_form_paragraph->input_space_below);
1555         fl_activate_object (fd_form_paragraph->choice_space_above);
1556         fl_activate_object (fd_form_paragraph->choice_space_below);
1557         fl_activate_object (fd_form_paragraph->check_space_above);
1558         fl_activate_object (fd_form_paragraph->check_space_below);
1559 }
1560
1561
1562 bool UpdateLayoutParagraph()
1563 {
1564         if (!current_view->available()) {
1565                 if (fd_form_paragraph->form_paragraph->visible) 
1566                         fl_hide_form(fd_form_paragraph->form_paragraph);
1567                 return false;
1568         }
1569
1570         Buffer * buf = current_view->buffer();
1571
1572         fl_set_input(fd_form_paragraph->input_labelwidth,
1573                      current_view->text->cursor.par->GetLabelWidthString().c_str());
1574         fl_set_button(fd_form_paragraph->radio_align_right, 0);
1575         fl_set_button(fd_form_paragraph->radio_align_left, 0);
1576         fl_set_button(fd_form_paragraph->radio_align_center, 0);
1577         fl_set_button(fd_form_paragraph->radio_align_block, 0);
1578
1579         int align = current_view->text->cursor.par->GetAlign();
1580         if (align == LYX_ALIGN_LAYOUT)
1581                 align = textclasslist.Style(buf->params.textclass,
1582                                             current_view->text->cursor.par->GetLayout()).align;
1583          
1584         switch (align) {
1585         case LYX_ALIGN_RIGHT:
1586                 fl_set_button(fd_form_paragraph->radio_align_right, 1);
1587                 break;
1588         case LYX_ALIGN_LEFT:
1589                 fl_set_button(fd_form_paragraph->radio_align_left, 1);
1590                 break;
1591         case LYX_ALIGN_CENTER:
1592                 fl_set_button(fd_form_paragraph->radio_align_center, 1);
1593                 break;
1594         default:
1595                 fl_set_button(fd_form_paragraph->radio_align_block, 1);
1596                 break;
1597         }
1598          
1599         fl_set_button(fd_form_paragraph->check_lines_top,
1600                       current_view->text->cursor.par->FirstPhysicalPar()->line_top);
1601         fl_set_button(fd_form_paragraph->check_lines_bottom,
1602                       current_view->text->cursor.par->FirstPhysicalPar()->line_bottom);
1603         fl_set_button(fd_form_paragraph->check_pagebreaks_top,
1604                       current_view->text->cursor.par->FirstPhysicalPar()->pagebreak_top);
1605         fl_set_button(fd_form_paragraph->check_pagebreaks_bottom,
1606                       current_view->text->cursor.par->FirstPhysicalPar()->pagebreak_bottom);
1607         fl_set_button(fd_form_paragraph->check_noindent,
1608                       current_view->text->cursor.par->FirstPhysicalPar()->noindent);
1609         fl_set_input (fd_form_paragraph->input_space_above, "");
1610         
1611         switch (current_view->text->cursor.par->FirstPhysicalPar()->added_space_top.kind()) {
1612         case VSpace::NONE:
1613                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
1614                 break;
1615         case VSpace::DEFSKIP:
1616                 fl_set_choice (fd_form_paragraph->choice_space_above, 2);
1617                 break;
1618         case VSpace::SMALLSKIP:
1619                 fl_set_choice (fd_form_paragraph->choice_space_above, 3);
1620                 break;
1621         case VSpace::MEDSKIP:
1622                 fl_set_choice (fd_form_paragraph->choice_space_above, 4);
1623                 break;
1624         case VSpace::BIGSKIP:
1625                 fl_set_choice (fd_form_paragraph->choice_space_above, 5);
1626                 break;
1627         case VSpace::VFILL:
1628                 fl_set_choice (fd_form_paragraph->choice_space_above, 6);
1629                 break;
1630         case VSpace::LENGTH:
1631                 fl_set_choice (fd_form_paragraph->choice_space_above, 7); 
1632                 fl_set_input  (fd_form_paragraph->input_space_above, 
1633                                current_view->text->cursor.par->FirstPhysicalPar()->added_space_top.length().asString().c_str());
1634                 break;
1635         }
1636         fl_set_button (fd_form_paragraph->check_space_above,
1637                        current_view->text->cursor.par->FirstPhysicalPar()->added_space_top.keep());
1638         fl_set_input (fd_form_paragraph->input_space_below, "");
1639         switch (current_view->text->cursor.par->FirstPhysicalPar()->added_space_bottom.kind()) {
1640         case VSpace::NONE:
1641                 fl_set_choice (fd_form_paragraph->choice_space_below,
1642                                1);
1643                 break;
1644         case VSpace::DEFSKIP:
1645                 fl_set_choice (fd_form_paragraph->choice_space_below,
1646                                2);
1647                 break;
1648         case VSpace::SMALLSKIP:
1649                 fl_set_choice (fd_form_paragraph->choice_space_below,
1650                                3);
1651                 break;
1652         case VSpace::MEDSKIP:
1653                 fl_set_choice (fd_form_paragraph->choice_space_below,
1654                                4);
1655                 break;
1656         case VSpace::BIGSKIP:
1657                 fl_set_choice (fd_form_paragraph->choice_space_below,
1658                                5);
1659                 break;
1660         case VSpace::VFILL:
1661                 fl_set_choice (fd_form_paragraph->choice_space_below,
1662                                6);
1663                 break;
1664         case VSpace::LENGTH:
1665                 fl_set_choice (fd_form_paragraph->choice_space_below,
1666                                7); 
1667                 fl_set_input  (fd_form_paragraph->input_space_below, 
1668                                current_view->text->cursor.par->FirstPhysicalPar()->added_space_bottom.length().asString().c_str());
1669                 break;
1670         }
1671         fl_set_button (fd_form_paragraph->check_space_below,
1672                        current_view->text->cursor.par->FirstPhysicalPar()->added_space_bottom.keep());
1673
1674         fl_set_button(fd_form_paragraph->check_noindent,
1675                       current_view->text->cursor.par->FirstPhysicalPar()->noindent);
1676
1677         if (current_view->buffer()->isReadonly()) {
1678                 DisableParagraphLayout();
1679         } else {
1680                 EnableParagraphLayout();
1681         }
1682         return true;
1683 }
1684
1685
1686 void MenuLayoutParagraph()
1687 {
1688         if (UpdateLayoutParagraph()) {
1689                 if (fd_form_paragraph->form_paragraph->visible) {
1690                         fl_raise_form(fd_form_paragraph->form_paragraph);
1691                 } else {
1692                         fl_show_form(fd_form_paragraph->form_paragraph,
1693                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1694                                      _("Paragraph Environment"));
1695                 }
1696         }
1697 }
1698
1699
1700 inline
1701 void DeactivateDocumentButtons ()
1702 {
1703         fl_deactivate_object (fd_form_document->button_ok);
1704         fl_deactivate_object (fd_form_document->button_apply);
1705         fl_set_object_lcol (fd_form_document->button_ok, FL_INACTIVE);
1706         fl_set_object_lcol (fd_form_document->button_apply, FL_INACTIVE);
1707 }
1708
1709
1710 inline
1711 void ActivateDocumentButtons ()
1712 {
1713         fl_activate_object (fd_form_document->button_ok);
1714         fl_activate_object (fd_form_document->button_apply);
1715         fl_set_object_lcol (fd_form_document->button_ok, FL_BLACK);
1716         fl_set_object_lcol (fd_form_document->button_apply, FL_BLACK);
1717 }
1718
1719
1720 inline
1721 void DisableDocumentLayout ()
1722 {
1723         DeactivateDocumentButtons ();
1724         fl_deactivate_object (fd_form_document->group_radio_separation);
1725         fl_deactivate_object (fd_form_document->radio_indent);
1726         fl_deactivate_object (fd_form_document->radio_skip);
1727         fl_deactivate_object (fd_form_document->choice_class);
1728         fl_deactivate_object (fd_form_document->choice_pagestyle);
1729         fl_deactivate_object (fd_form_document->choice_fonts);
1730         fl_deactivate_object (fd_form_document->choice_fontsize);
1731         fl_deactivate_object (fd_form_document->input_float_placement);
1732         fl_deactivate_object (fd_form_document->choice_postscript_driver);
1733         fl_deactivate_object (fd_form_document->choice_inputenc);
1734         fl_deactivate_object (fd_form_document->group_radio_sides);
1735         fl_deactivate_object (fd_form_document->radio_sides_one);
1736         fl_deactivate_object (fd_form_document->radio_sides_two);
1737         fl_deactivate_object (fd_form_document->group_radio_columns);
1738         fl_deactivate_object (fd_form_document->radio_columns_one);
1739         fl_deactivate_object (fd_form_document->radio_columns_two);
1740         fl_deactivate_object (fd_form_document->input_extra);
1741         fl_deactivate_object (fd_form_document->choice_language);
1742         combo_language->deactivate();
1743         fl_deactivate_object (fd_form_document->input_default_skip);
1744         fl_deactivate_object (fd_form_document->choice_default_skip);
1745         fl_deactivate_object (fd_form_document->slider_secnumdepth);
1746         fl_deactivate_object (fd_form_document->slider_tocdepth);
1747         fl_deactivate_object (fd_form_document->choice_spacing);
1748         fl_deactivate_object (fd_form_document->input_spacing);
1749         fl_deactivate_object (fd_form_document->check_use_amsmath);
1750 }
1751
1752
1753 inline
1754 void EnableDocumentLayout ()
1755 {
1756         ActivateDocumentButtons ();
1757         fl_activate_object (fd_form_document->group_radio_separation);
1758         fl_activate_object (fd_form_document->radio_indent);
1759         fl_activate_object (fd_form_document->radio_skip);
1760         fl_activate_object (fd_form_document->choice_class);
1761         fl_activate_object (fd_form_document->choice_pagestyle);
1762         fl_activate_object (fd_form_document->choice_fonts);
1763         fl_activate_object (fd_form_document->choice_fontsize);
1764         fl_activate_object (fd_form_document->input_float_placement);
1765         fl_activate_object (fd_form_document->choice_postscript_driver);
1766         fl_activate_object (fd_form_document->choice_inputenc);
1767         fl_activate_object (fd_form_document->group_radio_sides);
1768         fl_activate_object (fd_form_document->radio_sides_one);
1769         fl_activate_object (fd_form_document->radio_sides_two);
1770         fl_activate_object (fd_form_document->group_radio_columns);
1771         fl_activate_object (fd_form_document->radio_columns_one);
1772         fl_activate_object (fd_form_document->radio_columns_two);
1773         fl_activate_object (fd_form_document->input_extra);
1774         fl_activate_object (fd_form_document->choice_language);
1775         combo_language->activate();
1776         fl_activate_object (fd_form_document->input_default_skip);
1777         fl_activate_object (fd_form_document->choice_default_skip);
1778         fl_activate_object (fd_form_document->slider_secnumdepth);
1779         fl_activate_object (fd_form_document->slider_tocdepth);
1780         fl_activate_object (fd_form_document->choice_spacing);
1781         fl_activate_object (fd_form_document->input_spacing);
1782         fl_activate_object (fd_form_document->check_use_amsmath);
1783 }
1784
1785
1786 bool UpdateLayoutDocument(BufferParams * params)
1787 {
1788         if (!current_view->available()) {
1789                 if (fd_form_document->form_document->visible) 
1790                         fl_hide_form(fd_form_document->form_document);
1791                 return false;
1792         }               
1793
1794         if (params == 0)
1795                 params = &current_view->buffer()->params;
1796         LyXTextClass const & tclass = textclasslist.TextClass(params->textclass);
1797         
1798         fl_set_choice_text(fd_form_document->choice_class, 
1799                            textclasslist.DescOfClass(params->textclass).c_str());
1800         combo_language->select_text(params->language.c_str());
1801         
1802         fl_set_choice_text(fd_form_document->choice_fonts, 
1803                            params->fonts.c_str());
1804         fl_set_choice_text(fd_form_document->choice_inputenc, 
1805                            params->inputenc.c_str());
1806         fl_set_choice_text(fd_form_document->choice_postscript_driver, 
1807                            params->graphicsDriver.c_str());
1808
1809         // ale970405+lasgoutt970513
1810         fl_clear_choice(fd_form_document->choice_fontsize);
1811         fl_addto_choice(fd_form_document->choice_fontsize, "default");
1812         fl_addto_choice(fd_form_document->choice_fontsize, 
1813                         tclass.opt_fontsize().c_str());
1814         fl_set_choice(fd_form_document->choice_fontsize, 
1815                       tokenPos(tclass.opt_fontsize(), '|', params->fontsize) + 2);
1816
1817         // ale970405+lasgoutt970513
1818         fl_clear_choice(fd_form_document->choice_pagestyle);
1819         fl_addto_choice(fd_form_document->choice_pagestyle, "default");
1820         fl_addto_choice(fd_form_document->choice_pagestyle, 
1821                         tclass.opt_pagestyle().c_str());
1822     
1823         fl_set_choice(fd_form_document->choice_pagestyle,
1824                       tokenPos(tclass.opt_pagestyle(), '|', params->pagestyle) + 2);
1825
1826         fl_set_button(fd_form_document->radio_indent, 0);
1827         fl_set_button(fd_form_document->radio_skip, 0);
1828     
1829         
1830         fl_set_button(fd_form_document->check_use_amsmath, params->use_amsmath);
1831
1832         if (params->paragraph_separation == BufferParams::PARSEP_INDENT)
1833                 fl_set_button(fd_form_document->radio_indent, 1);
1834         else
1835                 fl_set_button(fd_form_document->radio_skip, 1);
1836
1837         switch (params->getDefSkip().kind()) {
1838         case VSpace::SMALLSKIP: 
1839                 fl_set_choice (fd_form_document->choice_default_skip, 1);
1840                 break;
1841         case VSpace::MEDSKIP: 
1842                 fl_set_choice (fd_form_document->choice_default_skip, 2);
1843                 break;
1844         case VSpace::BIGSKIP: 
1845                 fl_set_choice (fd_form_document->choice_default_skip, 3);
1846                 break;
1847         case VSpace::LENGTH: 
1848                 fl_set_choice (fd_form_document->choice_default_skip, 4);
1849                 fl_set_input (fd_form_document->input_default_skip,
1850                               params->getDefSkip().asLyXCommand().c_str());
1851                 break;
1852         default:
1853                 fl_set_choice (fd_form_document->choice_default_skip, 2);
1854                 break;
1855         }
1856    
1857         fl_set_button(fd_form_document->radio_sides_one, 0);
1858         fl_set_button(fd_form_document->radio_sides_two, 0);
1859    
1860         switch (params->sides) {
1861         case LyXTextClass::OneSide:
1862                 fl_set_button(fd_form_document->radio_sides_one, 1);
1863                 break;
1864         case LyXTextClass::TwoSides:
1865                 fl_set_button(fd_form_document->radio_sides_two, 1);
1866                 break;
1867         }
1868    
1869         fl_set_button(fd_form_document->radio_columns_one, 0);
1870         fl_set_button(fd_form_document->radio_columns_two, 0);
1871    
1872         if (params->columns == 2)
1873                 fl_set_button(fd_form_document->radio_columns_two, 1);
1874         else
1875                 fl_set_button(fd_form_document->radio_columns_one, 1);
1876    
1877         fl_set_input(fd_form_document->input_spacing, "");
1878         switch (params->spacing.getSpace()) {
1879         case Spacing::Single:
1880         {
1881                 // \singlespacing
1882                 fl_set_choice(fd_form_document->choice_spacing, 1);
1883                 break;
1884         }
1885         case Spacing::Onehalf:
1886         {
1887                 // \onehalfspacing
1888                 fl_set_choice(fd_form_document->choice_spacing, 2);
1889                 break;
1890         }
1891         case Spacing::Double:
1892         {
1893                 // \ doublespacing
1894                 fl_set_choice(fd_form_document->choice_spacing, 3);
1895                 break;
1896         }
1897         case Spacing::Other:
1898         {
1899                 fl_set_choice(fd_form_document->choice_spacing, 4);
1900                 //char sval[20];
1901                 //sprintf(sval, "%g", params->spacing.getValue()); 
1902 #ifdef HAVE_SSTREAM
1903                 std::ostringstream sval;
1904                 sval << params->spacing.getValue(); // setw?
1905                 fl_set_input(fd_form_document->input_spacing,
1906                              sval.str().c_str());
1907 #else
1908                 char tval[20];
1909                 ostrstream sval(tval, 20);
1910                 sval << params->spacing.getValue() << '\0'; // setw?
1911                 fl_set_input(fd_form_document->input_spacing, sval.str());
1912 #endif
1913                 break;
1914         }
1915         }
1916
1917
1918         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
1919                              params->secnumdepth);
1920         fl_set_counter_value(fd_form_document->slider_tocdepth, 
1921                              params->tocdepth);
1922         if (!params->float_placement.empty()) { // buffer local (Lgb)
1923                 fl_set_input(fd_form_document->input_float_placement,
1924                              params->float_placement.c_str());
1925         } else {
1926                 fl_set_input(fd_form_document->input_float_placement, "");
1927         }
1928         if (!params->options.empty())
1929                 fl_set_input(fd_form_document->input_extra,
1930                              params->options.c_str());
1931         else
1932                 fl_set_input(fd_form_document->input_extra, "");
1933
1934         if (current_view->buffer()->isSGML()) {
1935                 // bullets not used in SGML derived documents
1936                 fl_deactivate_object(fd_form_document->button_bullets);
1937                 fl_set_object_lcol(fd_form_document->button_bullets,
1938                                    FL_INACTIVE);
1939         } else {
1940                 fl_activate_object(fd_form_document->button_bullets);
1941                 fl_set_object_lcol(fd_form_document->button_bullets,
1942                                    FL_BLACK);
1943         }
1944
1945         if (current_view->buffer()->isReadonly()) {
1946                 DisableDocumentLayout();
1947         } else {
1948                 EnableDocumentLayout();
1949         }
1950
1951         return true;
1952 }
1953
1954
1955 void MenuLayoutDocument()
1956 {
1957         if (UpdateLayoutDocument()) {
1958                 if (fd_form_document->form_document->visible) {
1959                         fl_raise_form(fd_form_document->form_document);
1960                 } else {
1961                         fl_show_form(fd_form_document->form_document,
1962                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1963                                      _("Document Layout"));
1964                 }
1965         }
1966 }
1967
1968
1969 bool UpdateLayoutQuotes()
1970 {
1971         bool update = true;
1972         if (!current_view->available()
1973             || current_view->buffer()->isReadonly())
1974                 update = false;
1975         
1976         if (update) {
1977                 fl_set_choice(fd_form_quotes->choice_quotes_language,
1978                               current_view->buffer()->params.quotes_language + 1);
1979                 fl_set_button(fd_form_quotes->radio_single, 0);
1980                 fl_set_button(fd_form_quotes->radio_double, 0);
1981         
1982                 if (current_view->buffer()->params.quotes_times == InsetQuotes::SingleQ)
1983                         fl_set_button(fd_form_quotes->radio_single, 1);
1984                 else
1985                         fl_set_button(fd_form_quotes->radio_double, 1);
1986         } else if (fd_form_quotes->form_quotes->visible) {
1987                 fl_hide_form(fd_form_quotes->form_quotes);
1988         }
1989         return update;
1990 }
1991
1992
1993 void MenuLayoutQuotes()
1994 {
1995         if (UpdateLayoutQuotes()) {
1996                 if (fd_form_quotes->form_quotes->visible) {
1997                         fl_raise_form(fd_form_quotes->form_quotes);
1998                 } else {
1999                         fl_show_form(fd_form_quotes->form_quotes,
2000                                      FL_PLACE_MOUSE, FL_FULLBORDER,
2001                                      _("Quotes"));
2002                 }
2003         }
2004 }
2005
2006
2007 bool UpdateLayoutPreamble()
2008 {
2009         bool update = true;
2010         if (!current_view->available())
2011                 update = false;
2012
2013         if (update) {
2014                 fl_set_input(fd_form_preamble->input_preamble,
2015                              current_view->buffer()->params.preamble.c_str());
2016
2017                 if (current_view->buffer()->isReadonly()) {
2018                         fl_deactivate_object(fd_form_preamble->input_preamble);
2019                         fl_deactivate_object(fd_form_preamble->button_ok);
2020                         fl_deactivate_object(fd_form_preamble->button_apply);
2021                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_INACTIVE);
2022                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_INACTIVE);
2023                 }
2024                 else {
2025                         fl_activate_object(fd_form_preamble->input_preamble);
2026                         fl_activate_object(fd_form_preamble->button_ok);
2027                         fl_activate_object(fd_form_preamble->button_apply);
2028                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_BLACK);
2029                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_BLACK);
2030                 }
2031         } else if (fd_form_preamble->form_preamble->visible) {
2032                 fl_hide_form(fd_form_preamble->form_preamble);
2033         }
2034         return update;
2035 }
2036
2037
2038 void MenuLayoutPreamble()
2039 {
2040         static int ow = -1, oh;
2041
2042         if (UpdateLayoutPreamble()) {
2043                 if (fd_form_preamble->form_preamble->visible) {
2044                         fl_raise_form(fd_form_preamble->form_preamble);
2045                 } else {
2046                         fl_show_form(fd_form_preamble->form_preamble,
2047                                      FL_PLACE_MOUSE | FL_FREE_SIZE,
2048                                      FL_FULLBORDER,
2049                                      _("LaTeX Preamble"));
2050                         if (ow < 0) {
2051                                 ow = fd_form_preamble->form_preamble->w;
2052                                 oh = fd_form_preamble->form_preamble->h;
2053                         }
2054                         fl_set_form_minsize(fd_form_preamble->form_preamble,
2055                                             ow, oh);
2056                 }
2057         }
2058 }
2059
2060
2061 void MenuLayoutSave()
2062 {
2063         if (!current_view->available())
2064                 return;
2065
2066         if (AskQuestion(_("Do you want to save the current settings"),
2067                         _("for Character, Document, Paper and Quotes"),
2068                         _("as default for new documents?")))
2069                 current_view->buffer()->saveParamsAsDefaults();
2070 }
2071
2072
2073 /* -------> These CB's use ToggleFree() as the (one and only?) font-changer. 
2074                         They also show the current font state. */
2075
2076 static
2077 void ToggleAndShow(BufferView *, LyXFont const &);
2078
2079
2080 void FontSize(string const & size)
2081 {
2082         LyXFont font(LyXFont::ALL_IGNORE);
2083         font.setGUISize(size);
2084         ToggleAndShow(current_view, font);
2085 }
2086
2087
2088 void Emph()
2089 {
2090         LyXFont font(LyXFont::ALL_IGNORE);
2091         font.setEmph(LyXFont::TOGGLE);
2092         ToggleAndShow(current_view, font);
2093 }
2094
2095
2096 void Noun()
2097 {
2098         LyXFont font(LyXFont::ALL_IGNORE);
2099         font.setNoun(LyXFont::TOGGLE);
2100         ToggleAndShow(current_view, font);
2101 }
2102
2103
2104 void Bold()
2105 {
2106         LyXFont font(LyXFont::ALL_IGNORE);
2107         font.setSeries(LyXFont::BOLD_SERIES);
2108         ToggleAndShow(current_view, font);
2109 }
2110
2111
2112 void Underline()
2113 {
2114         LyXFont font(LyXFont::ALL_IGNORE);
2115         font.setUnderbar(LyXFont::TOGGLE);
2116         ToggleAndShow(current_view, font);
2117 }
2118
2119
2120 void Code()
2121 {
2122         LyXFont font(LyXFont::ALL_IGNORE);
2123         font.setFamily(LyXFont::TYPEWRITER_FAMILY); // no good
2124         ToggleAndShow(current_view, font);
2125 }
2126
2127
2128 void Sans()
2129 {
2130         LyXFont font(LyXFont::ALL_IGNORE);
2131         font.setFamily(LyXFont::SANS_FAMILY);
2132         ToggleAndShow(current_view, font);
2133 }
2134
2135
2136 void Roman()
2137 {
2138         LyXFont font(LyXFont::ALL_IGNORE);
2139         font.setFamily(LyXFont::ROMAN_FAMILY);
2140         ToggleAndShow(current_view, font);
2141 }
2142
2143
2144 void Tex()
2145 {
2146         LyXFont font(LyXFont::ALL_IGNORE);
2147         font.setLatex (LyXFont::TOGGLE);
2148         ToggleAndShow(current_view, font);
2149 }
2150
2151 void LangCB(string const & l)
2152 {
2153         LyXFont font(LyXFont::ALL_IGNORE);
2154         Languages::iterator lit = languages.find(l);
2155         if (lit != languages.end()) {
2156                 font.setLanguage(&(*lit).second);
2157                 ToggleAndShow(current_view, font);
2158         } else
2159                 WriteAlert(_("Error! unknown language"),l);
2160 }
2161
2162
2163 void StyleReset()
2164 {
2165         LyXFont font(LyXFont::ALL_INHERIT, ignore_language);
2166         ToggleAndShow(current_view, font);
2167 }
2168
2169
2170 /* -------> Returns the current font and depth by printing a message. In the
2171  * future perhaps we could try to implement a callback to the button-bar.
2172  * That is, `light' the bold button when the font is currently bold, etc.
2173  */
2174 string CurrentState()
2175 {
2176         string state;
2177         if (current_view->available()) { 
2178                 // I think we should only show changes from the default
2179                 // font. (Asger)
2180                 Buffer * buffer = current_view->buffer();
2181                 LyXFont font = current_view->text->real_current_font;
2182                 LyXFont defaultfont = textclasslist.TextClass(buffer->
2183                                                               params.textclass).defaultfont();
2184                 font.reduce(defaultfont);
2185                 state = _("Font: ") + font.stateText();
2186
2187                 int depth = current_view->text->GetDepth();
2188                 if (depth > 0) 
2189                         state += string(_(", Depth: ")) + tostr(depth);
2190         }
2191         return state;
2192 }
2193
2194
2195 // candidate for move to BufferView
2196 /* -------> Does the actual toggle job of the XxxCB() calls above.
2197  * Also shows the current font state.
2198  */
2199 static
2200 void ToggleAndShow(BufferView * bv, LyXFont const & font)
2201 {
2202         if (bv->available()) { 
2203                 bv->hideCursor();
2204                 bv->update(-2);
2205                 if (bv->the_locking_inset)
2206                         bv->the_locking_inset->SetFont(bv, font, toggleall);
2207                 else
2208                         bv->text->ToggleFree(font, toggleall);
2209                 bv->update(1);
2210         }
2211 }
2212
2213
2214 // candidate for move to BufferView
2215 void Margin(BufferView * bv)
2216 {
2217         if (bv->available()) {
2218                 bv->owner()->getMiniBuffer()->Set(_("Inserting margin note..."));
2219                 bv->hideCursor();
2220                 bv->update(-2);
2221                 bv->text->InsertFootnoteEnvironment(LyXParagraph::MARGIN);
2222                 bv->update(1);
2223         }
2224 }
2225
2226
2227 void Figure()
2228 {
2229         if (fd_form_figure->form_figure->visible) {
2230                 fl_raise_form(fd_form_figure->form_figure);
2231         } else {
2232                 fl_show_form(fd_form_figure->form_figure,
2233                              FL_PLACE_MOUSE, FL_FULLBORDER,
2234                              _("Insert Figure"));
2235         }
2236 }
2237
2238
2239 void Table()
2240 {
2241         if (fd_form_table->form_table->visible) {
2242                 fl_raise_form(fd_form_table->form_table);
2243         } else {
2244                 fl_show_form(fd_form_table->form_table,
2245                              FL_PLACE_MOUSE, FL_FULLBORDER,
2246                              _("Insert Table"));
2247         }
2248 }
2249
2250
2251 // candidate for move to BufferView
2252 void Melt(BufferView * bv)
2253 {
2254         if (!bv->available()) return;
2255         
2256         bv->owner()->getMiniBuffer()->Set(_("Melt"));
2257         bv->hideCursor();
2258         bv->beforeChange();
2259         bv->update(-2);
2260         bv->text->MeltFootnoteEnvironment();
2261         bv->update(1);
2262 }
2263
2264
2265 // candidate for move to BufferView
2266 // Change environment depth.
2267 // if decInc >= 0, increment depth
2268 // if decInc <  0, decrement depth
2269 void changeDepth(BufferView * bv, int decInc)
2270 {
2271         if (!bv->available()) return;
2272         
2273         bv->hideCursor();
2274         bv->update(-2);
2275         if (decInc >= 0)
2276                 bv->text->IncDepth();
2277         else
2278                 bv->text->DecDepth();
2279         bv->update(1);
2280         bv->owner()->getMiniBuffer()
2281                 ->Set(_("Changed environment depth"
2282                         " (in possible range, maybe not)"));
2283 }
2284
2285
2286 // This is both GUI and LyXFont dependent. Don't know where to put it. (Asger)
2287 // Well, it's mostly GUI dependent, so I guess it will stay here. (Asger)
2288 LyXFont UserFreeFont()
2289 {
2290         LyXFont font(LyXFont::ALL_IGNORE);
2291
2292         int pos = fl_get_choice(fd_form_character->choice_family);
2293         switch(pos) {
2294         case 1: font.setFamily(LyXFont::IGNORE_FAMILY); break;
2295         case 2: font.setFamily(LyXFont::ROMAN_FAMILY); break;
2296         case 3: font.setFamily(LyXFont::SANS_FAMILY); break;
2297         case 4: font.setFamily(LyXFont::TYPEWRITER_FAMILY); break;
2298         case 5: font.setFamily(LyXFont::INHERIT_FAMILY); break;
2299         }
2300
2301         pos = fl_get_choice(fd_form_character->choice_series);
2302         switch(pos) {
2303         case 1: font.setSeries(LyXFont::IGNORE_SERIES); break;
2304         case 2: font.setSeries(LyXFont::MEDIUM_SERIES); break;
2305         case 3: font.setSeries(LyXFont::BOLD_SERIES); break;
2306         case 4: font.setSeries(LyXFont::INHERIT_SERIES); break;
2307         }
2308
2309         pos = fl_get_choice(fd_form_character->choice_shape);
2310         switch(pos) {
2311         case 1: font.setShape(LyXFont::IGNORE_SHAPE); break;
2312         case 2: font.setShape(LyXFont::UP_SHAPE); break;
2313         case 3: font.setShape(LyXFont::ITALIC_SHAPE); break;
2314         case 4: font.setShape(LyXFont::SLANTED_SHAPE); break;
2315         case 5: font.setShape(LyXFont::SMALLCAPS_SHAPE); break;
2316         case 6: font.setShape(LyXFont::INHERIT_SHAPE); break;
2317         }
2318
2319         pos = fl_get_choice(fd_form_character->choice_size);
2320         switch(pos) {
2321         case 1: font.setSize(LyXFont::IGNORE_SIZE); break;
2322         case 2: font.setSize(LyXFont::SIZE_TINY); break;
2323         case 3: font.setSize(LyXFont::SIZE_SCRIPT); break;
2324         case 4: font.setSize(LyXFont::SIZE_FOOTNOTE); break;
2325         case 5: font.setSize(LyXFont::SIZE_SMALL); break;
2326         case 6: font.setSize(LyXFont::SIZE_NORMAL); break;
2327         case 7: font.setSize(LyXFont::SIZE_LARGE); break;
2328         case 8: font.setSize(LyXFont::SIZE_LARGER); break;
2329         case 9: font.setSize(LyXFont::SIZE_LARGEST); break;
2330         case 10: font.setSize(LyXFont::SIZE_HUGE); break;
2331         case 11: font.setSize(LyXFont::SIZE_HUGER); break;
2332         case 12: font.setSize(LyXFont::INCREASE_SIZE); break;
2333         case 13: font.setSize(LyXFont::DECREASE_SIZE); break;
2334         case 14: font.setSize(LyXFont::INHERIT_SIZE); break;
2335         }
2336
2337         pos = fl_get_choice(fd_form_character->choice_bar);
2338         switch(pos) {
2339         case 1: font.setEmph(LyXFont::IGNORE);
2340                 font.setUnderbar(LyXFont::IGNORE);
2341                 font.setNoun(LyXFont::IGNORE);
2342                 font.setLatex(LyXFont::IGNORE);
2343                 break;
2344         case 2: font.setEmph(LyXFont::TOGGLE); break;
2345         case 3: font.setUnderbar(LyXFont::TOGGLE); break;
2346         case 4: font.setNoun(LyXFont::TOGGLE); break;
2347         case 5: font.setLatex(LyXFont::TOGGLE); break;
2348         case 6: font.setEmph(LyXFont::INHERIT);
2349                 font.setUnderbar(LyXFont::INHERIT);
2350                 font.setNoun(LyXFont::INHERIT);
2351                 font.setLatex(LyXFont::INHERIT);
2352                 break;
2353         }
2354
2355         pos = fl_get_choice(fd_form_character->choice_color);
2356         switch(pos) {
2357         case 1: font.setColor(LColor::ignore); break;
2358         case 2: font.setColor(LColor::none); break;
2359         case 3: font.setColor(LColor::black); break;
2360         case 4: font.setColor(LColor::white); break;
2361         case 5: font.setColor(LColor::red); break;
2362         case 6: font.setColor(LColor::green); break;
2363         case 7: font.setColor(LColor::blue); break;
2364         case 8: font.setColor(LColor::cyan); break;
2365         case 9: font.setColor(LColor::magenta); break;
2366         case 10: font.setColor(LColor::yellow); break;
2367         case 11: font.setColor(LColor::inherit); break;
2368         }
2369
2370         return font; 
2371 }
2372
2373
2374 void Free()
2375 {
2376         ToggleAndShow(current_view, UserFreeFont());
2377 }
2378
2379
2380 /* callbacks for form form_title */
2381 extern "C" void TimerCB(FL_OBJECT *, long)
2382 {
2383         // only if the form still exists
2384         if (lyxrc.show_banner && fd_form_title->form_title != 0) {
2385                 if (fd_form_title->form_title->visible) {
2386                         fl_hide_form(fd_form_title->form_title);
2387                 }
2388                 fl_free_form(fd_form_title->form_title);
2389                 fd_form_title->form_title = 0;
2390         }
2391 }
2392
2393
2394 /* callbacks for form form_paragraph */
2395
2396 extern "C" void ParagraphVSpaceCB(FL_OBJECT * obj, long )
2397 {
2398         // "Synchronize" the choices and input fields, making it
2399         // impossible to commit senseless data.
2400
2401         FD_form_paragraph const * fp = fd_form_paragraph;
2402
2403         if (obj == fp->choice_space_above) {
2404                 if (fl_get_choice (fp->choice_space_above) != 7) {
2405                         fl_set_input (fp->input_space_above, "");
2406                         ActivateParagraphButtons();
2407                 }
2408         } else if (obj == fp->choice_space_below) {
2409                 if (fl_get_choice (fp->choice_space_below) != 7) {
2410                         fl_set_input (fp->input_space_below, "");
2411                         ActivateParagraphButtons();
2412                 }
2413         } else if (obj == fp->input_space_above) {
2414                 string input = fl_get_input (fp->input_space_above);
2415
2416                 if (input.empty()) {
2417                         fl_set_choice (fp->choice_space_above, 1);
2418                         ActivateParagraphButtons();
2419                 }
2420                 else if (isValidGlueLength (input)) {
2421                         fl_set_choice (fp->choice_space_above, 7);
2422                         ActivateParagraphButtons();
2423                 }
2424                 else {
2425                         fl_set_choice (fp->choice_space_above, 7);
2426                         DeactivateParagraphButtons();
2427                 }
2428         } else if (obj == fp->input_space_below) {
2429                 string input = fl_get_input (fp->input_space_below);
2430
2431                 if (input.empty()) {
2432                         fl_set_choice (fp->choice_space_below, 1);
2433                         ActivateParagraphButtons();
2434                 }
2435                 else if (isValidGlueLength (input)) {
2436                         fl_set_choice (fp->choice_space_below, 7);
2437                         ActivateParagraphButtons();
2438                 }
2439                 else {
2440                         fl_set_choice (fp->choice_space_below, 7);
2441                         DeactivateParagraphButtons();
2442                 }
2443         }
2444 }
2445
2446
2447 extern "C" void ParagraphApplyCB(FL_OBJECT *, long)
2448 {
2449         if (!current_view->available())
2450                 return;
2451         
2452         VSpace space_top, space_bottom;
2453         LyXAlignment align;
2454         string labelwidthstring;
2455         bool noindent;
2456
2457         // If a vspace kind is "Length" but there's no text in
2458         // the input field, reset the kind to "None". 
2459         if (fl_get_choice (fd_form_paragraph->choice_space_above) == 7
2460             && !*(fl_get_input (fd_form_paragraph->input_space_above))) {
2461                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
2462         }
2463         if (fl_get_choice (fd_form_paragraph->choice_space_below) == 7
2464             && !*(fl_get_input (fd_form_paragraph->input_space_below))) {
2465                 fl_set_choice (fd_form_paragraph->choice_space_below, 1);
2466         }
2467    
2468         bool line_top = fl_get_button(fd_form_paragraph->check_lines_top);
2469         bool line_bottom = fl_get_button(fd_form_paragraph->check_lines_bottom);
2470         bool pagebreak_top = fl_get_button(fd_form_paragraph->check_pagebreaks_top);
2471         bool pagebreak_bottom = fl_get_button(fd_form_paragraph->check_pagebreaks_bottom);
2472         switch (fl_get_choice (fd_form_paragraph->choice_space_above)) {
2473         case 1: space_top = VSpace(VSpace::NONE); break;
2474         case 2: space_top = VSpace(VSpace::DEFSKIP); break;
2475         case 3: space_top = VSpace(VSpace::SMALLSKIP); break;
2476         case 4: space_top = VSpace(VSpace::MEDSKIP); break;
2477         case 5: space_top = VSpace(VSpace::BIGSKIP); break;
2478         case 6: space_top = VSpace(VSpace::VFILL); break;
2479         case 7: space_top = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_above))); break;
2480         }
2481         if (fl_get_button (fd_form_paragraph->check_space_above))
2482                 space_top.setKeep (true);
2483         switch (fl_get_choice (fd_form_paragraph->choice_space_below)) {
2484         case 1: space_bottom = VSpace(VSpace::NONE); break;
2485         case 2: space_bottom = VSpace(VSpace::DEFSKIP); break;
2486         case 3: space_bottom = VSpace(VSpace::SMALLSKIP); break;
2487         case 4: space_bottom = VSpace(VSpace::MEDSKIP); break;
2488         case 5: space_bottom = VSpace(VSpace::BIGSKIP); break;
2489         case 6: space_bottom = VSpace(VSpace::VFILL); break;
2490         case 7: space_bottom = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_below))); break;
2491         }
2492         if (fl_get_button (fd_form_paragraph->check_space_below))
2493                 space_bottom.setKeep (true);
2494
2495         if (fl_get_button(fd_form_paragraph->radio_align_left))
2496                 align = LYX_ALIGN_LEFT;
2497         else if (fl_get_button(fd_form_paragraph->radio_align_right))
2498                 align = LYX_ALIGN_RIGHT;
2499         else if (fl_get_button(fd_form_paragraph->radio_align_center))
2500                 align = LYX_ALIGN_CENTER;
2501         else 
2502                 align = LYX_ALIGN_BLOCK;
2503    
2504         labelwidthstring = fl_get_input(fd_form_paragraph->input_labelwidth);
2505         noindent = fl_get_button(fd_form_paragraph->check_noindent);
2506
2507         current_view->text->SetParagraph(line_top,
2508                                          line_bottom,
2509                                          pagebreak_top,
2510                                          pagebreak_bottom,
2511                                          space_top,
2512                                          space_bottom,
2513                                          align, 
2514                                          labelwidthstring,
2515                                          noindent);
2516         current_view->update(1);
2517         current_view->owner()->getMiniBuffer()->Set(_("Paragraph layout set"));
2518 }
2519
2520
2521 extern "C" void ParagraphCancelCB(FL_OBJECT *, long)
2522 {
2523         fl_hide_form(fd_form_paragraph->form_paragraph);
2524 }
2525
2526
2527 extern "C" void ParagraphOKCB(FL_OBJECT *ob, long data)
2528 {
2529         ParagraphApplyCB(ob, data);
2530         ParagraphCancelCB(ob, data);
2531 }
2532
2533
2534 /* callbacks for form form_character */
2535
2536 extern "C" void CharacterApplyCB(FL_OBJECT *, long)
2537 {
2538         // we set toggleall locally here, since it should be true for
2539         // all other uses of ToggleAndShow() (JMarc)
2540         toggleall = fl_get_button(fd_form_character->check_toggle_all);
2541         ToggleAndShow(current_view, UserFreeFont());
2542         toggleall = true;
2543 }
2544
2545
2546 extern "C" void CharacterCloseCB(FL_OBJECT *, long)
2547 {
2548         fl_hide_form(fd_form_character->form_character);
2549 }
2550
2551
2552 extern "C" void CharacterOKCB(FL_OBJECT *ob, long data)
2553 {
2554         CharacterApplyCB(ob, data);
2555         CharacterCloseCB(ob, data);
2556 }
2557
2558
2559 /* callbacks for form form_document */
2560
2561 void UpdateDocumentButtons(BufferParams const & params) 
2562 {
2563         fl_set_choice(fd_form_document->choice_pagestyle, 1);
2564
2565         switch (params.sides) {
2566         case LyXTextClass::OneSide:
2567                 fl_set_button(fd_form_document->radio_sides_one, 1);
2568                 break;
2569         case LyXTextClass::TwoSides:
2570                 fl_set_button(fd_form_document->radio_sides_two, 1);
2571                 break;
2572         }
2573    
2574         if (params.columns == 2)
2575                 fl_set_button(fd_form_document->radio_columns_two, 1);
2576         else
2577                 fl_set_button(fd_form_document->radio_columns_one, 1);
2578         
2579         fl_set_input(fd_form_document->input_extra, params.options.c_str());
2580         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
2581                              params.secnumdepth);
2582         fl_set_counter_value(fd_form_document->slider_tocdepth, 
2583                              params.tocdepth);
2584         
2585 }
2586
2587 extern "C" void ChoiceClassCB(FL_OBJECT * ob, long)
2588 {
2589         ProhibitInput();
2590         if (textclasslist.Load(fl_get_choice(ob)-1)) {
2591                 if (AskQuestion(_("Should I set some parameters to"),
2592                                 fl_get_choice_text(ob),
2593                                 _("the defaults of this document class?"))) {
2594                         BufferParams params = BufferParams();
2595                         params.textclass = fl_get_choice(ob)-1;
2596                         params.useClassDefaults();
2597                         UpdateLayoutDocument(&params);
2598                         UpdateDocumentButtons(params);
2599                 }
2600         } else {
2601                 // unable to load new style
2602                 WriteAlert(_("Conversion Errors!"),
2603                            _("Unable to switch to new document class."),
2604                            _("Reverting to original document class."));
2605                 fl_set_choice(fd_form_document->choice_class, 
2606                               current_view->buffer()->params.textclass + 1);
2607         }
2608         AllowInput();
2609 }
2610
2611
2612 extern "C" void DocumentDefskipCB(FL_OBJECT * obj, long)
2613 {
2614         // "Synchronize" the choice and the input field, so that it
2615         // is impossible to commit senseless data.
2616         FD_form_document const * fd = fd_form_document;
2617
2618         if (obj == fd->choice_default_skip) {
2619                 if (fl_get_choice (fd->choice_default_skip) != 4) {
2620                         fl_set_input (fd->input_default_skip, "");
2621                         ActivateDocumentButtons();
2622                 }
2623         } else if (obj == fd->input_default_skip) {
2624
2625                 char const * input = fl_get_input (fd->input_default_skip);
2626
2627                 if (!*input) {
2628                         fl_set_choice (fd->choice_default_skip, 2);
2629                         ActivateDocumentButtons();
2630                 } else if (isValidGlueLength (input)) {
2631                         fl_set_choice (fd->choice_default_skip, 4);
2632                         ActivateDocumentButtons();
2633                 } else {
2634                         fl_set_choice (fd->choice_default_skip, 4);
2635                         DeactivateDocumentButtons();
2636                 }
2637         }
2638 }
2639
2640
2641 extern "C" void DocumentSpacingCB(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_spacing
2648             && fl_get_choice (fd->choice_spacing) != 4) {
2649                 fl_set_input(fd->input_spacing, "");
2650         } else if (obj == fd->input_spacing) {
2651
2652                 const char* input = fl_get_input (fd->input_spacing);
2653
2654                 if (!*input) {
2655                         fl_set_choice (fd->choice_spacing, 1);
2656                 } else {
2657                         fl_set_choice (fd->choice_spacing, 4);
2658                 }
2659         }
2660 }
2661
2662
2663 extern "C" void DocumentApplyCB(FL_OBJECT *, long)
2664 {
2665         bool redo = false;
2666         BufferParams * params = &(current_view->buffer()->params);
2667
2668         params->language = combo_language->getline();
2669         Languages::iterator lit = languages.find(params->language);
2670         if (lit != languages.end()) 
2671                 params->language_info = &(*lit).second;
2672         else
2673                 params->language_info = default_language;
2674
2675         // If default skip is a "Length" but there's no text in the
2676         // input field, reset the kind to "Medskip", which is the default.
2677         if (fl_get_choice (fd_form_document->choice_default_skip) == 4
2678             && !*(fl_get_input (fd_form_document->input_default_skip))) {
2679                 fl_set_choice (fd_form_document->choice_default_skip, 2);
2680         }
2681
2682         /* this shouldn't be done automatically IMO. For example I write german
2683          * documents with an american keyboard very often. Matthias */
2684    
2685         /* ChangeKeymap(buffer->parameters.language, TRUE, false,
2686            fl_get_choice(fd_form_document->choice_language)); */
2687         params->fonts = 
2688                 fl_get_choice_text(fd_form_document->choice_fonts);
2689         params->inputenc = 
2690                 fl_get_choice_text(fd_form_document->choice_inputenc);
2691         params->fontsize = 
2692                 fl_get_choice_text(fd_form_document->choice_fontsize);
2693         params->pagestyle = 
2694                 fl_get_choice_text(fd_form_document->choice_pagestyle);
2695         params->graphicsDriver = 
2696                 fl_get_choice_text(fd_form_document->choice_postscript_driver);
2697         params->use_amsmath = 
2698                 fl_get_button(fd_form_document->check_use_amsmath);
2699    
2700         if (!current_view->available())
2701                 return;
2702         current_view->text->SetCursor(current_view->text->cursor.par,
2703                                       current_view->text->cursor.pos);
2704         current_view->setState();
2705
2706         LyXTextClassList::ClassList::size_type new_class =
2707                 fl_get_choice(fd_form_document->choice_class) - 1;
2708
2709         if (params->textclass != new_class) {
2710                 // try to load new_class
2711                 if (textclasslist.Load(new_class)) {
2712                         // successfully loaded
2713                         redo = true;
2714                         current_view->owner()->getMiniBuffer()->
2715                                 Set(_("Converting document to new document class..."));
2716                         CutAndPaste cap;
2717                         int ret = cap.SwitchLayoutsBetweenClasses(
2718                                 current_view->buffer()->params.textclass,
2719                                 new_class,
2720                                 current_view->buffer()->paragraph);
2721
2722                         if (ret) {
2723                                 string s;
2724                                 if (ret == 1)
2725                                         s = _("One paragraph couldn't be converted");
2726                                 else {
2727                                         s += tostr(ret);
2728                                         s += _(" paragraphs couldn't be converted");
2729                                 }
2730                                 WriteAlert(_("Conversion Errors!"), s,
2731                                            _("into chosen document class"));
2732                         }
2733
2734                         params->textclass = new_class;
2735                 } else {
2736                         // problem changing class -- warn user and retain old style
2737                         WriteAlert(_("Conversion Errors!"),
2738                                    _("Unable to switch to new document class."),
2739                                    _("Reverting to original document class."));
2740                         fl_set_choice(fd_form_document->choice_class, params->textclass + 1);
2741                 }
2742         }
2743
2744         char tmpsep = params->paragraph_separation;
2745         if (fl_get_button(fd_form_document->radio_indent))
2746                 params->paragraph_separation = BufferParams::PARSEP_INDENT;
2747         else
2748                 params->paragraph_separation = BufferParams::PARSEP_SKIP;
2749         if (tmpsep != params->paragraph_separation)
2750                 redo = true;
2751    
2752         VSpace tmpdefskip = params->getDefSkip();
2753         switch (fl_get_choice (fd_form_document->choice_default_skip)) {
2754         case 1: params->setDefSkip(VSpace(VSpace::SMALLSKIP)); break;
2755         case 2: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2756         case 3: params->setDefSkip(VSpace(VSpace::BIGSKIP)); break;
2757         case 4: params->setDefSkip( 
2758                 VSpace (LyXGlueLength (fl_get_input 
2759                                        (fd_form_document->input_default_skip))));
2760         break;
2761         // DocumentDefskipCB assures that this never happens
2762         default: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2763         }
2764         if (!(tmpdefskip == params->getDefSkip()))
2765                 redo = true;
2766
2767         if (fl_get_button(fd_form_document->radio_columns_two))
2768                 params->columns = 2;
2769         else
2770                 params->columns = 1;
2771         if (fl_get_button(fd_form_document->radio_sides_two))
2772                 params->sides = LyXTextClass::TwoSides;
2773         else
2774                 params->sides = LyXTextClass::OneSide;
2775
2776         Spacing tmpSpacing = params->spacing;
2777         switch(fl_get_choice(fd_form_document->choice_spacing)) {
2778         case 1:
2779                 lyxerr.debug() << "Spacing: SINGLE" << endl;
2780                 params->spacing.set(Spacing::Single);
2781                 break;
2782         case 2:
2783                 lyxerr.debug() << "Spacing: ONEHALF" << endl;
2784                 params->spacing.set(Spacing::Onehalf);
2785                 break;
2786         case 3:
2787                 lyxerr.debug() << "Spacing: DOUBLE" << endl;
2788                 params->spacing.set(Spacing::Double);
2789                 break;
2790         case 4:
2791                 lyxerr.debug() << "Spacing: OTHER" << endl;
2792                 params->spacing.set(Spacing::Other, 
2793                                     fl_get_input(fd_form_document->input_spacing));
2794                 break;
2795         }
2796         if (tmpSpacing != params->spacing)
2797                 redo = true;
2798         
2799         signed char tmpchar =  
2800                 static_cast<signed char>(fl_get_counter_value(fd_form_document->slider_secnumdepth));
2801         if (params->secnumdepth != tmpchar)
2802                 redo = true;
2803         params->secnumdepth = tmpchar;
2804    
2805         params->tocdepth =  
2806                 static_cast<int>(fl_get_counter_value(fd_form_document->slider_tocdepth));
2807
2808         params->float_placement = 
2809                 fl_get_input(fd_form_document->input_float_placement);
2810
2811         // More checking should be done to ensure the string doesn't have
2812         // spaces or illegal placement characters in it. (thornley)
2813
2814         if (redo)
2815                 current_view->redoCurrentBuffer();
2816    
2817         current_view->owner()->getMiniBuffer()->Set(_("Document layout set"));
2818         current_view->buffer()->markDirty();
2819
2820         params->options = 
2821                 fl_get_input(fd_form_document->input_extra);
2822    
2823 }
2824
2825
2826 extern "C" void DocumentCancelCB(FL_OBJECT *, long)
2827 {
2828         fl_hide_form(fd_form_document->form_document);
2829 }
2830
2831
2832 extern "C" void DocumentOKCB(FL_OBJECT * ob, long data)
2833 {
2834         DocumentCancelCB(ob, data);
2835         DocumentApplyCB(ob, data);
2836 }
2837
2838
2839 extern "C" void DocumentBulletsCB(FL_OBJECT *, long)
2840 {
2841         bulletForm();
2842         // bullet callbacks etc. in bullet_panel.C -- ARRae
2843 }
2844
2845
2846 /* callbacks for form form_quotes */
2847
2848 extern "C" void QuotesApplyCB(FL_OBJECT *, long)
2849 {
2850         if (!current_view->available())
2851                 return;
2852         
2853         current_view->owner()->getMiniBuffer()->Set(_("Quotes type set"));
2854         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
2855         switch(fl_get_choice(fd_form_quotes->choice_quotes_language) - 1) {
2856         case 0:
2857                 lga = InsetQuotes::EnglishQ;
2858                 break;
2859         case 1:
2860                 lga = InsetQuotes::SwedishQ;
2861                 break;
2862         case 2:
2863                 lga = InsetQuotes::GermanQ;
2864                 break;
2865         case 3:
2866                 lga = InsetQuotes::PolishQ;
2867                 break;
2868         case 4:
2869                 lga = InsetQuotes::FrenchQ;
2870                 break;
2871         case 5:
2872                 lga = InsetQuotes::DanishQ;
2873                 break;
2874         }
2875         current_view->buffer()->params.quotes_language = lga;
2876         if (fl_get_button(fd_form_quotes->radio_single))   
2877                 current_view->buffer()->
2878                         params.quotes_times = InsetQuotes::SingleQ;
2879         else
2880                 current_view->buffer()->
2881                         params.quotes_times = InsetQuotes::DoubleQ;
2882 }
2883
2884
2885 extern "C" void QuotesCancelCB(FL_OBJECT *, long)
2886 {
2887         fl_hide_form(fd_form_quotes->form_quotes);
2888 }
2889
2890
2891 extern "C" void QuotesOKCB(FL_OBJECT * ob, long data)
2892 {
2893         QuotesApplyCB(ob, data);
2894         QuotesCancelCB(ob, data);
2895 }
2896
2897
2898
2899 /* callbacks for form form_preamble */
2900
2901 extern "C" void PreambleCancelCB(FL_OBJECT *, long)
2902 {
2903         fl_hide_form(fd_form_preamble->form_preamble);
2904 }
2905
2906
2907 extern "C" void PreambleApplyCB(FL_OBJECT *, long)
2908 {
2909         if (!current_view->available())
2910                 return;
2911         
2912         current_view->buffer()->params.preamble = 
2913                 fl_get_input(fd_form_preamble->input_preamble);
2914         current_view->buffer()->markDirty();
2915         current_view->owner()->getMiniBuffer()->Set(_("LaTeX preamble set"));
2916 }
2917
2918    
2919 extern "C" void PreambleOKCB(FL_OBJECT * ob, long data)
2920 {
2921         PreambleApplyCB(ob, data);
2922         PreambleCancelCB(ob, data);
2923 }
2924
2925
2926 /* callbacks for form form_table */
2927
2928 extern "C" void TableApplyCB(FL_OBJECT *, long)
2929 {
2930         if (!current_view->available())
2931                 return;
2932    
2933         // check for tables in tables
2934         if (current_view->text->cursor.par->table){
2935                 WriteAlert(_("Impossible Operation!"),
2936                            _("Cannot insert table in table."),
2937                            _("Sorry."));
2938                 return;
2939         }
2940  
2941         current_view->owner()->getMiniBuffer()->Set(_("Inserting table..."));
2942
2943         int ysize = int(fl_get_slider_value(fd_form_table->slider_columns) + 0.5);
2944         int xsize = int(fl_get_slider_value(fd_form_table->slider_rows) + 0.5);
2945    
2946    
2947         current_view->hideCursor();
2948         current_view->beforeChange();
2949         current_view->update(-2);
2950    
2951         current_view->text->SetCursorParUndo(); 
2952         current_view->text->FreezeUndo();
2953
2954         current_view->text->BreakParagraph();
2955         current_view->update(-1);
2956    
2957         if (current_view->text->cursor.par->Last()) {
2958                 current_view->text->CursorLeft();
2959       
2960                 current_view->text->BreakParagraph();
2961                 current_view->update(-1);
2962         }
2963
2964         current_view->text->current_font.setLatex(LyXFont::OFF);
2965         //if (!fl_get_button(fd_form_table->check_latex)){
2966         // insert the new wysiwy table
2967         current_view->text->SetLayout(0); // standard layout
2968         if (current_view->text->cursor.par->footnoteflag == 
2969             LyXParagraph::NO_FOOTNOTE) {
2970                 current_view->text
2971                         ->SetParagraph(0, 0,
2972                                        0, 0,
2973                                        VSpace (0.3 * current_view->buffer()->
2974                                                params.spacing.getValue(),
2975                                                LyXLength::CM),
2976                                        VSpace (0.3 * current_view->buffer()->
2977                                                params.spacing.getValue(),
2978                                                LyXLength::CM),
2979                                        LYX_ALIGN_CENTER,
2980                                        string(),
2981                                        0);
2982         } else {
2983                 current_view->text
2984                         ->SetParagraph(0, 0,
2985                                        0, 0,
2986                                        VSpace(VSpace::NONE),
2987                                        VSpace(VSpace::NONE),
2988                                        LYX_ALIGN_CENTER, 
2989                                        string(),
2990                                        0);
2991         }
2992         
2993         current_view->text->cursor.par->table =
2994                 new LyXTable(xsize, ysize);
2995
2996         Language const * lang = 
2997                 current_view->text->cursor.par->getParLanguage();
2998         LyXFont font(LyXFont::ALL_INHERIT,lang);
2999         for (int i = 0; i < xsize * ysize - 1; ++i) {
3000                 current_view->text->cursor.par->InsertChar(0, LyXParagraph::META_NEWLINE);
3001                 current_view->text->cursor.par->SetFont(0, font);
3002         }
3003         current_view->text->RedoParagraph();
3004    
3005         current_view->text->UnFreezeUndo();
3006      
3007         current_view->update(1);
3008         current_view->owner()->getMiniBuffer()->Set(_("Table inserted"));
3009         current_view->setState();
3010 }
3011
3012
3013 extern "C" void TableCancelCB(FL_OBJECT *, long)
3014 {
3015         fl_hide_form(fd_form_table->form_table);
3016 }
3017
3018
3019 extern "C" void TableOKCB(FL_OBJECT * ob, long data)
3020 {
3021         TableApplyCB(ob, data);
3022         TableCancelCB(ob, data);
3023 }
3024
3025
3026 /* callbacks for form form_print */
3027
3028 extern "C" void PrintCancelCB(FL_OBJECT *, long)
3029 {
3030         fl_hide_form(fd_form_print->form_print);
3031 }
3032
3033
3034 static
3035 bool stringOnlyContains (string const & LStr, char const * cset)
3036 {
3037 #if 0
3038         char const * cstr = LStr.c_str();
3039
3040         return strspn(cstr, cset) == strlen(cstr);
3041 #else
3042         return LStr.find_first_not_of(cset) == string::npos;
3043 #endif
3044 }
3045
3046
3047 extern "C" void PrintApplyCB(FL_OBJECT *, long)
3048 {
3049         if (!current_view->available())
3050                 return;
3051         Buffer * buffer = current_view->buffer();
3052         string path = OnlyPath(buffer->fileName());
3053
3054         string pageflag;
3055         if (fl_get_button(fd_form_print->radio_even_pages))
3056                 pageflag = lyxrc.print_evenpage_flag + ' ';
3057         else if (fl_get_button(fd_form_print->radio_odd_pages))
3058                 pageflag = lyxrc.print_oddpage_flag + ' ';
3059
3060 // Changes by Stephan Witt (stephan.witt@beusen.de), 19-Jan-99
3061 // User may give a page (range) list
3062 // User may print multiple (unsorted) copies
3063         string pages = subst(fl_get_input(fd_form_print->input_pages), ';',',');
3064         pages = subst(pages, '+',',');
3065         pages = frontStrip(strip(pages)) ;
3066         while (!pages.empty()) { // a page range was given
3067                 string piece ;
3068                 pages = split (pages, piece, ',') ;
3069                 piece = strip(piece) ;
3070                 piece = frontStrip(piece) ;
3071                 if ( !stringOnlyContains (piece, "0123456789-") ) {
3072                         WriteAlert(_("ERROR!  Unable to print!"),
3073                                    _("Check 'range of pages'!"));
3074                         return;
3075                 }
3076                 if (piece.find('-') == string::npos) { // not found
3077                         pageflag += lyxrc.print_pagerange_flag + piece + '-' + piece + ' ' ;
3078                 } else if (suffixIs(piece, "-") ) { // missing last page
3079                         pageflag += lyxrc.print_pagerange_flag + piece + "1000 ";
3080                 } else if (prefixIs(piece, "-") ) { // missing first page
3081                         pageflag += lyxrc.print_pagerange_flag + '1' + piece + ' ' ;
3082                 } else {
3083                         pageflag += lyxrc.print_pagerange_flag + piece + ' ' ;
3084                 }
3085         }
3086    
3087         string copies = frontStrip(strip(fl_get_input(fd_form_print->input_copies)));
3088         if (!copies.empty()) { // a number of copies was given
3089                 if ( !stringOnlyContains (copies, "0123456789") ) {
3090                         WriteAlert(_("ERROR!  Unable to print!"),
3091                                    _("Check 'number of copies'!"));
3092                         return;
3093                 }
3094                 if (fl_get_button(fd_form_print->do_unsorted))
3095                         pageflag += lyxrc.print_copies_flag;
3096                 else
3097                         pageflag += lyxrc.print_collcopies_flag;
3098                 pageflag += " " + copies + ' ' ;
3099         }
3100
3101         string reverseflag;
3102         if (fl_get_button(fd_form_print->radio_order_reverse))
3103                 reverseflag = lyxrc.print_reverse_flag + ' ';
3104    
3105         string orientationflag;
3106         if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
3107                 orientationflag = lyxrc.print_landscape_flag + ' ';
3108    
3109         string ps_file = fl_get_input(fd_form_print->input_file);
3110         string printer = strip(fl_get_input(fd_form_print->input_printer));
3111
3112         string printerflag;
3113         if (lyxrc.print_adapt_output // printer name should be passed to dvips
3114             && ! printer.empty()) // a printer name has been given
3115                 printerflag = lyxrc.print_to_printer + printer + ' ';
3116      
3117         string extraflags;
3118         if (!lyxrc.print_extra_options.empty())
3119                 extraflags = lyxrc.print_extra_options + ' ';
3120
3121         string command = lyxrc.print_command + ' ' 
3122                 + printerflag + pageflag + reverseflag 
3123                 + orientationflag + extraflags;
3124  
3125         char real_papersize = buffer->params.papersize;
3126         if (real_papersize == BufferParams::PAPER_DEFAULT)
3127                 real_papersize = lyxrc.default_papersize;
3128         
3129         string paper;
3130         switch (real_papersize) {
3131         case BufferParams::PAPER_USLETTER:
3132                 paper = "letter";
3133                 break;
3134         case BufferParams::PAPER_A3PAPER:
3135                 paper = "a3";
3136                 break;
3137         case BufferParams::PAPER_A4PAPER:
3138                 paper = "a4";
3139                 break;
3140         case BufferParams::PAPER_A5PAPER:
3141                 paper = "a5";
3142                 break;
3143         case BufferParams::PAPER_B5PAPER:
3144                 paper = "b5";
3145                 break;
3146         case BufferParams::PAPER_EXECUTIVEPAPER:
3147                 paper = "foolscap";
3148                 break;
3149         case BufferParams::PAPER_LEGALPAPER:
3150                 paper = "legal";
3151                 break;
3152         default: /* If nothing else fits, keep an empty value... */
3153                 break;
3154         }
3155
3156         if (buffer->params.use_geometry
3157             && buffer->params.papersize2 == BufferParams::VM_PAPER_CUSTOM
3158             && !lyxrc.print_paper_dimension_flag.empty()
3159             && !buffer->params.paperwidth.empty()
3160             && !buffer->params.paperheight.empty()) {
3161                 // using a custom papersize
3162                 command += ' ';
3163                 command += lyxrc.print_paper_dimension_flag + ' ';
3164                 command += buffer->params.paperwidth + ',';
3165                 command += buffer->params.paperheight + ' ';
3166         } else if (!lyxrc.print_paper_flag.empty()
3167                    && !paper.empty()
3168                    && (real_papersize != BufferParams::PAPER_USLETTER ||
3169                        buffer->params.orientation == BufferParams::ORIENTATION_PORTRAIT)) {
3170                 command += " " + lyxrc.print_paper_flag + " " + paper + " ";
3171         }
3172         if (fl_get_button(fd_form_print->radio_file))
3173                 command += lyxrc.print_to_file 
3174                         + QuoteName(MakeAbsPath(ps_file, path));
3175         else if (!lyxrc.print_spool_command.empty())
3176                 command += lyxrc.print_to_file 
3177                         + QuoteName(ps_file);
3178         
3179         // push directorypath, if necessary 
3180         if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)){
3181                 path = buffer->tmppath;
3182         }
3183         Path p(path);
3184
3185         bool result;
3186         if (!lyxrc.print_spool_command.empty() && 
3187             !fl_get_button(fd_form_print->radio_file)) {
3188                 string command2 = lyxrc.print_spool_command + ' ';
3189                 if (!printer.empty())
3190                         command2 += lyxrc.print_spool_printerprefix 
3191                                 + printer;
3192                 // First run dvips and, if succesful, then spool command
3193                 if ((result = RunScript(buffer, true, command))) {
3194                         result = RunScript(buffer, false, command2, ps_file);
3195                 }
3196         } else
3197                 result = RunScript(buffer, false, command);
3198
3199         if (!result)
3200                 WriteAlert(_("Error:"),
3201                            _("Unable to print"),
3202                            _("Check that your parameters are correct"));
3203 }
3204
3205
3206 extern "C" void PrintOKCB(FL_OBJECT * ob, long data)
3207 {
3208         PrintCancelCB(ob, data);  
3209         PrintApplyCB(ob, data);
3210 }
3211
3212
3213 /* callbacks for form form_figure */
3214 extern "C" void FigureApplyCB(FL_OBJECT *, long)
3215 {
3216         if (!current_view->available())
3217                 return;
3218
3219         Buffer * buffer = current_view->buffer();
3220         if(buffer->isReadonly()) // paranoia
3221                 return;
3222         
3223         current_view->owner()->getMiniBuffer()->Set(_("Inserting figure..."));
3224         if (fl_get_button(fd_form_figure->radio_inline)
3225             || current_view->text->cursor.par->table) {
3226                 InsetFig * new_inset = new InsetFig(100, 20, buffer);
3227                 current_view->insertInset(new_inset);
3228                 current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
3229                 new_inset->Edit(current_view, 0, 0, 0);
3230                 return;
3231         }
3232         
3233         current_view->hideCursor();
3234         current_view->update(-2);
3235         current_view->beforeChange();
3236       
3237         current_view->text->SetCursorParUndo(); 
3238         current_view->text->FreezeUndo();
3239
3240         current_view->text->BreakParagraph();
3241         current_view->update(-1);
3242       
3243         if (current_view->text->cursor.par->Last()) {
3244                 current_view->text->CursorLeft();
3245          
3246                 current_view->text->BreakParagraph();
3247                 current_view->update(-1);
3248         }
3249
3250         // The standard layout should always be numer 0;
3251         current_view->text->SetLayout(0);
3252         
3253         if (current_view->text->cursor.par->footnoteflag == 
3254             LyXParagraph::NO_FOOTNOTE) {
3255                 current_view->text->
3256                         SetParagraph(0, 0,
3257                                      0, 0,
3258                                      VSpace (0.3 * buffer->params.spacing.getValue(),
3259                                              LyXLength::CM),
3260                                      VSpace (0.3 *
3261                                              buffer->params.spacing.getValue(),
3262                                              LyXLength::CM),
3263                                      LYX_ALIGN_CENTER, string(), 0);
3264         } else {
3265                 current_view->text->SetParagraph(0, 0,
3266                                                  0, 0,
3267                                                  VSpace(VSpace::NONE),
3268                                                  VSpace(VSpace::NONE),
3269                                                  LYX_ALIGN_CENTER, 
3270                                                  string(),
3271                                                  0);
3272         }
3273         
3274         current_view->update(-1);
3275       
3276         Inset * new_inset = new InsetFig(100, 100, buffer);
3277         current_view->insertInset(new_inset);
3278         new_inset->Edit(current_view, 0, 0, 0);
3279         current_view->update(0);
3280         current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
3281         current_view->text->UnFreezeUndo();
3282         current_view->setState();
3283 }
3284
3285
3286 extern "C" void FigureCancelCB(FL_OBJECT *, long)
3287 {
3288         fl_hide_form(fd_form_figure->form_figure);
3289 }
3290
3291
3292 extern "C" void FigureOKCB(FL_OBJECT * ob, long data)
3293 {
3294         FigureApplyCB(ob, data);
3295         FigureCancelCB(ob, data);
3296 }
3297
3298
3299 extern "C" void ScreenApplyCB(FL_OBJECT *, long)
3300 {
3301         lyxrc.roman_font_name = fl_get_input(fd_form_screen->input_roman);
3302         lyxrc.sans_font_name = fl_get_input(fd_form_screen->input_sans);
3303         lyxrc.typewriter_font_name = fl_get_input(fd_form_screen->input_typewriter);
3304         lyxrc.font_norm = fl_get_input(fd_form_screen->input_font_norm);
3305         lyxrc.zoom = atoi(fl_get_input(fd_form_screen->intinput_size));
3306         fontloader.update();
3307    
3308         // All buffers will need resize
3309         bufferlist.resize();
3310
3311         current_view->owner()->getMiniBuffer()->Set(_("Screen options set"));
3312 }
3313
3314
3315 extern "C" void ScreenCancelCB(FL_OBJECT *, long)
3316 {
3317         fl_hide_form(fd_form_screen->form_screen);
3318 }
3319
3320
3321 extern "C" void ScreenOKCB(FL_OBJECT * ob, long data)
3322 {
3323         ScreenCancelCB(ob, data);
3324         ScreenApplyCB(ob, data);
3325 }
3326
3327
3328 void LaTeXOptions(BufferView * bv)
3329 {
3330         if (!bv->available())
3331                 return;
3332
3333         fl_set_button(fd_latex_options->accents,
3334                       int(bv->buffer()->params.allowAccents));
3335         
3336         if (fd_latex_options->LaTeXOptions->visible) {
3337                 fl_raise_form(fd_latex_options->LaTeXOptions);
3338         } else {
3339                 fl_show_form(fd_latex_options->LaTeXOptions,
3340                              FL_PLACE_MOUSE, FL_FULLBORDER,
3341                              _("LaTeX Options"));
3342         }
3343 }
3344
3345
3346 // This function runs "configure" and then rereads lyx.defaults to
3347 // reconfigure the automatic settings.
3348 void Reconfigure(BufferView * bv)
3349 {
3350         bv->owner()->getMiniBuffer()->Set(_("Running configure..."));
3351
3352         // Run configure in user lyx directory
3353         Path p(user_lyxdir);
3354         Systemcalls one(Systemcalls::System, 
3355                         AddName(system_lyxdir, "configure"));
3356         p.pop();
3357         bv->owner()->getMiniBuffer()->Set(_("Reloading configuration..."));
3358         lyxrc.read(LibFileSearch(string(), "lyxrc.defaults"));
3359         WriteAlert(_("The system has been reconfigured."), 
3360                    _("You need to restart LyX to make use of any"),
3361                    _("updated document class specifications."));
3362 }
3363
3364
3365 //
3366 // Table of Contents
3367 //
3368
3369 struct TocList {
3370         int counter[6];
3371         bool appendix;
3372         TocList * next;
3373 };
3374
3375
3376 static TocList * toclist = 0;
3377
3378
3379 extern "C" void TocSelectCB(FL_OBJECT * ob, long)
3380 {
3381         if (!current_view->available())
3382                 return;
3383    
3384         TocList * tmptoclist = toclist;
3385         int i = fl_get_browser(ob);
3386         for (int a = 1; a < i && tmptoclist->next; ++a) {
3387                 tmptoclist = tmptoclist->next;
3388         }
3389
3390         if (!tmptoclist)
3391                 return;
3392      
3393
3394         LyXParagraph * par = current_view->buffer()->paragraph;
3395         while (par && (par->GetFirstCounter(0) != tmptoclist->counter[0] ||
3396                        par->GetFirstCounter(1) != tmptoclist->counter[1] ||
3397                        par->GetFirstCounter(2) != tmptoclist->counter[2] ||
3398                        par->GetFirstCounter(3) != tmptoclist->counter[3] ||
3399                        par->GetFirstCounter(4) != tmptoclist->counter[4] ||
3400                        par->GetFirstCounter(5) != tmptoclist->counter[5] ||
3401                        par->appendix != tmptoclist->appendix)) {
3402                 par = par->LastPhysicalPar()->Next();
3403         }
3404    
3405         if (par) {
3406                 current_view->beforeChange();
3407                 current_view->text->SetCursor(par, 0);
3408                 current_view->text->sel_cursor = 
3409                         current_view->text->cursor;
3410                 current_view->update(0);
3411         }
3412         else {
3413                 WriteAlert(_("Error"), 
3414                            _("Couldn't find this label"), 
3415                            _("in current document."));
3416         }
3417           
3418 }
3419
3420
3421 extern "C" void TocCancelCB(FL_OBJECT *, long)
3422 {
3423         fl_hide_form(fd_form_toc->form_toc);
3424 }
3425
3426
3427 extern "C" void TocUpdateCB(FL_OBJECT *, long)
3428 {
3429         static LyXParagraph * stapar = 0;
3430         TocList * tmptoclist = 0;
3431    
3432         /* deleted the toclist */ 
3433         if (toclist){
3434                 while (toclist){
3435                         tmptoclist = toclist->next;
3436                         delete toclist;
3437                         toclist = tmptoclist;
3438                 }
3439         }
3440         toclist = 0;
3441         tmptoclist = toclist;
3442
3443
3444         fl_clear_browser(fd_form_toc->browser_toc);
3445         if (!current_view->available()) {
3446                 fl_add_browser_line(fd_form_toc->browser_toc,
3447                                     _("*** No Document ***"));
3448                 return;
3449         }
3450         fl_hide_object(fd_form_toc->browser_toc);
3451         /* get the table of contents */ 
3452         LyXParagraph * par = current_view->buffer()->paragraph;
3453         char labeltype;
3454         char * line = new char[200];
3455         int pos = 0;
3456         unsigned char c;
3457         int topline = 0;
3458    
3459         if (stapar == par)
3460                 topline = fl_get_browser_topline(fd_form_toc->browser_toc);
3461         stapar = par;
3462    
3463         while (par) {
3464                 labeltype = textclasslist.Style(current_view->buffer()->params.textclass, 
3465                                                 par->GetLayout()).labeltype;
3466       
3467                 if (labeltype >= LABEL_COUNTER_CHAPTER
3468                     && labeltype <= LABEL_COUNTER_CHAPTER +
3469                     current_view->buffer()->params.tocdepth) {
3470                         /* insert this into the table of contents */ 
3471                         /* first indent a little bit */ 
3472                         
3473                         for (pos = 0; 
3474                              pos < (labeltype - 
3475                                     textclasslist.TextClass(current_view->buffer()->
3476                                                             params.textclass).maxcounter()) * 4 + 2;
3477                              ++pos)
3478                                 line[pos] = ' ';
3479                         
3480                         // Then the labestring
3481                         if (!par->labelstring.empty()) {
3482                                 string::size_type i = 0;
3483                                 while (pos < 199 && i < par->labelstring.length()) {
3484                                         line[pos] = par->labelstring[i];
3485                                         ++i;
3486                                         ++pos;
3487                                 }
3488                         }
3489          
3490                         line[pos] = ' ';
3491                         ++pos;
3492                         
3493                         /* now the contents */
3494                         LyXParagraph::size_type i = 0;
3495                         while (pos < 199 && i < par->size()) {
3496                                 c = par->GetChar(i);
3497                                 if (isprint(c) || c >= 128) {
3498                                         line[pos] = c;
3499                                         ++pos;
3500                                 }
3501                                 ++i;
3502                         }
3503                         line[pos] = '\0';
3504                         fl_add_browser_line(fd_form_toc->browser_toc, line);
3505                         
3506                         /* make a toclist entry */
3507                         if (!tmptoclist){
3508                                 tmptoclist = new TocList;
3509                                 toclist = tmptoclist;
3510                         } else {
3511                                 tmptoclist->next = new TocList;
3512                                 tmptoclist = tmptoclist->next;
3513                         }
3514                         
3515                         tmptoclist->next = 0;
3516                         int a = 0;
3517                         for (a = 0; a < 6; ++a) {
3518                                 tmptoclist->counter[a] = par->GetFirstCounter(a);
3519                         }
3520                         tmptoclist->appendix = par->appendix;
3521                 }
3522                 par = par->LastPhysicalPar()->Next();
3523                 
3524         }
3525         delete[] line;
3526         fl_set_browser_topline(fd_form_toc->browser_toc, topline);
3527         fl_show_object(fd_form_toc->browser_toc);
3528 }
3529
3530
3531 /* callbacks for form form_ref */
3532 extern "C" void RefSelectCB(FL_OBJECT *, long data)
3533 {
3534         if (!current_view->available())
3535                 return;
3536
3537         string s = 
3538                 fl_get_browser_line(fd_form_ref->browser_ref,
3539                                     fl_get_browser(fd_form_ref->browser_ref));
3540         string u = frontStrip(strip(fl_get_input(fd_form_ref->ref_name)));
3541
3542         if (s.empty())
3543                 return;
3544
3545         if (data == 2) {
3546                 current_view->owner()->getLyXFunc()->Dispatch(LFUN_REFGOTO, s.c_str());
3547                 return;
3548         }
3549             
3550         string t;
3551         if (data == 0)
3552                 t += "\\ref";
3553         else
3554                 t += "\\pageref";
3555
3556         if(current_view->buffer()->isSGML())
3557                 t += "[" + u + "]" + "{" + s + "}";
3558         else
3559                 t += "{" + s + "}";
3560
3561         Inset * new_inset = 
3562                 new InsetRef(t, current_view->buffer());
3563         current_view->insertInset(new_inset);
3564 }
3565
3566
3567 extern "C" void RefUpdateCB(FL_OBJECT *, long)
3568 {
3569         if (!current_view->available()) {
3570                 fl_clear_browser(fd_form_ref->browser_ref);
3571                 return;
3572         }
3573
3574         FL_OBJECT * brow = fd_form_ref->browser_ref;
3575
3576         // Get the current line, in order to restore it later
3577         char const * const btmp = fl_get_browser_line(brow,
3578                                                       fl_get_browser(brow));
3579         string currentstr = btmp ? btmp : "";
3580
3581         fl_clear_browser(brow);
3582
3583         string refs = current_view->buffer()->getReferenceList('\n');
3584         int topline = 1;
3585
3586         fl_addto_browser_chars(brow, refs.c_str());
3587         int total_lines = fl_get_browser_maxline(brow);
3588         for (int i = 1; i <= total_lines ; ++i) {
3589                 if (fl_get_browser_line(brow, i) == currentstr) {
3590                         topline = i;
3591                         break;
3592                 }
3593         }
3594         fl_set_browser_topline(brow, topline);
3595
3596         if (!fl_get_browser_maxline(brow)) {
3597                 fl_add_browser_line(brow, 
3598                                     _("*** No labels found in document ***"));
3599                 fl_deactivate_object(brow);
3600         } else {
3601                 fl_select_browser_line(brow, topline);
3602                 fl_activate_object(brow);
3603         }
3604         if (current_view->buffer()->isReadonly()) {
3605                 // would be better to de/activate insert buttons
3606                 // but that's more work... besides this works. ARRae
3607                 fl_hide_form(fd_form_ref->form_ref);
3608         }
3609         if (!current_view->buffer()->isSGML()) {
3610                 fl_deactivate_object(fd_form_ref->ref_name);
3611                 fl_set_object_lcol(fd_form_ref->ref_name, FL_INACTIVE);
3612         }
3613         else {
3614                 fl_activate_object(fd_form_ref->ref_name);
3615                 fl_set_object_lcol(fd_form_ref->ref_name, FL_BLACK);
3616         }
3617 }
3618
3619
3620 extern "C" void RefHideCB(FL_OBJECT *, long)
3621 {
3622         fl_hide_form(fd_form_ref->form_ref);
3623 }