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