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