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