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