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