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