]> git.lyx.org Git - lyx.git/blob - src/lyx_cb.C
Fix for dicument popup update bug; fix for purify ABR report.
[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         switch (params->sides) {
1888         case LyXTextClass::OneSide:
1889                 fl_set_button(fd_form_document->radio_sides_one, 1);
1890                 break;
1891         case LyXTextClass::TwoSides:
1892                 fl_set_button(fd_form_document->radio_sides_two, 1);
1893                 break;
1894         }
1895    
1896         fl_set_button(fd_form_document->radio_columns_one, 0);
1897         fl_set_button(fd_form_document->radio_columns_two, 0);
1898    
1899         if (params->columns == 2)
1900                 fl_set_button(fd_form_document->radio_columns_two, 1);
1901         else
1902                 fl_set_button(fd_form_document->radio_columns_one, 1);
1903    
1904         fl_set_input(fd_form_document->input_spacing, "");
1905         switch (params->spacing.getSpace()) {
1906         case Spacing::Single:
1907         {
1908                 // \singlespacing
1909                 fl_set_choice(fd_form_document->choice_spacing, 1);
1910                 break;
1911         }
1912         case Spacing::Onehalf:
1913         {
1914                 // \onehalfspacing
1915                 fl_set_choice(fd_form_document->choice_spacing, 2);
1916                 break;
1917         }
1918         case Spacing::Double:
1919         {
1920                 // \ doublespacing
1921                 fl_set_choice(fd_form_document->choice_spacing, 3);
1922                 break;
1923         }
1924         case Spacing::Other:
1925         {
1926                 fl_set_choice(fd_form_document->choice_spacing, 4);
1927                 char sval[20];
1928                 sprintf(sval, "%g", params->spacing.getValue()); 
1929                 fl_set_input(fd_form_document->input_spacing, sval);
1930                 break;
1931         }
1932         }
1933
1934
1935         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
1936                              params->secnumdepth);
1937         fl_set_counter_value(fd_form_document->slider_tocdepth, 
1938                              params->tocdepth);
1939         if (!params->float_placement.empty()) { // buffer local (Lgb)
1940                 fl_set_input(fd_form_document->input_float_placement,
1941                              params->float_placement.c_str());
1942         } else {
1943                 fl_set_input(fd_form_document->input_float_placement, "");
1944         }
1945         if (!params->options.empty())
1946                 fl_set_input(fd_form_document->input_extra,
1947                              params->options.c_str());
1948         else
1949                 fl_set_input(fd_form_document->input_extra, "");
1950
1951         if (current_view->buffer()->isSGML()) {
1952                 // bullets not used in SGML derived documents
1953                 fl_deactivate_object(fd_form_document->button_bullets);
1954                 fl_set_object_lcol(fd_form_document->button_bullets,
1955                                    FL_INACTIVE);
1956         } else {
1957                 fl_activate_object(fd_form_document->button_bullets);
1958                 fl_set_object_lcol(fd_form_document->button_bullets,
1959                                    FL_BLACK);
1960         }
1961
1962         if (current_view->buffer()->isReadonly()) {
1963                 DisableDocumentLayout();
1964         } else {
1965                 EnableDocumentLayout();
1966         }
1967
1968         return true;
1969 }
1970
1971
1972 void MenuLayoutDocument()
1973 {
1974         if (UpdateLayoutDocument()) {
1975                 if (fd_form_document->form_document->visible) {
1976                         fl_raise_form(fd_form_document->form_document);
1977                 } else {
1978                         fl_show_form(fd_form_document->form_document,
1979                                      FL_PLACE_MOUSE, FL_FULLBORDER,
1980                                      _("Document Layout"));
1981                 }
1982         }
1983 }
1984
1985
1986 bool UpdateLayoutQuotes()
1987 {
1988         bool update = true;
1989         if (!current_view->getScreen()
1990             || !current_view->available()
1991             || current_view->buffer()->isReadonly())
1992                 update = false;
1993         
1994         if (update) {
1995                 fl_set_choice(fd_form_quotes->choice_quotes_language,
1996                               current_view->buffer()->params.quotes_language + 1);
1997                 fl_set_button(fd_form_quotes->radio_single, 0);
1998                 fl_set_button(fd_form_quotes->radio_double, 0);
1999         
2000                 if (current_view->buffer()->params.quotes_times == InsetQuotes::SingleQ)
2001                         fl_set_button(fd_form_quotes->radio_single, 1);
2002                 else
2003                         fl_set_button(fd_form_quotes->radio_double, 1);
2004         } else if (fd_form_quotes->form_quotes->visible) {
2005                 fl_hide_form(fd_form_quotes->form_quotes);
2006         }
2007         return update;
2008 }
2009
2010
2011 void MenuLayoutQuotes()
2012 {
2013         if (UpdateLayoutQuotes()) {
2014                 if (fd_form_quotes->form_quotes->visible) {
2015                         fl_raise_form(fd_form_quotes->form_quotes);
2016                 } else {
2017                         fl_show_form(fd_form_quotes->form_quotes,
2018                                      FL_PLACE_MOUSE, FL_FULLBORDER,
2019                                      _("Quotes"));
2020                 }
2021         }
2022 }
2023
2024
2025 bool UpdateLayoutPreamble()
2026 {
2027         bool update = true;
2028         if (!current_view->getScreen() || ! current_view->available())
2029                 update = false;
2030
2031         if (update) {
2032                 fl_set_input(fd_form_preamble->input_preamble,
2033                              current_view->buffer()->params.preamble.c_str());
2034
2035                 if (current_view->buffer()->isReadonly()) {
2036                         fl_deactivate_object(fd_form_preamble->input_preamble);
2037                         fl_deactivate_object(fd_form_preamble->button_ok);
2038                         fl_deactivate_object(fd_form_preamble->button_apply);
2039                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_INACTIVE);
2040                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_INACTIVE);
2041                 }
2042                 else {
2043                         fl_activate_object(fd_form_preamble->input_preamble);
2044                         fl_activate_object(fd_form_preamble->button_ok);
2045                         fl_activate_object(fd_form_preamble->button_apply);
2046                         fl_set_object_lcol(fd_form_preamble->button_ok, FL_BLACK);
2047                         fl_set_object_lcol(fd_form_preamble->button_apply, FL_BLACK);
2048                 }
2049         } else if (fd_form_preamble->form_preamble->visible) {
2050                 fl_hide_form(fd_form_preamble->form_preamble);
2051         }
2052         return update;
2053 }
2054
2055 void MenuLayoutPreamble()
2056 {
2057         static int ow = -1, oh;
2058
2059         if (UpdateLayoutPreamble()) {
2060                 if (fd_form_preamble->form_preamble->visible) {
2061                         fl_raise_form(fd_form_preamble->form_preamble);
2062                 } else {
2063                         fl_show_form(fd_form_preamble->form_preamble,
2064                                      FL_PLACE_MOUSE | FL_FREE_SIZE,
2065                                      FL_FULLBORDER,
2066                                      _("LaTeX Preamble"));
2067                         if (ow < 0) {
2068                                 ow = fd_form_preamble->form_preamble->w;
2069                                 oh = fd_form_preamble->form_preamble->h;
2070                         }
2071                         fl_set_form_minsize(fd_form_preamble->form_preamble,
2072                                             ow, oh);
2073                 }
2074         }
2075 }
2076
2077
2078 void MenuLayoutSave()
2079 {
2080         if (!current_view->getScreen() || ! current_view->available())
2081                 return;
2082
2083         if (AskQuestion(_("Do you want to save the current settings"),
2084                         _("for Character, Document, Paper and Quotes"),
2085                         _("as default for new documents?")))
2086                 current_view->buffer()->saveParamsAsDefaults();
2087 }
2088
2089
2090 void BufferView::insertNote()
2091 {
2092         InsetInfo * new_inset = new InsetInfo();
2093         insertInset(new_inset);
2094         new_inset->Edit(0, 0);
2095 }
2096
2097
2098 void BufferView::openStuff()
2099 {
2100         if (available()) {
2101                 owner()->getMiniBuffer()->Set(_("Open/Close..."));
2102                 getScreen()->HideCursor();
2103                 beforeChange();
2104                 update(-2);
2105                 text->OpenStuff();
2106                 update(0);
2107         }
2108 }
2109
2110
2111 void BufferView::toggleFloat()
2112 {
2113         if (available()) {
2114                 owner()->getMiniBuffer()->Set(_("Open/Close..."));
2115                 getScreen()->HideCursor();
2116                 beforeChange();
2117                 update(-2);
2118                 text->ToggleFootnote();
2119                 update(0);
2120         }
2121 }
2122
2123
2124 void BufferView::menuUndo()
2125 {
2126         if (available()) {
2127                 owner()->getMiniBuffer()->Set(_("Undo"));
2128                 getScreen()->HideCursor();
2129                 beforeChange();
2130                 update(-2);
2131                 if (!text->TextUndo())
2132                         owner()->getMiniBuffer()->Set(_("No further undo information"));
2133                 else
2134                         update(-1);
2135         }
2136 }
2137
2138
2139 void BufferView::menuRedo()
2140 {
2141         if (the_locking_inset) {
2142                 owner()->getMiniBuffer()->Set(_("Redo not yet supported in math mode"));
2143                 return;
2144         }    
2145    
2146         if (available()) {
2147                 owner()->getMiniBuffer()->Set(_("Redo"));
2148                 getScreen()->HideCursor();
2149                 beforeChange();
2150                 update(-2);
2151                 if (!text->TextRedo())
2152                         owner()->getMiniBuffer()->Set(_("No further redo information"));
2153                 else
2154                         update(-1);
2155         }
2156 }
2157
2158
2159 void BufferView::hyphenationPoint()
2160 {
2161         if (available()) {
2162                 getScreen()->HideCursor();
2163                 update(-2);
2164                 InsetSpecialChar * new_inset = 
2165                         new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
2166                 insertInset(new_inset);
2167         }
2168 }
2169
2170
2171 void BufferView::ldots()
2172 {
2173         if (available())  {
2174                 getScreen()->HideCursor();
2175                 update(-2);
2176                 InsetSpecialChar * new_inset = 
2177                         new InsetSpecialChar(InsetSpecialChar::LDOTS);
2178                 insertInset(new_inset);
2179         }
2180 }
2181
2182
2183 void BufferView::endOfSentenceDot()
2184 {
2185         if (available()) {
2186                 getScreen()->HideCursor();
2187                 update(-2);
2188                 InsetSpecialChar * new_inset = 
2189                         new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
2190                 insertInset(new_inset);
2191         }
2192 }
2193
2194
2195 void BufferView::menuSeparator()
2196 {
2197         if (available()) {
2198                 getScreen()->HideCursor();
2199                 update(-2);
2200                 InsetSpecialChar * new_inset = 
2201                         new InsetSpecialChar(InsetSpecialChar::MENU_SEPARATOR);
2202                 insertInset(new_inset);
2203         }
2204 }
2205
2206
2207 void BufferView::newline()
2208 {
2209         if (available()) {
2210                 getScreen()->HideCursor();
2211                 update(-2);
2212                 text->InsertChar(LyXParagraph::META_NEWLINE);
2213                 update(-1);
2214         }
2215 }
2216
2217
2218 void BufferView::protectedBlank()
2219 {
2220         if (available()) {
2221                 getScreen()->HideCursor();
2222                 update(-2);
2223                 text->InsertChar(LyXParagraph::META_PROTECTED_SEPARATOR);
2224                 update(-1);
2225         }
2226 }
2227
2228
2229 void BufferView::hfill()
2230 {
2231         if (available()) {
2232                 getScreen()->HideCursor();
2233                 update(-2);
2234                 text->InsertChar(LyXParagraph::META_HFILL);
2235                 update(-1);
2236         }
2237 }
2238
2239
2240 /* -------> These CB's use ToggleFree() as the (one and only?) font-changer. 
2241                         They also show the current font state. */
2242
2243 static
2244 void ToggleAndShow(LyXFont const &);
2245
2246
2247 void FontSizeCB(string const & size)
2248 {
2249         LyXFont font(LyXFont::ALL_IGNORE);
2250         font.setGUISize(size);
2251         ToggleAndShow(font);
2252 }
2253
2254
2255 void EmphCB()
2256 {
2257         LyXFont font(LyXFont::ALL_IGNORE);
2258         font.setEmph(LyXFont::TOGGLE);
2259         ToggleAndShow(font);
2260 }
2261
2262
2263 void NounCB()
2264 {
2265         LyXFont font(LyXFont::ALL_IGNORE);
2266         font.setNoun(LyXFont::TOGGLE);
2267         ToggleAndShow(font);
2268 }
2269
2270
2271 void BoldCB()
2272 {
2273         LyXFont font(LyXFont::ALL_IGNORE);
2274         font.setSeries(LyXFont::BOLD_SERIES);
2275         ToggleAndShow(font);
2276 }
2277
2278
2279 void UnderlineCB()
2280 {
2281         LyXFont font(LyXFont::ALL_IGNORE);
2282         font.setUnderbar(LyXFont::TOGGLE);
2283         ToggleAndShow(font);
2284 }
2285
2286
2287 void CodeCB()
2288 {
2289         LyXFont font(LyXFont::ALL_IGNORE);
2290         font.setFamily(LyXFont::TYPEWRITER_FAMILY); // no good
2291         ToggleAndShow(font);
2292 }
2293
2294
2295 void SansCB()
2296 {
2297         LyXFont font(LyXFont::ALL_IGNORE);
2298         font.setFamily(LyXFont::SANS_FAMILY);
2299         ToggleAndShow(font);
2300 }
2301
2302
2303 void RomanCB()
2304 {
2305         LyXFont font(LyXFont::ALL_IGNORE);
2306         font.setFamily(LyXFont::ROMAN_FAMILY);
2307         ToggleAndShow(font);
2308 }
2309
2310
2311 void TexCB()
2312 {
2313         LyXFont font(LyXFont::ALL_IGNORE);
2314         font.setLatex (LyXFont::TOGGLE);
2315         ToggleAndShow(font);
2316 }
2317
2318
2319 void StyleResetCB()
2320 {
2321         LyXFont font(LyXFont::ALL_INHERIT);
2322         ToggleAndShow(font);
2323 }
2324
2325
2326 /* -------> Returns the current font and depth by printing a message. In the
2327  * future perhaps we could try to implement a callback to the button-bar.
2328  * That is, `light' the bold button when the font is currently bold, etc.
2329  */
2330 string CurrentState()
2331 {
2332         string state;
2333         if (current_view->available()) { 
2334                 // I think we should only show changes from the default
2335                 // font. (Asger)
2336                 Buffer * buffer = current_view->buffer();
2337                 LyXFont font = current_view->text->real_current_font;
2338                 LyXFont defaultfont = textclasslist.TextClass(buffer->
2339                                                               params.textclass).defaultfont();
2340                 font.reduce(defaultfont);
2341                 state = _("Font: ") + font.stateText();
2342
2343                 int depth = current_view->text->GetDepth();
2344                 if (depth > 0) 
2345                         state += string(_(", Depth: ")) + tostr(depth);
2346         }
2347         return state;
2348 }
2349
2350
2351 // candidate for move to BufferView
2352 /* -------> Does the actual toggle job of the XxxCB() calls above.
2353  * Also shows the current font state.
2354  */
2355 static
2356 void ToggleAndShow(LyXFont const & font)
2357 {
2358         if (current_view->available()) { 
2359                 current_view->getScreen()->HideCursor();
2360                 current_view->update(-2);
2361                 current_view->text->ToggleFree(font, toggleall);
2362                 current_view->update(1);
2363         }
2364 }
2365
2366
2367 // candidate for move to BufferView
2368 extern "C" void MarginCB(FL_OBJECT *, long)
2369 {
2370         if (current_view->available()) {
2371                 current_view->owner()->getMiniBuffer()->Set(_("Inserting margin note..."));
2372                 current_view->getScreen()->HideCursor();
2373                 current_view->update(-2);
2374                 current_view->text->InsertFootnoteEnvironment(LyXParagraph::MARGIN);
2375                 current_view->update(1);
2376         }
2377 }
2378
2379
2380 extern "C" void FigureCB(FL_OBJECT *, long)
2381 {
2382         if (fd_form_figure->form_figure->visible) {
2383                 fl_raise_form(fd_form_figure->form_figure);
2384         } else {
2385                 fl_show_form(fd_form_figure->form_figure,
2386                              FL_PLACE_MOUSE, FL_FULLBORDER,
2387                              _("Insert Figure"));
2388         }
2389 }
2390
2391
2392 extern "C" void TableCB(FL_OBJECT *, long)
2393 {
2394         if (fd_form_table->form_table->visible) {
2395                 fl_raise_form(fd_form_table->form_table);
2396         } else {
2397                 fl_show_form(fd_form_table->form_table,
2398                              FL_PLACE_MOUSE, FL_FULLBORDER,
2399                              _("Insert Table"));
2400         }
2401 }
2402
2403
2404 void BufferView::copyEnvironment()
2405 {
2406         if (available()) {
2407                 text->copyEnvironmentType();
2408                 // clear the selection, even if mark_set
2409                 getScreen()->ToggleSelection();
2410                 text->ClearSelection();
2411                 update(-2);
2412                 owner()->getMiniBuffer()->Set(_("Paragraph environment type copied"));
2413         }
2414 }
2415
2416
2417 void BufferView::pasteEnvironment()
2418 {
2419         if (available()) {
2420                 text->pasteEnvironmentType();
2421                 owner()->getMiniBuffer()->Set(_("Paragraph environment type set"));
2422                 update(1);
2423         }
2424 }
2425
2426
2427 void BufferView::copy()
2428 {
2429         if (available()) {
2430                 text->CopySelection();
2431                 // clear the selection, even if mark_set
2432                 getScreen()->ToggleSelection();
2433                 text->ClearSelection();
2434                 update(-2);
2435                 owner()->getMiniBuffer()->Set(_("Copy"));
2436         }
2437 }
2438
2439
2440 void BufferView::cut()
2441 {
2442         if (available()) {
2443                 getScreen()->HideCursor();
2444                 update(-2);
2445                 text->CutSelection();
2446                 update(1);
2447                 owner()->getMiniBuffer()->Set(_("Cut"));
2448         }
2449 }
2450
2451
2452 void BufferView::paste()
2453 {
2454         if (!available()) return;
2455         
2456         owner()->getMiniBuffer()->Set(_("Paste"));
2457         getScreen()->HideCursor();
2458         // clear the selection
2459         getScreen()->ToggleSelection();
2460         text->ClearSelection();
2461         update(-2);
2462         
2463         // paste
2464         text->PasteSelection();
2465         update(1);
2466         
2467         // clear the selection 
2468         getScreen()->ToggleSelection();
2469         text->ClearSelection();
2470         update(-2);
2471 }
2472
2473
2474 // candidate for move to BufferView
2475 extern "C" void MeltCB(FL_OBJECT *, long)
2476 {
2477         if (!current_view->available()) return;
2478         
2479         current_view->owner()->getMiniBuffer()->Set(_("Melt"));
2480         current_view->getScreen()->HideCursor();
2481         current_view->beforeChange();
2482         current_view->update(-2);
2483         current_view->text->MeltFootnoteEnvironment();
2484         current_view->update(1);
2485 }
2486
2487
2488 // candidate for move to BufferView
2489 // Change environment depth.
2490 // if decInc == 0, depth change taking mouse button number into account
2491 // if decInc == 1, increment depth
2492 // if decInc == -1, decrement depth
2493 extern "C" void DepthCB(FL_OBJECT * ob, long decInc)
2494 {
2495         int button = 1;
2496
2497         /* When decInc != 0, fake a mouse button. This allows us to
2498            implement depth-plus and depth-min commands. RVDK_PATCH_5. */
2499         /* check out wether ob is defined, too (Matthias) */ 
2500         if ( decInc < 0 )
2501                 button = 0;
2502         else if (!decInc && ob) {
2503                 button = fl_get_button_numb(ob);
2504         }
2505   
2506         if (current_view->available()) {
2507                 current_view->getScreen()->HideCursor();
2508                 current_view->update(-2);
2509                 if (button == 1)
2510                         current_view->text->IncDepth();
2511                 else
2512                         current_view->text->DecDepth();
2513                 current_view->update(1);
2514                 current_view->owner()->getMiniBuffer()->Set(_("Changed environment depth"
2515                                   " (in possible range, maybe not)"));
2516         }
2517 }
2518
2519
2520 // This is both GUI and LyXFont dependent. Don't know where to put it. (Asger)
2521 // Well, it's mostly GUI dependent, so I guess it will stay here. (Asger)
2522 LyXFont UserFreeFont()
2523 {
2524         LyXFont font(LyXFont::ALL_IGNORE);
2525
2526         int pos = fl_get_choice(fd_form_character->choice_family);
2527         switch(pos) {
2528         case 1: font.setFamily(LyXFont::IGNORE_FAMILY); break;
2529         case 2: font.setFamily(LyXFont::ROMAN_FAMILY); break;
2530         case 3: font.setFamily(LyXFont::SANS_FAMILY); break;
2531         case 4: font.setFamily(LyXFont::TYPEWRITER_FAMILY); break;
2532         case 5: font.setFamily(LyXFont::INHERIT_FAMILY); break;
2533         }
2534
2535         pos = fl_get_choice(fd_form_character->choice_series);
2536         switch(pos) {
2537         case 1: font.setSeries(LyXFont::IGNORE_SERIES); break;
2538         case 2: font.setSeries(LyXFont::MEDIUM_SERIES); break;
2539         case 3: font.setSeries(LyXFont::BOLD_SERIES); break;
2540         case 4: font.setSeries(LyXFont::INHERIT_SERIES); break;
2541         }
2542
2543         pos = fl_get_choice(fd_form_character->choice_shape);
2544         switch(pos) {
2545         case 1: font.setShape(LyXFont::IGNORE_SHAPE); break;
2546         case 2: font.setShape(LyXFont::UP_SHAPE); break;
2547         case 3: font.setShape(LyXFont::ITALIC_SHAPE); break;
2548         case 4: font.setShape(LyXFont::SLANTED_SHAPE); break;
2549         case 5: font.setShape(LyXFont::SMALLCAPS_SHAPE); break;
2550         case 6: font.setShape(LyXFont::INHERIT_SHAPE); break;
2551         }
2552
2553         pos = fl_get_choice(fd_form_character->choice_size);
2554         switch(pos) {
2555         case 1: font.setSize(LyXFont::IGNORE_SIZE); break;
2556         case 2: font.setSize(LyXFont::SIZE_TINY); break;
2557         case 3: font.setSize(LyXFont::SIZE_SCRIPT); break;
2558         case 4: font.setSize(LyXFont::SIZE_FOOTNOTE); break;
2559         case 5: font.setSize(LyXFont::SIZE_SMALL); break;
2560         case 6: font.setSize(LyXFont::SIZE_NORMAL); break;
2561         case 7: font.setSize(LyXFont::SIZE_LARGE); break;
2562         case 8: font.setSize(LyXFont::SIZE_LARGER); break;
2563         case 9: font.setSize(LyXFont::SIZE_LARGEST); break;
2564         case 10: font.setSize(LyXFont::SIZE_HUGE); break;
2565         case 11: font.setSize(LyXFont::SIZE_HUGER); break;
2566         case 12: font.setSize(LyXFont::INCREASE_SIZE); break;
2567         case 13: font.setSize(LyXFont::DECREASE_SIZE); break;
2568         case 14: font.setSize(LyXFont::INHERIT_SIZE); break;
2569         }
2570
2571         pos = fl_get_choice(fd_form_character->choice_bar);
2572         switch(pos) {
2573         case 1: font.setEmph(LyXFont::IGNORE);
2574                 font.setUnderbar(LyXFont::IGNORE);
2575                 font.setNoun(LyXFont::IGNORE);
2576                 font.setLatex(LyXFont::IGNORE);
2577                 break;
2578         case 2: font.setEmph(LyXFont::TOGGLE); break;
2579         case 3: font.setUnderbar(LyXFont::TOGGLE); break;
2580         case 4: font.setNoun(LyXFont::TOGGLE); break;
2581         case 5: font.setLatex(LyXFont::TOGGLE); break;
2582         case 6: font.setEmph(LyXFont::INHERIT);
2583                 font.setUnderbar(LyXFont::INHERIT);
2584                 font.setNoun(LyXFont::INHERIT);
2585                 font.setLatex(LyXFont::INHERIT);
2586                 break;
2587         }
2588
2589         pos = fl_get_choice(fd_form_character->choice_color);
2590         switch(pos) {
2591         case 1: font.setColor(LyXFont::IGNORE_COLOR); break;
2592         case 2: font.setColor(LyXFont::NONE); break;
2593         case 3: font.setColor(LyXFont::BLACK); break;
2594         case 4: font.setColor(LyXFont::WHITE); break;
2595         case 5: font.setColor(LyXFont::RED); break;
2596         case 6: font.setColor(LyXFont::GREEN); break;
2597         case 7: font.setColor(LyXFont::BLUE); break;
2598         case 8: font.setColor(LyXFont::CYAN); break;
2599         case 9: font.setColor(LyXFont::MAGENTA); break;
2600         case 10: font.setColor(LyXFont::YELLOW); break;
2601         case 11: font.setColor(LyXFont::INHERIT_COLOR); break;
2602         }
2603
2604         return font; 
2605 }
2606
2607
2608 void FreeCB()
2609 {
2610         ToggleAndShow(UserFreeFont());
2611 }
2612
2613
2614 /* callbacks for form form_title */
2615 extern "C" void TimerCB(FL_OBJECT *, long)
2616 {
2617         // only if the form still exists
2618         if (fd_form_title->form_title != 0) {
2619                 if (fd_form_title->form_title->visible) {
2620                         fl_hide_form(fd_form_title->form_title);
2621                 }
2622                 fl_free_form(fd_form_title->form_title);
2623                 fd_form_title->form_title = 0;
2624         }
2625 }
2626
2627
2628 /* callbacks for form form_paragraph */
2629
2630 extern "C" void ParagraphVSpaceCB(FL_OBJECT * obj, long )
2631 {
2632         // "Synchronize" the choices and input fields, making it
2633         // impossible to commit senseless data.
2634
2635         FD_form_paragraph const * fp = fd_form_paragraph;
2636
2637         if (obj == fp->choice_space_above) {
2638                 if (fl_get_choice (fp->choice_space_above) != 7) {
2639                         fl_set_input (fp->input_space_above, "");
2640                         ActivateParagraphButtons();
2641                 }
2642         } else if (obj == fp->choice_space_below) {
2643                 if (fl_get_choice (fp->choice_space_below) != 7) {
2644                         fl_set_input (fp->input_space_below, "");
2645                         ActivateParagraphButtons();
2646                 }
2647         } else if (obj == fp->input_space_above) {
2648                 string input = fl_get_input (fp->input_space_above);
2649
2650                 if (input.empty()) {
2651                         fl_set_choice (fp->choice_space_above, 1);
2652                         ActivateParagraphButtons();
2653                 }
2654                 else if (isValidGlueLength (input)) {
2655                         fl_set_choice (fp->choice_space_above, 7);
2656                         ActivateParagraphButtons();
2657                 }
2658                 else {
2659                         fl_set_choice (fp->choice_space_above, 7);
2660                         DeactivateParagraphButtons();
2661                 }
2662         } else if (obj == fp->input_space_below) {
2663                 string input = fl_get_input (fp->input_space_below);
2664
2665                 if (input.empty()) {
2666                         fl_set_choice (fp->choice_space_below, 1);
2667                         ActivateParagraphButtons();
2668                 }
2669                 else if (isValidGlueLength (input)) {
2670                         fl_set_choice (fp->choice_space_below, 7);
2671                         ActivateParagraphButtons();
2672                 }
2673                 else {
2674                         fl_set_choice (fp->choice_space_below, 7);
2675                         DeactivateParagraphButtons();
2676                 }
2677         }
2678 }
2679
2680
2681 extern "C" void ParagraphApplyCB(FL_OBJECT *, long)
2682 {
2683         if (!current_view->available())
2684                 return;
2685         
2686         VSpace space_top, space_bottom;
2687         LyXAlignment align;
2688         string labelwidthstring;
2689         bool noindent;
2690
2691         // If a vspace kind is "Length" but there's no text in
2692         // the input field, reset the kind to "None". 
2693         if (fl_get_choice (fd_form_paragraph->choice_space_above) == 7
2694             && !*(fl_get_input (fd_form_paragraph->input_space_above))) {
2695                 fl_set_choice (fd_form_paragraph->choice_space_above, 1);
2696         }
2697         if (fl_get_choice (fd_form_paragraph->choice_space_below) == 7
2698             && !*(fl_get_input (fd_form_paragraph->input_space_below))) {
2699                 fl_set_choice (fd_form_paragraph->choice_space_below, 1);
2700         }
2701    
2702         bool line_top = fl_get_button(fd_form_paragraph->check_lines_top);
2703         bool line_bottom = fl_get_button(fd_form_paragraph->check_lines_bottom);
2704         bool pagebreak_top = fl_get_button(fd_form_paragraph->check_pagebreaks_top);
2705         bool pagebreak_bottom = fl_get_button(fd_form_paragraph->check_pagebreaks_bottom);
2706         switch (fl_get_choice (fd_form_paragraph->choice_space_above)) {
2707         case 1: space_top = VSpace(VSpace::NONE); break;
2708         case 2: space_top = VSpace(VSpace::DEFSKIP); break;
2709         case 3: space_top = VSpace(VSpace::SMALLSKIP); break;
2710         case 4: space_top = VSpace(VSpace::MEDSKIP); break;
2711         case 5: space_top = VSpace(VSpace::BIGSKIP); break;
2712         case 6: space_top = VSpace(VSpace::VFILL); break;
2713         case 7: space_top = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_above))); break;
2714         }
2715         if (fl_get_button (fd_form_paragraph->check_space_above))
2716                 space_top.setKeep (true);
2717         switch (fl_get_choice (fd_form_paragraph->choice_space_below)) {
2718         case 1: space_bottom = VSpace(VSpace::NONE); break;
2719         case 2: space_bottom = VSpace(VSpace::DEFSKIP); break;
2720         case 3: space_bottom = VSpace(VSpace::SMALLSKIP); break;
2721         case 4: space_bottom = VSpace(VSpace::MEDSKIP); break;
2722         case 5: space_bottom = VSpace(VSpace::BIGSKIP); break;
2723         case 6: space_bottom = VSpace(VSpace::VFILL); break;
2724         case 7: space_bottom = VSpace(LyXGlueLength (fl_get_input (fd_form_paragraph->input_space_below))); break;
2725         }
2726         if (fl_get_button (fd_form_paragraph->check_space_below))
2727                 space_bottom.setKeep (true);
2728
2729         if (fl_get_button(fd_form_paragraph->radio_align_left))
2730                 align = LYX_ALIGN_LEFT;
2731         else if (fl_get_button(fd_form_paragraph->radio_align_right))
2732                 align = LYX_ALIGN_RIGHT;
2733         else if (fl_get_button(fd_form_paragraph->radio_align_center))
2734                 align = LYX_ALIGN_CENTER;
2735         else 
2736                 align = LYX_ALIGN_BLOCK;
2737    
2738         labelwidthstring = fl_get_input(fd_form_paragraph->input_labelwidth);
2739         noindent = fl_get_button(fd_form_paragraph->check_noindent);
2740
2741         current_view->text->SetParagraph(line_top,
2742                                          line_bottom,
2743                                          pagebreak_top,
2744                                          pagebreak_bottom,
2745                                          space_top,
2746                                          space_bottom,
2747                                          align, 
2748                                          labelwidthstring,
2749                                          noindent);
2750         current_view->update(1);
2751         current_view->owner()->getMiniBuffer()->Set(_("Paragraph layout set"));
2752 }
2753
2754
2755 extern "C" void ParagraphCancelCB(FL_OBJECT *, long)
2756 {
2757         fl_hide_form(fd_form_paragraph->form_paragraph);
2758 }
2759
2760
2761 extern "C" void ParagraphOKCB(FL_OBJECT *ob, long data)
2762 {
2763         ParagraphApplyCB(ob, data);
2764         ParagraphCancelCB(ob, data);
2765 }
2766
2767
2768 /* callbacks for form form_character */
2769
2770 extern "C" void CharacterApplyCB(FL_OBJECT *, long)
2771 {
2772         // we set toggleall locally here, since it should be true for
2773         // all other uses of ToggleAndShow() (JMarc)
2774         toggleall = fl_get_button(fd_form_character->check_toggle_all);
2775         ToggleAndShow( UserFreeFont());
2776         toggleall = true;
2777 }
2778
2779
2780 extern "C" void CharacterCloseCB(FL_OBJECT *, long)
2781 {
2782         fl_hide_form(fd_form_character->form_character);
2783 }
2784
2785
2786 extern "C" void CharacterOKCB(FL_OBJECT *ob, long data)
2787 {
2788         CharacterApplyCB(ob, data);
2789         CharacterCloseCB(ob, data);
2790 }
2791
2792
2793 /* callbacks for form form_document */
2794
2795 void UpdateDocumentButtons(BufferParams const & params) 
2796 {
2797         fl_set_choice(fd_form_document->choice_pagestyle, 1);
2798
2799         switch (params.sides) {
2800         case LyXTextClass::OneSide:
2801                 fl_set_button(fd_form_document->radio_sides_one, 1);
2802                 break;
2803         case LyXTextClass::TwoSides:
2804                 fl_set_button(fd_form_document->radio_sides_two, 1);
2805                 break;
2806         }
2807    
2808         if (params.columns == 2)
2809                 fl_set_button(fd_form_document->radio_columns_two, 1);
2810         else
2811                 fl_set_button(fd_form_document->radio_columns_one, 1);
2812         
2813         fl_set_input(fd_form_document->input_extra, params.options.c_str());
2814         fl_set_counter_value(fd_form_document->slider_secnumdepth, 
2815                              params.secnumdepth);
2816         fl_set_counter_value(fd_form_document->slider_tocdepth, 
2817                              params.tocdepth);
2818         
2819 }
2820
2821 extern "C" void ChoiceClassCB(FL_OBJECT * ob, long)
2822 {
2823         ProhibitInput();
2824         if (textclasslist.Load(fl_get_choice(ob)-1)) {
2825                 if (AskQuestion(_("Should I set some parameters to"),
2826                                 fl_get_choice_text(ob),
2827                                 _("the defaults of this document class?"))) {
2828                         BufferParams params = BufferParams();
2829                         params.textclass = fl_get_choice(ob)-1;
2830                         params.useClassDefaults();
2831                         UpdateLayoutDocument(&params);
2832                         UpdateDocumentButtons(params);
2833                 }
2834         } else {
2835                 // unable to load new style
2836                 WriteAlert(_("Conversion Errors!"),
2837                            _("Unable to switch to new document class."),
2838                            _("Reverting to original document class."));
2839                 fl_set_choice(fd_form_document->choice_class, 
2840                               current_view->buffer()->params.textclass + 1);
2841         }
2842         AllowInput();
2843 }
2844
2845
2846 extern "C" void DocumentDefskipCB(FL_OBJECT * obj, long)
2847 {
2848         // "Synchronize" the choice and the input field, so that it
2849         // is impossible to commit senseless data.
2850         FD_form_document const * fd = fd_form_document;
2851
2852         if (obj == fd->choice_default_skip) {
2853                 if (fl_get_choice (fd->choice_default_skip) != 4) {
2854                         fl_set_input (fd->input_default_skip, "");
2855                         ActivateDocumentButtons();
2856                 }
2857         } else if (obj == fd->input_default_skip) {
2858
2859                 char const * input = fl_get_input (fd->input_default_skip);
2860
2861                 if (!*input) {
2862                         fl_set_choice (fd->choice_default_skip, 2);
2863                         ActivateDocumentButtons();
2864                 } else if (isValidGlueLength (input)) {
2865                         fl_set_choice (fd->choice_default_skip, 4);
2866                         ActivateDocumentButtons();
2867                 } else {
2868                         fl_set_choice (fd->choice_default_skip, 4);
2869                         DeactivateDocumentButtons();
2870                 }
2871         }
2872 }
2873
2874
2875 extern "C" void DocumentSpacingCB(FL_OBJECT * obj, long)
2876 {
2877         // "Synchronize" the choice and the input field, so that it
2878         // is impossible to commit senseless data.
2879         FD_form_document const * fd = fd_form_document;
2880
2881         if (obj == fd->choice_spacing
2882             && fl_get_choice (fd->choice_spacing) != 4) {
2883                 fl_set_input(fd->input_spacing, "");
2884         } else if (obj == fd->input_spacing) {
2885
2886                 const char* input = fl_get_input (fd->input_spacing);
2887
2888                 if (!*input) {
2889                         fl_set_choice (fd->choice_spacing, 1);
2890                 } else {
2891                         fl_set_choice (fd->choice_spacing, 4);
2892                 }
2893         }
2894 }
2895
2896
2897 extern "C" void DocumentApplyCB(FL_OBJECT *, long)
2898 {
2899         bool redo = false;
2900         BufferParams *params = &(current_view->buffer()->params);
2901         current_view->buffer()->params.language = 
2902                 combo_language->getline();
2903
2904         // If default skip is a "Length" but there's no text in the
2905         // input field, reset the kind to "Medskip", which is the default.
2906         if (fl_get_choice (fd_form_document->choice_default_skip) == 4
2907             && !*(fl_get_input (fd_form_document->input_default_skip))) {
2908                 fl_set_choice (fd_form_document->choice_default_skip, 2);
2909         }
2910
2911         /* this shouldn't be done automatically IMO. For example I write german
2912          * documents with an american keyboard very often. Matthias */
2913    
2914         /* ChangeKeymap(buffer->parameters.language, TRUE, false,
2915            fl_get_choice(fd_form_document->choice_language)); */
2916         params->fonts = 
2917                 fl_get_choice_text(fd_form_document->choice_fonts);
2918         params->inputenc = 
2919                 fl_get_choice_text(fd_form_document->choice_inputenc);
2920         params->fontsize = 
2921                 fl_get_choice_text(fd_form_document->choice_fontsize);
2922         params->pagestyle = 
2923                 fl_get_choice_text(fd_form_document->choice_pagestyle);
2924         params->graphicsDriver = 
2925                 fl_get_choice_text(fd_form_document->choice_postscript_driver);
2926         params->use_amsmath = 
2927                 fl_get_button(fd_form_document->check_use_amsmath);
2928    
2929         if (!current_view->available())
2930                 return;
2931
2932         LyXTextClassList::ClassList::size_type new_class = fl_get_choice(fd_form_document->choice_class) - 1;
2933         if (params->textclass != new_class) {
2934                 // try to load new_class
2935                 if (textclasslist.Load(new_class)) {
2936                         // successfully loaded
2937                         redo = true;
2938                         current_view->owner()->getMiniBuffer()->Set(_("Converting document to new document class..."));
2939                         int ret = current_view->text->
2940                                 SwitchLayoutsBetweenClasses(current_view->buffer()->
2941                                                             params.textclass,
2942                                                             new_class,
2943                                                             current_view->buffer()->
2944                                                             paragraph);
2945
2946                         if (ret) {
2947                                 string s;
2948                                 if (ret == 1)
2949                                         s = _("One paragraph couldn't be converted");
2950                                 else {
2951                                         s += tostr(ret);
2952                                         s += _(" paragraphs couldn't be converted");
2953                                 }
2954                                 WriteAlert(_("Conversion Errors!"), s,
2955                                            _("into chosen document class"));
2956                         }
2957
2958                         params->textclass = new_class;
2959                 } else {
2960                         // problem changing class -- warn user and retain old style
2961                         WriteAlert(_("Conversion Errors!"),
2962                                    _("Unable to switch to new document class."),
2963                                    _("Reverting to original document class."));
2964                         fl_set_choice(fd_form_document->choice_class, params->textclass + 1);
2965                 }
2966         }
2967
2968         char tmpsep = params->paragraph_separation;
2969         if (fl_get_button(fd_form_document->radio_indent))
2970                 params->paragraph_separation = BufferParams::PARSEP_INDENT;
2971         else
2972                 params->paragraph_separation = BufferParams::PARSEP_SKIP;
2973         if (tmpsep != params->paragraph_separation)
2974                 redo = true;
2975    
2976         VSpace tmpdefskip = params->getDefSkip();
2977         switch (fl_get_choice (fd_form_document->choice_default_skip)) {
2978         case 1: params->setDefSkip(VSpace(VSpace::SMALLSKIP)); break;
2979         case 2: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2980         case 3: params->setDefSkip(VSpace(VSpace::BIGSKIP)); break;
2981         case 4: params->setDefSkip( 
2982                 VSpace (LyXGlueLength (fl_get_input 
2983                                        (fd_form_document->input_default_skip))));
2984         break;
2985         // DocumentDefskipCB assures that this never happens
2986         default: params->setDefSkip(VSpace(VSpace::MEDSKIP)); break;
2987         }
2988         if (!(tmpdefskip == params->getDefSkip()))
2989                 redo = true;
2990
2991         if (fl_get_button(fd_form_document->radio_columns_two))
2992                 params->columns = 2;
2993         else
2994                 params->columns = 1;
2995         if (fl_get_button(fd_form_document->radio_sides_two))
2996                 params->sides = LyXTextClass::TwoSides;
2997         else
2998                 params->sides = LyXTextClass::OneSide;
2999
3000         Spacing tmpSpacing = params->spacing;
3001         switch(fl_get_choice(fd_form_document->choice_spacing)) {
3002         case 1:
3003                 lyxerr.debug() << "Spacing: SINGLE" << endl;
3004                 params->spacing.set(Spacing::Single);
3005                 break;
3006         case 2:
3007                 lyxerr.debug() << "Spacing: ONEHALF" << endl;
3008                 params->spacing.set(Spacing::Onehalf);
3009                 break;
3010         case 3:
3011                 lyxerr.debug() << "Spacing: DOUBLE" << endl;
3012                 params->spacing.set(Spacing::Double);
3013                 break;
3014         case 4:
3015                 lyxerr.debug() << "Spacing: OTHER" << endl;
3016                 params->spacing.set(Spacing::Other, 
3017                                     fl_get_input(fd_form_document->input_spacing));
3018                 break;
3019         }
3020         if (tmpSpacing != params->spacing)
3021                 redo = true;
3022         
3023         signed char tmpchar =  
3024                 static_cast<signed char>(fl_get_counter_value(fd_form_document->slider_secnumdepth));
3025         if (params->secnumdepth != tmpchar)
3026                 redo = true;
3027         params->secnumdepth = tmpchar;
3028    
3029         params->tocdepth =  
3030                 static_cast<int>(fl_get_counter_value(fd_form_document->slider_tocdepth));
3031
3032         params->float_placement = 
3033                 fl_get_input(fd_form_document->input_float_placement);
3034
3035         // More checking should be done to ensure the string doesn't have
3036         // spaces or illegal placement characters in it. (thornley)
3037
3038         if (redo)
3039                 current_view->redoCurrentBuffer();
3040    
3041         current_view->owner()->getMiniBuffer()->Set(_("Document layout set"));
3042         current_view->buffer()->markDirty();
3043
3044         params->options = 
3045                 fl_get_input(fd_form_document->input_extra);
3046    
3047 }
3048
3049
3050 extern "C" void DocumentCancelCB(FL_OBJECT *, long)
3051 {
3052         fl_hide_form(fd_form_document->form_document);
3053 }
3054
3055
3056 extern "C" void DocumentOKCB(FL_OBJECT * ob, long data)
3057 {
3058         DocumentCancelCB(ob, data);
3059         DocumentApplyCB(ob, data);
3060 }
3061
3062
3063 extern "C" void DocumentBulletsCB(FL_OBJECT *, long)
3064 {
3065         bulletForm();
3066         // bullet callbacks etc. in bullet_panel.C -- ARRae
3067 }
3068
3069
3070 void BufferView::gotoNote()
3071 {
3072         if (!getScreen()) return;
3073    
3074         getScreen()->HideCursor();
3075         beforeChange();
3076         update(-2);
3077         LyXCursor tmp;
3078    
3079         if (!text->GotoNextNote()) {
3080                 if (text->cursor.pos 
3081                     || text->cursor.par != text->FirstParagraph()) {
3082                                 tmp = text->cursor;
3083                                 text->cursor.par = text->FirstParagraph();
3084                                 text->cursor.pos = 0;
3085                                 if (!text->GotoNextNote()) {
3086                                         text->cursor = tmp;
3087                                         owner()->getMiniBuffer()->Set(_("No more notes"));
3088                                         LyXBell();
3089                                 }
3090                         } else {
3091                                 owner()->getMiniBuffer()->Set(_("No more notes"));
3092                                 LyXBell();
3093                         }
3094         }
3095         update(0);
3096         text->sel_cursor = text->cursor;
3097 }
3098
3099
3100 void BufferView::insertCorrectQuote()
3101 {
3102         char c;
3103
3104         if (text->cursor.pos)
3105                 c = text->cursor.par->GetChar(text->cursor.pos - 1);
3106         else 
3107                 c = ' ';
3108
3109         insertInset(new InsetQuotes(c, buffer()->params));
3110 }
3111
3112
3113 /* callbacks for form form_quotes */
3114
3115 extern "C" void QuotesApplyCB(FL_OBJECT *, long)
3116 {
3117         if (!current_view->available())
3118                 return;
3119         
3120         current_view->owner()->getMiniBuffer()->Set(_("Quotes type set"));
3121         //current_view->buffer()->params.quotes_language = 
3122         //      fl_get_choice(fd_form_quotes->choice_quotes_language) - 1;
3123         InsetQuotes::quote_language lga = InsetQuotes::EnglishQ;
3124         switch(fl_get_choice(fd_form_quotes->choice_quotes_language) - 1) {
3125         case 0:
3126                 lga = InsetQuotes::EnglishQ;
3127                 break;
3128         case 1:
3129                 lga = InsetQuotes::SwedishQ;
3130                 break;
3131         case 2:
3132                 lga = InsetQuotes::GermanQ;
3133                 break;
3134         case 3:
3135                 lga = InsetQuotes::PolishQ;
3136                 break;
3137         case 4:
3138                 lga = InsetQuotes::FrenchQ;
3139                 break;
3140         case 5:
3141                 lga = InsetQuotes::DanishQ;
3142                 break;
3143         }
3144         current_view->buffer()->params.quotes_language = lga;
3145         if (fl_get_button(fd_form_quotes->radio_single))   
3146                 current_view->buffer()->
3147                         params.quotes_times = InsetQuotes::SingleQ;
3148         else
3149                 current_view->buffer()->
3150                         params.quotes_times = InsetQuotes::DoubleQ;
3151 }
3152
3153
3154 extern "C" void QuotesCancelCB(FL_OBJECT *, long)
3155 {
3156         fl_hide_form(fd_form_quotes->form_quotes);
3157 }
3158
3159
3160 extern "C" void QuotesOKCB(FL_OBJECT * ob, long data)
3161 {
3162         QuotesApplyCB(ob, data);
3163         QuotesCancelCB(ob, data);
3164 }
3165
3166
3167
3168 /* callbacks for form form_preamble */
3169
3170 extern "C" void PreambleCancelCB(FL_OBJECT *, long)
3171 {
3172         fl_hide_form(fd_form_preamble->form_preamble);
3173 }
3174
3175
3176 extern "C" void PreambleApplyCB(FL_OBJECT *, long)
3177 {
3178         if (!current_view->available())
3179                 return;
3180         
3181         current_view->buffer()->params.preamble = 
3182                 fl_get_input(fd_form_preamble->input_preamble);
3183         current_view->buffer()->markDirty();
3184         current_view->owner()->getMiniBuffer()->Set(_("LaTeX preamble set"));
3185 }
3186
3187    
3188 extern "C" void PreambleOKCB(FL_OBJECT * ob, long data)
3189 {
3190         PreambleApplyCB(ob, data);
3191         PreambleCancelCB(ob, data);
3192 }
3193
3194
3195 /* callbacks for form form_table */
3196
3197 extern "C" void TableApplyCB(FL_OBJECT *, long)
3198 {
3199         if (!current_view->getScreen())
3200                 return;
3201    
3202         // check for tables in tables
3203         if (current_view->text->cursor.par->table){
3204                 WriteAlert(_("Impossible Operation!"),
3205                            _("Cannot insert table in table."),
3206                            _("Sorry."));
3207                 return;
3208         }
3209  
3210         current_view->owner()->getMiniBuffer()->Set(_("Inserting table..."));
3211
3212         int ysize = int(fl_get_slider_value(fd_form_table->slider_columns) + 0.5);
3213         int xsize = int(fl_get_slider_value(fd_form_table->slider_rows) + 0.5);
3214    
3215    
3216         current_view->getScreen()->HideCursor();
3217         current_view->beforeChange();
3218         current_view->update(-2);
3219    
3220         current_view->text->SetCursorParUndo(); 
3221         current_view->text->FreezeUndo();
3222
3223         current_view->text->BreakParagraph();
3224         current_view->update(-1);
3225    
3226         if (current_view->text->cursor.par->Last()) {
3227                 current_view->text->CursorLeft();
3228       
3229                 current_view->text->BreakParagraph();
3230                 current_view->update(-1);
3231         }
3232
3233         current_view->text->current_font.setLatex(LyXFont::OFF);
3234         //if (!fl_get_button(fd_form_table->check_latex)){
3235         // insert the new wysiwy table
3236         current_view->text->SetLayout(0); // standard layout
3237         if (current_view->text->cursor.par->footnoteflag == 
3238             LyXParagraph::NO_FOOTNOTE) {
3239                 current_view->text
3240                         ->SetParagraph(0, 0,
3241                                        0, 0,
3242                                        VSpace (0.3 * current_view->buffer()->
3243                                                params.spacing.getValue(),
3244                                                LyXLength::CM),
3245                                        VSpace (0.3 * current_view->buffer()->
3246                                                params.spacing.getValue(),
3247                                                LyXLength::CM),
3248                                        LYX_ALIGN_CENTER,
3249                                        string(),
3250                                        0);
3251         }
3252         else
3253                 current_view->text
3254                         ->SetParagraph(0, 0,
3255                                        0, 0,
3256                                        VSpace(VSpace::NONE),
3257                                        VSpace(VSpace::NONE),
3258                                        LYX_ALIGN_CENTER, 
3259                                        string(),
3260                                        0);
3261         
3262         current_view->text->cursor.par->table =
3263                 new LyXTable(xsize, ysize);
3264
3265         for (int i = 0; i < xsize * ysize - 1; ++i)
3266                 current_view->text->cursor.par->InsertChar(0, LyXParagraph::META_NEWLINE);
3267         current_view->text->RedoParagraph();
3268    
3269         current_view->text->UnFreezeUndo();
3270      
3271         current_view->update(1);
3272         current_view->owner()->getMiniBuffer()->Set(_("Table inserted"));
3273 }
3274
3275
3276 extern "C" void TableCancelCB(FL_OBJECT *, long)
3277 {
3278         fl_hide_form(fd_form_table->form_table);
3279 }
3280
3281
3282 extern "C" void TableOKCB(FL_OBJECT * ob, long data)
3283 {
3284         TableApplyCB(ob, data);
3285         TableCancelCB(ob, data);
3286 }
3287
3288
3289 /* callbacks for form form_print */
3290
3291 extern "C" void PrintCancelCB(FL_OBJECT *, long)
3292 {
3293         fl_hide_form(fd_form_print->form_print);
3294 }
3295
3296 static bool stringOnlyContains (string const & LStr, char const * cset)
3297 {
3298         char const * cstr = LStr.c_str() ;
3299
3300         return strspn(cstr, cset) == strlen(cstr) ;
3301 }
3302
3303 extern "C" void PrintApplyCB(FL_OBJECT *, long)
3304 {
3305         if (!current_view->available())
3306                 return;
3307         Buffer * buffer = current_view->buffer();
3308         string path = OnlyPath(buffer->fileName());
3309
3310         string pageflag;
3311         if (fl_get_button(fd_form_print->radio_even_pages))
3312                 pageflag = lyxrc->print_evenpage_flag + ' ';
3313         else if (fl_get_button(fd_form_print->radio_odd_pages))
3314                 pageflag = lyxrc->print_oddpage_flag + ' ';
3315
3316 // Changes by Stephan Witt (stephan.witt@beusen.de), 19-Jan-99
3317 // User may give a page (range) list
3318 // User may print multiple (unsorted) copies
3319         string pages = subst(fl_get_input(fd_form_print->input_pages), ';',',');
3320         pages = subst(pages, '+',',');
3321         pages = frontStrip(strip(pages)) ;
3322         while (!pages.empty()) { // a page range was given
3323                 string piece ;
3324                 pages = split (pages, piece, ',') ;
3325                 piece = strip(piece) ;
3326                 piece = frontStrip(piece) ;
3327                 if ( !stringOnlyContains (piece, "0123456789-") ) {
3328                         WriteAlert(_("ERROR!  Unable to print!"),
3329                                    _("Check 'range of pages'!"));
3330                         return;
3331                 }
3332                 if (piece.find('-') == string::npos) { // not found
3333                         pageflag += lyxrc->print_pagerange_flag + piece + '-' + piece + ' ' ;
3334                 } else if (suffixIs(piece, "-") ) { // missing last page
3335                         pageflag += lyxrc->print_pagerange_flag + piece + "1000 ";
3336                 } else if (prefixIs(piece, "-") ) { // missing first page
3337                         pageflag += lyxrc->print_pagerange_flag + '1' + piece + ' ' ;
3338                 } else {
3339                         pageflag += lyxrc->print_pagerange_flag + piece + ' ' ;
3340                 }
3341         }
3342    
3343         string copies = frontStrip(strip(fl_get_input(fd_form_print->input_copies)));
3344         if (!copies.empty()) { // a number of copies was given
3345                 if ( !stringOnlyContains (copies, "0123456789") ) {
3346                         WriteAlert(_("ERROR!  Unable to print!"),
3347                                    _("Check 'number of copies'!"));
3348                         return;
3349                 }
3350                 if (fl_get_button(fd_form_print->do_unsorted))
3351                         pageflag += lyxrc->print_copies_flag;
3352                 else
3353                         pageflag += lyxrc->print_collcopies_flag;
3354                 pageflag += " " + copies + ' ' ;
3355         }
3356
3357         string reverseflag;
3358         if (fl_get_button(fd_form_print->radio_order_reverse))
3359                 reverseflag = lyxrc->print_reverse_flag + ' ';
3360    
3361         string orientationflag;
3362         if (buffer->params.orientation == BufferParams::ORIENTATION_LANDSCAPE)
3363                 orientationflag = lyxrc->print_landscape_flag + ' ';
3364    
3365         string ps_file = fl_get_input(fd_form_print->input_file);
3366         string printer = strip(fl_get_input(fd_form_print->input_printer));
3367
3368         string printerflag;
3369         if (lyxrc->print_adapt_output // printer name should be passed to dvips
3370             && ! printer.empty()) // a printer name has been given
3371                 printerflag = lyxrc->print_to_printer + printer + ' ';
3372      
3373         string extraflags;
3374         if (!lyxrc->print_extra_options.empty())
3375                 extraflags = lyxrc->print_extra_options + ' ';
3376
3377         string command = lyxrc->print_command + ' ' 
3378                 + printerflag + pageflag + reverseflag 
3379                 + orientationflag + extraflags;
3380  
3381         char real_papersize = buffer->params.papersize;
3382         if (real_papersize == BufferParams::PAPER_DEFAULT)
3383                 real_papersize = lyxrc->default_papersize;
3384         
3385         string paper;
3386         switch (real_papersize) {
3387         case BufferParams::PAPER_USLETTER:
3388                 paper = "letter";
3389                 break;
3390         case BufferParams::PAPER_A3PAPER:
3391                 paper = "a3";
3392                 break;
3393         case BufferParams::PAPER_A4PAPER:
3394                 paper = "a4";
3395                 break;
3396         case BufferParams::PAPER_A5PAPER:
3397                 paper = "a5";
3398                 break;
3399         case BufferParams::PAPER_B5PAPER:
3400                 paper = "b5";
3401                 break;
3402         case BufferParams::PAPER_EXECUTIVEPAPER:
3403                 paper = "foolscap";
3404                 break;
3405         case BufferParams::PAPER_LEGALPAPER:
3406                 paper = "legal";
3407                 break;
3408         default: /* If nothing else fits, keep an empty value... */
3409                 break;
3410         }
3411
3412         if (buffer->params.use_geometry
3413             && buffer->params.papersize2 == BufferParams::VM_PAPER_CUSTOM
3414             && !lyxrc->print_paper_dimension_flag.empty()
3415             && !buffer->params.paperwidth.empty()
3416             && !buffer->params.paperheight.empty()) {
3417                 // using a custom papersize
3418                 command += ' ';
3419                 command += lyxrc->print_paper_dimension_flag + ' ';
3420                 command += buffer->params.paperwidth + ',';
3421                 command += buffer->params.paperheight + ' ';
3422         } else if (!lyxrc->print_paper_flag.empty()
3423                    && !paper.empty()
3424                    && (real_papersize != BufferParams::PAPER_USLETTER ||
3425                        buffer->params.orientation == BufferParams::ORIENTATION_PORTRAIT)) {
3426                 command += " " + lyxrc->print_paper_flag + " " + paper + " ";
3427         }
3428         if (fl_get_button(fd_form_print->radio_file))
3429                 command += lyxrc->print_to_file 
3430                         + QuoteName(MakeAbsPath(ps_file, path));
3431         else if (!lyxrc->print_spool_command.empty())
3432                 command += lyxrc->print_to_file 
3433                         + QuoteName(ps_file);
3434         
3435         // push directorypath, if necessary 
3436         if (lyxrc->use_tempdir || (IsDirWriteable(path) < 1)){
3437                 path = buffer->tmppath;
3438         }
3439         Path p(path);
3440
3441         bool result;
3442         if (!lyxrc->print_spool_command.empty() && 
3443             !fl_get_button(fd_form_print->radio_file)) {
3444                 string command2 = lyxrc->print_spool_command + ' ';
3445                 if (!printer.empty())
3446                         command2 += lyxrc->print_spool_printerprefix 
3447                                 + printer;
3448                 // First run dvips and, if succesful, then spool command
3449                 if ((result = RunScript(buffer, true, command))) {
3450                         result = RunScript(buffer, false, command2, ps_file);
3451                 }
3452         } else
3453                 result = RunScript(buffer, false, command);
3454
3455         if (!result)
3456                 WriteAlert(_("Error:"),
3457                            _("Unable to print"),
3458                            _("Check that your parameters are correct"));
3459 }
3460
3461
3462 extern "C" void PrintOKCB(FL_OBJECT * ob, long data)
3463 {
3464         PrintCancelCB(ob, data);  
3465         PrintApplyCB(ob, data);
3466 }
3467
3468
3469 /* callbacks for form form_figure */
3470 extern "C" void FigureApplyCB(FL_OBJECT *, long)
3471 {
3472         if (!current_view->available())
3473                 return;
3474
3475         Buffer * buffer = current_view->buffer();
3476         if(buffer->isReadonly()) // paranoia
3477                 return;
3478         
3479         current_view->owner()->getMiniBuffer()->Set(_("Inserting figure..."));
3480         if (fl_get_button(fd_form_figure->radio_inline)
3481             || current_view->text->cursor.par->table) {
3482                 InsetFig * new_inset = new InsetFig(100, 20, buffer);
3483                 current_view->insertInset(new_inset);
3484                 current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
3485                 new_inset->Edit(0, 0);
3486                 return;
3487         }
3488         
3489         current_view->getScreen()->HideCursor();
3490         current_view->update(-2);
3491         current_view->beforeChange();
3492       
3493         current_view->text->SetCursorParUndo(); 
3494         current_view->text->FreezeUndo();
3495
3496         current_view->text->BreakParagraph();
3497         current_view->update(-1);
3498       
3499         if (current_view->text->cursor.par->Last()) {
3500                 current_view->text->CursorLeft();
3501          
3502                 current_view->text->BreakParagraph();
3503                 current_view->update(-1);
3504         }
3505
3506         // The standard layout should always be numer 0;
3507         current_view->text->SetLayout(0);
3508         
3509         if (current_view->text->cursor.par->footnoteflag == 
3510             LyXParagraph::NO_FOOTNOTE) {
3511                 current_view->text->
3512                         SetParagraph(0, 0,
3513                                      0, 0,
3514                                      VSpace (0.3 * buffer->params.spacing.getValue(),
3515                                              LyXLength::CM),
3516                                      VSpace (0.3 *
3517                                              buffer->params.spacing.getValue(),
3518                                              LyXLength::CM),
3519                                      LYX_ALIGN_CENTER, string(), 0);
3520         } else
3521                 current_view->text->SetParagraph(0, 0,
3522                                                  0, 0,
3523                                                  VSpace(VSpace::NONE),
3524                                                  VSpace(VSpace::NONE),
3525                                                  LYX_ALIGN_CENTER, 
3526                                                  string(),
3527                                                  0);
3528         
3529         current_view->update(-1);
3530       
3531         Inset * new_inset = new InsetFig(100, 100, buffer);
3532         current_view->insertInset(new_inset);
3533         new_inset->Edit(0, 0);
3534         current_view->update(0);
3535         current_view->owner()->getMiniBuffer()->Set(_("Figure inserted"));
3536         current_view->text->UnFreezeUndo();
3537 }
3538
3539
3540 extern "C" void FigureCancelCB(FL_OBJECT *, long)
3541 {
3542         fl_hide_form(fd_form_figure->form_figure);
3543 }
3544
3545
3546 extern "C" void FigureOKCB(FL_OBJECT * ob, long data)
3547 {
3548         FigureApplyCB(ob, data);
3549         FigureCancelCB(ob, data);
3550 }
3551
3552
3553 extern "C" void ScreenApplyCB(FL_OBJECT *, long)
3554 {
3555         lyxrc->roman_font_name = fl_get_input(fd_form_screen->input_roman);
3556         lyxrc->sans_font_name = fl_get_input(fd_form_screen->input_sans);
3557         lyxrc->typewriter_font_name = fl_get_input(fd_form_screen->input_typewriter);
3558         lyxrc->font_norm = fl_get_input(fd_form_screen->input_font_norm);
3559         lyxrc->zoom = atoi(fl_get_input(fd_form_screen->intinput_size));
3560         fontloader.update();
3561    
3562         // All buffers will need resize
3563         bufferlist.resize();
3564
3565         current_view->owner()->getMiniBuffer()->Set(_("Screen options set"));
3566 }
3567
3568
3569 extern "C" void ScreenCancelCB(FL_OBJECT *, long)
3570 {
3571         fl_hide_form(fd_form_screen->form_screen);
3572 }
3573
3574
3575 extern "C" void ScreenOKCB(FL_OBJECT * ob, long data)
3576 {
3577         ScreenCancelCB(ob, data);
3578         ScreenApplyCB(ob, data);
3579 }
3580
3581
3582 void LaTeXOptions()
3583 {
3584         if (!current_view->available())
3585                 return;
3586
3587         fl_set_button(fd_latex_options->accents,
3588                       int(current_view->buffer()->params.allowAccents));
3589         
3590         if (fd_latex_options->LaTeXOptions->visible) {
3591                 fl_raise_form(fd_latex_options->LaTeXOptions);
3592         } else {
3593                 fl_show_form(fd_latex_options->LaTeXOptions,
3594                              FL_PLACE_MOUSE, FL_FULLBORDER,
3595                              _("LaTeX Options"));
3596         }
3597 }
3598
3599
3600 // This function runs "configure" and then rereads lyx.defaults to
3601 // reconfigure the automatic settings.
3602 void Reconfigure()
3603 {
3604         current_view->owner()->getMiniBuffer()->Set(_("Running configure..."));
3605
3606         // Run configure in user lyx directory
3607         Path p(user_lyxdir);
3608         Systemcalls one(Systemcalls::System, 
3609                         AddName(system_lyxdir, "configure"));
3610         p.pop();
3611         current_view->owner()->getMiniBuffer()->Set(_("Reloading configuration..."));
3612         lyxrc->read(LibFileSearch(string(), "lyxrc.defaults"));
3613         WriteAlert(_("The system has been reconfigured."), 
3614                    _("You need to restart LyX to make use of any"),
3615                    _("updated document class specifications."));
3616 }
3617
3618
3619 /* these functions are for the spellchecker */ 
3620 char * BufferView::nextWord(float & value)
3621 {
3622         if (!available()) {
3623                 value = 1;
3624                 return 0;
3625         }
3626
3627         char * string = text->SelectNextWord(value);
3628
3629         return string;
3630 }
3631
3632   
3633 void BufferView::selectLastWord()
3634 {
3635         if (!available()) return;
3636    
3637         getScreen()->HideCursor();
3638         beforeChange();
3639         text->SelectSelectedWord();
3640         getScreen()->ToggleSelection(false);
3641         update(0);
3642 }
3643
3644
3645 void BufferView::endOfSpellCheck()
3646 {
3647         if (!available()) return;
3648    
3649         getScreen()->HideCursor();
3650         beforeChange();
3651         text->SelectSelectedWord();
3652         text->ClearSelection();
3653         update(0);
3654 }
3655
3656
3657 void BufferView::replaceWord(string const & replacestring)
3658 {
3659         if (!getScreen()) return;
3660
3661         getScreen()->HideCursor();
3662         update(-2);
3663    
3664         /* clear the selection (if there is any) */ 
3665         getScreen()->ToggleSelection(false);
3666         update(-2);
3667    
3668         /* clear the selection (if there is any) */ 
3669         getScreen()->ToggleSelection(false);
3670         text->ReplaceSelectionWithString(replacestring.c_str());
3671    
3672         text->SetSelectionOverString(replacestring.c_str());
3673
3674         // Go back so that replacement string is also spellchecked
3675         for (string::size_type i = 0; i < replacestring.length() + 1; ++i) {
3676                 text->CursorLeftIntern();
3677         }
3678         update(1);
3679 }
3680 // End of spellchecker stuff
3681
3682
3683
3684 //
3685 // Table of Contents
3686 //
3687
3688 struct TocList {
3689         int counter[6];
3690         bool appendix;
3691         TocList * next;
3692 };
3693
3694
3695 static TocList * toclist = 0;
3696
3697
3698 extern "C" void TocSelectCB(FL_OBJECT * ob, long)
3699 {
3700         if (!current_view->available())
3701                 return;
3702    
3703         TocList * tmptoclist = toclist;
3704         int i = fl_get_browser(ob);
3705         for (int a = 1; a < i && tmptoclist->next; ++a) {
3706                 tmptoclist = tmptoclist->next;
3707         }
3708
3709         if (!tmptoclist)
3710                 return;
3711      
3712
3713         LyXParagraph * par = current_view->buffer()->paragraph;
3714         while (par && (par->GetFirstCounter(0) != tmptoclist->counter[0] ||
3715                        par->GetFirstCounter(1) != tmptoclist->counter[1] ||
3716                        par->GetFirstCounter(2) != tmptoclist->counter[2] ||
3717                        par->GetFirstCounter(3) != tmptoclist->counter[3] ||
3718                        par->GetFirstCounter(4) != tmptoclist->counter[4] ||
3719                        par->GetFirstCounter(5) != tmptoclist->counter[5] ||
3720                        par->appendix != tmptoclist->appendix)) {
3721                 par = par->LastPhysicalPar()->Next();
3722         }
3723    
3724         if (par) {
3725                 current_view->beforeChange();
3726                 current_view->text->SetCursor(par, 0);
3727                 current_view->text->sel_cursor = 
3728                         current_view->text->cursor;
3729                 current_view->update(0);
3730         }
3731         else {
3732                 WriteAlert(_("Error"), 
3733                            _("Couldn't find this label"), 
3734                            _("in current document."));
3735         }
3736           
3737 }
3738
3739
3740 extern "C" void TocCancelCB(FL_OBJECT *, long)
3741 {
3742         fl_hide_form(fd_form_toc->form_toc);
3743 }
3744
3745
3746 extern "C" void TocUpdateCB(FL_OBJECT *, long)
3747 {
3748         static LyXParagraph * stapar = 0;
3749         TocList * tmptoclist = 0;
3750    
3751         /* deleted the toclist */ 
3752         if (toclist){
3753                 while (toclist){
3754                         tmptoclist = toclist->next;
3755                         delete toclist;
3756                         toclist = tmptoclist;
3757                 }
3758         }
3759         toclist = 0;
3760         tmptoclist = toclist;
3761
3762
3763         fl_clear_browser(fd_form_toc->browser_toc);
3764         if (!current_view->available()) {
3765                 fl_add_browser_line(fd_form_toc->browser_toc,
3766                                     _("*** No Document ***"));
3767                 return;
3768         }
3769         fl_hide_object(fd_form_toc->browser_toc);
3770         /* get the table of contents */ 
3771         LyXParagraph * par = current_view->buffer()->paragraph;
3772         char labeltype;
3773         char * line = new char[200];
3774         int pos = 0;
3775         unsigned char c;
3776         int topline = 0;
3777    
3778         if (stapar == par)
3779                 topline = fl_get_browser_topline(fd_form_toc->browser_toc);
3780         stapar = par;
3781    
3782         while (par) {
3783                 labeltype = textclasslist.Style(current_view->buffer()->params.textclass, 
3784                                                 par->GetLayout()).labeltype;
3785       
3786                 if (labeltype >= LABEL_COUNTER_CHAPTER
3787                     && labeltype <= LABEL_COUNTER_CHAPTER +
3788                     current_view->buffer()->params.tocdepth) {
3789                         /* insert this into the table of contents */ 
3790                         /* first indent a little bit */ 
3791                         
3792                         for (pos = 0; 
3793                              pos < (labeltype - 
3794                                     textclasslist.TextClass(current_view->buffer()->
3795                                                             params.textclass).maxcounter()) * 4 + 2;
3796                              ++pos)
3797                                 line[pos] = ' ';
3798                         
3799                         // Then the labestring
3800                         if (!par->labelstring.empty()) {
3801                                 string::size_type i = 0;
3802                                 while (pos < 199 && i < par->labelstring.length()) {
3803                                         line[pos] = par->labelstring[i];
3804                                         ++i;
3805                                         ++pos;
3806                                 }
3807                         }
3808          
3809                         line[pos] = ' ';
3810                         ++pos;
3811                         
3812                         /* now the contents */
3813                         LyXParagraph::size_type i = 0;
3814                         while (pos < 199 && i < par->size()) {
3815                                 c = par->GetChar(i);
3816                                 if (isprint(c) || c >= 128) {
3817                                         line[pos] = c;
3818                                         ++pos;
3819                                 }
3820                                 ++i;
3821                         }
3822                         line[pos] = '\0';
3823                         fl_add_browser_line(fd_form_toc->browser_toc, line);
3824                         
3825                         /* make a toclist entry */
3826                         if (!tmptoclist){
3827                                 tmptoclist = new TocList;
3828                                 toclist = tmptoclist;
3829                         } else {
3830                                 tmptoclist->next = new TocList;
3831                                 tmptoclist = tmptoclist->next;
3832                         }
3833                         
3834                         tmptoclist->next = 0;
3835                         int a = 0;
3836                         for (a = 0; a < 6; ++a) {
3837                                 tmptoclist->counter[a] = par->GetFirstCounter(a);
3838                         }
3839                         tmptoclist->appendix = par->appendix;
3840                 }
3841                 par = par->LastPhysicalPar()->Next();
3842                 
3843         }
3844         delete[] line;
3845         fl_set_browser_topline(fd_form_toc->browser_toc, topline);
3846         fl_show_object(fd_form_toc->browser_toc);
3847 }
3848
3849
3850 /* callbacks for form form_ref */
3851 extern "C" void RefSelectCB(FL_OBJECT *, long data)
3852 {
3853         if (!current_view->available())
3854                 return;
3855
3856         string s = 
3857                 fl_get_browser_line(fd_form_ref->browser_ref,
3858                                     fl_get_browser(fd_form_ref->browser_ref));
3859         string u = frontStrip(strip(fl_get_input(fd_form_ref->ref_name)));
3860
3861         if (s.empty())
3862                 return;
3863
3864         if (data == 2) {
3865                 current_view->owner()->getLyXFunc()->Dispatch(LFUN_REFGOTO, s.c_str());
3866                 return;
3867         }
3868             
3869         string t;
3870         if (data == 0)
3871                 t += "\\ref";
3872         else
3873                 t += "\\pageref";
3874
3875         if(current_view->buffer()->isSGML())
3876                 t += "[" + u + "]" + "{" + s + "}";
3877         else
3878                 t += "{" + s + "}";
3879
3880         Inset * new_inset = 
3881                 new InsetRef(t, current_view->buffer());
3882         current_view->insertInset(new_inset);
3883 }
3884
3885
3886 extern "C" void RefUpdateCB(FL_OBJECT *, long)
3887 {
3888         if (!current_view->available()) {
3889                 fl_clear_browser(fd_form_ref->browser_ref);
3890                 return;
3891         }
3892
3893         FL_OBJECT * brow = fd_form_ref->browser_ref;
3894
3895         // Get the current line, in order to restore it later
3896         char const * const btmp = fl_get_browser_line(brow,
3897                                                       fl_get_browser(brow));
3898         string currentstr = btmp ? btmp : "";
3899
3900         fl_clear_browser(brow);
3901
3902         string refs = current_view->buffer()->getReferenceList('\n');
3903         int topline = 1;
3904
3905 #if FL_REVISION > 85
3906         fl_addto_browser_chars(brow, refs.c_str());
3907         int total_lines = fl_get_browser_maxline(brow);
3908         for (int i = 1; i <= total_lines ; ++i) {
3909                 if (fl_get_browser_line(brow, i) == currentstr) {
3910                         topline = i;
3911                         break;
3912                 }
3913         }
3914         fl_set_browser_topline(brow, topline);
3915 #else
3916         // Keep the old ugly code for xforms 0.81 compatibility
3917         string curr_ref;
3918         int ref_num = 0;
3919                                        
3920         while(true) {
3921                 curr_ref = refs.token('\n', ref_num);
3922                 if (curr_ref.empty())
3923                         break;
3924                 fl_add_browser_line(brow, curr_ref.c_str());
3925                 ++ref_num;
3926         }
3927 #endif
3928
3929         if (!fl_get_browser_maxline(brow)) {
3930                 fl_add_browser_line(brow, 
3931                                     _("*** No labels found in document ***"));
3932                 fl_deactivate_object(brow);
3933         } else {
3934                 fl_select_browser_line(brow, topline);
3935                 fl_activate_object(brow);
3936         }
3937         if (current_view->buffer()->isReadonly()) {
3938                 // would be better to de/activate insert buttons
3939                 // but that's more work... besides this works. ARRae
3940                 fl_hide_form(fd_form_ref->form_ref);
3941         }
3942         if (!current_view->buffer()->isSGML()) {
3943                 fl_deactivate_object(fd_form_ref->ref_name);
3944                 fl_set_object_lcol(fd_form_ref->ref_name, FL_INACTIVE);
3945         }
3946         else {
3947                 fl_activate_object(fd_form_ref->ref_name);
3948                 fl_set_object_lcol(fd_form_ref->ref_name, FL_BLACK);
3949         }
3950 }
3951
3952
3953 extern "C" void RefHideCB(FL_OBJECT *, long)
3954 {
3955         fl_hide_form(fd_form_ref->form_ref);
3956 }
3957
3958
3959 // candidate for move to BufferView
3960 void UpdateInset(Inset * inset, bool mark_dirty)
3961 {
3962         if (!inset)
3963                 return;
3964
3965         /* very first check for locking insets*/
3966         if (current_view->the_locking_inset == inset) {
3967                 if (current_view->text->UpdateInset(inset)){
3968                         current_view->update();
3969                         if (mark_dirty){
3970                                 if (current_view->buffer()->isLyxClean())
3971                                         current_view->owner()->getMiniBuffer()->setTimer(4);
3972                                 current_view->buffer()->markDirty();
3973                         }
3974                         current_view->updateScrollbar();
3975                         return;
3976                 }
3977         }
3978   
3979         /* first check the current buffer */
3980         if (current_view->available()){
3981                 current_view->getScreen()->HideCursor();
3982                 current_view->update(-3);
3983                 if (current_view->text->UpdateInset(inset)){
3984                         if (mark_dirty)
3985                                 current_view->update(1);
3986                         else 
3987                                 current_view->update(3);
3988                         return;
3989                 }
3990         }
3991   
3992         // check all buffers
3993         bufferlist.updateInset(inset, mark_dirty);
3994
3995 }
3996
3997
3998 /* these functions return 1 if an error occured, 
3999    otherwise 0 */
4000 int BufferView::lockInset(UpdatableInset * inset)
4001 {
4002         if (!the_locking_inset && inset){
4003                 the_locking_inset = inset;
4004                 return 0;
4005         }
4006         return 1;
4007 }
4008
4009
4010 void BufferView::showLockedInsetCursor(long x, long y, int asc, int desc)
4011 {
4012         if (the_locking_inset && getScreen()) {
4013                 y += text->cursor.y;
4014                 getScreen()->ShowManualCursor(x, y,
4015                                               asc, desc);
4016         }
4017 }
4018
4019
4020 void BufferView::hideLockedInsetCursor(long x, long y, int asc, int desc)
4021 {
4022         if (the_locking_inset && getScreen()) {
4023                 y += text->cursor.y;
4024                 getScreen()->HideManualCursor(x, y,
4025                                               asc, desc);
4026         }
4027 }
4028
4029
4030 void BufferView::fitLockedInsetCursor(long x, long y, int asc, int desc)
4031 {
4032         if (the_locking_inset && getScreen()){
4033                 y += text->cursor.y;
4034                 if (getScreen()->FitManualCursor(x, y, asc, desc))
4035                         updateScrollbar();
4036         }
4037 }
4038
4039
4040 int BufferView::unlockInset(UpdatableInset * inset)
4041 {
4042         if (inset && the_locking_inset == inset) {
4043                 inset->InsetUnlock();
4044                 the_locking_inset = 0;
4045                 text->FinishUndo();
4046                 return 0;
4047         }
4048         return bufferlist.unlockInset(inset);
4049 }
4050
4051
4052 void BufferView::lockedInsetStoreUndo(Undo::undo_kind kind)
4053 {
4054         if (!the_locking_inset)
4055                 return; // shouldn't happen
4056         if (kind == Undo::EDIT) // in this case insets would not be stored!
4057                 kind = Undo::FINISH;
4058         text->SetUndo(kind,
4059                       text->cursor.par->
4060                       ParFromPos(text->cursor.pos)->previous, 
4061                       text->cursor.par->
4062                       ParFromPos(text->cursor.pos)->next);
4063 }
4064
4065
4066 void PutInsetIntoInsetUpdateList(Inset * inset)
4067 {
4068         Assert(inset);
4069         InsetUpdateStruct * tmp = new InsetUpdateStruct();
4070         tmp->inset = inset;
4071         tmp->next = InsetUpdateList;
4072         InsetUpdateList = tmp;
4073 }
4074
4075
4076 void UpdateInsetUpdateList()
4077 {
4078         InsetUpdateStruct * tmp = InsetUpdateList;
4079         while (tmp) {
4080                 UpdateInset(tmp->inset, false); // "false" because no document change
4081                 tmp = tmp->next;
4082         }
4083   
4084         // delete the update list
4085         while (InsetUpdateList) {
4086                 tmp = InsetUpdateList;
4087                 InsetUpdateList = InsetUpdateList->next;
4088                 delete tmp;
4089         }
4090         InsetUpdateList = 0;
4091 }
4092
4093
4094 #ifdef WITH_WARNINGS
4095 #warning UGLY!!
4096 #endif
4097 // I know we shouldn't put anything in here but this seems the fastest
4098 // way to do this (and the cleanest for now). This function just inserts
4099 // a newline in the string and the inserts 'depth'-spaces so that the
4100 // code is indented in the right way!!!
4101 void addNewlineAndDepth(string & file, int const depth)
4102 {
4103         file += '\n';
4104         file.append(depth, ' ');
4105 }