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