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