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