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