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