]> git.lyx.org Git - lyx.git/blob - src/lyx_cb.C
95718cf7167557f8931d1704db8919ab68a5ae44
[lyx.git] / src / lyx_cb.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich,
7  *          Copyright 1995-2000 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #include <fstream>
14 #include <algorithm>
15 #include <iostream>
16
17 #include "LString.h"
18 #include FORMS_H_LOCATION
19 #include "lyx.h"
20 #include "layout_forms.h"
21 #include "bullet_forms.h"
22 #include "print_form.h"
23 #include "form1.h"
24 #include "lyx_main.h"
25 #include "lyx_cb.h"
26 #include "insets/insetref.h"
27 #include "insets/insetlabel.h"
28 #include "insets/figinset.h"
29 #include "lyxfunc.h"
30 #include "minibuffer.h"
31 #include "combox.h"
32 #include "bufferlist.h"
33 #include "filedlg.h"
34 #include "lyx_gui_misc.h"
35 #include "LyXView.h"
36 #include "BufferView.h"
37 #include "lastfiles.h"
38 #include "bufferview_funcs.h"
39 #include "support/FileInfo.h"
40 #include "support/syscall.h"
41 #include "support/filetools.h"
42 #include "support/path.h"
43 #include "lyxserver.h"
44 #include "FontLoader.h"
45 #include "lyxrc.h"
46 #include "lyxtext.h"
47 #include "CutAndPaste.h"
48 #include "TextCache.h"
49
50 using std::ifstream;
51 using std::copy;
52 using std::back_inserter;
53 using std::endl;
54 using std::cout;
55 using std::ios;
56 using std::istream_iterator;
57 using std::pair;
58
59 extern Combox * combo_language;
60 extern Combox * combo_language2;
61 extern BufferList bufferlist;
62 extern void show_symbols_form();
63 extern FD_form_title * fd_form_title;
64 extern FD_form_paragraph * fd_form_paragraph;
65 extern FD_form_character * fd_form_character;
66 extern FD_form_document * fd_form_document;
67 extern FD_form_quotes * fd_form_quotes;
68 extern FD_form_preamble * fd_form_preamble;
69 extern FD_form_table * fd_form_table;
70 extern FD_form_print * fd_form_print;
71 extern FD_form_figure * fd_form_figure;
72 extern FD_form_screen * fd_form_screen;
73 extern FD_form_toc * fd_form_toc;
74 extern FD_form_ref * fd_form_ref;
75 extern FD_LaTeXOptions * fd_latex_options;
76 extern FD_form_bullet * fd_form_bullet;
77
78 extern BufferView * current_view; // called too many times in this file...
79
80 extern void DeleteSimpleCutBuffer(); /* for the cleanup when exiting */
81
82 extern bool send_fax(string const & fname, string const & sendcmd);
83 extern void MenuSendto();
84
85 extern LyXServer * lyxserver;
86
87 // this should be static, but I need it in buffer.C
88 bool quitting;  // flag, that we are quitting the program
89 extern bool finished; // all cleanup done just let it run through now.
90
91 char ascii_type; /* for selection notify callbacks */
92
93 bool scrolling = false;
94
95 // This is used to make the dreaded font toggle problem hopefully go
96 // away. Definitely not the best solution, but I think it sorta works.
97 bool toggleall = true;
98
99 /* 
100    This is the inset locking stuff needed for mathed --------------------
101
102    an inset can simple call LockInset in it's edit call and *ONLY* in it's
103    edit call.
104    Inset::Edit() can only be called by the main lyx module.
105
106    Then the inset may modify the menu's and/or iconbars. 
107
108    Unlocking is either done by LyX or the inset itself with a UnlockInset-call
109
110    During the lock, all button and keyboard events will be modified
111    and send to the inset through the following inset-features. Note that
112    Inset::InsetUnlock will be called from inside UnlockInset. It is meant
113    to contain the code for restoring the menus and things like this.
114
115    
116    virtual void InsetButtonPress(int x, int y, int button);
117    virtual void InsetButtonRelease(int x, int y, int button);
118    virtual void InsetKeyPress(XKeyEvent *ev);
119    virtual void InsetMotionNotify(int x, int y, int state);
120    virtual void InsetUnlock();
121
122    If a inset wishes any redraw and/or update it just has to call
123    UpdateInset(this).
124    It's is completly irrelevant, where the inset is. UpdateInset will
125    find it in any paragraph in any buffer. 
126    Of course the_locking_inset and the insets in the current paragraph/buffer
127    are checked first, so no performance problem should occur.
128    
129    Hope that's ok for the beginning, Alejandro,
130    sorry that I needed so much time,
131
132                   Matthias
133    */
134
135 //void UpdateInset(BufferView * bv, Inset * inset, bool mark_dirty = true);
136
137 /* these functions return 1 if an error occured, 
138    otherwise 0 */
139 // Now they work only for updatable insets. [Alejandro 080596]
140 //int LockInset(UpdatableInset * inset);
141 void ToggleLockedInsetCursor(long x, long y, int asc, int desc);
142 //void FitLockedInsetCursor(long x, long y, int asc, int desc);
143 //int UnlockInset(UpdatableInset * inset);
144 //void LockedInsetStoreUndo(Undo::undo_kind kind);
145
146 /* this is for asyncron updating. UpdateInsetUpdateList will be called
147    automatically from LyX. Just insert the Inset into the Updatelist */
148 //void UpdateInsetUpdateList();
149 //void PutInsetIntoInsetUpdateList(Inset * inset);
150
151 //InsetUpdateStruct * InsetUpdateList = 0;
152
153
154 /*
155   -----------------------------------------------------------------------
156  */
157
158 /* some function prototypes */
159
160 int RunLinuxDoc(BufferView *, int, string const &);
161 int RunDocBook(int, string const &);
162 void MenuWrite(Buffer * buf);
163 void MenuWriteAs(Buffer * buffer);
164 void MenuReload(Buffer * buf);
165 void MenuLayoutSave();
166
167
168 void ShowMessage(Buffer * buf,
169                  string const & msg1,
170                  string const & msg2 = string(),
171                  string const & msg3 = string(), int delay = 6)
172 {
173         if (lyxrc.use_gui) {
174                 buf->getUser()->owner()->getMiniBuffer()->Set(msg1, msg2,
175                                                               msg3, delay);
176         } else {
177                 // can somebody think of something more clever? cerr?
178                 cout << msg1 << msg2 << msg3 << endl;
179         }
180 }
181
182
183 // only called from this file, LyXView and LyXFunc
184 char updatetimer = 0;
185
186
187 // only called from BufferView_pimpl and LyXFunc
188 void FreeUpdateTimer()
189 {
190         /* a real free timer would be better but I don't know 
191          * how to do this with xforms */
192         updatetimer = 0;
193 }
194
195
196 // Only called from LyXFunc
197 void SetUpdateTimer(float time)
198 {
199         fl_set_timer(current_view->owner()->getMainForm()->timer_update, time);
200         updatetimer = 1;
201 }
202
203
204 //
205 // Menu callbacks
206 //
207
208 //
209 // File menu
210 //
211
212 // should be moved to lyxfunc.C
213 void MenuWrite(Buffer * buffer)
214 {
215         XFlush(fl_display);
216         if (!buffer->save()) {
217                 string fname = buffer->fileName();
218                 string s = MakeAbsPath(fname);
219                 if (AskQuestion(_("Save failed. Rename and try again?"),
220                                 MakeDisplayPath(s, 50),
221                                 _("(If not, document is not saved.)"))) {
222                         MenuWriteAs(buffer);
223                 }
224         } else {
225                 lastfiles->newFile(buffer->fileName());
226         }
227 }
228
229
230 // should be moved to BufferView.C
231 // Half of this func should be in LyXView, the rest in BufferView.
232 void MenuWriteAs(Buffer * buffer)
233 {
234         // Why do we require BufferView::text to be able to write a
235         // document? I see no point in that. (Lgb)
236         //if (!bv->text) return;
237
238         string fname = buffer->fileName();
239         string oldname = fname;
240         LyXFileDlg fileDlg;
241
242         ProhibitInput(current_view);
243         fileDlg.SetButton(0, _("Documents"), lyxrc.document_path);
244         fileDlg.SetButton(1, _("Templates"), lyxrc.template_path);
245
246         if (!IsLyXFilename(fname))
247                 fname += ".lyx";
248
249         fname = fileDlg.Select(_("Enter Filename to Save Document as"), 
250                                OnlyPath(fname),
251                                "*.lyx", 
252                                OnlyFilename(fname));
253         AllowInput(current_view);
254
255         if (fname.empty()) {
256                 return;
257         }
258         // Make sure the absolute filename ends with appropriate suffix
259         string s = MakeAbsPath(fname);
260         if (!IsLyXFilename(s))
261                 s += ".lyx";
262
263         // Same name as we have already?
264         if (s == oldname) {
265                 if (!AskQuestion(_("Same name as document already has:"),
266                                  MakeDisplayPath(s, 50),
267                                  _("Save anyway?")))
268                         return;
269                 // Falls through to name change and save
270         } 
271         // No, but do we have another file with this name open?
272         else if (bufferlist.exists(s)) {
273                 if (AskQuestion(_("Another document with same name open!"),
274                                 MakeDisplayPath(s, 50),
275                                 _("Replace with current document?")))
276                         {
277                                 bufferlist.close(bufferlist.getBuffer(s));
278
279                                 // Ok, change the name of the buffer, but don't save!
280                                 buffer->fileName(s);
281                                 buffer->markDirty();
282
283                                 ShowMessage(buffer, _("Document renamed to '"),
284                                                 MakeDisplayPath(s), _("', but not saved..."));
285                         }
286                 return;
287         } // Check whether the file exists
288         else {
289                 FileInfo myfile(s);
290                 if (myfile.isOK() && !AskQuestion(_("Document already exists:"), 
291                                                   MakeDisplayPath(s, 50),
292                                                   _("Replace file?")))
293                         return;
294         }
295
296         // Ok, change the name of the buffer
297         buffer->fileName(s);
298         buffer->markDirty();
299         // And save
300         // Small bug: If the save fails, we have irreversible changed the name
301         // of the document.
302         MenuWrite(buffer);
303 }    
304
305
306 int MenuRunLaTeX(Buffer * buffer)
307 {
308         int ret = 0;
309
310         if (buffer->isLinuxDoc())
311                 ret = RunLinuxDoc(buffer->getUser(), 1, buffer->fileName());
312         else if (buffer->isLiterate())
313                 ret = buffer->runLiterate();
314         else if (buffer->isDocBook())
315                 ret = RunDocBook(1, buffer->fileName());
316         else
317                 ret = buffer->runLaTeX();
318    
319         if (ret > 0) {
320                 string s;
321                 string t;
322                 if (ret == 1) {
323                         s = _("One error detected");
324                         t = _("You should try to fix it.");
325                 } else {
326                         s += tostr(ret);
327                         s += _(" errors detected.");
328                         t = _("You should try to fix them.");
329                 }
330                 WriteAlert(_("There were errors during the LaTeX run."), s, t);
331         }
332         return ret;
333 }
334
335
336 int MenuBuildProg(Buffer * buffer)
337 {
338         int ret = 0;
339         
340         if (buffer->isLiterate())
341                 ret = buffer->buildProgram();
342         else {
343                 string s = _("Wrong type of document");
344                 string t = _("The Build operation is not allowed in this document");
345                 WriteAlert(_("There were errors during the Build process."), s, t);
346                 return 1;
347         }
348         
349         if (ret > 0) {
350                 string s;
351                 string t;
352                 if (ret == 1) {
353                         s = _("One error detected");
354                         t = _("You should try to fix it.");
355                 } else {
356                         s += tostr(ret);
357                         s += _(" errors detected.");
358                         t = _("You should try to fix them.");
359                 }
360                 WriteAlert(_("There were errors during the Build process."), s, t);
361         }
362         return ret;
363 }
364
365
366 int MenuRunChktex(Buffer * buffer)
367 {
368         int ret;
369
370         if (buffer->isSGML()) {
371                 WriteAlert(_("Chktex does not work with SGML derived documents."));
372                 return 0;
373         } else 
374                 ret = buffer->runChktex();
375    
376         if (ret >= 0) {
377                 string s;
378                 string t;
379                 if (ret == 0) {
380                         s = _("No warnings found.");
381                 } else if (ret == 1) {
382                         s = _("One warning found.");
383                         t = _("Use 'Edit->Go to Error' to find it.");
384                 } else {
385                         s += tostr(ret);
386                         s += _(" warnings found.");
387                         t = _("Use 'Edit->Go to Error' to find them.");
388                 }
389                 WriteAlert(_("Chktex run successfully"), s, t);
390         } else {
391                 WriteAlert(_("Error!"), _("It seems chktex does not work."));
392         }
393         return ret;
394 }
395
396  
397 int MakeLaTeXOutput(Buffer * buffer)
398 {
399         // Who cares?
400         //if (!bv->text)
401         //      return 1;
402         int ret = 0;
403         string path = OnlyPath(buffer->fileName());
404         if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)) {
405                 path = buffer->tmppath;
406         }
407         if (!buffer->isDviClean()) {
408                 Path p(path);
409                 ret = MenuRunLaTeX(buffer);
410         }
411         return ret;
412 }
413
414
415 /* wait == false means don't wait for termination */
416 /* wait == true means wait for termination       */
417 // The bool should be placed last on the argument line. (Lgb)
418 // Returns false if we fail.
419 bool RunScript(Buffer * buffer, bool wait,
420                string const & command,
421                string const & orgname = string(),
422                bool need_shell = true)
423 {
424         string path;
425         string cmd;
426         string name = orgname;
427         int result = 0;
428         
429         if (MakeLaTeXOutput(buffer) > 0)
430                 return false;
431         /* get DVI-Filename */
432         if (name.empty())
433                 name = ChangeExtension(buffer->getLatexName(),
434                                        ".dvi", true);
435
436         path = OnlyPath(name);
437         if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)) {
438                 path = buffer->tmppath;
439         }
440         Path p(path);
441         // At this point we check whether the command contains the
442         // filename parameter $$FName and if that's the case we
443         // substitute the real file name otherwise the filename is
444         // simply appended. rokrau 1/12/00
445         cmd = command;
446         string::size_type i;
447         if ( (i=command.find("$$FName")) != string::npos)
448         {
449                 cmd.replace(i,7,QuoteName(name));
450         }
451         else
452                 cmd = command + ' ' + QuoteName(name);
453
454         Systemcalls one;
455
456         if (need_shell) {
457 #ifndef __EMX__
458                 if (!wait)
459                         cmd += " &";
460 #else
461                 // OS/2 cmd.exe has another use for '&'
462                 if (!wait) {
463                         // This is not NLS safe, but it's OK, I think.
464                         string sh = OnlyFilename(GetEnvPath("EMXSHELL"));
465                         if (sh.empty()) {
466                                 // COMSPEC is set, unless user unsets 
467                                 sh = OnlyFilename(GetEnvPath("COMSPEC"));
468                                 if (sh.empty())
469                                         sh = "cmd.exe";
470                         }
471                         sh = lowercase(sh);
472                         if (contains(sh, "cmd.exe")
473                             || contains(sh, "4os2.exe"))
474                                 cmd = "start /min/n " + cmd;
475                         else
476                                 cmd += " &";
477                 }
478 #endif
479                 // It seems that, if wait is false, we never get back
480                 // the return code of the command. This means that all
481                 // the code I added in PrintApplyCB is currently
482                 // useless...
483                 // CHECK What should we do here?
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
1282         // CHECK remove this once we have a proper geometry class
1283
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         string language = combo_language2->getline();
2063         Languages::iterator lit = languages.find(language);
2064         if (lit != languages.end()) 
2065                 font.setLanguage(&(*lit).second);
2066         else
2067                 font.setLanguage(ignore_language);
2068
2069
2070         return font; 
2071 }
2072
2073
2074
2075
2076 /* callbacks for form form_title */
2077 extern "C" void TimerCB(FL_OBJECT *, long)
2078 {
2079         // only if the form still exists
2080         if (lyxrc.show_banner && fd_form_title->form_title != 0) {
2081                 if (fd_form_title->form_title->visible) {
2082                         fl_hide_form(fd_form_title->form_title);
2083                 }
2084                 fl_free_form(fd_form_title->form_title);
2085                 fd_form_title->form_title = 0;
2086         }
2087 }
2088
2089
2090 /* callbacks for form form_paragraph */
2091
2092 extern "C" void ParagraphVSpaceCB(FL_OBJECT * obj, long )
2093 {
2094         // "Synchronize" the choices and input fields, making it
2095         // impossible to commit senseless data.
2096
2097         FD_form_paragraph const * fp = fd_form_paragraph;
2098
2099         if (obj == fp->choice_space_above) {
2100                 if (fl_get_choice (fp->choice_space_above) != 7) {
2101                         fl_set_input (fp->input_space_above, "");
2102                         ActivateParagraphButtons();
2103                 }
2104         } else if (obj == fp->choice_space_below) {
2105                 if (fl_get_choice (fp->choice_space_below) != 7) {
2106                         fl_set_input (fp->input_space_below, "");
2107                         ActivateParagraphButtons();
2108                 }
2109         } else if (obj == fp->input_space_above) {
2110                 string input = fl_get_input (fp->input_space_above);
2111
2112                 if (input.empty()) {
2113                         fl_set_choice (fp->choice_space_above, 1);
2114                         ActivateParagraphButtons();
2115                 }
2116                 else if (isValidGlueLength (input)) {
2117                         fl_set_choice (fp->choice_space_above, 7);
2118                         ActivateParagraphButtons();
2119                 }
2120                 else {
2121                         fl_set_choice (fp->choice_space_above, 7);
2122                         DeactivateParagraphButtons();
2123                 }
2124         } else if (obj == fp->input_space_below) {
2125                 string input = fl_get_input (fp->input_space_below);
2126
2127                 if (input.empty()) {
2128                         fl_set_choice (fp->choice_space_below, 1);
2129                         ActivateParagraphButtons();
2130                 }
2131                 else if (isValidGlueLength (input)) {
2132                         fl_set_choice (fp->choice_space_below, 7);
2133                         ActivateParagraphButtons();
2134                 }
2135                 else {
2136                         fl_set_choice (fp->choice_space_below, 7);
2137                         DeactivateParagraphButtons();
2138                 }
2139         }
2140 }
2141
2142
2143 extern "C" void ParagraphApplyCB(FL_OBJECT *, long)
2144 {
2145         if (!current_view->available())
2146                 return;
2147         
2148         VSpace space_top, space_bottom;
2149         LyXAlignment align;
2150         string labelwidthstring;
2151         bool noindent;
2152
2153         // If a vspace kind is "Length" but there's no text in
2154         // the input field, reset the kind to "None". 
2155         if (fl_get_choice (fd_form_paragraph->choice_space_above) == 7
2156             && !*(fl_get_input (fd_form_paragraph->input_space_above))) {
2157                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
2158         }
2159         if (fl_get_choice (fd_form_paragraph->choice_space_below) == 7
2160             && !*(fl_get_input (fd_form_paragraph->input_space_below))) {
2161                 fl_set_choice (fd_form_paragraph->choice_space_below, 1);
2162         }
2163    
2164         bool line_top = fl_get_button(fd_form_paragraph->check_lines_top);
2165         bool line_bottom = fl_get_button(fd_form_paragraph->check_lines_bottom);
2166         bool pagebreak_top = fl_get_button(fd_form_paragraph->check_pagebreaks_top);
2167         bool pagebreak_bottom = fl_get_button(fd_form_paragraph->check_pagebreaks_bottom);
2168         switch (fl_get_choice (fd_form_paragraph->choice_space_above)) {
2169         case 1: space_top = VSpace(VSpace::NONE); break;
2170         case 2: space_top = VSpace(VSpace::DEFSKIP); break;
2171         case 3: space_top = VSpace(VSpace::SMALLSKIP); break;
2172         case 4: space_top = VSpace(VSpace::MEDSKIP); break;
2173         case 5: space_top = VSpace(VSpace::BIGSKIP); break;
2174         case 6: space_top = VSpace(VSpace::VFILL); break;
2175         case 7: space_top = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_above))); break;
2176         }
2177         if (fl_get_button (fd_form_paragraph->check_space_above))
2178                 space_top.setKeep (true);
2179         switch (fl_get_choice (fd_form_paragraph->choice_space_below)) {
2180         case 1: space_bottom = VSpace(VSpace::NONE); break;
2181         case 2: space_bottom = VSpace(VSpace::DEFSKIP); break;
2182         case 3: space_bottom = VSpace(VSpace::SMALLSKIP); break;
2183         case 4: space_bottom = VSpace(VSpace::MEDSKIP); break;
2184         case 5: space_bottom = VSpace(VSpace::BIGSKIP); break;
2185         case 6: space_bottom = VSpace(VSpace::VFILL); break;
2186         case 7: space_bottom = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_below))); break;
2187         }
2188         if (fl_get_button (fd_form_paragraph->check_space_below))
2189                 space_bottom.setKeep (true);
2190
2191         if (fl_get_button(fd_form_paragraph->radio_align_left))
2192                 align = LYX_ALIGN_LEFT;
2193         else if (fl_get_button(fd_form_paragraph->radio_align_right))
2194                 align = LYX_ALIGN_RIGHT;
2195         else if (fl_get_button(fd_form_paragraph->radio_align_center))
2196                 align = LYX_ALIGN_CENTER;
2197         else 
2198                 align = LYX_ALIGN_BLOCK;
2199    
2200         labelwidthstring = fl_get_input(fd_form_paragraph->input_labelwidth);
2201         noindent = fl_get_button(fd_form_paragraph->check_noindent);
2202
2203         current_view->text->SetParagraph(line_top,
2204                                          line_bottom,
2205                                          pagebreak_top,
2206                                          pagebreak_bottom,
2207                                          space_top,
2208                                          space_bottom,
2209                                          align, 
2210                                          labelwidthstring,
2211                                          noindent);
2212         current_view->update(1);
2213         current_view->owner()->getMiniBuffer()->Set(_("Paragraph layout set"));
2214 }
2215
2216
2217 extern "C" void ParagraphCancelCB(FL_OBJECT *, long)
2218 {
2219         fl_hide_form(fd_form_paragraph->form_paragraph);
2220 }
2221
2222
2223 extern "C" void ParagraphOKCB(FL_OBJECT *ob, long data)
2224 {
2225         ParagraphApplyCB(ob, data);
2226         ParagraphCancelCB(ob, data);
2227 }
2228
2229
2230 /* callbacks for form form_character */
2231
2232 extern "C" void CharacterApplyCB(FL_OBJECT *, long)
2233 {
2234         // we set toggleall locally here, since it should be true for
2235         // all other uses of ToggleAndShow() (JMarc)
2236         toggleall = fl_get_button(fd_form_character->check_toggle_all);
2237         ToggleAndShow(current_view, UserFreeFont());
2238         current_view->setState();
2239         toggleall = true;
2240 }
2241
2242
2243 extern "C" void CharacterCloseCB(FL_OBJECT *, long)
2244 {
2245         fl_hide_form(fd_form_character->form_character);
2246 }
2247
2248
2249 extern "C" void CharacterOKCB(FL_OBJECT *ob, long data)
2250 {
2251         CharacterApplyCB(ob, data);
2252         CharacterCloseCB(ob, data);
2253 }
2254
2255
2256 /* callbacks for form form_document */
2257
2258 void UpdateDocumentButtons(BufferParams const & params) 
2259 {
2260         fl_set_choice(fd_form_document->choice_pagestyle, 1);
2261
2262         switch (params.sides) {
2263         case LyXTextClass::OneSide:
2264                 fl_set_button(fd_form_document->radio_sides_one, 1);
2265                 break;
2266         case LyXTextClass::TwoSides:
2267                 fl_set_button(fd_form_document->radio_sides_two, 1);
2268                 break;
2269         }
2270    
2271         if (params.columns == 2)
2272                 fl_set_button(fd_form_document->radio_columns_two, 1);
2273         else
2274                 fl_set_button(fd_form_document->radio_columns_one, 1);
2275         
2276         fl_set_input(fd_form_document->input_extra, params.options.c_str());
2277         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
2278                              params.secnumdepth);
2279         fl_set_counter_value(fd_form_document->slider_tocdepth, 
2280                              params.tocdepth);
2281         
2282 }
2283
2284 extern "C" void ChoiceClassCB(FL_OBJECT * ob, long)
2285 {
2286         ProhibitInput(current_view);
2287         if (textclasslist.Load(fl_get_choice(ob)-1)) {
2288                 if (AskQuestion(_("Should I set some parameters to"),
2289                                 fl_get_choice_text(ob),
2290                                 _("the defaults of this document class?"))) {
2291                         BufferParams params = BufferParams();
2292                         params.textclass = fl_get_choice(ob)-1;
2293                         params.useClassDefaults();
2294                         UpdateLayoutDocument(&params);
2295                         UpdateDocumentButtons(params);
2296                 }
2297         } else {
2298                 // unable to load new style
2299                 WriteAlert(_("Conversion Errors!"),
2300                            _("Unable to switch to new document class."),
2301                            _("Reverting to original document class."));
2302                 fl_set_choice(fd_form_document->choice_class, 
2303                               current_view->buffer()->params.textclass + 1);
2304         }
2305         AllowInput(current_view);
2306 }
2307
2308
2309 extern "C" void DocumentDefskipCB(FL_OBJECT * obj, long)
2310 {
2311         // "Synchronize" the choice and the input field, so that it
2312         // is impossible to commit senseless data.
2313         FD_form_document const * fd = fd_form_document;
2314
2315         if (obj == fd->choice_default_skip) {
2316                 if (fl_get_choice (fd->choice_default_skip) != 4) {
2317                         fl_set_input (fd->input_default_skip, "");
2318                         ActivateDocumentButtons();
2319                 }
2320         } else if (obj == fd->input_default_skip) {
2321
2322                 char const * input = fl_get_input (fd->input_default_skip);
2323
2324                 if (!*input) {
2325                         fl_set_choice (fd->choice_default_skip, 2);
2326                         ActivateDocumentButtons();
2327                 } else if (isValidGlueLength (input)) {
2328                         fl_set_choice (fd->choice_default_skip, 4);
2329                         ActivateDocumentButtons();
2330                 } else {
2331                         fl_set_choice (fd->choice_default_skip, 4);
2332                         DeactivateDocumentButtons();
2333                 }
2334         }
2335 }
2336
2337
2338 extern "C" void DocumentSpacingCB(FL_OBJECT * obj, long)
2339 {
2340         // "Synchronize" the choice and the input field, so that it
2341         // is impossible to commit senseless data.
2342         FD_form_document const * fd = fd_form_document;
2343
2344         if (obj == fd->choice_spacing
2345             && fl_get_choice (fd->choice_spacing) != 4) {
2346                 fl_set_input(fd->input_spacing, "");
2347         } else if (obj == fd->input_spacing) {
2348
2349                 const char* input = fl_get_input (fd->input_spacing);
2350
2351                 if (!*input) {
2352                         fl_set_choice (fd->choice_spacing, 1);
2353                 } else {
2354                         fl_set_choice (fd->choice_spacing, 4);
2355                 }
2356         }
2357 }
2358
2359
2360 extern "C" void DocumentApplyCB(FL_OBJECT *, long)
2361 {
2362         bool redo = false;
2363         BufferParams * params = &(current_view->buffer()->params);
2364
2365         Language const * old_language = params->language_info;
2366         params->language = combo_language->getline();
2367         Languages::iterator lit = languages.find(params->language);
2368
2369         Language const * new_language;
2370         if (lit != languages.end()) 
2371                 new_language = &(*lit).second;
2372         else
2373                 new_language = default_language;
2374
2375         if (current_view->available()) {
2376                 if (old_language != new_language &&
2377                     old_language->RightToLeft == new_language->RightToLeft && 
2378                     ! current_view->buffer()->isMultiLingual() ) {
2379                         current_view->buffer()->ChangeLanguage(old_language,
2380                                                                new_language);
2381                         current_view->buffer()->redraw();
2382                 }
2383         }
2384         params->language_info = new_language;
2385
2386         // If default skip is a "Length" but there's no text in the
2387         // input field, reset the kind to "Medskip", which is the default.
2388         if (fl_get_choice (fd_form_document->choice_default_skip) == 4
2389             && !*(fl_get_input (fd_form_document->input_default_skip))) {
2390                 fl_set_choice (fd_form_document->choice_default_skip, 2);
2391         }
2392
2393         /* this shouldn't be done automatically IMO. For example I write german
2394          * documents with an american keyboard very often. Matthias */
2395    
2396         /* ChangeKeymap(buffer->parameters.language, TRUE, false,
2397            fl_get_choice(fd_form_document->choice_language)); */
2398         params->fonts = 
2399                 fl_get_choice_text(fd_form_document->choice_fonts);
2400         params->inputenc = 
2401                 fl_get_choice_text(fd_form_document->choice_inputenc);
2402         params->fontsize = 
2403                 fl_get_choice_text(fd_form_document->choice_fontsize);
2404         params->pagestyle = 
2405                 fl_get_choice_text(fd_form_document->choice_pagestyle);
2406         params->graphicsDriver = 
2407                 fl_get_choice_text(fd_form_document->choice_postscript_driver);
2408         params->use_amsmath = 
2409                 fl_get_button(fd_form_document->check_use_amsmath);
2410    
2411         if (!current_view->available())
2412                 return;
2413
2414         current_view->text->SetCursor(current_view->text->cursor.par,
2415                                       current_view->text->cursor.pos);
2416         current_view->setState();
2417
2418         LyXTextClassList::ClassList::size_type new_class =
2419                 fl_get_choice(fd_form_document->choice_class) - 1;
2420
2421         if (params->textclass != new_class) {
2422                 // try to load new_class
2423                 if (textclasslist.Load(new_class)) {
2424                         // successfully loaded
2425                         redo = true;
2426                         current_view->owner()->getMiniBuffer()->
2427                                 Set(_("Converting document to new document class..."));
2428                         CutAndPaste cap;
2429                         int ret = cap.SwitchLayoutsBetweenClasses(
2430                                 current_view->buffer()->params.textclass,
2431                                 new_class,
2432                                 current_view->buffer()->paragraph);
2433
2434                         if (ret) {
2435                                 string s;
2436                                 if (ret == 1)
2437                                         s = _("One paragraph couldn't be converted");
2438                                 else {
2439                                         s += tostr(ret);
2440                                         s += _(" paragraphs couldn't be converted");
2441                                 }
2442                                 WriteAlert(_("Conversion Errors!"), s,
2443                                            _("into chosen document class"));
2444                         }
2445
2446                         params->textclass = new_class;
2447                 } else {
2448                         // problem changing class -- warn user and retain old style
2449                         WriteAlert(_("Conversion Errors!"),
2450                                    _("Unable to switch to new document class."),
2451                                    _("Reverting to original document class."));
2452                         fl_set_choice(fd_form_document->choice_class, params->textclass + 1);
2453                 }
2454         }
2455
2456         char tmpsep = params->paragraph_separation;
2457         if (fl_get_button(fd_form_document->radio_indent))
2458                 params->paragraph_separation = BufferParams::PARSEP_INDENT;
2459         else
2460                 params->paragraph_separation = BufferParams::PARSEP_SKIP;
2461         if (tmpsep != params->paragraph_separation)
2462                 redo = true;
2463    
2464         VSpace tmpdefskip = params->getDefSkip();
2465         switch (fl_get_choice (fd_form_document->choice_default_skip)) {
2466         case 1: params->setDefSkip(VSpace(VSpace::SMALLSKIP)); break;
2467         case 2: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2468         case 3: params->setDefSkip(VSpace(VSpace::BIGSKIP)); break;
2469         case 4: params->setDefSkip( 
2470                 VSpace (LyXGlueLength (fl_get_input 
2471                                        (fd_form_document->input_default_skip))));
2472         break;
2473         // DocumentDefskipCB assures that this never happens
2474         default: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2475         }
2476         if (!(tmpdefskip == params->getDefSkip()))
2477                 redo = true;
2478
2479         if (fl_get_button(fd_form_document->radio_columns_two))
2480                 params->columns = 2;
2481         else
2482                 params->columns = 1;
2483         if (fl_get_button(fd_form_document->radio_sides_two))
2484                 params->sides = LyXTextClass::TwoSides;
2485         else
2486                 params->sides = LyXTextClass::OneSide;
2487
2488         Spacing tmpSpacing = params->spacing;
2489         switch(fl_get_choice(fd_form_document->choice_spacing)) {
2490         case 1:
2491                 lyxerr.debug() << "Spacing: SINGLE" << endl;
2492                 params->spacing.set(Spacing::Single);
2493                 break;
2494         case 2:
2495                 lyxerr.debug() << "Spacing: ONEHALF" << endl;
2496                 params->spacing.set(Spacing::Onehalf);
2497                 break;
2498         case 3:
2499                 lyxerr.debug() << "Spacing: DOUBLE" << endl;
2500                 params->spacing.set(Spacing::Double);
2501                 break;
2502         case 4:
2503                 lyxerr.debug() << "Spacing: OTHER" << endl;
2504                 params->spacing.set(Spacing::Other, 
2505                                     fl_get_input(fd_form_document->input_spacing));
2506                 break;
2507         }
2508         if (tmpSpacing != params->spacing)
2509                 redo = true;
2510         
2511         signed char tmpchar =  
2512                 static_cast<signed char>(fl_get_counter_value(fd_form_document->slider_secnumdepth));
2513         if (params->secnumdepth != tmpchar)
2514                 redo = true;
2515         params->secnumdepth = tmpchar;
2516    
2517         params->tocdepth =  
2518                 static_cast<int>(fl_get_counter_value(fd_form_document->slider_tocdepth));
2519
2520         params->float_placement = 
2521                 fl_get_input(fd_form_document->input_float_placement);
2522
2523         // More checking should be done to ensure the string doesn't have
2524         // spaces or illegal placement characters in it. (thornley)
2525
2526         if (redo)
2527                 current_view->redoCurrentBuffer();
2528    
2529         current_view->owner()->getMiniBuffer()->Set(_("Document layout set"));
2530         current_view->buffer()->markDirty();
2531
2532         params->options = 
2533                 fl_get_input(fd_form_document->input_extra);
2534    
2535 }
2536
2537
2538 extern "C" void DocumentCancelCB(FL_OBJECT *, long)
2539 {
2540         fl_hide_form(fd_form_document->form_document);
2541 }
2542
2543
2544 extern "C" void DocumentOKCB(FL_OBJECT * ob, long data)
2545 {
2546         DocumentCancelCB(ob, data);
2547         DocumentApplyCB(ob, data);
2548 }
2549
2550
2551 extern "C" void DocumentBulletsCB(FL_OBJECT *, long)
2552 {
2553         bulletForm();
2554         // bullet callbacks etc. in bullet_panel.C -- ARRae
2555 }
2556
2557
2558 /* callbacks for form form_quotes */
2559
2560 extern "C" void QuotesApplyCB(FL_OBJECT *, long)
2561 {
2562         if (!current_view->available())
2563                 return;
2564         
2565         current_view->owner()->getMiniBuffer()->Set(_("Quotes type set"));
2566         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
2567         switch(fl_get_choice(fd_form_quotes->choice_quotes_language) - 1) {
2568         case 0:
2569                 lga = InsetQuotes::EnglishQ;
2570                 break;
2571         case 1:
2572                 lga = InsetQuotes::SwedishQ;
2573                 break;
2574         case 2:
2575                 lga = InsetQuotes::GermanQ;
2576                 break;
2577         case 3:
2578                 lga = InsetQuotes::PolishQ;
2579                 break;
2580         case 4:
2581                 lga = InsetQuotes::FrenchQ;
2582                 break;
2583         case 5:
2584                 lga = InsetQuotes::DanishQ;
2585                 break;
2586         }
2587         current_view->buffer()->params.quotes_language = lga;
2588         if (fl_get_button(fd_form_quotes->radio_single))   
2589                 current_view->buffer()->
2590                         params.quotes_times = InsetQuotes::SingleQ;
2591         else
2592                 current_view->buffer()->
2593                         params.quotes_times = InsetQuotes::DoubleQ;
2594 }
2595
2596
2597 extern "C" void QuotesCancelCB(FL_OBJECT *, long)
2598 {
2599         fl_hide_form(fd_form_quotes->form_quotes);
2600 }
2601
2602
2603 extern "C" void QuotesOKCB(FL_OBJECT * ob, long data)
2604 {
2605         QuotesApplyCB(ob, data);
2606         QuotesCancelCB(ob, data);
2607 }
2608
2609
2610
2611 /* callbacks for form form_preamble */
2612
2613 extern "C" void PreambleCancelCB(FL_OBJECT *, long)
2614 {
2615         fl_hide_form(fd_form_preamble->form_preamble);
2616 }
2617
2618
2619 extern "C" void PreambleApplyCB(FL_OBJECT *, long)
2620 {
2621         if (!current_view->available())
2622                 return;
2623         
2624         current_view->buffer()->params.preamble = 
2625                 fl_get_input(fd_form_preamble->input_preamble);
2626         current_view->buffer()->markDirty();
2627         current_view->owner()->getMiniBuffer()->Set(_("LaTeX preamble set"));
2628 }
2629
2630    
2631 extern "C" void PreambleOKCB(FL_OBJECT * ob, long data)
2632 {
2633         PreambleApplyCB(ob, data);
2634         PreambleCancelCB(ob, data);
2635 }
2636
2637
2638 /* callbacks for form form_table */
2639
2640 extern "C" void TableApplyCB(FL_OBJECT *, long)
2641 {
2642         if (!current_view->available())
2643                 return;
2644    
2645         // check for tables in tables
2646         if (current_view->text->cursor.par->table){
2647                 WriteAlert(_("Impossible Operation!"),
2648                            _("Cannot insert table in table."),
2649                            _("Sorry."));
2650                 return;
2651         }
2652  
2653         current_view->owner()->getMiniBuffer()->Set(_("Inserting table..."));
2654
2655         int ysize = int(fl_get_slider_value(fd_form_table->slider_columns) + 0.5);
2656         int xsize = int(fl_get_slider_value(fd_form_table->slider_rows) + 0.5);
2657    
2658    
2659         current_view->hideCursor();
2660         current_view->beforeChange();
2661         current_view->update(-2);
2662    
2663         current_view->text->SetCursorParUndo(); 
2664         current_view->text->FreezeUndo();
2665
2666         current_view->text->BreakParagraph();
2667         current_view->update(-1);
2668    
2669         if (current_view->text->cursor.par->Last()) {
2670                 current_view->text->CursorLeft();
2671       
2672                 current_view->text->BreakParagraph();
2673                 current_view->update(-1);
2674         }
2675
2676         current_view->text->current_font.setLatex(LyXFont::OFF);
2677         //if (!fl_get_button(fd_form_table->check_latex)){
2678         // insert the new wysiwy table
2679         current_view->text->SetLayout(0); // standard layout
2680         if (current_view->text->cursor.par->footnoteflag == 
2681             LyXParagraph::NO_FOOTNOTE) {
2682                 current_view->text
2683                         ->SetParagraph(0, 0,
2684                                        0, 0,
2685                                        VSpace (0.3 * current_view->buffer()->
2686                                                params.spacing.getValue(),
2687                                                LyXLength::CM),
2688                                        VSpace (0.3 * current_view->buffer()->
2689                                                params.spacing.getValue(),
2690                                                LyXLength::CM),
2691                                        LYX_ALIGN_CENTER,
2692                                        string(),
2693                                        0);
2694         } else {
2695                 current_view->text
2696                         ->SetParagraph(0, 0,
2697                                        0, 0,
2698                                        VSpace(VSpace::NONE),
2699                                        VSpace(VSpace::NONE),
2700                                        LYX_ALIGN_CENTER, 
2701                                        string(),
2702                                        0);
2703         }
2704         
2705         current_view->text->cursor.par->table =
2706                 new LyXTable(xsize, ysize);
2707
2708         Language const * lang = 
2709                 current_view->text->cursor.par->getParLanguage();
2710         LyXFont font(LyXFont::ALL_INHERIT, lang);
2711         for (int i = 0; i < xsize * ysize - 1; ++i) {
2712                 current_view->text->cursor.par->InsertChar(0, LyXParagraph::META_NEWLINE);
2713                 current_view->text->cursor.par->SetFont(0, font);
2714         }
2715         current_view->text->RedoParagraph();
2716    
2717         current_view->text->UnFreezeUndo();
2718      
2719         current_view->update(1);
2720         current_view->owner()->getMiniBuffer()->Set(_("Table inserted"));
2721         current_view->setState();
2722 }
2723
2724
2725 extern "C" void TableCancelCB(FL_OBJECT *, long)
2726 {
2727         fl_hide_form(fd_form_table->form_table);
2728 }
2729
2730
2731 extern "C" void TableOKCB(FL_OBJECT * ob, long data)
2732 {
2733         TableApplyCB(ob, data);
2734         TableCancelCB(ob, data);
2735 }
2736
2737
2738 /* callbacks for form form_print */
2739
2740 extern "C" void PrintCancelCB(FL_OBJECT *, long)
2741 {
2742         fl_hide_form(fd_form_print->form_print);
2743 }
2744
2745
2746 static
2747 bool stringOnlyContains (string const & LStr, char const * cset)
2748 {
2749         return LStr.find_first_not_of(cset) == string::npos;
2750 }
2751
2752
2753 extern "C" void PrintApplyCB(FL_OBJECT *, long)
2754 {
2755         if (!current_view->available())
2756                 return;
2757         Buffer * buffer = current_view->buffer();
2758         string path = OnlyPath(buffer->fileName());
2759
2760         string pageflag;
2761         if (fl_get_button(fd_form_print->radio_even_pages))
2762                 pageflag = lyxrc.print_evenpage_flag + ' ';
2763         else if (fl_get_button(fd_form_print->radio_odd_pages))
2764                 pageflag = lyxrc.print_oddpage_flag + ' ';
2765
2766 // Changes by Stephan Witt (stephan.witt@beusen.de), 19-Jan-99
2767 // User may give a page (range) list
2768 // User may print multiple (unsorted) copies
2769         string pages = subst(fl_get_input(fd_form_print->input_pages), ';',',');
2770         pages = subst(pages, '+',',');
2771         pages = frontStrip(strip(pages)) ;
2772         while (!pages.empty()) { // a page range was given
2773                 string piece ;
2774                 pages = split (pages, piece, ',') ;
2775                 piece = strip(piece) ;
2776                 piece = frontStrip(piece) ;
2777                 if ( !stringOnlyContains (piece, "0123456789-") ) {
2778                         WriteAlert(_("ERROR!  Unable to print!"),
2779                                    _("Check 'range of pages'!"));
2780                         return;
2781                 }
2782                 if (piece.find('-') == string::npos) { // not found
2783                         pageflag += lyxrc.print_pagerange_flag + piece + '-' + piece + ' ' ;
2784                 } else if (suffixIs(piece, "-") ) { // missing last page
2785                         pageflag += lyxrc.print_pagerange_flag + piece + "1000 ";
2786                 } else if (prefixIs(piece, "-") ) { // missing first page
2787                         pageflag += lyxrc.print_pagerange_flag + '1' + piece + ' ' ;
2788                 } else {
2789                         pageflag += lyxrc.print_pagerange_flag + piece + ' ' ;
2790                 }
2791         }
2792    
2793         string copies = frontStrip(strip(fl_get_input(fd_form_print->input_copies)));
2794         if (!copies.empty()) { // a number of copies was given
2795                 if ( !stringOnlyContains (copies, "0123456789") ) {
2796                         WriteAlert(_("ERROR!  Unable to print!"),
2797                                    _("Check 'number of copies'!"));
2798                         return;
2799                 }
2800                 if (fl_get_button(fd_form_print->do_unsorted))
2801                         pageflag += lyxrc.print_copies_flag;
2802                 else
2803                         pageflag += lyxrc.print_collcopies_flag;
2804                 pageflag += " " + copies + ' ' ;
2805         }
2806
2807         string reverseflag;
2808         if (fl_get_button(fd_form_print->radio_order_reverse))
2809                 reverseflag = lyxrc.print_reverse_flag + ' ';
2810    
2811         string orientationflag;
2812         if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
2813                 orientationflag = lyxrc.print_landscape_flag + ' ';
2814    
2815         string ps_file = fl_get_input(fd_form_print->input_file);
2816         string printer = strip(fl_get_input(fd_form_print->input_printer));
2817
2818         string printerflag;
2819         if (lyxrc.print_adapt_output // printer name should be passed to dvips
2820             && ! printer.empty()) // a printer name has been given
2821                 printerflag = lyxrc.print_to_printer + printer + ' ';
2822      
2823         string extraflags;
2824         if (!lyxrc.print_extra_options.empty())
2825                 extraflags = lyxrc.print_extra_options + ' ';
2826
2827         string command = lyxrc.print_command + ' ' 
2828                 + printerflag + pageflag + reverseflag 
2829                 + orientationflag + extraflags;
2830  
2831         char real_papersize = buffer->params.papersize;
2832         if (real_papersize == BufferParams::PAPER_DEFAULT)
2833                 real_papersize = lyxrc.default_papersize;
2834         
2835         string paper;
2836         switch (real_papersize) {
2837         case BufferParams::PAPER_USLETTER:
2838                 paper = "letter";
2839                 break;
2840         case BufferParams::PAPER_A3PAPER:
2841                 paper = "a3";
2842                 break;
2843         case BufferParams::PAPER_A4PAPER:
2844                 paper = "a4";
2845                 break;
2846         case BufferParams::PAPER_A5PAPER:
2847                 paper = "a5";
2848                 break;
2849         case BufferParams::PAPER_B5PAPER:
2850                 paper = "b5";
2851                 break;
2852         case BufferParams::PAPER_EXECUTIVEPAPER:
2853                 paper = "foolscap";
2854                 break;
2855         case BufferParams::PAPER_LEGALPAPER:
2856                 paper = "legal";
2857                 break;
2858         default: /* If nothing else fits, keep an empty value... */
2859                 break;
2860         }
2861
2862         if (buffer->params.use_geometry
2863             && buffer->params.papersize2 == BufferParams::VM_PAPER_CUSTOM
2864             && !lyxrc.print_paper_dimension_flag.empty()
2865             && !buffer->params.paperwidth.empty()
2866             && !buffer->params.paperheight.empty()) {
2867                 // using a custom papersize
2868                 command += ' ';
2869                 command += lyxrc.print_paper_dimension_flag + ' ';
2870                 command += buffer->params.paperwidth + ',';
2871                 command += buffer->params.paperheight + ' ';
2872         } else if (!lyxrc.print_paper_flag.empty()
2873                    && !paper.empty()
2874                    && (real_papersize != BufferParams::PAPER_USLETTER ||
2875                        buffer->params.orientation == BufferParams::ORIENTATION_PORTRAIT)) {
2876                 command += " " + lyxrc.print_paper_flag + " " + paper + " ";
2877         }
2878         if (fl_get_button(fd_form_print->radio_file))
2879                 command += lyxrc.print_to_file 
2880                         + QuoteName(MakeAbsPath(ps_file, path));
2881         else if (!lyxrc.print_spool_command.empty())
2882                 command += lyxrc.print_to_file 
2883                         + QuoteName(ps_file);
2884         
2885         // push directorypath, if necessary 
2886         if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)){
2887                 path = buffer->tmppath;
2888         }
2889         Path p(path);
2890
2891         bool result;
2892         if (!lyxrc.print_spool_command.empty() && 
2893             !fl_get_button(fd_form_print->radio_file)) {
2894                 string command2 = lyxrc.print_spool_command + ' ';
2895                 if (!printer.empty())
2896                         command2 += lyxrc.print_spool_printerprefix 
2897                                 + printer;
2898                 // First run dvips and, if succesful, then spool command
2899                 if ((result = RunScript(buffer, true, command))) {
2900                         result = RunScript(buffer, false, command2, ps_file);
2901                 }
2902         } else
2903                 result = RunScript(buffer, false, command);
2904
2905         if (!result)
2906                 WriteAlert(_("Error:"),
2907                            _("Unable to print"),
2908                            _("Check that your parameters are correct"));
2909 }
2910
2911
2912 extern "C" void PrintOKCB(FL_OBJECT * ob, long data)
2913 {
2914         PrintCancelCB(ob, data);  
2915         PrintApplyCB(ob, data);
2916 }
2917
2918
2919 void Figure()
2920 {
2921         if (fd_form_figure->form_figure->visible) {
2922                 fl_raise_form(fd_form_figure->form_figure);
2923         } else {
2924                 fl_show_form(fd_form_figure->form_figure,
2925                              FL_PLACE_MOUSE, FL_FULLBORDER,
2926                              _("Insert Figure"));
2927         }
2928 }
2929
2930
2931 void Table()
2932 {
2933         if (fd_form_table->form_table->visible) {
2934                 fl_raise_form(fd_form_table->form_table);
2935         } else {
2936                 fl_show_form(fd_form_table->form_table,
2937                              FL_PLACE_MOUSE, FL_FULLBORDER,
2938                              _("Insert Table"));
2939         }
2940 }
2941
2942
2943 /* callbacks for form form_figure */
2944 extern "C" void FigureApplyCB(FL_OBJECT *, long)
2945 {
2946         if (!current_view->available())
2947                 return;
2948
2949         Buffer * buffer = current_view->buffer();
2950         if(buffer->isReadonly()) // paranoia
2951                 return;
2952         
2953         current_view->owner()->getMiniBuffer()->Set(_("Inserting figure..."));
2954         if (fl_get_button(fd_form_figure->radio_inline)
2955             || current_view->text->cursor.par->table) {
2956                 InsetFig * new_inset = new InsetFig(100, 20, buffer);
2957                 current_view->insertInset(new_inset);
2958                 current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
2959                 new_inset->Edit(current_view, 0, 0, 0);
2960                 return;
2961         }
2962         
2963         current_view->hideCursor();
2964         current_view->update(-2);
2965         current_view->beforeChange();
2966       
2967         current_view->text->SetCursorParUndo(); 
2968         current_view->text->FreezeUndo();
2969
2970         current_view->text->BreakParagraph();
2971         current_view->update(-1);
2972       
2973         if (current_view->text->cursor.par->Last()) {
2974                 current_view->text->CursorLeft();
2975          
2976                 current_view->text->BreakParagraph();
2977                 current_view->update(-1);
2978         }
2979
2980         // The standard layout should always be numer 0;
2981         current_view->text->SetLayout(0);
2982         
2983         if (current_view->text->cursor.par->footnoteflag == 
2984             LyXParagraph::NO_FOOTNOTE) {
2985                 current_view->text->
2986                         SetParagraph(0, 0,
2987                                      0, 0,
2988                                      VSpace (0.3 * buffer->params.spacing.getValue(),
2989                                              LyXLength::CM),
2990                                      VSpace (0.3 *
2991                                              buffer->params.spacing.getValue(),
2992                                              LyXLength::CM),
2993                                      LYX_ALIGN_CENTER, string(), 0);
2994         } else {
2995                 current_view->text->SetParagraph(0, 0,
2996                                                  0, 0,
2997                                                  VSpace(VSpace::NONE),
2998                                                  VSpace(VSpace::NONE),
2999                                                  LYX_ALIGN_CENTER, 
3000                                                  string(),
3001                                                  0);
3002         }
3003         
3004         current_view->update(-1);
3005       
3006         Inset * new_inset = new InsetFig(100, 100, buffer);
3007         current_view->insertInset(new_inset);
3008         new_inset->Edit(current_view, 0, 0, 0);
3009         current_view->update(0);
3010         current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
3011         current_view->text->UnFreezeUndo();
3012         current_view->setState();
3013 }
3014
3015
3016 extern "C" void FigureCancelCB(FL_OBJECT *, long)
3017 {
3018         fl_hide_form(fd_form_figure->form_figure);
3019 }
3020
3021
3022 extern "C" void FigureOKCB(FL_OBJECT * ob, long data)
3023 {
3024         FigureApplyCB(ob, data);
3025         FigureCancelCB(ob, data);
3026 }
3027
3028
3029 extern "C" void ScreenApplyCB(FL_OBJECT *, long)
3030 {
3031         lyxrc.roman_font_name = fl_get_input(fd_form_screen->input_roman);
3032         lyxrc.sans_font_name = fl_get_input(fd_form_screen->input_sans);
3033         lyxrc.typewriter_font_name = fl_get_input(fd_form_screen->input_typewriter);
3034         lyxrc.font_norm = fl_get_input(fd_form_screen->input_font_norm);
3035         lyxrc.zoom = atoi(fl_get_input(fd_form_screen->intinput_size));
3036         fontloader.update();
3037
3038         // Of course we should only to the resize and the textcahce.clear
3039         // if values really changed...but not very important right now. (Lgb)
3040         
3041         // All buffers will need resize
3042         bufferlist.resize();
3043         // We also need to empty the textcache so that
3044         // the buffer will be formatted correctly after
3045         // a zoom change.
3046         textcache.clear();
3047         
3048         current_view->owner()->getMiniBuffer()->Set(_("Screen options set"));
3049 }
3050
3051
3052 extern "C" void ScreenCancelCB(FL_OBJECT *, long)
3053 {
3054         fl_hide_form(fd_form_screen->form_screen);
3055 }
3056
3057
3058 extern "C" void ScreenOKCB(FL_OBJECT * ob, long data)
3059 {
3060         ScreenCancelCB(ob, data);
3061         ScreenApplyCB(ob, data);
3062 }
3063
3064
3065 void LaTeXOptions(BufferView * bv)
3066 {
3067         if (!bv->available())
3068                 return;
3069
3070         fl_set_button(fd_latex_options->accents,
3071                       int(bv->buffer()->params.allowAccents));
3072         
3073         if (fd_latex_options->LaTeXOptions->visible) {
3074                 fl_raise_form(fd_latex_options->LaTeXOptions);
3075         } else {
3076                 fl_show_form(fd_latex_options->LaTeXOptions,
3077                              FL_PLACE_MOUSE, FL_FULLBORDER,
3078                              _("LaTeX Options"));
3079         }
3080 }
3081
3082
3083 // This function runs "configure" and then rereads lyx.defaults to
3084 // reconfigure the automatic settings.
3085 void Reconfigure(BufferView * bv)
3086 {
3087         bv->owner()->getMiniBuffer()->Set(_("Running configure..."));
3088
3089         // Run configure in user lyx directory
3090         Path p(user_lyxdir);
3091         Systemcalls one(Systemcalls::System, 
3092                         AddName(system_lyxdir, "configure"));
3093         p.pop();
3094         bv->owner()->getMiniBuffer()->Set(_("Reloading configuration..."));
3095         lyxrc.read(LibFileSearch(string(), "lyxrc.defaults"));
3096         WriteAlert(_("The system has been reconfigured."), 
3097                    _("You need to restart LyX to make use of any"),
3098                    _("updated document class specifications."));
3099 }
3100
3101
3102 //
3103 // Table of Contents
3104 //
3105
3106 struct TocList {
3107         int counter[6];
3108         bool appendix;
3109         TocList * next;
3110 };
3111
3112
3113 static TocList * toclist = 0;
3114
3115
3116 extern "C" void TocSelectCB(FL_OBJECT * ob, long)
3117 {
3118         if (!current_view->available())
3119                 return;
3120    
3121         TocList * tmptoclist = toclist;
3122         int i = fl_get_browser(ob);
3123         for (int a = 1; a < i && tmptoclist->next; ++a) {
3124                 tmptoclist = tmptoclist->next;
3125         }
3126
3127         if (!tmptoclist)
3128                 return;
3129      
3130
3131         LyXParagraph * par = current_view->buffer()->paragraph;
3132         while (par && (par->GetFirstCounter(0) != tmptoclist->counter[0] ||
3133                        par->GetFirstCounter(1) != tmptoclist->counter[1] ||
3134                        par->GetFirstCounter(2) != tmptoclist->counter[2] ||
3135                        par->GetFirstCounter(3) != tmptoclist->counter[3] ||
3136                        par->GetFirstCounter(4) != tmptoclist->counter[4] ||
3137                        par->GetFirstCounter(5) != tmptoclist->counter[5] ||
3138                        par->appendix != tmptoclist->appendix)) {
3139                 par = par->LastPhysicalPar()->Next();
3140         }
3141    
3142         if (par) {
3143                 current_view->beforeChange();
3144                 current_view->text->SetCursor(par, 0);
3145                 current_view->text->sel_cursor = 
3146                         current_view->text->cursor;
3147                 current_view->update(0);
3148         }
3149         else {
3150                 WriteAlert(_("Error"), 
3151                            _("Couldn't find this label"), 
3152                            _("in current document."));
3153         }
3154           
3155 }
3156
3157
3158 extern "C" void TocCancelCB(FL_OBJECT *, long)
3159 {
3160         fl_hide_form(fd_form_toc->form_toc);
3161 }
3162
3163
3164 extern "C" void TocUpdateCB(FL_OBJECT *, long)
3165 {
3166         static LyXParagraph * stapar = 0;
3167         TocList * tmptoclist = 0;
3168    
3169         /* deleted the toclist */ 
3170         if (toclist){
3171                 while (toclist){
3172                         tmptoclist = toclist->next;
3173                         delete toclist;
3174                         toclist = tmptoclist;
3175                 }
3176         }
3177         toclist = 0;
3178         tmptoclist = toclist;
3179
3180
3181         fl_clear_browser(fd_form_toc->browser_toc);
3182         if (!current_view->available()) {
3183                 fl_add_browser_line(fd_form_toc->browser_toc,
3184                                     _("*** No Document ***"));
3185                 return;
3186         }
3187         fl_hide_object(fd_form_toc->browser_toc);
3188         /* get the table of contents */ 
3189         LyXParagraph * par = current_view->buffer()->paragraph;
3190         char labeltype;
3191         char * line = new char[200];
3192         int pos = 0;
3193         unsigned char c;
3194         int topline = 0;
3195    
3196         if (stapar == par)
3197                 topline = fl_get_browser_topline(fd_form_toc->browser_toc);
3198         stapar = par;
3199    
3200         while (par) {
3201                 labeltype = textclasslist.Style(current_view->buffer()->params.textclass, 
3202                                                 par->GetLayout()).labeltype;
3203       
3204                 if (labeltype >= LABEL_COUNTER_CHAPTER
3205                     && labeltype <= LABEL_COUNTER_CHAPTER +
3206                     current_view->buffer()->params.tocdepth) {
3207                         /* insert this into the table of contents */ 
3208                         /* first indent a little bit */ 
3209                         
3210                         for (pos = 0; 
3211                              pos < (labeltype - 
3212                                     textclasslist.TextClass(current_view->buffer()->
3213                                                             params.textclass).maxcounter()) * 4 + 2;
3214                              ++pos)
3215                                 line[pos] = ' ';
3216                         
3217                         // Then the labestring
3218                         if (!par->labelstring.empty()) {
3219                                 string::size_type i = 0;
3220                                 while (pos < 199 && i < par->labelstring.length()) {
3221                                         line[pos] = par->labelstring[i];
3222                                         ++i;
3223                                         ++pos;
3224                                 }
3225                         }
3226          
3227                         line[pos] = ' ';
3228                         ++pos;
3229                         
3230                         /* now the contents */
3231                         LyXParagraph::size_type i = 0;
3232                         while (pos < 199 && i < par->size()) {
3233                                 c = par->GetChar(i);
3234                                 if (isprint(c) || c >= 128) {
3235                                         line[pos] = c;
3236                                         ++pos;
3237                                 }
3238                                 ++i;
3239                         }
3240                         line[pos] = '\0';
3241                         fl_add_browser_line(fd_form_toc->browser_toc, line);
3242                         
3243                         /* make a toclist entry */
3244                         if (!tmptoclist){
3245                                 tmptoclist = new TocList;
3246                                 toclist = tmptoclist;
3247                         } else {
3248                                 tmptoclist->next = new TocList;
3249                                 tmptoclist = tmptoclist->next;
3250                         }
3251                         
3252                         tmptoclist->next = 0;
3253                         int a = 0;
3254                         for (a = 0; a < 6; ++a) {
3255                                 tmptoclist->counter[a] = par->GetFirstCounter(a);
3256                         }
3257                         tmptoclist->appendix = par->appendix;
3258                 }
3259                 par = par->LastPhysicalPar()->Next();
3260                 
3261         }
3262         delete[] line;
3263         fl_set_browser_topline(fd_form_toc->browser_toc, topline);
3264         fl_show_object(fd_form_toc->browser_toc);
3265 }
3266
3267
3268 /* callbacks for form form_ref */
3269 extern "C" void RefSelectCB(FL_OBJECT *, long data)
3270 {
3271         if (!current_view->available())
3272                 return;
3273
3274         string s = 
3275                 fl_get_browser_line(fd_form_ref->browser_ref,
3276                                     fl_get_browser(fd_form_ref->browser_ref));
3277         string u = frontStrip(strip(fl_get_input(fd_form_ref->ref_name)));
3278
3279         if (s.empty())
3280                 return;
3281
3282         if (data == 2) {
3283                 current_view->owner()->getLyXFunc()->Dispatch(LFUN_REFGOTO, s.c_str());
3284                 return;
3285         }
3286             
3287         string t;
3288         if (data == 0)
3289                 t += "\\ref";
3290         else
3291                 t += "\\pageref";
3292
3293         if(current_view->buffer()->isSGML())
3294                 t += "[" + u + "]" + "{" + s + "}";
3295         else
3296                 t += "{" + s + "}";
3297
3298         Inset * new_inset = 
3299                 new InsetRef(t, current_view->buffer());
3300         current_view->insertInset(new_inset);
3301 }
3302
3303
3304 extern "C" void RefUpdateCB(FL_OBJECT *, long)
3305 {
3306         if (!current_view->available()) {
3307                 fl_clear_browser(fd_form_ref->browser_ref);
3308                 return;
3309         }
3310
3311         FL_OBJECT * brow = fd_form_ref->browser_ref;
3312
3313         // Get the current line, in order to restore it later
3314         char const * const btmp = fl_get_browser_line(brow,
3315                                                       fl_get_browser(brow));
3316         string currentstr = btmp ? btmp : "";
3317
3318         fl_clear_browser(brow);
3319
3320         string refs = current_view->buffer()->getReferenceList('\n');
3321         int topline = 1;
3322
3323         fl_addto_browser_chars(brow, refs.c_str());
3324         int total_lines = fl_get_browser_maxline(brow);
3325         for (int i = 1; i <= total_lines ; ++i) {
3326                 if (fl_get_browser_line(brow, i) == currentstr) {
3327                         topline = i;
3328                         break;
3329                 }
3330         }
3331         fl_set_browser_topline(brow, topline);
3332
3333         if (!fl_get_browser_maxline(brow)) {
3334                 fl_add_browser_line(brow, 
3335                                     _("*** No labels found in document ***"));
3336                 fl_deactivate_object(brow);
3337         } else {
3338                 fl_select_browser_line(brow, topline);
3339                 fl_activate_object(brow);
3340         }
3341         if (current_view->buffer()->isReadonly()) {
3342                 // would be better to de/activate insert buttons
3343                 // but that's more work... besides this works. ARRae
3344                 fl_hide_form(fd_form_ref->form_ref);
3345         }
3346         if (!current_view->buffer()->isSGML()) {
3347                 fl_deactivate_object(fd_form_ref->ref_name);
3348                 fl_set_object_lcol(fd_form_ref->ref_name, FL_INACTIVE);
3349         }
3350         else {
3351                 fl_activate_object(fd_form_ref->ref_name);
3352                 fl_set_object_lcol(fd_form_ref->ref_name, FL_BLACK);
3353         }
3354 }
3355
3356
3357 extern "C" void RefHideCB(FL_OBJECT *, long)
3358 {
3359         fl_hide_form(fd_form_ref->form_ref);
3360 }