]> git.lyx.org Git - lyx.git/blob - src/lyx_cb.C
73d595d2f7bae9778cc2813ea64fa63446a5ad36
[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                 
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         }
724 }
725
726
727 void MenuMakeLinuxDoc(Buffer * buffer)
728 {
729         // Who cares?
730         //if (!bv->text) return;
731         
732         if (!buffer->isLinuxDoc()) {
733                 WriteAlert(_("Error!"), _("Document class must be linuxdoc."));
734                 return;
735         }
736         
737         // Get LinuxDoc-Filename
738         string s = ChangeExtension(buffer->fileName(), ".sgml");
739
740         if (!AskOverwrite(buffer, s))
741                 return;
742         
743         ShowMessage(buffer, _("Building LinuxDoc SGML file `"),
744                                           MakeDisplayPath(s),"'...");
745         
746         buffer->makeLinuxDocFile(s, 65);
747         buffer->redraw();
748         ShowMessage(buffer, _("LinuxDoc SGML file save as"),
749                                           MakeDisplayPath(s)); 
750 }
751
752
753 void MenuMakeDocBook(Buffer * buffer)
754 {
755         // Who cares?
756         //if (!bv->text) return;
757         
758         if (!buffer->isDocBook()) {
759                 WriteAlert(_("Error!"),
760                            _("Document class must be docbook."));
761                 return;
762         }
763         
764         // Get DocBook-Filename
765         string s = ChangeExtension(buffer->fileName(), ".sgml");
766
767         if (!AskOverwrite(buffer, s))
768                 return;
769         
770         ShowMessage(buffer, _("Building DocBook SGML file `"),
771                                           MakeDisplayPath(s), "'..."); 
772         
773         buffer->makeDocBookFile(s, 65);
774         buffer->redraw();
775         ShowMessage(buffer, _("DocBook SGML file save as"),
776                                           MakeDisplayPath(s)); 
777 }
778
779
780 void MenuMakeAscii(Buffer * buffer)
781 {
782         // Who cares?
783         //if (!bv->text) return;
784         
785         /* get LaTeX-Filename */
786         string s = ChangeExtension (buffer->fileName(), ".txt");
787         
788
789         if (!AskOverwrite(buffer, s))
790                 return;
791         
792         buffer->writeFileAscii(s, lyxrc.ascii_linelen);
793         
794         ShowMessage(buffer, _("Ascii file saved as"), MakeDisplayPath(s));
795 }
796
797
798 void MenuMakeHTML(Buffer * buffer)
799 {
800         // First, create LaTeX file
801         MenuMakeLaTeX(buffer);
802
803         // And now, run the converter
804         string file = buffer->fileName();
805         Path path(OnlyPath(file));
806         // the tex file name has to be correct for
807         // latex, but the html file name can be
808         // anything.
809         string result = ChangeExtension(file, ".html");
810         string infile = buffer->getLatexName(false);
811         string tmp = lyxrc.html_command;
812         tmp = subst(tmp, "$$FName", infile);
813         tmp = subst(tmp, "$$OutName", result);
814         Systemcalls one;
815         int res = one.startscript(Systemcalls::System, tmp);
816         if (res == 0) {
817                 ShowMessage(buffer, _("Document exported as HTML to file `")
818                                                   + MakeDisplayPath(result) +'\'');
819         } else {
820                 ShowMessage(buffer, _("Unable to convert to HTML the file `")
821                                                   + MakeDisplayPath(infile) 
822                                                   + '\'');
823         }
824
825 }
826
827
828 void MenuMakeHTML_LinuxDoc(Buffer * buffer)
829 {
830         // First, create LinuxDoc file
831         MenuMakeLinuxDoc(buffer);
832
833         // And now, run the converter
834         string file = buffer->fileName();
835
836         string result = ChangeExtension(file, ".html");
837         string infile = ChangeExtension(file, ".sgml");
838         string tmp = lyxrc.linuxdoc_to_html_command;
839         tmp = subst(tmp, "$$FName", infile);
840         tmp = subst(tmp, "$$OutName", result);
841         Systemcalls one;
842         int res = one.startscript(Systemcalls::System, tmp);
843         if (res == 0) {
844                 ShowMessage(buffer,_("Document exported as HTML to file `")
845                                                   + MakeDisplayPath(result) +'\'');
846         } else {
847                 ShowMessage(buffer,_("Unable to convert to HTML the file `")
848                                                   + MakeDisplayPath(infile) 
849                                                   + '\'');
850         }
851
852 }
853
854 void MenuMakeHTML_DocBook(Buffer * buffer)
855 {
856         // First, create LaTeX file
857         MenuMakeDocBook(buffer);
858
859         // And now, run the converter
860         string file = buffer->fileName();
861         string result = ChangeExtension(file, ".html");
862         string infile = ChangeExtension(file, ".sgml");
863         string tmp = lyxrc.docbook_to_html_command;
864         tmp = subst(tmp, "$$FName", infile);
865         tmp = subst(tmp, "$$OutName", result);
866         Systemcalls one;
867         int res = one.startscript(Systemcalls::System, tmp);
868         if (res == 0) {
869                 ShowMessage(buffer,_("Document exported as HTML to file `")
870                                                   + MakeDisplayPath(result) +'\'');
871         } else {
872                 ShowMessage(buffer,_("Unable to convert to HTML the file `")
873                                                   + MakeDisplayPath(infile) 
874                                                   + '\'');
875         }
876
877 }
878
879
880 void MenuExport(Buffer * buffer, string const & extyp) 
881 {
882         // latex
883         if (extyp == "latex") {
884                 // make sure that this buffer is not linuxdoc
885                 MenuMakeLaTeX(buffer);
886         }
887         // linuxdoc
888         else if (extyp == "linuxdoc") {
889                 // make sure that this buffer is not latex
890                 MenuMakeLinuxDoc(buffer);
891         }
892         // docbook
893         else if (extyp == "docbook") {
894                 // make sure that this buffer is not latex or linuxdoc
895                 MenuMakeDocBook(buffer);
896         }
897         // dvi
898         else if (extyp == "dvi") {
899                 // Run LaTeX as "Update dvi..." Bernhard.
900                 // We want the dvi in the current directory. This
901                 // is achieved by temporarily disabling use of
902                 // temp directory. As a side-effect, we get
903                 // *.log and *.aux files also. (Asger)
904                 bool flag = lyxrc.use_tempdir;
905                 lyxrc.use_tempdir = false;
906                 MenuRunLaTeX(buffer);
907                 lyxrc.use_tempdir = flag;
908         }
909         // postscript
910         else if (extyp == "postscript") {
911                 // Start Print-dialog. Not as good as dvi... Bernhard.
912         //should start lyxview->getDialogs()->showPrint();
913         // to get same as before
914         //              MenuPrint(buffer);
915                 // Since the MenuPrint is a pop-up, we can't use
916                 // the same trick as above. (Asger)
917                 // MISSING: Move of ps-file :-(
918                 // And MenuPrint should not be used for this at all...
919         }
920         // ascii
921         else if (extyp == "ascii") {
922                 MenuMakeAscii(buffer);
923         }
924         else if (extyp == "custom") {
925                 MenuSendto();
926         }
927         // HTML
928         else if (extyp == "html") {
929                 MenuMakeHTML(buffer);
930         }
931         // HTML from linuxdoc
932         else if (extyp == "html-linuxdoc") {
933                 MenuMakeHTML_LinuxDoc(buffer);
934         }
935         // HTML from docbook
936         else if (extyp == "html-docbook") {
937                 MenuMakeHTML_DocBook(buffer);
938         }
939         else {
940                 ShowMessage(buffer, _("Unknown export type: ") + extyp);
941         }
942 }
943
944
945 void QuitLyX()
946 {
947         lyxerr.debug() << "Running QuitLyX." << endl;
948
949         if (!bufferlist.QwriteAll())
950                 return;
951
952         lastfiles->writeFile(lyxrc.lastfiles);
953
954         // Set a flag that we do quitting from the program,
955         // so no refreshes are necessary.
956         quitting = true;
957
958         // close buffers first
959         bufferlist.closeAll();
960
961         // do any other cleanup procedures now
962         lyxerr.debug() << "Deleting tmp dir " << system_tempdir << endl;
963
964         DestroyLyXTmpDir(system_tempdir);
965
966         finished = true;
967 }
968
969
970
971 void AutoSave(BufferView * bv)
972         // should probably be moved into BufferList (Lgb)
973         // Perfect target for a thread...
974 {
975         if (!bv->available())
976                 return;
977
978         if (bv->buffer()->isBakClean()
979             || bv->buffer()->isReadonly()) {
980                 // We don't save now, but we'll try again later
981                 bv->owner()->resetAutosaveTimer();
982                 return;
983         }
984
985         bv->owner()->getMiniBuffer()->Set(_("Autosaving current document..."));
986         
987         // create autosave filename
988         string fname =  OnlyPath(bv->buffer()->fileName());
989         fname += "#";
990         fname += OnlyFilename(bv->buffer()->fileName());
991         fname += "#";
992         
993         // tmp_ret will be located (usually) in /tmp
994         // will that be a problem?
995         string tmp_ret = tmpnam(0);
996         
997         pid_t pid = fork(); // If you want to debug the autosave
998         // you should set pid to -1, and comment out the
999         // fork.
1000         if (pid == 0 || pid == -1) {
1001                 // pid = -1 signifies that lyx was unable
1002                 // to fork. But we will do the save
1003                 // anyway.
1004                 bool failed = false;
1005                 if (!tmp_ret.empty()) {
1006                         bv->buffer()->writeFile(tmp_ret, 1);
1007                         // assume successful write of tmp_ret
1008                         if (rename(tmp_ret.c_str(), fname.c_str()) == -1) {
1009                                 failed = true;
1010                                 // most likely couldn't move between filesystems
1011                                 // unless write of tmp_ret failed
1012                                 // so remove tmp file (if it exists)
1013                                 remove(tmp_ret.c_str());
1014                         }
1015                 } else {
1016                         failed = true;
1017                 }
1018                 
1019                 if (failed) {
1020                         // failed to write/rename tmp_ret so try writing direct
1021                         if (!bv->buffer()->writeFile(fname, 1)) {
1022                                 // It is dangerous to do this in the child,
1023                                 // but safe in the parent, so...
1024                                 if (pid == -1)
1025                                         bv->owner()->getMiniBuffer()->Set(_("Autosave Failed!"));
1026                         }
1027                 }
1028                 if (pid == 0) { // we are the child so...
1029                         _exit(0);
1030                 }
1031         }
1032         
1033         bv->buffer()->markBakClean();
1034         bv->owner()->resetAutosaveTimer();
1035 }
1036
1037
1038 //
1039 // Copyright CHT Software Service GmbH
1040 // Uwe C. Schroeder
1041 //
1042 // create new file with template
1043 // SERVERCMD !
1044 //
1045 Buffer * NewLyxFile(string const & filename)
1046 {
1047         // Split argument by :
1048         string name;
1049         string tmpname = split(filename, name, ':');
1050 #ifdef __EMX__ // Fix me! lyx_cb.C may not be low level enough to allow this.
1051         if (name.length() == 1
1052             && isalpha(static_cast<unsigned char>(name[0]))
1053             && (prefixIs(tmpname, "/") || prefixIs(tmpname, "\\"))) {
1054                 name += ':';
1055                 name += token(tmpname, ':', 0);
1056                 tmpname = split(tmpname, ':');
1057         }
1058 #endif
1059         lyxerr.debug() << "Arg is " << filename
1060                        << "\nName is " << name
1061                        << "\nTemplate is " << tmpname << endl;
1062
1063         // find a free buffer 
1064         Buffer * tmpbuf = bufferlist.newFile(name, tmpname);
1065         if (tmpbuf)
1066                 lastfiles->newFile(tmpbuf->fileName());
1067         return tmpbuf;
1068 }
1069
1070
1071 // Insert ascii file (if filename is empty, prompt for one)
1072 void InsertAsciiFile(BufferView * bv, string const & f, bool asParagraph)
1073 {
1074         string fname = f;
1075         LyXFileDlg fileDlg;
1076  
1077         if (!bv->available()) return;
1078      
1079         if (fname.empty()) {
1080                 ProhibitInput(bv);
1081                 fname = fileDlg.Select(_("File to Insert"), 
1082                                        bv->owner()->buffer()->filepath,
1083                                        "*");
1084                 AllowInput(bv);
1085                 if (fname.empty()) return;
1086         }
1087
1088         FileInfo fi(fname);
1089
1090         if (!fi.readable()) {
1091                 WriteFSAlert(_("Error! Specified file is unreadable: "),
1092                              MakeDisplayPath(fname, 50));
1093                 return;
1094         }
1095
1096         ifstream ifs(fname.c_str());
1097         if (!ifs) {
1098                 WriteFSAlert(_("Error! Cannot open specified file: "),
1099                              MakeDisplayPath(fname, 50));
1100                 return;
1101         }
1102
1103         ifs.unsetf(ios::skipws);
1104         istream_iterator<char> ii(ifs);
1105         istream_iterator<char> end;
1106         //string tmpstr(ii, end); // yet a reason for using std::string
1107         // alternate approach to get the file into a string:
1108         string tmpstr;
1109         copy(ii, end, back_inserter(tmpstr));
1110         // insert the string
1111         current_view->hideCursor();
1112         
1113         // clear the selection
1114         bv->beforeChange();
1115         if (!asParagraph)
1116                 bv->text->InsertStringA(bv, tmpstr);
1117         else
1118                 bv->text->InsertStringB(bv, tmpstr);
1119         bv->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1120 }
1121
1122
1123 void MenuShowTableOfContents()
1124 {
1125         static int ow = -1, oh;
1126
1127         TocUpdateCB(0, 0);
1128         if (fd_form_toc->form_toc->visible) {
1129                 fl_raise_form(fd_form_toc->form_toc);
1130         } else {
1131                 fl_show_form(fd_form_toc->form_toc,
1132                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
1133                              _("Table Of Contents"));
1134                 if (ow < 0) {
1135                         ow = fd_form_toc->form_toc->w;
1136                         oh = fd_form_toc->form_toc->h;
1137                 }
1138                 fl_set_form_minsize(fd_form_toc->form_toc, ow, oh);
1139         }
1140 }
1141
1142
1143 void MenuInsertLabel(char const * arg)
1144 {
1145         string label = arg;
1146         ProhibitInput(current_view);
1147         if (label.empty()) {
1148                 pair<bool, string>
1149                         result = askForText(_("Enter new label to insert:"));
1150                 if (result.first) {
1151                         label = frontStrip(strip(result.second));
1152                 }
1153         }
1154         if (!label.empty()) {
1155                 InsetLabel * new_inset = new InsetLabel;
1156                 new_inset->setContents(label);
1157                 current_view->insertInset(new_inset);
1158         }
1159         AllowInput(current_view);
1160 }
1161
1162
1163 void MenuInsertRef()
1164 {
1165         static int ow = -1, oh;
1166
1167         RefUpdateCB(0, 0);
1168         if (fd_form_ref->form_ref->visible) {
1169                 fl_raise_form(fd_form_ref->form_ref);
1170         } else {
1171                 fl_show_form(fd_form_ref->form_ref,
1172                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
1173                              _("Insert Reference"));
1174                 if (ow < 0) {
1175                         ow = fd_form_ref->form_ref->w;
1176                         oh = fd_form_ref->form_ref->h;
1177                 }
1178                 fl_set_form_minsize(fd_form_ref->form_ref, ow, oh);
1179         }
1180 }
1181
1182
1183 // candidate for move to LyXView
1184 // This is only used in toolbar.C
1185 void LayoutsCB(int sel, void *)
1186 {
1187         string tmp = tostr(sel);
1188         current_view->owner()->getLyXFunc()->Dispatch(LFUN_LAYOUTNO,
1189                                                       tmp.c_str());
1190 }
1191
1192
1193 /*
1194  * SGML Linuxdoc support:
1195  * (flag == 0) make TeX output
1196  * (flag == 1) make dvi output
1197  */
1198 int RunLinuxDoc(BufferView * bv, int flag, string const & filename)
1199 {
1200         string s2;
1201         string add_flags;
1202
1203         int errorcode = 0;
1204
1205         /* generate a path-less extension name */
1206         string name = OnlyFilename(ChangeExtension (filename, ".sgml"));
1207         string path = OnlyPath (filename);
1208         if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)) {
1209                 path = bv->buffer()->tmppath;
1210         }
1211         Path p(path);
1212         
1213         if (!bv->available())
1214                 return 0;
1215         bv->buffer()->makeLinuxDocFile(name, 0);
1216
1217         // CHECK remove this once we have a proper geometry class
1218
1219         BufferParams::PAPER_SIZE ps =
1220                 static_cast<BufferParams::PAPER_SIZE>(bv->buffer()->params.papersize);
1221         switch (ps) {
1222         case BufferParams::PAPER_A4PAPER:
1223                 add_flags = "-p a4";
1224                 break;
1225         case BufferParams::PAPER_USLETTER:
1226                 add_flags = "-p letter";
1227                 break;
1228         default: /* nothing to be done yet ;-) */     break; 
1229         }
1230         
1231         ProhibitInput(bv);
1232         
1233         Systemcalls one;
1234         switch (flag) {
1235         case 0: /* TeX output asked */
1236               bv->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to TeX file..."));
1237                 s2 = lyxrc.linuxdoc_to_latex_command + ' ' + add_flags + " -o tex " + ' ' + name;
1238                 if (one.startscript(Systemcalls::System, s2)) 
1239                         errorcode = 1;
1240                 break;
1241         case 1: /* dvi output asked */
1242                 bv->owner()->getMiniBuffer()->Set(_("Converting LinuxDoc SGML to dvi file..."));
1243                 s2 = lyxrc.linuxdoc_to_latex_command + ' ' + add_flags + " -o dvi " + ' ' + name;
1244                 if (one.startscript(Systemcalls::System, s2)) {
1245                         errorcode = 1;
1246                 } 
1247                 break;
1248         default: /* unknown output */
1249                 break;
1250         }
1251         
1252         AllowInput(bv);
1253
1254         bv->buffer()->redraw();
1255         return errorcode;
1256 }
1257
1258
1259 /*
1260  * SGML DocBook support:
1261  * (flag == 1) make dvi output
1262  */
1263 int RunDocBook(int flag, string const & filename)
1264 {
1265         /* generate a path-less extension name */
1266         string name = OnlyFilename(ChangeExtension (filename, ".sgml"));
1267         string path = OnlyPath (filename);
1268         if (lyxrc.use_tempdir || (IsDirWriteable(path) < 1)) {
1269                 path = current_view->buffer()->tmppath;
1270         }
1271         Path p(path);
1272
1273         if (!current_view->available())
1274                 return 0;
1275         
1276         current_view->buffer()->makeDocBookFile(name, 0);
1277
1278         // Shall this code go or should it stay? (Lgb)
1279         // This code is a placeholder for future implementation. (Jose')
1280 //      string add_flags;
1281 //      LYX_PAPER_SIZE ps = (LYX_PAPER_SIZE) current_view->buffer()->params.papersize;
1282 //      switch (ps) {
1283 //      case BufferParams::PAPER_A4PAPER:  add_flags = "-p a4";     break;
1284 //      case BufferParams::PAPER_USLETTER: add_flags = "-p letter"; break;
1285 //      default: /* nothing to be done yet ;-) */     break; 
1286 //      }
1287         ProhibitInput(current_view);
1288         
1289         int errorcode = 0;
1290         Systemcalls one;
1291         switch (flag) {
1292         case 1: /* dvi output asked */
1293         {
1294                 current_view->owner()->getMiniBuffer()->Set(_("Converting DocBook SGML to dvi file..."));
1295                 string s2 = lyxrc.docbook_to_dvi_command + ' ' + name;
1296                 if (one.startscript(Systemcalls::System, s2)) {
1297                         errorcode = 1;
1298                 }
1299         }
1300         break;
1301         default: /* unknown output */
1302                 break;
1303         }
1304         
1305         AllowInput(current_view);
1306
1307         current_view->buffer()->redraw();
1308         return errorcode;
1309 }
1310
1311
1312 void MenuLayoutCharacter()
1313 {
1314         static int ow = -1, oh;
1315
1316         if (fd_form_character->form_character->visible) {
1317                 fl_raise_form(fd_form_character->form_character);
1318         } else {
1319                 fl_show_form(fd_form_character->form_character,
1320                              FL_PLACE_MOUSE | FL_FREE_SIZE, FL_FULLBORDER,
1321                              _("Character Style"));
1322                 if (ow < 0) {
1323                         ow = fd_form_character->form_character->w;
1324                         oh = fd_form_character->form_character->h;
1325                 }
1326                 fl_set_form_minsize(fd_form_character->form_character, ow, oh);
1327         }
1328 }
1329
1330
1331 inline
1332 void DeactivateParagraphButtons ()
1333 {
1334         fl_deactivate_object (fd_form_paragraph->button_ok);
1335         fl_deactivate_object (fd_form_paragraph->button_apply);
1336         fl_set_object_lcol (fd_form_paragraph->button_ok, FL_INACTIVE);
1337         fl_set_object_lcol (fd_form_paragraph->button_apply, FL_INACTIVE);
1338 }
1339
1340
1341 inline
1342 void ActivateParagraphButtons ()
1343 {
1344         fl_activate_object (fd_form_paragraph->button_ok);
1345         fl_activate_object (fd_form_paragraph->button_apply);
1346         fl_set_object_lcol (fd_form_paragraph->button_ok, FL_BLACK);
1347         fl_set_object_lcol (fd_form_paragraph->button_apply, FL_BLACK);
1348 }
1349
1350
1351 inline
1352 void DisableParagraphLayout ()
1353 {
1354         DeactivateParagraphButtons();
1355         fl_deactivate_object (fd_form_paragraph->input_labelwidth);
1356         fl_deactivate_object (fd_form_paragraph->check_lines_top);
1357         fl_deactivate_object (fd_form_paragraph->check_lines_bottom);
1358         fl_deactivate_object (fd_form_paragraph->check_pagebreaks_top);
1359         fl_deactivate_object (fd_form_paragraph->check_pagebreaks_bottom);
1360         fl_deactivate_object (fd_form_paragraph->check_noindent);
1361         fl_deactivate_object (fd_form_paragraph->group_radio_alignment);
1362         fl_deactivate_object (fd_form_paragraph->radio_align_right);
1363         fl_deactivate_object (fd_form_paragraph->radio_align_left);
1364         fl_deactivate_object (fd_form_paragraph->radio_align_block);
1365         fl_deactivate_object (fd_form_paragraph->radio_align_center);
1366         fl_deactivate_object (fd_form_paragraph->input_space_above);
1367         fl_deactivate_object (fd_form_paragraph->input_space_below);
1368         fl_deactivate_object (fd_form_paragraph->choice_space_above);
1369         fl_deactivate_object (fd_form_paragraph->choice_space_below);
1370         fl_deactivate_object (fd_form_paragraph->check_space_above);
1371         fl_deactivate_object (fd_form_paragraph->check_space_below);
1372 }
1373
1374
1375 inline
1376 void EnableParagraphLayout ()
1377 {
1378         ActivateParagraphButtons();
1379         fl_activate_object (fd_form_paragraph->input_labelwidth);
1380         fl_activate_object (fd_form_paragraph->check_lines_top);
1381         fl_activate_object (fd_form_paragraph->check_lines_bottom);
1382         fl_activate_object (fd_form_paragraph->check_pagebreaks_top);
1383         fl_activate_object (fd_form_paragraph->check_pagebreaks_bottom);
1384         fl_activate_object (fd_form_paragraph->check_noindent);
1385         fl_activate_object (fd_form_paragraph->group_radio_alignment);
1386         fl_activate_object (fd_form_paragraph->radio_align_right);
1387         fl_activate_object (fd_form_paragraph->radio_align_left);
1388         fl_activate_object (fd_form_paragraph->radio_align_block);
1389         fl_activate_object (fd_form_paragraph->radio_align_center);
1390         fl_activate_object (fd_form_paragraph->input_space_above);
1391         fl_activate_object (fd_form_paragraph->input_space_below);
1392         fl_activate_object (fd_form_paragraph->choice_space_above);
1393         fl_activate_object (fd_form_paragraph->choice_space_below);
1394         fl_activate_object (fd_form_paragraph->check_space_above);
1395         fl_activate_object (fd_form_paragraph->check_space_below);
1396 }
1397
1398
1399 bool UpdateLayoutParagraph()
1400 {
1401         if (!current_view->available()) {
1402                 if (fd_form_paragraph->form_paragraph->visible) 
1403                         fl_hide_form(fd_form_paragraph->form_paragraph);
1404                 return false;
1405         }
1406
1407         Buffer * buf = current_view->buffer();
1408
1409         fl_set_input(fd_form_paragraph->input_labelwidth,
1410                      current_view->text->cursor.par()->GetLabelWidthString().c_str());
1411         fl_set_button(fd_form_paragraph->radio_align_right, 0);
1412         fl_set_button(fd_form_paragraph->radio_align_left, 0);
1413         fl_set_button(fd_form_paragraph->radio_align_center, 0);
1414         fl_set_button(fd_form_paragraph->radio_align_block, 0);
1415
1416         int align = current_view->text->cursor.par()->GetAlign();
1417         if (align == LYX_ALIGN_LAYOUT)
1418                 align = textclasslist.Style(buf->params.textclass,
1419                                             current_view->text->cursor.par()->GetLayout()).align;
1420          
1421         switch (align) {
1422         case LYX_ALIGN_RIGHT:
1423                 fl_set_button(fd_form_paragraph->radio_align_right, 1);
1424                 break;
1425         case LYX_ALIGN_LEFT:
1426                 fl_set_button(fd_form_paragraph->radio_align_left, 1);
1427                 break;
1428         case LYX_ALIGN_CENTER:
1429                 fl_set_button(fd_form_paragraph->radio_align_center, 1);
1430                 break;
1431         default:
1432                 fl_set_button(fd_form_paragraph->radio_align_block, 1);
1433                 break;
1434         }
1435          
1436         fl_set_button(fd_form_paragraph->check_lines_top,
1437                       current_view->text->cursor.par()->FirstPhysicalPar()->line_top);
1438         fl_set_button(fd_form_paragraph->check_lines_bottom,
1439                       current_view->text->cursor.par()->FirstPhysicalPar()->line_bottom);
1440         fl_set_button(fd_form_paragraph->check_pagebreaks_top,
1441                       current_view->text->cursor.par()->FirstPhysicalPar()->pagebreak_top);
1442         fl_set_button(fd_form_paragraph->check_pagebreaks_bottom,
1443                       current_view->text->cursor.par()->FirstPhysicalPar()->pagebreak_bottom);
1444         fl_set_button(fd_form_paragraph->check_noindent,
1445                       current_view->text->cursor.par()->FirstPhysicalPar()->noindent);
1446         fl_set_input (fd_form_paragraph->input_space_above, "");
1447         
1448         switch (current_view->text->cursor.par()->FirstPhysicalPar()->added_space_top.kind()) {
1449         case VSpace::NONE:
1450                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
1451                 break;
1452         case VSpace::DEFSKIP:
1453                 fl_set_choice (fd_form_paragraph->choice_space_above, 2);
1454                 break;
1455         case VSpace::SMALLSKIP:
1456                 fl_set_choice (fd_form_paragraph->choice_space_above, 3);
1457                 break;
1458         case VSpace::MEDSKIP:
1459                 fl_set_choice (fd_form_paragraph->choice_space_above, 4);
1460                 break;
1461         case VSpace::BIGSKIP:
1462                 fl_set_choice (fd_form_paragraph->choice_space_above, 5);
1463                 break;
1464         case VSpace::VFILL:
1465                 fl_set_choice (fd_form_paragraph->choice_space_above, 6);
1466                 break;
1467         case VSpace::LENGTH:
1468                 fl_set_choice (fd_form_paragraph->choice_space_above, 7); 
1469                 fl_set_input  (fd_form_paragraph->input_space_above, 
1470                                current_view->text->cursor.par()->FirstPhysicalPar()->added_space_top.length().asString().c_str());
1471                 break;
1472         }
1473         fl_set_button (fd_form_paragraph->check_space_above,
1474                        current_view->text->cursor.par()->FirstPhysicalPar()->added_space_top.keep());
1475         fl_set_input (fd_form_paragraph->input_space_below, "");
1476         switch (current_view->text->cursor.par()->FirstPhysicalPar()->added_space_bottom.kind()) {
1477         case VSpace::NONE:
1478                 fl_set_choice (fd_form_paragraph->choice_space_below,
1479                                1);
1480                 break;
1481         case VSpace::DEFSKIP:
1482                 fl_set_choice (fd_form_paragraph->choice_space_below,
1483                                2);
1484                 break;
1485         case VSpace::SMALLSKIP:
1486                 fl_set_choice (fd_form_paragraph->choice_space_below,
1487                                3);
1488                 break;
1489         case VSpace::MEDSKIP:
1490                 fl_set_choice (fd_form_paragraph->choice_space_below,
1491                                4);
1492                 break;
1493         case VSpace::BIGSKIP:
1494                 fl_set_choice (fd_form_paragraph->choice_space_below,
1495                                5);
1496                 break;
1497         case VSpace::VFILL:
1498                 fl_set_choice (fd_form_paragraph->choice_space_below,
1499                                6);
1500                 break;
1501         case VSpace::LENGTH:
1502                 fl_set_choice (fd_form_paragraph->choice_space_below,
1503                                7); 
1504                 fl_set_input  (fd_form_paragraph->input_space_below, 
1505                                current_view->text->cursor.par()->FirstPhysicalPar()->added_space_bottom.length().asString().c_str());
1506                 break;
1507         }
1508         fl_set_button (fd_form_paragraph->check_space_below,
1509                        current_view->text->cursor.par()->FirstPhysicalPar()->added_space_bottom.keep());
1510
1511         fl_set_button(fd_form_paragraph->check_noindent,
1512                       current_view->text->cursor.par()->FirstPhysicalPar()->noindent);
1513
1514         if (current_view->buffer()->isReadonly()) {
1515                 DisableParagraphLayout();
1516         } else {
1517                 EnableParagraphLayout();
1518         }
1519         return true;
1520 }
1521
1522
1523 void MenuLayoutParagraph()
1524 {
1525         if (UpdateLayoutParagraph()) {
1526                 if (fd_form_paragraph->form_paragraph->visible) {
1527                         fl_raise_form(fd_form_paragraph->form_paragraph);
1528                 } else {
1529                         fl_show_form(fd_form_paragraph->form_paragraph,
1530                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1531                                      _("Paragraph Environment"));
1532                 }
1533         }
1534 }
1535
1536
1537 inline
1538 void DeactivateDocumentButtons ()
1539 {
1540         fl_deactivate_object (fd_form_document->button_ok);
1541         fl_deactivate_object (fd_form_document->button_apply);
1542         fl_set_object_lcol (fd_form_document->button_ok, FL_INACTIVE);
1543         fl_set_object_lcol (fd_form_document->button_apply, FL_INACTIVE);
1544 }
1545
1546
1547 inline
1548 void ActivateDocumentButtons ()
1549 {
1550         fl_activate_object (fd_form_document->button_ok);
1551         fl_activate_object (fd_form_document->button_apply);
1552         fl_set_object_lcol (fd_form_document->button_ok, FL_BLACK);
1553         fl_set_object_lcol (fd_form_document->button_apply, FL_BLACK);
1554 }
1555
1556
1557 inline
1558 void DisableDocumentLayout ()
1559 {
1560         DeactivateDocumentButtons ();
1561         fl_deactivate_object (fd_form_document->group_radio_separation);
1562         fl_deactivate_object (fd_form_document->radio_indent);
1563         fl_deactivate_object (fd_form_document->radio_skip);
1564         fl_deactivate_object (fd_form_document->choice_class);
1565         fl_deactivate_object (fd_form_document->choice_pagestyle);
1566         fl_deactivate_object (fd_form_document->choice_fonts);
1567         fl_deactivate_object (fd_form_document->choice_fontsize);
1568         fl_deactivate_object (fd_form_document->input_float_placement);
1569         fl_deactivate_object (fd_form_document->choice_postscript_driver);
1570         fl_deactivate_object (fd_form_document->choice_inputenc);
1571         fl_deactivate_object (fd_form_document->group_radio_sides);
1572         fl_deactivate_object (fd_form_document->radio_sides_one);
1573         fl_deactivate_object (fd_form_document->radio_sides_two);
1574         fl_deactivate_object (fd_form_document->group_radio_columns);
1575         fl_deactivate_object (fd_form_document->radio_columns_one);
1576         fl_deactivate_object (fd_form_document->radio_columns_two);
1577         fl_deactivate_object (fd_form_document->input_extra);
1578         fl_deactivate_object (fd_form_document->choice_language);
1579         combo_language->deactivate();
1580         fl_deactivate_object (fd_form_document->input_default_skip);
1581         fl_deactivate_object (fd_form_document->choice_default_skip);
1582         fl_deactivate_object (fd_form_document->slider_secnumdepth);
1583         fl_deactivate_object (fd_form_document->slider_tocdepth);
1584         fl_deactivate_object (fd_form_document->choice_spacing);
1585         fl_deactivate_object (fd_form_document->input_spacing);
1586         fl_deactivate_object (fd_form_document->check_use_amsmath);
1587 }
1588
1589
1590 inline
1591 void EnableDocumentLayout ()
1592 {
1593         ActivateDocumentButtons ();
1594         fl_activate_object (fd_form_document->group_radio_separation);
1595         fl_activate_object (fd_form_document->radio_indent);
1596         fl_activate_object (fd_form_document->radio_skip);
1597         fl_activate_object (fd_form_document->choice_class);
1598         fl_activate_object (fd_form_document->choice_pagestyle);
1599         fl_activate_object (fd_form_document->choice_fonts);
1600         fl_activate_object (fd_form_document->choice_fontsize);
1601         fl_activate_object (fd_form_document->input_float_placement);
1602         fl_activate_object (fd_form_document->choice_postscript_driver);
1603         fl_activate_object (fd_form_document->choice_inputenc);
1604         fl_activate_object (fd_form_document->group_radio_sides);
1605         fl_activate_object (fd_form_document->radio_sides_one);
1606         fl_activate_object (fd_form_document->radio_sides_two);
1607         fl_activate_object (fd_form_document->group_radio_columns);
1608         fl_activate_object (fd_form_document->radio_columns_one);
1609         fl_activate_object (fd_form_document->radio_columns_two);
1610         fl_activate_object (fd_form_document->input_extra);
1611         fl_activate_object (fd_form_document->choice_language);
1612         combo_language->activate();
1613         fl_activate_object (fd_form_document->input_default_skip);
1614         fl_activate_object (fd_form_document->choice_default_skip);
1615         fl_activate_object (fd_form_document->slider_secnumdepth);
1616         fl_activate_object (fd_form_document->slider_tocdepth);
1617         fl_activate_object (fd_form_document->choice_spacing);
1618         fl_activate_object (fd_form_document->input_spacing);
1619         fl_activate_object (fd_form_document->check_use_amsmath);
1620 }
1621
1622
1623 bool UpdateLayoutDocument(BufferParams * params)
1624 {
1625         if (!current_view->available()) {
1626                 if (fd_form_document->form_document->visible) 
1627                         fl_hide_form(fd_form_document->form_document);
1628                 return false;
1629         }               
1630
1631         if (params == 0)
1632                 params = &current_view->buffer()->params;
1633         LyXTextClass const & tclass = textclasslist.TextClass(params->textclass);
1634         
1635         fl_set_choice_text(fd_form_document->choice_class, 
1636                            textclasslist.DescOfClass(params->textclass).c_str());
1637         combo_language->select_text(params->language.c_str());
1638         
1639         fl_set_choice_text(fd_form_document->choice_fonts, 
1640                            params->fonts.c_str());
1641         fl_set_choice_text(fd_form_document->choice_inputenc, 
1642                            params->inputenc.c_str());
1643         fl_set_choice_text(fd_form_document->choice_postscript_driver, 
1644                            params->graphicsDriver.c_str());
1645
1646         // ale970405+lasgoutt970513
1647         fl_clear_choice(fd_form_document->choice_fontsize);
1648         fl_addto_choice(fd_form_document->choice_fontsize, "default");
1649         fl_addto_choice(fd_form_document->choice_fontsize, 
1650                         tclass.opt_fontsize().c_str());
1651         fl_set_choice(fd_form_document->choice_fontsize, 
1652                       tokenPos(tclass.opt_fontsize(), '|', params->fontsize) + 2);
1653
1654         // ale970405+lasgoutt970513
1655         fl_clear_choice(fd_form_document->choice_pagestyle);
1656         fl_addto_choice(fd_form_document->choice_pagestyle, "default");
1657         fl_addto_choice(fd_form_document->choice_pagestyle, 
1658                         tclass.opt_pagestyle().c_str());
1659     
1660         fl_set_choice(fd_form_document->choice_pagestyle,
1661                       tokenPos(tclass.opt_pagestyle(), '|', params->pagestyle) + 2);
1662
1663         fl_set_button(fd_form_document->radio_indent, 0);
1664         fl_set_button(fd_form_document->radio_skip, 0);
1665     
1666         
1667         fl_set_button(fd_form_document->check_use_amsmath, params->use_amsmath);
1668
1669         if (params->paragraph_separation == BufferParams::PARSEP_INDENT)
1670                 fl_set_button(fd_form_document->radio_indent, 1);
1671         else
1672                 fl_set_button(fd_form_document->radio_skip, 1);
1673
1674         switch (params->getDefSkip().kind()) {
1675         case VSpace::SMALLSKIP: 
1676                 fl_set_choice (fd_form_document->choice_default_skip, 1);
1677                 break;
1678         case VSpace::MEDSKIP: 
1679                 fl_set_choice (fd_form_document->choice_default_skip, 2);
1680                 break;
1681         case VSpace::BIGSKIP: 
1682                 fl_set_choice (fd_form_document->choice_default_skip, 3);
1683                 break;
1684         case VSpace::LENGTH: 
1685                 fl_set_choice (fd_form_document->choice_default_skip, 4);
1686                 fl_set_input (fd_form_document->input_default_skip,
1687                               params->getDefSkip().asLyXCommand().c_str());
1688                 break;
1689         default:
1690                 fl_set_choice (fd_form_document->choice_default_skip, 2);
1691                 break;
1692         }
1693    
1694         fl_set_button(fd_form_document->radio_sides_one, 0);
1695         fl_set_button(fd_form_document->radio_sides_two, 0);
1696    
1697         switch (params->sides) {
1698         case LyXTextClass::OneSide:
1699                 fl_set_button(fd_form_document->radio_sides_one, 1);
1700                 break;
1701         case LyXTextClass::TwoSides:
1702                 fl_set_button(fd_form_document->radio_sides_two, 1);
1703                 break;
1704         }
1705    
1706         fl_set_button(fd_form_document->radio_columns_one, 0);
1707         fl_set_button(fd_form_document->radio_columns_two, 0);
1708    
1709         if (params->columns == 2)
1710                 fl_set_button(fd_form_document->radio_columns_two, 1);
1711         else
1712                 fl_set_button(fd_form_document->radio_columns_one, 1);
1713    
1714         fl_set_input(fd_form_document->input_spacing, "");
1715         switch (params->spacing.getSpace()) {
1716         case Spacing::Default: // nothing bad should happen with this
1717         case Spacing::Single:
1718         {
1719                 // \singlespacing
1720                 fl_set_choice(fd_form_document->choice_spacing, 1);
1721                 break;
1722         }
1723         case Spacing::Onehalf:
1724         {
1725                 // \onehalfspacing
1726                 fl_set_choice(fd_form_document->choice_spacing, 2);
1727                 break;
1728         }
1729         case Spacing::Double:
1730         {
1731                 // \ doublespacing
1732                 fl_set_choice(fd_form_document->choice_spacing, 3);
1733                 break;
1734         }
1735         case Spacing::Other:
1736         {
1737                 fl_set_choice(fd_form_document->choice_spacing, 4);
1738                 //char sval[20];
1739                 //sprintf(sval, "%g", params->spacing.getValue()); 
1740 #ifdef HAVE_SSTREAM
1741                 std::ostringstream sval;
1742                 sval << params->spacing.getValue(); // setw?
1743                 fl_set_input(fd_form_document->input_spacing,
1744                              sval.str().c_str());
1745 #else
1746                 char tval[20];
1747                 ostrstream sval(tval, 20);
1748                 sval << params->spacing.getValue() << '\0'; // setw?
1749                 fl_set_input(fd_form_document->input_spacing, sval.str());
1750 #endif
1751                 break;
1752         }
1753         }
1754
1755
1756         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
1757                              params->secnumdepth);
1758         fl_set_counter_value(fd_form_document->slider_tocdepth, 
1759                              params->tocdepth);
1760         if (!params->float_placement.empty()) { // buffer local (Lgb)
1761                 fl_set_input(fd_form_document->input_float_placement,
1762                              params->float_placement.c_str());
1763         } else {
1764                 fl_set_input(fd_form_document->input_float_placement, "");
1765         }
1766         if (!params->options.empty())
1767                 fl_set_input(fd_form_document->input_extra,
1768                              params->options.c_str());
1769         else
1770                 fl_set_input(fd_form_document->input_extra, "");
1771
1772         if (current_view->buffer()->isSGML()) {
1773                 // bullets not used in SGML derived documents
1774                 fl_deactivate_object(fd_form_document->button_bullets);
1775                 fl_set_object_lcol(fd_form_document->button_bullets,
1776                                    FL_INACTIVE);
1777         } else {
1778                 fl_activate_object(fd_form_document->button_bullets);
1779                 fl_set_object_lcol(fd_form_document->button_bullets,
1780                                    FL_BLACK);
1781         }
1782
1783         if (current_view->buffer()->isReadonly()) {
1784                 DisableDocumentLayout();
1785         } else {
1786                 EnableDocumentLayout();
1787         }
1788
1789         return true;
1790 }
1791
1792
1793 void MenuLayoutDocument()
1794 {
1795         if (UpdateLayoutDocument()) {
1796                 if (fd_form_document->form_document->visible) {
1797                         fl_raise_form(fd_form_document->form_document);
1798                 } else {
1799                         fl_show_form(fd_form_document->form_document,
1800                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1801                                      _("Document Layout"));
1802                 }
1803         }
1804 }
1805
1806
1807 bool UpdateLayoutQuotes()
1808 {
1809         bool update = true;
1810         if (!current_view->available()
1811             || current_view->buffer()->isReadonly())
1812                 update = false;
1813         
1814         if (update) {
1815                 fl_set_choice(fd_form_quotes->choice_quotes_language,
1816                               current_view->buffer()->params.quotes_language + 1);
1817                 fl_set_button(fd_form_quotes->radio_single, 0);
1818                 fl_set_button(fd_form_quotes->radio_double, 0);
1819         
1820                 if (current_view->buffer()->params.quotes_times == InsetQuotes::SingleQ)
1821                         fl_set_button(fd_form_quotes->radio_single, 1);
1822                 else
1823                         fl_set_button(fd_form_quotes->radio_double, 1);
1824         } else if (fd_form_quotes->form_quotes->visible) {
1825                 fl_hide_form(fd_form_quotes->form_quotes);
1826         }
1827         return update;
1828 }
1829
1830
1831 void MenuLayoutQuotes()
1832 {
1833         if (UpdateLayoutQuotes()) {
1834                 if (fd_form_quotes->form_quotes->visible) {
1835                         fl_raise_form(fd_form_quotes->form_quotes);
1836                 } else {
1837                         fl_show_form(fd_form_quotes->form_quotes,
1838                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1839                                      _("Quotes"));
1840                 }
1841         }
1842 }
1843
1844
1845 bool UpdateLayoutPreamble()
1846 {
1847         bool update = true;
1848         if (!current_view->available())
1849                 update = false;
1850
1851         if (update) {
1852                 fl_set_input(fd_form_preamble->input_preamble,
1853                              current_view->buffer()->params.preamble.c_str());
1854
1855                 if (current_view->buffer()->isReadonly()) {
1856                         fl_deactivate_object(fd_form_preamble->input_preamble);
1857                         fl_deactivate_object(fd_form_preamble->button_ok);
1858                         fl_deactivate_object(fd_form_preamble->button_apply);
1859                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_INACTIVE);
1860                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_INACTIVE);
1861                 }
1862                 else {
1863                         fl_activate_object(fd_form_preamble->input_preamble);
1864                         fl_activate_object(fd_form_preamble->button_ok);
1865                         fl_activate_object(fd_form_preamble->button_apply);
1866                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_BLACK);
1867                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_BLACK);
1868                 }
1869         } else if (fd_form_preamble->form_preamble->visible) {
1870                 fl_hide_form(fd_form_preamble->form_preamble);
1871         }
1872         return update;
1873 }
1874
1875
1876 void MenuLayoutPreamble()
1877 {
1878         static int ow = -1, oh;
1879
1880         if (UpdateLayoutPreamble()) {
1881                 if (fd_form_preamble->form_preamble->visible) {
1882                         fl_raise_form(fd_form_preamble->form_preamble);
1883                 } else {
1884                         fl_show_form(fd_form_preamble->form_preamble,
1885                                      FL_PLACE_MOUSE | FL_FREE_SIZE,
1886                                      FL_FULLBORDER,
1887                                      _("LaTeX Preamble"));
1888                         if (ow < 0) {
1889                                 ow = fd_form_preamble->form_preamble->w;
1890                                 oh = fd_form_preamble->form_preamble->h;
1891                         }
1892                         fl_set_form_minsize(fd_form_preamble->form_preamble,
1893                                             ow, oh);
1894                 }
1895         }
1896 }
1897
1898
1899 void MenuLayoutSave()
1900 {
1901         if (!current_view->available())
1902                 return;
1903
1904         if (AskQuestion(_("Do you want to save the current settings"),
1905                         _("for Character, Document, Paper and Quotes"),
1906                         _("as default for new documents?")))
1907                 current_view->buffer()->saveParamsAsDefaults();
1908 }
1909
1910
1911 // This is both GUI and LyXFont dependent. Don't know where to put it. (Asger)
1912 // Well, it's mostly GUI dependent, so I guess it will stay here. (Asger)
1913 LyXFont UserFreeFont()
1914 {
1915         LyXFont font(LyXFont::ALL_IGNORE);
1916
1917         int pos = fl_get_choice(fd_form_character->choice_family);
1918         switch(pos) {
1919         case 1: font.setFamily(LyXFont::IGNORE_FAMILY); break;
1920         case 2: font.setFamily(LyXFont::ROMAN_FAMILY); break;
1921         case 3: font.setFamily(LyXFont::SANS_FAMILY); break;
1922         case 4: font.setFamily(LyXFont::TYPEWRITER_FAMILY); break;
1923         case 5: font.setFamily(LyXFont::INHERIT_FAMILY); break;
1924         }
1925
1926         pos = fl_get_choice(fd_form_character->choice_series);
1927         switch(pos) {
1928         case 1: font.setSeries(LyXFont::IGNORE_SERIES); break;
1929         case 2: font.setSeries(LyXFont::MEDIUM_SERIES); break;
1930         case 3: font.setSeries(LyXFont::BOLD_SERIES); break;
1931         case 4: font.setSeries(LyXFont::INHERIT_SERIES); break;
1932         }
1933
1934         pos = fl_get_choice(fd_form_character->choice_shape);
1935         switch(pos) {
1936         case 1: font.setShape(LyXFont::IGNORE_SHAPE); break;
1937         case 2: font.setShape(LyXFont::UP_SHAPE); break;
1938         case 3: font.setShape(LyXFont::ITALIC_SHAPE); break;
1939         case 4: font.setShape(LyXFont::SLANTED_SHAPE); break;
1940         case 5: font.setShape(LyXFont::SMALLCAPS_SHAPE); break;
1941         case 6: font.setShape(LyXFont::INHERIT_SHAPE); break;
1942         }
1943
1944         pos = fl_get_choice(fd_form_character->choice_size);
1945         switch(pos) {
1946         case 1: font.setSize(LyXFont::IGNORE_SIZE); break;
1947         case 2: font.setSize(LyXFont::SIZE_TINY); break;
1948         case 3: font.setSize(LyXFont::SIZE_SCRIPT); break;
1949         case 4: font.setSize(LyXFont::SIZE_FOOTNOTE); break;
1950         case 5: font.setSize(LyXFont::SIZE_SMALL); break;
1951         case 6: font.setSize(LyXFont::SIZE_NORMAL); break;
1952         case 7: font.setSize(LyXFont::SIZE_LARGE); break;
1953         case 8: font.setSize(LyXFont::SIZE_LARGER); break;
1954         case 9: font.setSize(LyXFont::SIZE_LARGEST); break;
1955         case 10: font.setSize(LyXFont::SIZE_HUGE); break;
1956         case 11: font.setSize(LyXFont::SIZE_HUGER); break;
1957         case 12: font.setSize(LyXFont::INCREASE_SIZE); break;
1958         case 13: font.setSize(LyXFont::DECREASE_SIZE); break;
1959         case 14: font.setSize(LyXFont::INHERIT_SIZE); break;
1960         }
1961
1962         pos = fl_get_choice(fd_form_character->choice_bar);
1963         switch(pos) {
1964         case 1: font.setEmph(LyXFont::IGNORE);
1965                 font.setUnderbar(LyXFont::IGNORE);
1966                 font.setNoun(LyXFont::IGNORE);
1967                 font.setLatex(LyXFont::IGNORE);
1968                 break;
1969         case 2: font.setEmph(LyXFont::TOGGLE); break;
1970         case 3: font.setUnderbar(LyXFont::TOGGLE); break;
1971         case 4: font.setNoun(LyXFont::TOGGLE); break;
1972         case 5: font.setLatex(LyXFont::TOGGLE); break;
1973         case 6: font.setEmph(LyXFont::INHERIT);
1974                 font.setUnderbar(LyXFont::INHERIT);
1975                 font.setNoun(LyXFont::INHERIT);
1976                 font.setLatex(LyXFont::INHERIT);
1977                 break;
1978         }
1979
1980         pos = fl_get_choice(fd_form_character->choice_color);
1981         switch(pos) {
1982         case 1: font.setColor(LColor::ignore); break;
1983         case 2: font.setColor(LColor::none); break;
1984         case 3: font.setColor(LColor::black); break;
1985         case 4: font.setColor(LColor::white); break;
1986         case 5: font.setColor(LColor::red); break;
1987         case 6: font.setColor(LColor::green); break;
1988         case 7: font.setColor(LColor::blue); break;
1989         case 8: font.setColor(LColor::cyan); break;
1990         case 9: font.setColor(LColor::magenta); break;
1991         case 10: font.setColor(LColor::yellow); break;
1992         case 11: font.setColor(LColor::inherit); break;
1993         }
1994
1995         string language = combo_language2->getline();
1996         Languages::iterator lit = languages.find(language);
1997         if (lit != languages.end()) 
1998                 font.setLanguage(&(*lit).second);
1999         else
2000                 font.setLanguage(ignore_language);
2001
2002
2003         return font; 
2004 }
2005
2006
2007
2008
2009 /* callbacks for form form_title */
2010 extern "C" void TimerCB(FL_OBJECT *, long)
2011 {
2012         // only if the form still exists
2013         if (lyxrc.show_banner && fd_form_title->form_title != 0) {
2014                 if (fd_form_title->form_title->visible) {
2015                         fl_hide_form(fd_form_title->form_title);
2016                 }
2017                 fl_free_form(fd_form_title->form_title);
2018                 fd_form_title->form_title = 0;
2019         }
2020 }
2021
2022
2023 /* callbacks for form form_paragraph */
2024
2025 extern "C" void ParagraphVSpaceCB(FL_OBJECT * obj, long )
2026 {
2027         // "Synchronize" the choices and input fields, making it
2028         // impossible to commit senseless data.
2029
2030         FD_form_paragraph const * fp = fd_form_paragraph;
2031
2032         if (obj == fp->choice_space_above) {
2033                 if (fl_get_choice (fp->choice_space_above) != 7) {
2034                         fl_set_input (fp->input_space_above, "");
2035                         ActivateParagraphButtons();
2036                 }
2037         } else if (obj == fp->choice_space_below) {
2038                 if (fl_get_choice (fp->choice_space_below) != 7) {
2039                         fl_set_input (fp->input_space_below, "");
2040                         ActivateParagraphButtons();
2041                 }
2042         } else if (obj == fp->input_space_above) {
2043                 string input = fl_get_input (fp->input_space_above);
2044
2045                 if (input.empty()) {
2046                         fl_set_choice (fp->choice_space_above, 1);
2047                         ActivateParagraphButtons();
2048                 }
2049                 else if (isValidGlueLength (input)) {
2050                         fl_set_choice (fp->choice_space_above, 7);
2051                         ActivateParagraphButtons();
2052                 }
2053                 else {
2054                         fl_set_choice (fp->choice_space_above, 7);
2055                         DeactivateParagraphButtons();
2056                 }
2057         } else if (obj == fp->input_space_below) {
2058                 string input = fl_get_input (fp->input_space_below);
2059
2060                 if (input.empty()) {
2061                         fl_set_choice (fp->choice_space_below, 1);
2062                         ActivateParagraphButtons();
2063                 }
2064                 else if (isValidGlueLength (input)) {
2065                         fl_set_choice (fp->choice_space_below, 7);
2066                         ActivateParagraphButtons();
2067                 }
2068                 else {
2069                         fl_set_choice (fp->choice_space_below, 7);
2070                         DeactivateParagraphButtons();
2071                 }
2072         }
2073 }
2074
2075
2076 extern "C" void ParagraphApplyCB(FL_OBJECT *, long)
2077 {
2078         if (!current_view->available())
2079                 return;
2080         
2081         VSpace space_top, space_bottom;
2082         LyXAlignment align;
2083         string labelwidthstring;
2084         bool noindent;
2085
2086         // If a vspace kind is "Length" but there's no text in
2087         // the input field, reset the kind to "None". 
2088         if (fl_get_choice (fd_form_paragraph->choice_space_above) == 7
2089             && !*(fl_get_input (fd_form_paragraph->input_space_above))) {
2090                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
2091         }
2092         if (fl_get_choice (fd_form_paragraph->choice_space_below) == 7
2093             && !*(fl_get_input (fd_form_paragraph->input_space_below))) {
2094                 fl_set_choice (fd_form_paragraph->choice_space_below, 1);
2095         }
2096    
2097         bool line_top = fl_get_button(fd_form_paragraph->check_lines_top);
2098         bool line_bottom = fl_get_button(fd_form_paragraph->check_lines_bottom);
2099         bool pagebreak_top = fl_get_button(fd_form_paragraph->check_pagebreaks_top);
2100         bool pagebreak_bottom = fl_get_button(fd_form_paragraph->check_pagebreaks_bottom);
2101         switch (fl_get_choice (fd_form_paragraph->choice_space_above)) {
2102         case 1: space_top = VSpace(VSpace::NONE); break;
2103         case 2: space_top = VSpace(VSpace::DEFSKIP); break;
2104         case 3: space_top = VSpace(VSpace::SMALLSKIP); break;
2105         case 4: space_top = VSpace(VSpace::MEDSKIP); break;
2106         case 5: space_top = VSpace(VSpace::BIGSKIP); break;
2107         case 6: space_top = VSpace(VSpace::VFILL); break;
2108         case 7: space_top = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_above))); break;
2109         }
2110         if (fl_get_button (fd_form_paragraph->check_space_above))
2111                 space_top.setKeep (true);
2112         switch (fl_get_choice (fd_form_paragraph->choice_space_below)) {
2113         case 1: space_bottom = VSpace(VSpace::NONE); break;
2114         case 2: space_bottom = VSpace(VSpace::DEFSKIP); break;
2115         case 3: space_bottom = VSpace(VSpace::SMALLSKIP); break;
2116         case 4: space_bottom = VSpace(VSpace::MEDSKIP); break;
2117         case 5: space_bottom = VSpace(VSpace::BIGSKIP); break;
2118         case 6: space_bottom = VSpace(VSpace::VFILL); break;
2119         case 7: space_bottom = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_below))); break;
2120         }
2121         if (fl_get_button (fd_form_paragraph->check_space_below))
2122                 space_bottom.setKeep (true);
2123
2124         if (fl_get_button(fd_form_paragraph->radio_align_left))
2125                 align = LYX_ALIGN_LEFT;
2126         else if (fl_get_button(fd_form_paragraph->radio_align_right))
2127                 align = LYX_ALIGN_RIGHT;
2128         else if (fl_get_button(fd_form_paragraph->radio_align_center))
2129                 align = LYX_ALIGN_CENTER;
2130         else 
2131                 align = LYX_ALIGN_BLOCK;
2132    
2133         labelwidthstring = fl_get_input(fd_form_paragraph->input_labelwidth);
2134         noindent = fl_get_button(fd_form_paragraph->check_noindent);
2135
2136         current_view->text->SetParagraph(current_view,
2137                                          line_top,
2138                                          line_bottom,
2139                                          pagebreak_top,
2140                                          pagebreak_bottom,
2141                                          space_top,
2142                                          space_bottom,
2143                                          align, 
2144                                          labelwidthstring,
2145                                          noindent);
2146         current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2147         current_view->owner()->getMiniBuffer()->Set(_("Paragraph layout set"));
2148 }
2149
2150
2151 extern "C" void ParagraphCancelCB(FL_OBJECT *, long)
2152 {
2153         fl_hide_form(fd_form_paragraph->form_paragraph);
2154 }
2155
2156
2157 extern "C" void ParagraphOKCB(FL_OBJECT *ob, long data)
2158 {
2159         ParagraphApplyCB(ob, data);
2160         ParagraphCancelCB(ob, data);
2161 }
2162
2163
2164 /* callbacks for form form_character */
2165
2166 extern "C" void CharacterApplyCB(FL_OBJECT *, long)
2167 {
2168         // we set toggleall locally here, since it should be true for
2169         // all other uses of ToggleAndShow() (JMarc)
2170         toggleall = fl_get_button(fd_form_character->check_toggle_all);
2171         ToggleAndShow(current_view, UserFreeFont());
2172         current_view->setState();
2173         toggleall = true;
2174 }
2175
2176
2177 extern "C" void CharacterCloseCB(FL_OBJECT *, long)
2178 {
2179         fl_hide_form(fd_form_character->form_character);
2180 }
2181
2182
2183 extern "C" void CharacterOKCB(FL_OBJECT *ob, long data)
2184 {
2185         CharacterApplyCB(ob, data);
2186         CharacterCloseCB(ob, data);
2187 }
2188
2189
2190 /* callbacks for form form_document */
2191
2192 void UpdateDocumentButtons(BufferParams const & params) 
2193 {
2194         fl_set_choice(fd_form_document->choice_pagestyle, 1);
2195
2196         switch (params.sides) {
2197         case LyXTextClass::OneSide:
2198                 fl_set_button(fd_form_document->radio_sides_one, 1);
2199                 break;
2200         case LyXTextClass::TwoSides:
2201                 fl_set_button(fd_form_document->radio_sides_two, 1);
2202                 break;
2203         }
2204    
2205         if (params.columns == 2)
2206                 fl_set_button(fd_form_document->radio_columns_two, 1);
2207         else
2208                 fl_set_button(fd_form_document->radio_columns_one, 1);
2209         
2210         fl_set_input(fd_form_document->input_extra, params.options.c_str());
2211         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
2212                              params.secnumdepth);
2213         fl_set_counter_value(fd_form_document->slider_tocdepth, 
2214                              params.tocdepth);
2215         
2216 }
2217
2218 extern "C" void ChoiceClassCB(FL_OBJECT * ob, long)
2219 {
2220         ProhibitInput(current_view);
2221         if (textclasslist.Load(fl_get_choice(ob)-1)) {
2222                 if (AskQuestion(_("Should I set some parameters to"),
2223                                 fl_get_choice_text(ob),
2224                                 _("the defaults of this document class?"))) {
2225                         BufferParams params = BufferParams();
2226                         params.textclass = fl_get_choice(ob)-1;
2227                         params.useClassDefaults();
2228                         UpdateLayoutDocument(&params);
2229                         UpdateDocumentButtons(params);
2230                 }
2231         } else {
2232                 // unable to load new style
2233                 WriteAlert(_("Conversion Errors!"),
2234                            _("Unable to switch to new document class."),
2235                            _("Reverting to original document class."));
2236                 fl_set_choice(fd_form_document->choice_class, 
2237                               current_view->buffer()->params.textclass + 1);
2238         }
2239         AllowInput(current_view);
2240 }
2241
2242
2243 extern "C" void DocumentDefskipCB(FL_OBJECT * obj, long)
2244 {
2245         // "Synchronize" the choice and the input field, so that it
2246         // is impossible to commit senseless data.
2247         FD_form_document const * fd = fd_form_document;
2248
2249         if (obj == fd->choice_default_skip) {
2250                 if (fl_get_choice (fd->choice_default_skip) != 4) {
2251                         fl_set_input (fd->input_default_skip, "");
2252                         ActivateDocumentButtons();
2253                 }
2254         } else if (obj == fd->input_default_skip) {
2255
2256                 char const * input = fl_get_input (fd->input_default_skip);
2257
2258                 if (!*input) {
2259                         fl_set_choice (fd->choice_default_skip, 2);
2260                         ActivateDocumentButtons();
2261                 } else if (isValidGlueLength (input)) {
2262                         fl_set_choice (fd->choice_default_skip, 4);
2263                         ActivateDocumentButtons();
2264                 } else {
2265                         fl_set_choice (fd->choice_default_skip, 4);
2266                         DeactivateDocumentButtons();
2267                 }
2268         }
2269 }
2270
2271
2272 extern "C" void DocumentSpacingCB(FL_OBJECT * obj, long)
2273 {
2274         // "Synchronize" the choice and the input field, so that it
2275         // is impossible to commit senseless data.
2276         FD_form_document const * fd = fd_form_document;
2277
2278         if (obj == fd->choice_spacing
2279             && fl_get_choice (fd->choice_spacing) != 4) {
2280                 fl_set_input(fd->input_spacing, "");
2281         } else if (obj == fd->input_spacing) {
2282
2283                 const char* input = fl_get_input (fd->input_spacing);
2284
2285                 if (!*input) {
2286                         fl_set_choice (fd->choice_spacing, 1);
2287                 } else {
2288                         fl_set_choice (fd->choice_spacing, 4);
2289                 }
2290         }
2291 }
2292
2293
2294 extern "C" void DocumentApplyCB(FL_OBJECT *, long)
2295 {
2296         bool redo = false;
2297         BufferParams * params = &(current_view->buffer()->params);
2298
2299         Language const * old_language = params->language_info;
2300         params->language = combo_language->getline();
2301         Languages::iterator lit = languages.find(params->language);
2302
2303         Language const * new_language;
2304         if (lit != languages.end()) 
2305                 new_language = &(*lit).second;
2306         else
2307                 new_language = default_language;
2308
2309         if (current_view->available()) {
2310                 if (old_language != new_language
2311                     && old_language->RightToLeft() == new_language->RightToLeft()
2312                     && !current_view->buffer()->isMultiLingual())
2313                         current_view->buffer()->ChangeLanguage(old_language,
2314                                                                new_language);
2315                 if (old_language != new_language) {
2316                                 //current_view->buffer()->redraw();
2317                         redo = true;
2318                 }
2319         }
2320         params->language_info = new_language;
2321
2322         // If default skip is a "Length" but there's no text in the
2323         // input field, reset the kind to "Medskip", which is the default.
2324         if (fl_get_choice (fd_form_document->choice_default_skip) == 4
2325             && !*(fl_get_input (fd_form_document->input_default_skip))) {
2326                 fl_set_choice (fd_form_document->choice_default_skip, 2);
2327         }
2328
2329         /* this shouldn't be done automatically IMO. For example I write german
2330          * documents with an american keyboard very often. Matthias */
2331    
2332         /* ChangeKeymap(buffer->parameters.language, TRUE, false,
2333            fl_get_choice(fd_form_document->choice_language)); */
2334         params->fonts = 
2335                 fl_get_choice_text(fd_form_document->choice_fonts);
2336         params->inputenc = 
2337                 fl_get_choice_text(fd_form_document->choice_inputenc);
2338         params->fontsize = 
2339                 fl_get_choice_text(fd_form_document->choice_fontsize);
2340         params->pagestyle = 
2341                 fl_get_choice_text(fd_form_document->choice_pagestyle);
2342         params->graphicsDriver = 
2343                 fl_get_choice_text(fd_form_document->choice_postscript_driver);
2344         params->use_amsmath = 
2345                 fl_get_button(fd_form_document->check_use_amsmath);
2346    
2347         if (!current_view->available())
2348                 return;
2349
2350         current_view->text->SetCursor(current_view,
2351                                       current_view->text->cursor.par(),
2352                                       current_view->text->cursor.pos());
2353         current_view->setState();
2354
2355         LyXTextClassList::ClassList::size_type new_class =
2356                 fl_get_choice(fd_form_document->choice_class) - 1;
2357
2358         if (params->textclass != new_class) {
2359                 // try to load new_class
2360                 if (textclasslist.Load(new_class)) {
2361                         // successfully loaded
2362                         redo = true;
2363                         current_view->owner()->getMiniBuffer()->
2364                                 Set(_("Converting document to new document class..."));
2365                         CutAndPaste cap;
2366                         int ret = cap.SwitchLayoutsBetweenClasses(
2367                                 current_view->buffer()->params.textclass,
2368                                 new_class,
2369                                 current_view->buffer()->paragraph);
2370
2371                         if (ret) {
2372                                 string s;
2373                                 if (ret == 1)
2374                                         s = _("One paragraph couldn't be converted");
2375                                 else {
2376                                         s += tostr(ret);
2377                                         s += _(" paragraphs couldn't be converted");
2378                                 }
2379                                 WriteAlert(_("Conversion Errors!"), s,
2380                                            _("into chosen document class"));
2381                         }
2382
2383                         params->textclass = new_class;
2384                 } else {
2385                         // problem changing class -- warn user and retain old style
2386                         WriteAlert(_("Conversion Errors!"),
2387                                    _("Unable to switch to new document class."),
2388                                    _("Reverting to original document class."));
2389                         fl_set_choice(fd_form_document->choice_class, params->textclass + 1);
2390                 }
2391         }
2392
2393         char tmpsep = params->paragraph_separation;
2394         if (fl_get_button(fd_form_document->radio_indent))
2395                 params->paragraph_separation = BufferParams::PARSEP_INDENT;
2396         else
2397                 params->paragraph_separation = BufferParams::PARSEP_SKIP;
2398         if (tmpsep != params->paragraph_separation)
2399                 redo = true;
2400    
2401         VSpace tmpdefskip = params->getDefSkip();
2402         switch (fl_get_choice (fd_form_document->choice_default_skip)) {
2403         case 1: params->setDefSkip(VSpace(VSpace::SMALLSKIP)); break;
2404         case 2: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2405         case 3: params->setDefSkip(VSpace(VSpace::BIGSKIP)); break;
2406         case 4: params->setDefSkip( 
2407                 VSpace (LyXGlueLength (fl_get_input 
2408                                        (fd_form_document->input_default_skip))));
2409         break;
2410         // DocumentDefskipCB assures that this never happens
2411         default: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2412         }
2413         if (!(tmpdefskip == params->getDefSkip()))
2414                 redo = true;
2415
2416         if (fl_get_button(fd_form_document->radio_columns_two))
2417                 params->columns = 2;
2418         else
2419                 params->columns = 1;
2420         if (fl_get_button(fd_form_document->radio_sides_two))
2421                 params->sides = LyXTextClass::TwoSides;
2422         else
2423                 params->sides = LyXTextClass::OneSide;
2424
2425         Spacing tmpSpacing = params->spacing;
2426         switch(fl_get_choice(fd_form_document->choice_spacing)) {
2427         case 1:
2428                 lyxerr.debug() << "Spacing: SINGLE" << endl;
2429                 params->spacing.set(Spacing::Single);
2430                 break;
2431         case 2:
2432                 lyxerr.debug() << "Spacing: ONEHALF" << endl;
2433                 params->spacing.set(Spacing::Onehalf);
2434                 break;
2435         case 3:
2436                 lyxerr.debug() << "Spacing: DOUBLE" << endl;
2437                 params->spacing.set(Spacing::Double);
2438                 break;
2439         case 4:
2440                 lyxerr.debug() << "Spacing: OTHER" << endl;
2441                 params->spacing.set(Spacing::Other, 
2442                                     fl_get_input(fd_form_document->input_spacing));
2443                 break;
2444         }
2445         if (tmpSpacing != params->spacing)
2446                 redo = true;
2447         
2448         signed char tmpchar =  
2449                 static_cast<signed char>(fl_get_counter_value(fd_form_document->slider_secnumdepth));
2450         if (params->secnumdepth != tmpchar)
2451                 redo = true;
2452         params->secnumdepth = tmpchar;
2453    
2454         params->tocdepth =  
2455                 static_cast<int>(fl_get_counter_value(fd_form_document->slider_tocdepth));
2456
2457         params->float_placement = 
2458                 fl_get_input(fd_form_document->input_float_placement);
2459
2460         // More checking should be done to ensure the string doesn't have
2461         // spaces or illegal placement characters in it. (thornley)
2462
2463         if (redo)
2464                 current_view->redoCurrentBuffer();
2465    
2466         current_view->owner()->getMiniBuffer()->Set(_("Document layout set"));
2467         current_view->buffer()->markDirty();
2468         
2469         params->options = 
2470                 fl_get_input(fd_form_document->input_extra);
2471 }
2472
2473
2474 extern "C" void DocumentCancelCB(FL_OBJECT *, long)
2475 {
2476         fl_hide_form(fd_form_document->form_document);
2477 }
2478
2479
2480 extern "C" void DocumentOKCB(FL_OBJECT * ob, long data)
2481 {
2482         DocumentCancelCB(ob, data);
2483         DocumentApplyCB(ob, data);
2484 }
2485
2486
2487 extern "C" void DocumentBulletsCB(FL_OBJECT *, long)
2488 {
2489         bulletForm();
2490         // bullet callbacks etc. in bullet_panel.C -- ARRae
2491 }
2492
2493
2494 /* callbacks for form form_quotes */
2495
2496 extern "C" void QuotesApplyCB(FL_OBJECT *, long)
2497 {
2498         if (!current_view->available())
2499                 return;
2500         
2501         current_view->owner()->getMiniBuffer()->Set(_("Quotes type set"));
2502         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
2503         switch(fl_get_choice(fd_form_quotes->choice_quotes_language) - 1) {
2504         case 0:
2505                 lga = InsetQuotes::EnglishQ;
2506                 break;
2507         case 1:
2508                 lga = InsetQuotes::SwedishQ;
2509                 break;
2510         case 2:
2511                 lga = InsetQuotes::GermanQ;
2512                 break;
2513         case 3:
2514                 lga = InsetQuotes::PolishQ;
2515                 break;
2516         case 4:
2517                 lga = InsetQuotes::FrenchQ;
2518                 break;
2519         case 5:
2520                 lga = InsetQuotes::DanishQ;
2521                 break;
2522         }
2523         current_view->buffer()->params.quotes_language = lga;
2524         if (fl_get_button(fd_form_quotes->radio_single))   
2525                 current_view->buffer()->
2526                         params.quotes_times = InsetQuotes::SingleQ;
2527         else
2528                 current_view->buffer()->
2529                         params.quotes_times = InsetQuotes::DoubleQ;
2530 }
2531
2532
2533 extern "C" void QuotesCancelCB(FL_OBJECT *, long)
2534 {
2535         fl_hide_form(fd_form_quotes->form_quotes);
2536 }
2537
2538
2539 extern "C" void QuotesOKCB(FL_OBJECT * ob, long data)
2540 {
2541         QuotesApplyCB(ob, data);
2542         QuotesCancelCB(ob, data);
2543 }
2544
2545
2546
2547 /* callbacks for form form_preamble */
2548
2549 extern "C" void PreambleCancelCB(FL_OBJECT *, long)
2550 {
2551         fl_hide_form(fd_form_preamble->form_preamble);
2552 }
2553
2554
2555 extern "C" void PreambleApplyCB(FL_OBJECT *, long)
2556 {
2557         if (!current_view->available())
2558                 return;
2559         
2560         current_view->buffer()->params.preamble = 
2561                 fl_get_input(fd_form_preamble->input_preamble);
2562         current_view->buffer()->markDirty();
2563         current_view->owner()->getMiniBuffer()->Set(_("LaTeX preamble set"));
2564 }
2565
2566    
2567 extern "C" void PreambleOKCB(FL_OBJECT * ob, long data)
2568 {
2569         PreambleApplyCB(ob, data);
2570         PreambleCancelCB(ob, data);
2571 }
2572
2573
2574 /* callbacks for form form_table */
2575
2576 extern "C" void TableApplyCB(FL_OBJECT *, long)
2577 {
2578         if (!current_view->available())
2579                 return;
2580    
2581         // check for tables in tables
2582         if (current_view->text->cursor.par()->table){
2583                 WriteAlert(_("Impossible Operation!"),
2584                            _("Cannot insert table in table."),
2585                            _("Sorry."));
2586                 return;
2587         }
2588  
2589         current_view->owner()->getMiniBuffer()->Set(_("Inserting table..."));
2590
2591         int ysize = int(fl_get_slider_value(fd_form_table->slider_columns) + 0.5);
2592         int xsize = int(fl_get_slider_value(fd_form_table->slider_rows) + 0.5);
2593    
2594    
2595         current_view->hideCursor();
2596         current_view->beforeChange();
2597         current_view->update(BufferView::SELECT|BufferView::FITCUR);
2598    
2599         current_view->text->SetCursorParUndo(current_view->buffer()); 
2600         current_view->text->FreezeUndo();
2601
2602         current_view->text->BreakParagraph(current_view);
2603         current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2604    
2605         if (current_view->text->cursor.par()->Last()) {
2606                 current_view->text->CursorLeft(current_view);
2607       
2608                 current_view->text->BreakParagraph(current_view);
2609                 current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2610         }
2611
2612         current_view->text->current_font.setLatex(LyXFont::OFF);
2613         //if (!fl_get_button(fd_form_table->check_latex)){
2614         // insert the new wysiwy table
2615         current_view->text->SetLayout(current_view, 0); // standard layout
2616         if (current_view->text->cursor.par()->footnoteflag == 
2617             LyXParagraph::NO_FOOTNOTE) {
2618                 current_view->text
2619                         ->SetParagraph(current_view, 0, 0,
2620                                        0, 0,
2621                                        VSpace (0.3 * current_view->buffer()->
2622                                                params.spacing.getValue(),
2623                                                LyXLength::CM),
2624                                        VSpace (0.3 * current_view->buffer()->
2625                                                params.spacing.getValue(),
2626                                                LyXLength::CM),
2627                                        LYX_ALIGN_CENTER,
2628                                        string(),
2629                                        0);
2630         } else {
2631                 current_view->text
2632                         ->SetParagraph(current_view, 0, 0,
2633                                        0, 0,
2634                                        VSpace(VSpace::NONE),
2635                                        VSpace(VSpace::NONE),
2636                                        LYX_ALIGN_CENTER, 
2637                                        string(),
2638                                        0);
2639         }
2640         
2641         current_view->text->cursor.par()->table =
2642                 new LyXTable(xsize, ysize);
2643
2644         Language const * lang = 
2645                 current_view->text->cursor.par()->getParLanguage(current_view->buffer()->params);
2646         LyXFont font(LyXFont::ALL_INHERIT, lang);
2647         for (int i = 0; i < xsize * ysize - 1; ++i) {
2648                 current_view->text->cursor.par()->InsertChar(0, LyXParagraph::META_NEWLINE);
2649                 current_view->text->cursor.par()->SetFont(0, font);
2650         }
2651         current_view->text->RedoParagraph(current_view);
2652    
2653         current_view->text->UnFreezeUndo();
2654      
2655         current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2656         current_view->owner()->getMiniBuffer()->Set(_("Table inserted"));
2657         current_view->setState();
2658 }
2659
2660
2661 extern "C" void TableCancelCB(FL_OBJECT *, long)
2662 {
2663         fl_hide_form(fd_form_table->form_table);
2664 }
2665
2666
2667 extern "C" void TableOKCB(FL_OBJECT * ob, long data)
2668 {
2669         TableApplyCB(ob, data);
2670         TableCancelCB(ob, data);
2671 }
2672
2673
2674 void Figure()
2675 {
2676         if (fd_form_figure->form_figure->visible) {
2677                 fl_raise_form(fd_form_figure->form_figure);
2678         } else {
2679                 fl_show_form(fd_form_figure->form_figure,
2680                              FL_PLACE_MOUSE, FL_FULLBORDER,
2681                              _("Insert Figure"));
2682         }
2683 }
2684
2685
2686 void Table()
2687 {
2688         if (fd_form_table->form_table->visible) {
2689                 fl_raise_form(fd_form_table->form_table);
2690         } else {
2691                 fl_show_form(fd_form_table->form_table,
2692                              FL_PLACE_MOUSE, FL_FULLBORDER,
2693                              _("Insert Table"));
2694         }
2695 }
2696
2697
2698 /* callbacks for form form_figure */
2699 extern "C" void FigureApplyCB(FL_OBJECT *, long)
2700 {
2701         if (!current_view->available())
2702                 return;
2703
2704         Buffer * buffer = current_view->buffer();
2705         if(buffer->isReadonly()) // paranoia
2706                 return;
2707         
2708         current_view->owner()->getMiniBuffer()->Set(_("Inserting figure..."));
2709         if (fl_get_button(fd_form_figure->radio_inline)
2710             || current_view->text->cursor.par()->table) {
2711                 InsetFig * new_inset = new InsetFig(100, 20, buffer);
2712                 current_view->insertInset(new_inset);
2713                 current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
2714                 new_inset->Edit(current_view, 0, 0, 0);
2715                 return;
2716         }
2717         
2718         current_view->hideCursor();
2719         current_view->update(BufferView::SELECT|BufferView::FITCUR);
2720         current_view->beforeChange();
2721       
2722         current_view->text->SetCursorParUndo(current_view->buffer()); 
2723         current_view->text->FreezeUndo();
2724
2725         current_view->text->BreakParagraph(current_view);
2726         current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2727       
2728         if (current_view->text->cursor.par()->Last()) {
2729                 current_view->text->CursorLeft(current_view);
2730          
2731                 current_view->text->BreakParagraph(current_view);
2732                 current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2733         }
2734
2735         // The standard layout should always be numer 0;
2736         current_view->text->SetLayout(current_view, 0);
2737         
2738         if (current_view->text->cursor.par()->footnoteflag == 
2739             LyXParagraph::NO_FOOTNOTE) {
2740                 current_view->text->
2741                         SetParagraph(current_view, 0, 0,
2742                                      0, 0,
2743                                      VSpace (0.3 * buffer->params.spacing.getValue(),
2744                                              LyXLength::CM),
2745                                      VSpace (0.3 *
2746                                              buffer->params.spacing.getValue(),
2747                                              LyXLength::CM),
2748                                      LYX_ALIGN_CENTER, string(), 0);
2749         } else {
2750                 current_view->text->SetParagraph(current_view, 0, 0,
2751                                                  0, 0,
2752                                                  VSpace(VSpace::NONE),
2753                                                  VSpace(VSpace::NONE),
2754                                                  LYX_ALIGN_CENTER, 
2755                                                  string(),
2756                                                  0);
2757         }
2758         
2759         current_view->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2760       
2761         Inset * new_inset = new InsetFig(100, 100, buffer);
2762         current_view->insertInset(new_inset);
2763         new_inset->Edit(current_view, 0, 0, 0);
2764         current_view->update(BufferView::SELECT|BufferView::FITCUR);
2765         current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
2766         current_view->text->UnFreezeUndo();
2767         current_view->setState();
2768 }
2769
2770
2771 extern "C" void FigureCancelCB(FL_OBJECT *, long)
2772 {
2773         fl_hide_form(fd_form_figure->form_figure);
2774 }
2775
2776
2777 extern "C" void FigureOKCB(FL_OBJECT * ob, long data)
2778 {
2779         FigureApplyCB(ob, data);
2780         FigureCancelCB(ob, data);
2781 }
2782
2783
2784 extern "C" void ScreenApplyCB(FL_OBJECT *, long)
2785 {
2786         lyxrc.roman_font_name = fl_get_input(fd_form_screen->input_roman);
2787         lyxrc.sans_font_name = fl_get_input(fd_form_screen->input_sans);
2788         lyxrc.typewriter_font_name = fl_get_input(fd_form_screen->input_typewriter);
2789         lyxrc.font_norm = fl_get_input(fd_form_screen->input_font_norm);
2790         lyxrc.zoom = atoi(fl_get_input(fd_form_screen->intinput_size));
2791         fontloader.update();
2792
2793         // Of course we should only to the resize and the textcahce.clear
2794         // if values really changed...but not very important right now. (Lgb)
2795         
2796         // All buffers will need resize
2797         bufferlist.resize();
2798         // We also need to empty the textcache so that
2799         // the buffer will be formatted correctly after
2800         // a zoom change.
2801         textcache.clear();
2802         
2803         current_view->owner()->getMiniBuffer()->Set(_("Screen options set"));
2804 }
2805
2806
2807 extern "C" void ScreenCancelCB(FL_OBJECT *, long)
2808 {
2809         fl_hide_form(fd_form_screen->form_screen);
2810 }
2811
2812
2813 extern "C" void ScreenOKCB(FL_OBJECT * ob, long data)
2814 {
2815         ScreenCancelCB(ob, data);
2816         ScreenApplyCB(ob, data);
2817 }
2818
2819
2820 void LaTeXOptions(BufferView * bv)
2821 {
2822         if (!bv->available())
2823                 return;
2824
2825         fl_set_button(fd_latex_options->accents,
2826                       int(bv->buffer()->params.allowAccents));
2827         
2828         if (fd_latex_options->LaTeXOptions->visible) {
2829                 fl_raise_form(fd_latex_options->LaTeXOptions);
2830         } else {
2831                 fl_show_form(fd_latex_options->LaTeXOptions,
2832                              FL_PLACE_MOUSE, FL_FULLBORDER,
2833                              _("LaTeX Options"));
2834         }
2835 }
2836
2837
2838 // This function runs "configure" and then rereads lyx.defaults to
2839 // reconfigure the automatic settings.
2840 void Reconfigure(BufferView * bv)
2841 {
2842         bv->owner()->getMiniBuffer()->Set(_("Running configure..."));
2843
2844         // Run configure in user lyx directory
2845         Path p(user_lyxdir);
2846         Systemcalls one(Systemcalls::System, 
2847                         AddName(system_lyxdir, "configure"));
2848         p.pop();
2849         bv->owner()->getMiniBuffer()->Set(_("Reloading configuration..."));
2850         lyxrc.read(LibFileSearch(string(), "lyxrc.defaults"));
2851         WriteAlert(_("The system has been reconfigured."), 
2852                    _("You need to restart LyX to make use of any"),
2853                    _("updated document class specifications."));
2854 }
2855
2856
2857 //
2858 // Table of Contents
2859 //
2860
2861 static vector<Buffer::TocItem> toclist;
2862
2863
2864 extern "C" void TocSelectCB(FL_OBJECT * ob, long)
2865 {
2866         if (!current_view->available())
2867                 return;
2868    
2869         TocUpdateCB(0, 0);
2870         unsigned int choice = fl_get_browser(ob);
2871         if (0 < choice && choice - 1 < toclist.size()) {
2872                 current_view->beforeChange();
2873                 current_view->text->SetCursor(current_view, toclist[choice-1].par, 0);
2874                 current_view->text->sel_cursor = 
2875                         current_view->text->cursor;
2876                 current_view->update(BufferView::SELECT|BufferView::FITCUR);
2877         } else {
2878                 WriteAlert(_("Error"), 
2879                            _("Couldn't find this label"), 
2880                            _("in current document."));
2881         }
2882 }
2883
2884
2885 extern "C" void TocCancelCB(FL_OBJECT *, long)
2886 {
2887         fl_hide_form(fd_form_toc->form_toc);
2888 }
2889
2890
2891 extern "C"
2892 void TocUpdateCB(FL_OBJECT *, long)
2893 {
2894         if (!current_view->available()) {
2895                 toclist.clear();
2896                 fl_clear_browser(fd_form_toc->browser_toc);
2897                 fl_add_browser_line(fd_form_toc->browser_toc,
2898                                     _("*** No Document ***"));
2899                 return;
2900         }
2901
2902         vector<vector<Buffer::TocItem> > tmp =
2903                 current_view->buffer()->getTocList();
2904         int type = fl_get_choice(fd_form_toc->toctype)-1;
2905         //if (toclist == tmp[type])
2906         //      return;
2907         if (toclist.size() == tmp[type].size()) {
2908                 // Check if all elements are the same.
2909                 unsigned int i = 0;
2910                 for (; i < toclist.size(); ++i) {
2911                         if (toclist[i] !=  tmp[type][i])
2912                                 break;
2913                 }
2914                 if (i >= toclist.size()) return;
2915         }
2916
2917         toclist = tmp[type];
2918
2919         static Buffer * buffer = 0;
2920         int topline = 0;
2921         int line = 0;
2922         if (buffer == current_view->buffer()) {
2923                 topline = fl_get_browser_topline(fd_form_toc->browser_toc);
2924                 line = fl_get_browser(fd_form_toc->browser_toc);
2925         } else
2926                 buffer = current_view->buffer();
2927
2928         fl_clear_browser(fd_form_toc->browser_toc);
2929         fl_hide_object(fd_form_toc->browser_toc);
2930
2931         for (vector<Buffer::TocItem>::const_iterator it = toclist.begin();
2932              it != toclist.end(); ++it)
2933                 fl_add_browser_line(fd_form_toc->browser_toc,
2934                                     (string(4*(*it).depth,' ')+
2935                                      (*it).str).c_str());
2936
2937         fl_set_browser_topline(fd_form_toc->browser_toc, topline);
2938         fl_select_browser_line(fd_form_toc->browser_toc, line);
2939         fl_show_object(fd_form_toc->browser_toc);
2940 }
2941
2942
2943 /* callbacks for form form_ref */
2944 extern "C" void RefSelectCB(FL_OBJECT *, long data)
2945 {
2946         if (!current_view->available())
2947                 return;
2948
2949         string s = 
2950                 fl_get_browser_line(fd_form_ref->browser_ref,
2951                                     fl_get_browser(fd_form_ref->browser_ref));
2952         string u = frontStrip(strip(fl_get_input(fd_form_ref->ref_name)));
2953
2954         if (s.empty())
2955                 return;
2956
2957         if (data == 5) {
2958                 current_view->owner()->getLyXFunc()->Dispatch(LFUN_REFGOTO, s.c_str());
2959                 if (!current_view->NoSavedPositions()) {
2960                         fl_activate_object(fd_form_ref->back);
2961                         fl_set_object_lcol(fd_form_ref->back, FL_BLACK);
2962                 }
2963                 return;
2964         } else if (data >= 6) {
2965                 current_view->owner()->getLyXFunc()->Dispatch(LFUN_REFBACK);
2966                 if (current_view->NoSavedPositions()) {
2967                         fl_deactivate_object(fd_form_ref->back);
2968                         fl_set_object_lcol(fd_form_ref->back, FL_INACTIVE);
2969                 }
2970                 return;
2971         }       
2972
2973         static string const commands[5]
2974                 = { "\\ref", "\\pageref", "\\vref", "\\vpageref",
2975                     "\\prettyref"};
2976         string t = commands[data];
2977
2978         if (current_view->buffer()->isSGML())
2979                 t += "[" + u + "]" + "{" + s + "}";
2980         else
2981                 t += "{" + s + "}";
2982
2983         Inset * new_inset = 
2984                 new InsetRef(t, current_view->buffer());
2985         current_view->insertInset(new_inset);
2986 }
2987
2988
2989 extern "C" void RefUpdateCB(FL_OBJECT *, long)
2990 {
2991         if (!current_view->available()) {
2992                 fl_clear_browser(fd_form_ref->browser_ref);
2993                 return;
2994         }
2995
2996         FL_OBJECT * brow = fd_form_ref->browser_ref;
2997
2998         // Get the current line, in order to restore it later
2999         char const * const btmp = fl_get_browser_line(brow,
3000                                                       fl_get_browser(brow));
3001         string currentstr = btmp ? btmp : "";
3002
3003         fl_clear_browser(brow);
3004         fl_hide_object(brow);
3005
3006         vector<string> refs = current_view->buffer()->getLabelList();
3007         if (fl_get_button(fd_form_ref->sort))
3008                 sort(refs.begin(),refs.end());
3009         for (vector<string>::const_iterator it = refs.begin();
3010              it != refs.end(); ++it)
3011                 fl_add_browser_line(brow, (*it).c_str());
3012
3013         int topline = 1;
3014         int total_lines = fl_get_browser_maxline(brow);
3015         for (int i = 1; i <= total_lines ; ++i) {
3016                 if (fl_get_browser_line(brow, i) == currentstr) {
3017                         topline = i;
3018                         break;
3019                 }
3020         }
3021         fl_set_browser_topline(brow, topline);
3022
3023         bool empty = refs.empty();
3024         bool sgml = current_view->buffer()->isSGML();
3025         bool readonly = current_view->buffer()->isReadonly();
3026
3027         if (current_view->NoSavedPositions()) {
3028                 fl_deactivate_object(fd_form_ref->back);
3029                 fl_set_object_lcol(fd_form_ref->back, FL_INACTIVE);
3030         } else {
3031                 fl_activate_object(fd_form_ref->back);
3032                 fl_set_object_lcol(fd_form_ref->back, FL_BLACK);
3033         }
3034
3035         if (empty) {
3036                 fl_add_browser_line(brow, 
3037                                     _("*** No labels found in document ***"));
3038                 fl_deactivate_object(brow);
3039                 fl_deactivate_object(fd_form_ref->gotoref);
3040                 fl_set_object_lcol(fd_form_ref->gotoref, FL_INACTIVE);
3041         } else {
3042                 fl_select_browser_line(brow, topline);
3043                 fl_activate_object(brow);
3044                 fl_activate_object(fd_form_ref->gotoref);
3045                 fl_set_object_lcol(fd_form_ref->gotoref, FL_BLACK);
3046         }
3047
3048         if (empty || readonly) {
3049                 fl_deactivate_object(fd_form_ref->ref);
3050                 fl_set_object_lcol(fd_form_ref->ref, FL_INACTIVE);
3051                 fl_deactivate_object(fd_form_ref->pageref);
3052                 fl_set_object_lcol(fd_form_ref->pageref, FL_INACTIVE);
3053         } else {
3054                 fl_activate_object(fd_form_ref->ref);
3055                 fl_set_object_lcol(fd_form_ref->ref, FL_BLACK);
3056                 fl_activate_object(fd_form_ref->pageref);
3057                 fl_set_object_lcol(fd_form_ref->pageref, FL_BLACK);
3058         }
3059         
3060         if (empty || readonly || sgml) {
3061                 fl_deactivate_object(fd_form_ref->vref);
3062                 fl_set_object_lcol(fd_form_ref->vref, FL_INACTIVE);
3063                 fl_deactivate_object(fd_form_ref->vpageref);
3064                 fl_set_object_lcol(fd_form_ref->vpageref, FL_INACTIVE);
3065                 fl_deactivate_object(fd_form_ref->prettyref);
3066                 fl_set_object_lcol(fd_form_ref->prettyref, FL_INACTIVE);
3067         } else {
3068                 fl_activate_object(fd_form_ref->vref);
3069                 fl_set_object_lcol(fd_form_ref->vref, FL_BLACK);
3070                 fl_activate_object(fd_form_ref->vpageref);
3071                 fl_set_object_lcol(fd_form_ref->vpageref, FL_BLACK);
3072                 fl_activate_object(fd_form_ref->prettyref);
3073                 fl_set_object_lcol(fd_form_ref->prettyref, FL_BLACK);
3074         }
3075
3076         if (sgml) {
3077                 fl_activate_object(fd_form_ref->ref_name);
3078                 fl_set_object_lcol(fd_form_ref->ref_name, FL_BLACK);
3079         } else {
3080                 fl_deactivate_object(fd_form_ref->ref_name);
3081                 fl_set_object_lcol(fd_form_ref->ref_name, FL_INACTIVE);
3082         }
3083
3084         fl_show_object(brow);
3085 }
3086
3087
3088 extern "C" void RefHideCB(FL_OBJECT *, long)
3089 {
3090         fl_hide_form(fd_form_ref->form_ref);
3091 }