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