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