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