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