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