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