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