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