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