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