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