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