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