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