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