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