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