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