]> git.lyx.org Git - features.git/blob - src/lyxfunc.C
The command-sequence patch from Andre'; also remove the comment in first
[features.git] / src / lyxfunc.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-1999 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #include <cstdlib>
14 #include <cctype>
15 #include <cstring>
16
17 #ifdef __GNUG__
18 #pragma implementation
19 #endif
20
21 #include "lyxlookup.h"
22 #include "kbmap.h"
23 #include "lyxfunc.h"
24 #include "bufferlist.h"
25 #include "lyxserver.h"
26 #include "lyx.h"
27 #include "intl.h"
28 #include "lyx_main.h"
29 #include "lyx_cb.h"
30 #if 0
31 #include "insets/insetlatex.h"
32 #endif
33 #include "insets/inseturl.h"
34 #include "insets/insetlatexaccent.h"
35 #include "insets/insettoc.h"
36 #include "insets/insetlof.h"
37 #include "insets/insetloa.h"
38 #include "insets/insetlot.h"
39 #include "insets/insetref.h"
40 #include "insets/insetparent.h"
41 #include "insets/insetindex.h"
42 #include "insets/insetinclude.h"
43 #include "insets/insetbib.h"
44 #include "mathed/formulamacro.h"
45 #include "toolbar.h"
46 #include "spellchecker.h" // RVDK_PATCH_5
47 #include "minibuffer.h"
48 #include "vspace.h"
49 #include "LyXView.h"
50 #include "filedlg.h"
51 #include "lyx_gui_misc.h"
52 #include "support/filetools.h"
53 #include "support/FileInfo.h"
54 #include "support/LAssert.h"
55 #include "support/syscall.h"
56 #include "support/lstrings.h"
57 #include "support/path.h"
58 #include "lyxscreen.h"
59 #include "debug.h"
60 #include "lyxrc.h"
61 #include "lyxtext.h"
62 #include "gettext.h"
63 #include "trans_mgr.h"
64 #include "ImportLaTeX.h"
65 #include "ImportNoweb.h"
66 #include "layout.h"
67
68 extern bool cursor_follows_scrollbar;
69
70 extern void InsertAsciiFile(string const &, bool);
71 extern void math_insert_symbol(char const*);
72 extern Bool math_insert_greek(char const); // why "Bool"?
73 extern BufferList bufferlist;
74 extern LyXServer * lyxserver;
75 extern short greek_kb_flag;
76 extern FD_form_toc * fd_form_toc;
77 extern bool selection_possible;
78
79 extern kb_keymap * toplevel_keymap;
80
81 extern void BeforeChange();
82 extern void MenuWrite(Buffer*);
83 extern void MenuWriteAs(Buffer*);
84 extern int  MenuRunLaTeX(Buffer*);
85 extern int  MenuBuildProg(Buffer*);
86 extern int  MenuRunChktex(Buffer*);
87 extern bool MenuRunDvips(Buffer *, bool);
88 extern void MenuPrint(Buffer*);
89 extern void MenuSendto();
90 extern void QuitLyX();
91 extern void MenuFax(Buffer *);
92 extern void MenuMakeLaTeX(Buffer *);
93 extern void MenuMakeLinuxDoc(Buffer *);
94 extern void MenuMakeDocBook(Buffer *);
95 extern void MenuMakeAscii(Buffer *);
96 extern void MenuPasteSelection(char at);
97 extern LyXAction lyxaction;
98 // (alkis)
99 extern tex_accent_struct get_accent(kb_action action);
100
101 extern void AutoSave();
102 extern void MenuSearch();
103 extern void CopyCB();
104 extern void CopyEnvironmentCB();
105 extern void PasteEnvironmentCB();
106 extern void GotoNote();
107 extern void NoteCB();
108 extern void OpenStuff();
109 extern void HyphenationPoint();
110 extern void Ldots();
111 extern void EndOfSentenceDot();
112 extern void MenuSeparator();
113 extern void HFill();
114 extern void MenuUndo();
115 extern void MenuRedo();
116 extern void SmallUpdate(signed char);
117 extern void SetUpdateTimer(float timer= 0.3);
118 extern void FreeUpdateTimer();
119 extern bool MenuPreview(Buffer*);
120 extern bool MenuPreviewPS(Buffer*);
121 extern void MenuInsertLabel(char const *);
122 extern void MenuInsertRef();
123 extern void MenuLayoutCharacter();
124 extern void MenuLayoutParagraph();
125 extern void MenuLayoutDocument();
126 extern void MenuLayoutPaper();
127 extern void MenuLayoutTable(int flag);
128 extern void MenuLayoutQuotes();
129 extern void MenuLayoutPreamble();
130 extern void MenuLayoutSave();
131 extern void bulletForm();
132
133 extern Buffer * NewLyxFile(string const &);
134 extern void LoadLyXFile(string const &);
135 extern void Reconfigure();
136
137 extern int current_layout;
138 extern int getISOCodeFromLaTeX(char *);
139
140 extern int UnlockInset(UpdatableInset*);
141
142 extern void ShowLatexLog();
143
144 extern void UpdateInset(Inset* inset, bool mark_dirty = true);
145
146 /* === globals =========================================================== */
147
148 bool LyXFunc::show_sc = true;
149
150
151 LyXFunc::LyXFunc(LyXView *o)
152         :owner(o)
153 {
154         meta_fake_bit = 0;
155         lyx_dead_action = LFUN_NOACTION;
156         lyx_calling_dead_action = LFUN_NOACTION;
157         setupLocalKeymap();
158 }
159
160
161 LyXFunc::~LyXFunc()
162 {
163 }
164
165
166 // I changed this func slightly. I commented out the ...FinishUndo(),
167 // this means that all places that used to have a moveCursorUpdate, now
168 // have a ...FinishUndo() as the preceeding statement. I have also added
169 // a moveCursorUpdate to some of the functions that updated the cursor, but
170 // that did not show its new position.
171 inline
172 void LyXFunc::moveCursorUpdate(bool selecting)
173 {
174         if (selecting || owner->buffer()->text->mark_set) {
175                 owner->buffer()->text->SetSelection();
176                 owner->currentView()->getScreen()->ToggleToggle();
177                 owner->buffer()->update(0);
178         } else {
179                 owner->buffer()->update(-2); // this IS necessary
180                 // (Matthias) 
181         }
182         owner->currentView()->getScreen()->ShowCursor();
183         
184         /* ---> Everytime the cursor is moved, show the current font state. */
185         // should this too me moved out of this func?
186         //owner->getMiniBuffer()->Set(CurrentState());
187 }
188
189
190 int LyXFunc::processKeyEvent(XEvent *ev)
191 {
192         char s_r[10];
193         s_r[9] = '\0';
194         int num_bytes;
195         int action; 
196         string argument;
197         XKeyEvent *keyevent = &ev->xkey;
198         KeySym keysym_return;
199
200         num_bytes = LyXLookupString(ev, s_r, 10, &keysym_return);
201
202         if (lyxerr.debugging(Debug::KEY)) {
203                 lyxerr << "KeySym is "
204                        << XKeysymToString(keysym_return)
205                        << "["
206                        << keysym_return << "]"
207                        << " and num_bytes is "
208                        << num_bytes
209                        << " the string returned is \""
210                        << s_r << '\"' << endl;
211         }
212         // Do nothing if we have nothing (JMarc)
213         if (num_bytes == 0 && keysym_return == NoSymbol) {
214                 lyxerr[Debug::KEY] << "Empty kbd action (probably composing)"
215                                    << endl;
216                 return 0;
217         }
218         
219         // this function should be used always [asierra060396]
220         if (owner->currentView()->available() &&
221             owner->buffer()->the_locking_inset &&
222             keysym_return == XK_Escape) {
223                 UnlockInset(owner->buffer()->the_locking_inset);
224                 owner->buffer()->text->CursorRight();
225                 return 0;
226         }
227
228         // Can we be sure that this will work for all X-Windows
229         // implementations? (Lgb)
230         // This code snippet makes lyx ignore some keys. Perhaps
231         // all of them should be explictly mentioned?
232         if((keysym_return >= XK_Shift_L && keysym_return <= XK_Hyper_R)
233            || keysym_return == XK_Mode_switch || keysym_return == 0x0)
234                 return 0;
235
236         // Do a one-deep top-level lookup for
237         // cancel and meta-fake keys. RVDK_PATCH_5
238         cancel_meta_seq.reset();
239
240         action = cancel_meta_seq.addkey(keysym_return, keyevent->state
241                                         &(ShiftMask|ControlMask
242                                           |Mod1Mask)); 
243
244         // When not cancel or meta-fake, do the normal lookup. 
245         // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards.
246         // Mostly, meta_fake_bit = 0. RVDK_PATCH_5.
247         if ( (action != LFUN_CANCEL) && (action != LFUN_META_FAKE) ) {
248
249                 // remove Caps Lock and Mod2 as a modifiers
250                 action = keyseq.addkey(keysym_return,
251                                        (keyevent->state | meta_fake_bit)
252                                        &(ShiftMask|ControlMask
253                                          |Mod1Mask));      
254         }
255         // Dont remove this unless you know what you are doing.
256         meta_fake_bit = 0;
257                 
258         if (action == 0) action = LFUN_PREFIX;
259
260         if (lyxerr.debugging(Debug::KEY)) {
261                 char buf[100];
262                 keyseq.print(buf, 100);
263                 lyxerr << "Key ["
264                        << action << "]["
265                        << buf << "]["
266                        << num_bytes << "]" << endl;
267         }
268
269         // already here we know if it any point in going further
270         // why not return already here if action == -1 and
271         // num_bytes == 0? (Lgb)
272
273         if(keyseq.length>1 || keyseq.length<-1){
274                 char buf[100];
275                 keyseq.print(buf, 100);
276                 owner->getMiniBuffer()->Set(buf);
277         }
278
279         if (action == -1) {
280                 if (keyseq.length<-1) { // unknown key sequence...
281                         char buf[100];
282                         LyXBell();
283                         keyseq.print(buf, 100);
284                         owner->getMiniBuffer()->Set(_("Unknown sequence:"), buf);
285                         return 0;
286                 }
287         
288                 char isochar = keyseq.getiso();
289                 if (!(keyevent->state&ControlMask) &&
290                     !(keyevent->state&Mod1Mask) &&
291                     (isochar && keysym_return < 0xF000)) {
292                         argument += isochar;
293                 }
294                 if (argument.empty()) {
295                         lyxerr.debug() << "Empty argument!" << endl;
296                         // This can`t possibly be of any use
297                         // so we`ll skip the dispatch.
298                         return 0;
299                 }
300         } else
301                 if (action == LFUN_SELFINSERT) {
302                         argument = s_r[0];
303                 }
304     
305         bool tmp_sc = show_sc;
306         show_sc = false;
307         Dispatch(action, argument.c_str());
308         show_sc = tmp_sc;
309         
310         return 0;
311
312
313
314 string LyXFunc::Dispatch(string const& s) 
315 {
316   // Split command string into command and argument
317         string cmd, line = frontStrip(s);
318         string arg = strip(frontStrip(split(line, cmd, ' ')));
319
320         return Dispatch(lyxaction.LookupFunc(cmd.c_str()), arg.c_str());
321 }
322
323
324 string LyXFunc::Dispatch(int ac,
325                           char const *do_not_use_this_arg)
326 {
327         string argument;
328         kb_action action;
329         
330
331         FL_OBJECT *ob = 0;  // This will disapear soon
332     
333         // we have not done anything wrong yet.
334         errorstat = false;
335         dispatch_buffer = string();
336         
337         // if action is a pseudo-action, we need the real action
338         if (lyxaction.isPseudoAction(ac)) {
339                 char const *tmparg = 0;
340                 action = (kb_action)lyxaction.retrieveActionArg(ac, &tmparg);
341                 if (tmparg)
342                         argument = tmparg;
343         } else {
344                 action = (kb_action)ac;
345                 if (do_not_use_this_arg)
346                         argument = do_not_use_this_arg; // except here
347         }
348     
349         selection_possible = false;
350         
351         if (owner->currentView()->available() 
352             && owner->currentView()->getScreen())
353                 owner->currentView()->getScreen()->HideCursor();
354
355         if(!owner->currentView()->available()) {
356                 // This lists the allowed funcs when we have no
357                 // buffer loaded
358                 switch(action){
359                 case LFUN_MENU_OPEN_BY_NAME:
360                 case LFUN_PREFIX:
361                 case LFUN_MENUNEW:
362                 case LFUN_MENUNEWTMPLT:
363                 case LFUN_MENUOPEN:
364                 case LFUN_QUIT:
365                 case LFUN_PUSH_TOOLBAR:
366                 case LFUN_ADD_TO_TOOLBAR:
367                 case LFUN_EXEC_COMMAND:
368                 case LFUN_DROP_LAYOUTS_CHOICE:
369                 case LFUN_FILE_NEW:
370                 case LFUN_FILE_OPEN:
371                 case LFUN_IMPORT:
372                 case LFUN_RECONFIGURE:
373                 case LFUN_CANCEL:
374                 case LFUN_APROPOS:
375                 case LFUN_META_FAKE:
376
377                         break;
378                 case LFUN_UNKNOWN_ACTION:
379                         setErrorMessage(N_("Unknown action"));
380                         goto exit_with_message;
381                 default:
382                         setErrorMessage(N_("Command not allowed with"
383                                         "out any document open"));
384                         goto exit_with_message;  // action not allowed
385                 }
386         }
387         
388         commandshortcut = string();
389         
390         if (lyxrc->display_shortcuts && show_sc) {
391                 if (action != LFUN_SELFINSERT) {
392                         // Put name of command and list of shortcuts
393                         // for it in minibuffer
394                         string comname = lyxaction.getActionName(action);
395
396                         int pseudoaction = action;
397                         bool argsadded = false;
398
399                         if (!argument.empty()) {
400                                 // If we have the command with argument, 
401                                 // this is better
402                                 pseudoaction = 
403                                         lyxaction.searchActionArg(action,
404                                                                   argument.c_str());
405
406                                 if (pseudoaction == -1) {
407                                         pseudoaction = action;
408                                 } else {
409                                         comname += " " + argument;
410                                         argsadded = true;
411                                 }
412                         }
413
414                         string shortcuts = toplevel_keymap->findbinding(pseudoaction);
415
416                         if (!shortcuts.empty()) {
417                                 comname += ": " + shortcuts;
418                         } else if (!argsadded) {
419                                 comname += " " + argument;
420                         }
421
422                         if (!comname.empty()) {
423                                 comname = strip(comname);
424                                 commandshortcut = "(" + comname + ')';
425                                 owner->getMiniBuffer()->Set(commandshortcut);
426                                 // Here we could even add a small pause,
427                                 // to annoy the user and make him learn
428                                 // the shortcuts.
429                                 // No! That will just annoy, not teach
430                                 // anything. The user will read the messages
431                                 // if they are interested. (Asger)
432                         }
433                 }
434         }
435
436         // Now that we know which action, if the buffer is RO let's check 
437         // whether the action is legal.  Alejandro 970603
438         if (owner->currentView()->available() && 
439             owner->buffer()->isReadonly() && 
440             lyxaction.isFuncRO(action)) {
441                 setErrorMessage(N_("Document is read-only"));
442                 lyxerr.debug() << "Error: Document is read-only." << endl;
443                 goto exit_with_message;
444         }
445
446         // If in math mode pass the control to
447         // the math inset [asierra060396]
448         if (owner->currentView()->available() &&
449             owner->buffer()->the_locking_inset) {
450                 if (action>1 || (action == LFUN_UNKNOWN_ACTION && keyseq.length>= -1)) {
451                         if (action == LFUN_UNKNOWN_ACTION && argument.empty()) {
452                                 argument = keyseq.getiso();
453                         }
454                         // Undo/Redo pre 0.13 is a bit tricky for insets.                   
455                         if (action == LFUN_UNDO) {
456                                 int slx, sly;
457                                 UpdatableInset* inset = 
458                                         owner->buffer()->the_locking_inset;
459                                 inset->GetCursorPos(slx, sly);
460                                 UnlockInset(inset);
461                                 MenuUndo();
462                                 inset = (UpdatableInset*)owner->buffer()->text->cursor.par->GetInset(owner->buffer()->text->cursor.pos);
463                                 if (inset) 
464                                         inset->Edit(slx, sly);
465                                 return string();
466                         } else 
467                                 if (action == LFUN_REDO) {
468                                         int slx, sly;
469                                         UpdatableInset* inset = owner->buffer()->the_locking_inset;
470                                         inset->GetCursorPos(slx, sly);
471                                         UnlockInset(inset);
472                                         MenuRedo();
473                                         inset = (UpdatableInset*)owner->buffer()->text->cursor.par->GetInset(owner->buffer()->text->cursor.pos);
474                                         if (inset)
475                                                 inset->Edit(slx, sly);
476                                         return string();
477                                 } else
478                                         if (owner->buffer()->the_locking_inset->LocalDispatch(action, argument.c_str()))
479                                                 return string();
480                                         else {
481                                                 setMessage(N_("Text mode"));
482                                                 if (action == LFUN_RIGHT || action == -1)
483                                                         owner->buffer()->text->CursorRight();
484                                                 if (action == LFUN_LEFT || action == LFUN_RIGHT)
485                                                         return string();
486                                         }
487                 }
488         }
489
490         switch(action) {
491                 // --- Misc -------------------------------------------
492         case LFUN_WORDFINDFORWARD  : 
493         case LFUN_WORDFINDBACKWARD : {
494                 static string last_search;
495                 string searched_string;
496             
497                 if (!argument.empty()) {
498                         last_search = argument;
499                         searched_string = argument;
500                 } else {
501                         searched_string = last_search;
502                 }
503
504                 LyXText * ltCur = owner->currentView()->buffer()->text ;
505
506                 if (!searched_string.empty() &&
507                     (    (action == LFUN_WORDFINDBACKWARD) ? 
508                          ltCur->SearchBackward( searched_string.c_str() ) :
509                          ltCur->SearchForward(  searched_string.c_str() ) 
510                          )){
511
512                         // ??? What is that ???
513                         owner->currentView()->buffer()->update(-2);
514
515                         // ??? Needed ???
516                         // clear the selection (if there is any) 
517                         owner->currentView()->getScreen()->ToggleSelection();
518                         owner->currentView()->buffer()->text->ClearSelection();
519
520                         // Move cursor so that successive C-s 's will not stand in place. 
521                         if( action == LFUN_WORDFINDFORWARD ) 
522                                 owner->buffer()->text->CursorRightOneWord();
523                         owner->buffer()->text->FinishUndo();
524                         moveCursorUpdate(false);
525
526                         // ??? Needed ???
527                         // set the new selection 
528                         // SetSelectionOverLenChars(owner->currentView()->currentBuffer()->text, iLenSelected);
529                         owner->currentView()->getScreen()->ToggleSelection(false);
530                 } else 
531                         LyXBell();      
532          
533                 // REMOVED : if (owner->currentView()->getWorkArea()->focus)
534                 owner->currentView()->getScreen()->ShowCursor();
535         }
536         break;
537
538         case LFUN_PREFIX:
539         {
540                 if (owner->currentView()->available()
541                     && owner->currentView()->getScreen()) {
542                         owner->buffer()->update(-2);
543                 }
544                 char buf[100];
545                 keyseq.print(buf, 100, true);
546                 owner->getMiniBuffer()->Set(buf, string(), string(), 1);
547         }
548         break;
549
550         // --- Misc -------------------------------------------
551         case LFUN_EXEC_COMMAND:
552                 owner->getMiniBuffer()->ExecCommand(); 
553                 break;
554                 
555         case LFUN_CANCEL:                   // RVDK_PATCH_5
556                 keyseq.reset();
557                 meta_fake_bit = 0;
558                 if(owner->currentView()->available())
559                         // cancel any selection
560                         Dispatch(int(LFUN_MARK_OFF), 0);
561                 setMessage(N_("Cancel"));
562                 break;
563
564         case LFUN_META_FAKE:                                 // RVDK_PATCH_5
565         {
566                 meta_fake_bit = Mod1Mask;
567                 char buf[100];
568                 keyseq.print(buf, 98, true);
569                 string res = string("M-") + buf;
570                 setMessage(buf); // RVDK_PATCH_5
571         }
572         break;  
573
574         case LFUN_READ_ONLY_TOGGLE:
575                 if (owner->buffer()->lyxvc.inUse()) {
576                         owner->buffer()->lyxvc.toggleReadOnly();
577                 } else {
578                         owner->buffer()->setReadonly(
579                                 !owner->buffer()->isReadonly());
580                 }
581                 break;
582                 
583         case LFUN_CENTER: // this is center and redraw.
584                 BeforeChange();
585                 if (owner->buffer()->text->cursor.y >
586                     owner->currentView()->getWorkArea()->h / 2) {
587                         owner->currentView()->getScreen()->
588                                 Draw(owner->buffer()->text->cursor.y -
589                                      owner->currentView()->getWorkArea()->h/2);
590                 } else { // <= 
591                         owner->currentView()->getScreen()->
592                                 Draw(0);
593                 }
594                 owner->buffer()->update(0);
595                 owner->currentView()->redraw();
596                 break;
597                 
598         case LFUN_APPENDIX:
599                 if (owner->currentView()->available()) {
600                         owner->buffer()->text->toggleAppendix();
601                         owner->buffer()->update(1);
602                 }
603                 break;
604
605         // --- Menus -----------------------------------------------
606         case LFUN_MENUNEW:
607                 MenuNew(false);
608                 break;
609                 
610         case LFUN_MENUNEWTMPLT:
611                 MenuNew(true);
612                 break;
613                 
614         case LFUN_MENUOPEN:
615                 MenuOpen();
616                 break;
617                 
618         case LFUN_CLOSEBUFFER:
619                 CloseBuffer();
620                 break;
621                 
622         case LFUN_MENUWRITE:
623                 MenuWrite(owner->buffer());
624                 break;
625                 
626         case LFUN_MENUWRITEAS:
627                 MenuWriteAs(owner->buffer());
628                 break;
629                 
630         case LFUN_MENURELOAD:
631                 reloadBuffer();
632                 break;
633                 
634         case LFUN_PREVIEW:
635                 MenuPreview(owner->buffer());
636                 break;
637                         
638         case LFUN_PREVIEWPS:
639                 MenuPreviewPS(owner->buffer());
640                 break;
641                 
642         case LFUN_RUNLATEX:
643                 MenuRunLaTeX(owner->buffer());
644                 break;
645                 
646         case LFUN_BUILDPROG:
647                 MenuBuildProg(owner->buffer());
648                 break;
649                 
650         case LFUN_RUNCHKTEX:
651                 MenuRunChktex(owner->buffer());
652                 break;
653                 
654         case LFUN_RUNDVIPS:
655                 MenuRunDvips(owner->buffer(), false);
656                 break;
657                 
658         case LFUN_MENUPRINT:
659                 MenuPrint(owner->buffer());
660                 break;
661                 
662         case LFUN_FAX:
663                 MenuFax(owner->buffer());
664                 break;
665                         
666         case LFUN_EXPORT:
667         {
668                 //needs argument as string
669                 string extyp= argument;
670                 
671                 // latex
672                 if (extyp == "latex") {
673                         // make sure that this buffer is not linuxdoc
674                         MenuMakeLaTeX(owner->buffer());
675                 }
676                 // linuxdoc
677                 else if (extyp == "linuxdoc") {
678                         // make sure that this buffer is not latex
679                         MenuMakeLinuxDoc(owner->buffer());
680                 }
681                 // docbook
682                 else if (extyp == "docbook") {
683                         // make sure that this buffer is not latex or linuxdoc
684                         MenuMakeDocBook(owner->buffer());
685                 }
686                 // dvi
687                 else if (extyp == "dvi") {
688                         // Run LaTeX as "Update dvi..." Bernhard.
689                         // We want the dvi in the current directory. This
690                         // is achieved by temporarily disabling use of
691                         // temp directory. As a side-effect, we get
692                         // *.log and *.aux files also. (Asger)
693                         bool flag = lyxrc->use_tempdir;
694                         lyxrc->use_tempdir = false;
695                         MenuRunLaTeX(owner->buffer());
696                         lyxrc->use_tempdir = flag;
697                 }
698                 // postscript
699                 else if (extyp == "postscript") {
700                         // Start Print-dialog. Not as good as dvi... Bernhard.
701                         MenuPrint(owner->buffer());
702                         // Since the MenuPrint is a pop-up, we can't use
703                         // the same trick as above. (Asger)
704                         // MISSING: Move of ps-file :-(
705                 }
706                 // ascii
707                 else if (extyp == "ascii") {
708                         MenuMakeAscii(owner->buffer());
709                 }
710                 else if (extyp == "custom") {
711                         MenuSendto();
712                         break;
713                 }
714                 // HTML
715                 else if (extyp == "html" && lyxrc->html_command != "none") {
716                         // First, create LaTeX file
717                         MenuMakeLaTeX(owner->buffer());
718
719                         // And now, run the converter
720                         string file = owner->buffer()->getFileName();
721                         Path path(OnlyPath(file));
722                         // the tex file name has to be correct for
723                         // latex, but the html file name can be
724                         // anything.
725                         string result = ChangeExtension(file, ".html", false);
726                         file = ChangeExtension(SpaceLess(file), ".tex", false);
727                         string tmp = lyxrc->html_command;
728                         tmp = subst(tmp, "$$FName", file);
729                         tmp = subst(tmp, "$$OutName", result);
730                         Systemcalls one;
731                         int res = one.startscript(Systemcalls::System, tmp);
732                         if (res == 0) {
733                                 setMessage(_("Document exported as HTML to file `")
734                                            + MakeDisplayPath(result) +'\'');
735                         } else {
736                                 setErrorMessage(_("Unable to convert to HTML the file `")
737                                                 + MakeDisplayPath(file) 
738                                                 + '\'');
739                         }
740                 }
741                 else {
742                         setErrorMessage(_("Unknown export type: ")
743                                         + extyp);
744                 }
745         }
746         break;
747
748         case LFUN_IMPORT:
749         {
750                 //needs argument as string
751                 string imtyp= argument;
752                 
753                 // latex
754                 if (imtyp == "latex") {
755                         doImportLaTeX(false);
756                 }
757                 // ascii
758                 else if (imtyp == "ascii") {
759                         doImportASCII(false);
760                 } else if (imtyp == "asciiparagraph") {
761                         doImportASCII(true);
762                 // noweb
763                 } else if (imtyp == "noweb") {
764                         doImportLaTeX(true);
765                 } else {
766                         setErrorMessage(string(N_("Unknown import type: "))
767                                         + imtyp);
768                 }
769                 break;
770         }
771                 
772         case LFUN_QUIT:
773                 QuitLyX();
774                 break;
775                 
776         case LFUN_TOCVIEW:
777                 TocUpdateCB(ob, 0);
778                 if (fd_form_toc->form_toc->visible) {
779                         fl_raise_form(fd_form_toc->form_toc);
780                 } else {
781                         static int ow = -1, oh;
782                         fl_show_form(fd_form_toc->form_toc,
783                                      FL_PLACE_MOUSE |
784                                      FL_FREE_SIZE, FL_FULLBORDER,
785                                      _("Table of Contents"));
786                         if (ow < 0) {
787                                 ow = fd_form_toc->form_toc->w;
788                                 oh = fd_form_toc->form_toc->h;
789                         }
790                         fl_set_form_minsize(fd_form_toc->form_toc, ow, oh);
791                 }
792                 break;
793                 
794         case LFUN_TOC_INSERT:
795         {
796                 Inset *new_inset = 
797                         new InsetTOC(owner->buffer());
798                 owner->buffer()->insertInset(new_inset,
799                                                     "Standard", true);
800                 break;
801         }
802         
803         case LFUN_LOF_INSERT:
804         {
805                 Inset *new_inset = 
806                         new InsetLOF(owner->buffer());
807                 owner->buffer()->insertInset(new_inset,
808                                                     "Standard", true);
809                 break;
810         }
811         
812         case LFUN_LOA_INSERT:
813         {
814                 Inset *new_inset = 
815                         new InsetLOA(owner->buffer());
816                 owner->buffer()->insertInset(new_inset,
817                                                     "Standard", true);
818                 break;
819         }
820
821         case LFUN_LOT_INSERT:
822         {
823                 Inset *new_inset = 
824                         new InsetLOT(owner->buffer());
825                 owner->buffer()->insertInset(new_inset,
826                                                     "Standard", true);
827                 break;
828         }
829                 
830         case LFUN_TABLE:
831                 TableCB(ob, 0);
832                 break;
833                 
834         case LFUN_FIGURE:
835                 FigureCB(ob, 0);
836                 break;
837                 
838         case LFUN_AUTOSAVE:
839                 AutoSave();
840                 break;
841                 
842         case LFUN_UNDO:
843                 MenuUndo();
844                 break;
845                 
846         case LFUN_REDO:
847                 MenuRedo();
848                 break;
849                 
850         case LFUN_MENUSEARCH:
851                 MenuSearch();
852                 break;
853                 
854         case LFUN_PASTE:
855                 PasteCB();
856                 break;
857                 
858         case LFUN_PASTESELECTION:
859         {
860                 bool asPara = false;
861                 if (string(argument) == "paragraph") asPara = true;
862                 MenuPasteSelection(asPara);
863                 break;
864         }
865
866         case LFUN_CUT:
867                 CutCB();
868                 break;
869                 
870         case LFUN_COPY:
871                 CopyCB();
872                 break;
873                 
874         case LFUN_LAYOUT_COPY:
875                 CopyEnvironmentCB();
876                 break;
877                 
878         case LFUN_LAYOUT_PASTE:
879                 PasteEnvironmentCB();
880                 break;
881                 
882         case LFUN_GOTOERROR:
883                 owner->currentView()->gotoError();
884                 break;
885                 
886         case LFUN_REMOVEERRORS:
887                 if (owner->buffer()->removeAutoInsets()) {
888                         owner->currentView()->redraw();
889                         owner->currentView()->fitCursor();
890                         owner->currentView()->updateScrollbar();
891                 }
892                 break;
893                 
894         case LFUN_GOTONOTE:
895                 GotoNote();
896                 break;
897                 
898         case LFUN_OPENSTUFF:
899                 OpenStuff();
900                 break;
901                 
902         case LFUN_HYPHENATION:
903                 HyphenationPoint();
904                 break;
905                 
906         case LFUN_LDOTS:
907                 Ldots();
908                 break;
909                 
910         case LFUN_END_OF_SENTENCE:
911                 EndOfSentenceDot();
912                 break;
913
914         case LFUN_MENU_SEPARATOR:
915                 MenuSeparator();
916                 break;
917                 
918         case LFUN_HFILL:
919                 HFill();
920                 break;
921                 
922         case LFUN_DEPTH:
923                 DepthCB(ob, 0);
924                 break;
925                 
926         case LFUN_DEPTH_MIN:
927                 DepthCB(ob, -1);
928                 break;
929                 
930         case LFUN_DEPTH_PLUS:
931                 DepthCB(ob, 1);
932                 break;
933                 
934         case LFUN_FREE:
935                 FreeCB();
936                 break;
937                 
938         case LFUN_TEX:
939                 TexCB();
940                 break;
941                 
942         case LFUN_MELT:
943                 MeltCB(ob, 0);
944                 break;
945                 
946         case LFUN_RECONFIGURE:
947                 Reconfigure();
948                 break;
949
950         case LFUN_FOOTMELT:
951                 if (owner->currentView()->available()
952                     && !owner->buffer()->text->selection
953                     && owner->buffer()->text->cursor.par->footnoteflag
954                     != LyXParagraph::NO_FOOTNOTE)
955                 { // only melt footnotes with FOOTMELT, not margins etc
956                   if(owner->buffer()->text->cursor.par->footnotekind == LyXParagraph::FOOTNOTE)
957                         MeltCB(ob, 0);
958                 }
959                 else
960                         FootCB(ob, 0); 
961                 break;
962
963         case LFUN_MARGINMELT:
964                 if (owner->currentView()->available()
965                     && !owner->buffer()->text->selection
966                     && owner->buffer()->text->cursor.par->footnoteflag
967                     != LyXParagraph::NO_FOOTNOTE)
968                 { // only melt margins
969                   if(owner->buffer()->text->cursor.par->footnotekind == LyXParagraph::MARGIN)
970                         MeltCB(ob, 0);
971                 }
972                 else
973                         MarginCB(ob, 0); 
974                 break;
975                 
976                 // --- version control -------------------------------
977         case LFUN_VC_REGISTER:
978         {
979                 if (!owner->buffer()->lyxvc.inUse())
980                         owner->buffer()->lyxvc.registrer();
981         }
982         break;
983                 
984         case LFUN_VC_CHECKIN:
985         {
986                 if (owner->buffer()->lyxvc.inUse()
987                     && !owner->buffer()->isReadonly())
988                         owner->buffer()->lyxvc.checkIn();
989         }
990         break;
991                 
992         case LFUN_VC_CHECKOUT:
993         {
994                 if (owner->buffer()->lyxvc.inUse()
995                     && owner->buffer()->isReadonly())
996                         owner->buffer()->lyxvc.checkOut();
997         }
998         break;
999         
1000         case LFUN_VC_REVERT:
1001         {
1002                 owner->buffer()->lyxvc.revert();
1003         }
1004         break;
1005                 
1006         case LFUN_VC_UNDO:
1007         {
1008                 owner->buffer()->lyxvc.undoLast();
1009         }
1010         break;
1011                 
1012         case LFUN_VC_HISTORY:
1013         {
1014                 owner->buffer()->lyxvc.showLog();
1015                 break;
1016         }
1017         
1018         // --- buffers ----------------------------------------
1019         case LFUN_PREVBUFFER:
1020 #ifdef WITH_WARNINGS
1021 #warning fix this please
1022 #endif
1023                 // it is the LyXView or the BufferView that should
1024                 // remember the previous buffer, not bufferlist.
1025 //                      if (owner->currentView()->available()){   
1026 //                              BeforeChange();
1027 //                              owner->buffer()->update(-2);
1028 //                      }
1029 //                      owner->currentView()->setBuffer(bufferlist.prev());
1030
1031 //                      owner->currentView()->
1032 //                              resizeCurrentBufferPseudoExpose();
1033                 break;
1034                         
1035         case LFUN_FILE_INSERT:
1036         {
1037                 MenuInsertLyXFile(argument);
1038         }
1039         break;
1040         
1041         case LFUN_FILE_INSERT_ASCII:
1042         {
1043                 bool asPara = false;
1044                 asPara = (string(argument) == "paragraph");
1045                 InsertAsciiFile(string(), asPara);
1046         }
1047         break;
1048         
1049         case LFUN_FILE_NEW:
1050         {
1051                 // servercmd: argument must be <file>:<template>
1052                 Buffer * tmpbuf = 0;
1053                 tmpbuf = NewLyxFile(argument);
1054                 if (tmpbuf)
1055                         owner->currentView()->buffer(tmpbuf);
1056         }
1057                 break;
1058                         
1059         case LFUN_FILE_OPEN:
1060                 owner->currentView()->buffer(
1061                         bufferlist.loadLyXFile(argument));
1062                 break;
1063
1064         case LFUN_LATEX_LOG:
1065                 ShowLatexLog();
1066                 break;
1067                 
1068         case LFUN_LAYOUTNO:
1069         {
1070                 lyxerr.debug() << "LFUN_LAYOUTNO: (arg) " << argument << endl;
1071                 int sel = strToInt(argument);
1072                 lyxerr.debug() << "LFUN_LAYOUTNO: (sel) "<< sel << endl;
1073                 
1074                 // Should this give a setMessage instead?
1075                 if (sel == 0) 
1076                         return string(); // illegal argument
1077
1078                 sel--; // sel 1..., but layout 0...
1079
1080                 // Pretend we got the name instead.
1081                 Dispatch(int(LFUN_LAYOUT), 
1082                          textclasslist.NameOfLayout(owner->buffer()->
1083                                                text->parameters->
1084                                                textclass,
1085                                                sel).c_str());
1086                 return string();
1087         }
1088                 
1089         case LFUN_LAYOUT:
1090         {
1091                 lyxerr.debug() << "LFUN_LAYOUT: (arg) "
1092                                << argument << endl;
1093                 
1094                 // Derive layout number from given argument (string)
1095                 // and current buffer's textclass (number). */    
1096                 int layoutno = -1;
1097                 layoutno = 
1098                         textclasslist.NumberOfLayout(owner->
1099                                                 buffer()->
1100                                                 text->parameters->
1101                                                 textclass,
1102                                                 argument).second;
1103
1104                 // see if we found the layout number:
1105                 if (layoutno == -1) {
1106                         setErrorMessage(string(N_("Layout ")) + argument + 
1107                                         N_(" not known"));
1108                         break;
1109                 }
1110                         
1111                 if (current_layout != layoutno) {
1112                         owner->currentView()->getScreen()->HideCursor();
1113                         current_layout = layoutno;
1114                         owner->buffer()->update(-2);
1115                         owner->buffer()->text->
1116                                 SetLayout(layoutno);
1117                         owner->getToolbar()->combox->
1118                                 select(owner->buffer()->
1119                                        text->cursor.par->
1120                                        GetLayout() + 1);
1121                         owner->buffer()->update(1);
1122                 }
1123         }
1124         break;
1125
1126         case LFUN_LAYOUT_DOCUMENT:
1127                 MenuLayoutDocument();
1128                 break;
1129                 
1130         case LFUN_LAYOUT_PARAGRAPH:
1131                 MenuLayoutParagraph();
1132                 break;
1133                 
1134         case LFUN_LAYOUT_CHARACTER:
1135                 MenuLayoutCharacter();
1136                 break;
1137                 
1138         case LFUN_LAYOUT_TABLE:
1139         {
1140                 int flag = 0;
1141                 if (string(argument) == "true") flag = 1;
1142                 MenuLayoutTable(flag);
1143         }
1144         break;
1145                 
1146         case LFUN_LAYOUT_PAPER:
1147                 MenuLayoutPaper();
1148                 break;
1149                 
1150         case LFUN_LAYOUT_QUOTES:
1151                 MenuLayoutQuotes();
1152                 break;
1153                 
1154         case LFUN_LAYOUT_PREAMBLE:
1155                 MenuLayoutPreamble();
1156                 break;
1157                 
1158         case LFUN_LAYOUT_SAVE_DEFAULT:
1159                 MenuLayoutSave();
1160                 break;
1161                 
1162         case LFUN_DROP_LAYOUTS_CHOICE:
1163                 owner->getToolbar()->combox->Show();
1164                 break;
1165
1166         case LFUN_EMPH:
1167                 EmphCB();
1168                 break;
1169                 
1170         case LFUN_BOLD:
1171                 BoldCB();
1172                 break;
1173                 
1174         case LFUN_NOUN:
1175                 NounCB();
1176                 break;
1177                 
1178         case LFUN_CODE:
1179                 CodeCB();
1180                 break;
1181                 
1182         case LFUN_SANS:
1183                 SansCB();
1184                 break;
1185                 
1186         case LFUN_ROMAN:
1187                 RomanCB();
1188                 break;
1189                 
1190         case LFUN_DEFAULT:
1191                 StyleResetCB();
1192                 break;
1193                 
1194         case LFUN_UNDERLINE:
1195                 UnderlineCB();
1196                 break;
1197                 
1198         case LFUN_FONT_SIZE:
1199                 FontSizeCB(argument);
1200                 break;
1201                 
1202         case LFUN_FONT_STATE:
1203                 setMessage(CurrentState());
1204                 break;
1205                 
1206         case LFUN_UPCASE_WORD:
1207                 owner->buffer()->update(-2);
1208                 FreeUpdateTimer();
1209                 owner->buffer()->text->ChangeWordCase(LyXText::text_uppercase);
1210                 owner->buffer()->update(1);
1211                 SetUpdateTimer();
1212                 break;
1213                 
1214         case LFUN_LOWCASE_WORD:
1215                 owner->buffer()->update(-2);
1216                 FreeUpdateTimer();
1217                 owner->buffer()->text->ChangeWordCase(LyXText::text_lowercase);
1218                 owner->buffer()->update(1);
1219                 SetUpdateTimer();
1220                 break;
1221                 
1222         case LFUN_CAPITALIZE_WORD:
1223                 owner->buffer()->update(-2);
1224                 FreeUpdateTimer();
1225                 owner->buffer()->text->ChangeWordCase(LyXText::text_capitalization);
1226                 owner->buffer()->update(1);
1227                 SetUpdateTimer();
1228                 break;
1229                 
1230         case LFUN_INSERT_LABEL:
1231                 MenuInsertLabel(argument.c_str());
1232                 break;
1233                 
1234         case LFUN_INSERT_REF:
1235                 MenuInsertRef();
1236                 break;
1237                 
1238         case LFUN_REFTOGGLE:
1239         {
1240                 InsetRef *inset = 
1241                         (InsetRef*)getInsetByCode(Inset::REF_CODE);
1242                 if (inset) {
1243                         if (inset->getFlag() == InsetRef::REF)
1244                                 inset->setFlag(InsetRef::PAGE_REF);
1245                         else
1246                                 inset->setFlag(InsetRef::REF);
1247                         UpdateInset(inset);
1248                 } else {
1249                         setErrorMessage(N_("No cross-reference to toggle"));
1250                 }
1251         }
1252         break;
1253         
1254         case LFUN_REFBACK:
1255         {
1256                 owner->currentView()->restorePosition();
1257         }
1258         break;
1259
1260         case LFUN_REFGOTO:
1261         {
1262                 string label(argument);
1263                 if (label.empty()) {
1264                         InsetRef *inset = 
1265                                 (InsetRef*)getInsetByCode(Inset::REF_CODE);
1266                         if (inset)
1267                                 label = inset->getContents();
1268                 }
1269                 
1270                 if (!label.empty()) {
1271                         owner->currentView()->savePosition();
1272                         owner->buffer()->gotoLabel(label.c_str());
1273                 }
1274         }
1275         break;
1276                 
1277         case LFUN_MENU_OPEN_BY_NAME:
1278                 owner->getMenus()->openByName(argument);
1279                 break; // RVDK_PATCH_5
1280                 
1281         case LFUN_SPELLCHECK:
1282                 if (lyxrc->isp_command != "none")
1283                         ShowSpellChecker();
1284                 break; // RVDK_PATCH_5
1285                 
1286                 // --- Cursor Movements -----------------------------
1287         case LFUN_RIGHT:
1288         {
1289                 Buffer *tmpbuffer = owner->buffer();
1290                 LyXText *tmptext = owner->buffer()->text;
1291                 if(!tmptext->mark_set)
1292                         BeforeChange();
1293                 tmpbuffer->update(-2);
1294                 if (tmptext->cursor.pos < tmptext->cursor.par->Last()
1295                     && tmptext->cursor.par->GetChar(tmptext->cursor.pos)
1296                     == LyXParagraph::META_INSET
1297                     && tmptext->cursor.par->GetInset(tmptext->cursor.pos)
1298                     && tmptext->cursor.par->GetInset(tmptext->cursor.pos)->Editable() == 2){
1299                         Inset* tmpinset = tmptext->cursor.par->GetInset(tmptext->cursor.pos);
1300                         setMessage(tmpinset->EditMessage());
1301                         tmpinset->Edit(0, 0);
1302                         break;
1303                 }
1304                 tmptext->CursorRight();
1305                 owner->buffer()->text->FinishUndo();
1306                 moveCursorUpdate(false);
1307                 owner->getMiniBuffer()->Set(CurrentState());
1308         }
1309         break;
1310                 
1311         case LFUN_LEFT:
1312         {
1313                 // This is soooo ugly. Isn`t it possible to make
1314                 // it simpler? (Lgb)
1315                 LyXText *txt= owner->buffer()->text;
1316                 if(!txt->mark_set) BeforeChange();
1317                 owner->buffer()->update(-2);
1318                 txt->CursorLeft();
1319                 if (txt->cursor.pos < txt->cursor.par->Last()
1320                     && txt->cursor.par->GetChar(txt->cursor.pos)
1321                     == LyXParagraph::META_INSET
1322                     && txt->cursor.par->GetInset(txt->cursor.pos)
1323                     && txt->cursor.par->GetInset(txt->cursor.pos)->Editable() == 2) {
1324                         Inset* tmpinset = txt->cursor.par->GetInset(txt->cursor.pos);
1325                         setMessage(tmpinset->EditMessage());
1326                         tmpinset->Edit(tmpinset->Width(txt->GetFont(txt->cursor.par,
1327                                                                     txt->cursor.pos)), 0);
1328                         //                      tmpinset->Edit(-1, 0);  // -1 means go rightmost
1329                         break;
1330                 }
1331                 owner->buffer()->text->FinishUndo();
1332                 moveCursorUpdate(false);
1333                 owner->getMiniBuffer()->Set(CurrentState());
1334         }
1335         break;
1336                 
1337         case LFUN_UP:
1338                 if(!owner->buffer()->text->mark_set) BeforeChange();
1339                 owner->buffer()->update(-3);
1340                 owner->buffer()->text->CursorUp();
1341                 owner->buffer()->text->FinishUndo();
1342                 moveCursorUpdate(false);
1343                 owner->getMiniBuffer()->Set(CurrentState());
1344                 break;
1345                 
1346         case LFUN_DOWN:
1347                 if(!owner->buffer()->text->mark_set)
1348                         BeforeChange();
1349                 owner->buffer()->update(-3);
1350                 owner->buffer()->text->CursorDown();
1351                 owner->buffer()->text->FinishUndo();
1352                 moveCursorUpdate(false);
1353                 owner->getMiniBuffer()->Set(CurrentState());
1354                 break;
1355
1356         case LFUN_UP_PARAGRAPH:
1357                 if(!owner->buffer()->text->mark_set)
1358                         BeforeChange();
1359                 owner->buffer()->update(-3);
1360                 owner->buffer()->text->CursorUpParagraph();
1361                 owner->buffer()->text->FinishUndo();
1362                 moveCursorUpdate(false);
1363                 owner->getMiniBuffer()->Set(CurrentState());
1364                 break;
1365                 
1366         case LFUN_DOWN_PARAGRAPH:
1367                 if(!owner->buffer()->text->mark_set)
1368                         BeforeChange();
1369                 owner->buffer()->update(-3);
1370                 owner->buffer()->text->CursorDownParagraph();
1371                 owner->buffer()->text->FinishUndo();
1372                 moveCursorUpdate(false);
1373                 owner->getMiniBuffer()->Set(CurrentState());
1374                 break;
1375                 
1376         case LFUN_PRIOR:
1377                 if(!owner->buffer()->text->mark_set)
1378                         BeforeChange();
1379                 owner->buffer()->update(-3);
1380                 owner->currentView()->cursorPrevious();
1381                 owner->buffer()->text->FinishUndo();
1382                 moveCursorUpdate(false);
1383                 owner->getMiniBuffer()->Set(CurrentState());
1384                 break;
1385                 
1386         case LFUN_NEXT:
1387                 if(!owner->buffer()->text->mark_set)
1388                         BeforeChange();
1389                 owner->buffer()->update(-3);
1390                 owner->currentView()->cursorNext();
1391                 owner->buffer()->text->FinishUndo();
1392                 moveCursorUpdate(false);
1393                 owner->getMiniBuffer()->Set(CurrentState());
1394                 break;
1395                 
1396         case LFUN_HOME:
1397                 if(!owner->buffer()->text->mark_set)
1398                         BeforeChange();
1399                 owner->buffer()->update(-2);
1400                 owner->buffer()->text->CursorHome();
1401                 owner->buffer()->text->FinishUndo();
1402                 moveCursorUpdate(false);
1403                 owner->getMiniBuffer()->Set(CurrentState());
1404                 break;
1405                 
1406         case LFUN_END:
1407                 if(!owner->buffer()->text->mark_set)
1408                         BeforeChange();
1409                 owner->buffer()->update(-2);
1410                 owner->buffer()->text->CursorEnd();
1411                 owner->buffer()->text->FinishUndo();
1412                 moveCursorUpdate(false);
1413                 owner->getMiniBuffer()->Set(CurrentState());
1414                 break;
1415                 
1416         case LFUN_TAB:
1417                 if(!owner->buffer()->text->mark_set)
1418                         BeforeChange();
1419                 owner->buffer()->update(-2);
1420                 owner->buffer()->text->CursorTab();
1421                 owner->buffer()->text->FinishUndo();
1422                 moveCursorUpdate(false);
1423                 owner->getMiniBuffer()->Set(CurrentState());
1424                 break;
1425                 
1426         case LFUN_WORDRIGHT:
1427                 if(!owner->buffer()->text->mark_set)
1428                         BeforeChange();
1429                 owner->buffer()->update(-2);
1430                 owner->buffer()->text->CursorRightOneWord();
1431                 owner->buffer()->text->FinishUndo();
1432                 moveCursorUpdate(false);
1433                 owner->getMiniBuffer()->Set(CurrentState());
1434                 break;
1435                 
1436         case LFUN_WORDLEFT:
1437                 if(!owner->buffer()->text->mark_set)
1438                         BeforeChange();
1439                 owner->buffer()->update(-2);
1440                 owner->buffer()->text->CursorLeftOneWord();
1441                 owner->buffer()->text->FinishUndo();
1442                 moveCursorUpdate(false);
1443                 owner->getMiniBuffer()->Set(CurrentState());
1444                 break;
1445                 
1446         case LFUN_BEGINNINGBUF:
1447                 if(!owner->buffer()->text->mark_set)
1448                         BeforeChange();
1449                 owner->buffer()->update(-2);
1450                 owner->buffer()->text->CursorTop();
1451                 owner->buffer()->text->FinishUndo();
1452                 moveCursorUpdate(false);
1453                 owner->getMiniBuffer()->Set(CurrentState());
1454                 break;
1455                 
1456         case LFUN_ENDBUF:
1457                 if(!owner->buffer()->text->mark_set)
1458                         BeforeChange();
1459                 owner->buffer()->update(-2);
1460                 owner->buffer()->text->CursorBottom();
1461                 owner->buffer()->text->FinishUndo();
1462                 moveCursorUpdate(false);
1463                 owner->getMiniBuffer()->Set(CurrentState());
1464                 break;
1465
1466       
1467                 /* cursor selection ---------------------------- */
1468         case LFUN_RIGHTSEL:
1469                 owner->buffer()->update(-2);
1470                 owner->buffer()->text->CursorRight();
1471                 owner->buffer()->text->FinishUndo();
1472                 moveCursorUpdate(true);
1473                 owner->getMiniBuffer()->Set(CurrentState());
1474                 break;
1475                 
1476         case LFUN_LEFTSEL:
1477                 owner->buffer()->update(-2);
1478                 owner->buffer()->text->CursorLeft();
1479                 owner->buffer()->text->FinishUndo();
1480                 moveCursorUpdate(true);
1481                 owner->getMiniBuffer()->Set(CurrentState());
1482                 break;
1483                 
1484         case LFUN_UPSEL:
1485                 owner->buffer()->update(-2);
1486                 owner->buffer()->text->CursorUp();
1487                 owner->buffer()->text->FinishUndo();
1488                 moveCursorUpdate(true);
1489                 owner->getMiniBuffer()->Set(CurrentState());
1490                 break;
1491                 
1492         case LFUN_DOWNSEL:
1493                 owner->buffer()->update(-2);
1494                 owner->buffer()->text->CursorDown();
1495                 owner->buffer()->text->FinishUndo();
1496                 moveCursorUpdate(true);
1497                 owner->getMiniBuffer()->Set(CurrentState());
1498                 break;
1499
1500         case LFUN_UP_PARAGRAPHSEL:
1501                 owner->buffer()->update(-2);
1502                 owner->buffer()->text->CursorUpParagraph();
1503                 owner->buffer()->text->FinishUndo();
1504                 moveCursorUpdate(true);
1505                 owner->getMiniBuffer()->Set(CurrentState());
1506                 break;
1507                 
1508         case LFUN_DOWN_PARAGRAPHSEL:
1509                 owner->buffer()->update(-2);
1510                 owner->buffer()->text->CursorDownParagraph();
1511                 owner->buffer()->text->FinishUndo();
1512                 moveCursorUpdate(true);
1513                 owner->getMiniBuffer()->Set(CurrentState());
1514                 break;
1515                 
1516         case LFUN_PRIORSEL:
1517                 owner->buffer()->update(-2);
1518                 owner->currentView()->cursorPrevious();
1519                 owner->buffer()->text->FinishUndo();
1520                 moveCursorUpdate(true);
1521                 owner->getMiniBuffer()->Set(CurrentState());
1522                 break;
1523                 
1524         case LFUN_NEXTSEL:
1525                 owner->buffer()->update(-2);
1526                 owner->currentView()->cursorNext();
1527                 owner->buffer()->text->FinishUndo();
1528                 moveCursorUpdate(true);
1529                 owner->getMiniBuffer()->Set(CurrentState());
1530                 break;
1531                 
1532         case LFUN_HOMESEL:
1533                 owner->buffer()->update(-2);
1534                 owner->buffer()->text->CursorHome();
1535                 owner->buffer()->text->FinishUndo();
1536                 moveCursorUpdate(true);
1537                 owner->getMiniBuffer()->Set(CurrentState());
1538                 break;
1539                 
1540         case LFUN_ENDSEL:
1541                 owner->buffer()->update(-2);
1542                 owner->buffer()->text->CursorEnd();
1543                 owner->buffer()->text->FinishUndo();
1544                 moveCursorUpdate(true);
1545                 owner->getMiniBuffer()->Set(CurrentState());
1546                 break;
1547                 
1548         case LFUN_WORDRIGHTSEL:
1549                 owner->buffer()->update(-2);
1550                 owner->buffer()->text->CursorRightOneWord();
1551                 owner->buffer()->text->FinishUndo();
1552                 moveCursorUpdate(true);
1553                 owner->getMiniBuffer()->Set(CurrentState());
1554                 break;
1555                 
1556         case LFUN_WORDLEFTSEL:
1557                 owner->buffer()->update(-2);
1558                 owner->buffer()->text->CursorLeftOneWord();
1559                 owner->buffer()->text->FinishUndo();
1560                 moveCursorUpdate(true);
1561                 owner->getMiniBuffer()->Set(CurrentState());
1562                 break;
1563                 
1564         case LFUN_BEGINNINGBUFSEL:
1565                 owner->buffer()->update(-2);
1566                 owner->buffer()->text->CursorTop();
1567                 owner->buffer()->text->FinishUndo();
1568                 moveCursorUpdate(true);
1569                 owner->getMiniBuffer()->Set(CurrentState());
1570                 break;
1571                 
1572         case LFUN_ENDBUFSEL:
1573                 owner->buffer()->update(-2);
1574                 owner->buffer()->text->CursorBottom();
1575                 owner->buffer()->text->FinishUndo();
1576                 moveCursorUpdate(true);
1577                 owner->getMiniBuffer()->Set(CurrentState());
1578                 break;
1579
1580                 // --- text changing commands ------------------------
1581         case LFUN_BREAKLINE:
1582                 BeforeChange();
1583                 owner->buffer()->text->InsertChar(LyXParagraph::META_NEWLINE);
1584                 SmallUpdate(1);
1585                 SetUpdateTimer(0.01);
1586                 moveCursorUpdate(false);
1587                 break;
1588                 
1589         case LFUN_PROTECTEDSPACE:
1590                 BeforeChange();
1591                 owner->buffer()->text->
1592                         InsertChar(LyXParagraph::META_PROTECTED_SEPARATOR);
1593                 SmallUpdate(1);
1594                 SetUpdateTimer();
1595                 moveCursorUpdate(false);
1596                 break;
1597                 
1598         case LFUN_SETMARK:
1599                 if(owner->buffer()->text->mark_set) {
1600                         BeforeChange();
1601                         owner->buffer()->update(0);
1602                         setMessage(N_("Mark removed"));
1603                 } else {
1604                         BeforeChange();
1605                         owner->buffer()->text->mark_set = 1;
1606                         owner->buffer()->update(0);
1607                         setMessage(N_("Mark set"));
1608                 }
1609                 owner->buffer()->text->sel_cursor = 
1610                         owner->buffer()->text->cursor;
1611                 break;
1612                 
1613         case LFUN_DELETE:
1614                 FreeUpdateTimer();
1615                 if (!owner->buffer()->text->selection) {
1616                         owner->buffer()->text->Delete();
1617                         owner->buffer()->text->sel_cursor = 
1618                                 owner->buffer()->text->cursor;
1619                         SmallUpdate(1);
1620                         // It is possible to make it a lot faster still
1621                         // just comment out the lone below...
1622                         owner->currentView()->getScreen()->ShowCursor();
1623                 } else {
1624                         CutCB();
1625                 }
1626                 SetUpdateTimer();
1627                 break;
1628
1629         case LFUN_DELETE_SKIP:
1630         {
1631                 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
1632                 
1633                 LyXCursor cursor = owner->buffer()->text->cursor;
1634
1635                 FreeUpdateTimer();
1636                 if (!owner->buffer()->text->selection) {
1637                         if (cursor.pos == cursor.par->Last()) {
1638                                 owner->buffer()->text->CursorRight();
1639                                 cursor = owner->buffer()->text->cursor;
1640                                 if (cursor.pos == 0
1641                                     && !(cursor.par->added_space_top 
1642                                          == VSpace (VSpace::NONE))) {
1643                                         owner->buffer()->text->SetParagraph
1644                                                 (cursor.par->line_top,
1645                                                  cursor.par->line_bottom,
1646                                                  cursor.par->pagebreak_top, 
1647                                                  cursor.par->pagebreak_bottom,
1648                                                  VSpace(VSpace::NONE), 
1649                                                  cursor.par->added_space_bottom,
1650                                                  cursor.par->align, 
1651                                                  cursor.par->labelwidthstring, 0);
1652                                         owner->buffer()->text->CursorLeft();
1653                                         owner->buffer()->update (1);
1654                                 } else {
1655                                         owner->buffer()->text->CursorLeft();
1656                                         owner->buffer()->text->Delete();
1657                                         owner->buffer()->text->sel_cursor = 
1658                                                 owner->buffer()->text->cursor;
1659                                         SmallUpdate(1);
1660                                 }
1661                         } else {
1662                                 owner->buffer()->text->Delete();
1663                                 owner->buffer()->text->sel_cursor = 
1664                                         owner->buffer()->text->cursor;
1665                                 SmallUpdate(1);
1666                         }
1667                 } else {
1668                         CutCB();
1669                 }
1670                 SetUpdateTimer();
1671         }
1672         break;
1673
1674         /* -------> Delete word forward. */
1675         case LFUN_DELETE_WORD_FORWARD:
1676                 owner->buffer()->update(-2);
1677                 FreeUpdateTimer();
1678                 owner->buffer()->text->DeleteWordForward();
1679                 owner->buffer()->update( 1 );
1680                 SetUpdateTimer();
1681                 moveCursorUpdate(false);
1682                 break;
1683
1684                 /* -------> Delete word backward. */
1685         case LFUN_DELETE_WORD_BACKWARD:
1686                 owner->buffer()->update(-2);
1687                 FreeUpdateTimer();
1688                 owner->buffer()->text->DeleteWordBackward();
1689                 owner->buffer()->update( 1 );
1690                 SetUpdateTimer();
1691                 moveCursorUpdate(false);
1692                 break;
1693                 
1694                 /* -------> Kill to end of line. */
1695         case LFUN_DELETE_LINE_FORWARD:
1696                 FreeUpdateTimer();
1697                 owner->buffer()->update(-2);
1698                 owner->buffer()->text->DeleteLineForward();
1699                 owner->buffer()->update( 1 );
1700                 SetUpdateTimer();
1701                 moveCursorUpdate(false);
1702                 break;
1703                 
1704                 /* -------> Set mark off. */
1705         case LFUN_MARK_OFF:
1706                 BeforeChange();
1707                 owner->buffer()->update(0);
1708                 owner->buffer()->text->sel_cursor = 
1709                         owner->buffer()->text->cursor;
1710                 setMessage(N_("Mark off"));
1711                 break;
1712
1713                 /* -------> Set mark on. */
1714         case LFUN_MARK_ON:
1715                 BeforeChange();
1716                 owner->buffer()->text->mark_set = 1;
1717                 owner->buffer()->update( 0 );
1718                 owner->buffer()->text->sel_cursor = 
1719                         owner->buffer()->text->cursor;
1720                 setMessage(N_("Mark on"));
1721                 break;
1722                 
1723         case LFUN_BACKSPACE:
1724         {
1725                 FreeUpdateTimer();
1726                 if (!owner->buffer()->text->selection) {
1727                         if (owner->getIntl()->getTrans()->backspace()) {
1728                                 owner->buffer()->text->Backspace();
1729                                 owner->buffer()->text->sel_cursor = 
1730                                         owner->buffer()->text->cursor;
1731                                 SmallUpdate(1);
1732                                 // It is possible to make it a lot faster still
1733                                 // just comment out the lone below...
1734                                 owner->currentView()->getScreen()->ShowCursor();
1735                         }
1736                 } else {
1737                         CutCB();
1738                 }
1739                 SetUpdateTimer();
1740         }
1741         break;
1742
1743         case LFUN_BACKSPACE_SKIP:
1744         {
1745                 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
1746                 
1747                 LyXCursor cursor = owner->buffer()->text->cursor;
1748                 
1749                 FreeUpdateTimer();
1750                 if (!owner->buffer()->text->selection) {
1751                         if (cursor.pos == 0 
1752                             && !(cursor.par->added_space_top 
1753                                  == VSpace (VSpace::NONE))) {
1754                                 owner->buffer()->text->SetParagraph 
1755                                         (cursor.par->line_top,      
1756                                          cursor.par->line_bottom,
1757                                          cursor.par->pagebreak_top, 
1758                                          cursor.par->pagebreak_bottom,
1759                                          VSpace(VSpace::NONE), cursor.par->added_space_bottom,
1760                                          cursor.par->align, 
1761                                          cursor.par->labelwidthstring, 0);
1762                                 owner->buffer()->update (1);
1763                         } else {
1764                                 owner->buffer()->text->Backspace();
1765                                 owner->buffer()->text->sel_cursor 
1766                                         = cursor;
1767                                 SmallUpdate (1);
1768                         }
1769                 } else
1770                         CutCB();
1771                 SetUpdateTimer();
1772         }
1773         break;
1774
1775         case LFUN_BREAKPARAGRAPH:
1776         {
1777                 BeforeChange();
1778                 owner->buffer()->text->BreakParagraph(0);
1779                 SmallUpdate(1);
1780                 SetUpdateTimer(0.01);
1781                 owner->buffer()->text->sel_cursor = 
1782                         owner->buffer()->text->cursor;
1783                 break;
1784         }
1785
1786         case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
1787         {
1788                 BeforeChange();
1789                 owner->buffer()->text->BreakParagraph(1);
1790                 SmallUpdate(1);
1791                 SetUpdateTimer(0.01);
1792                 owner->buffer()->text->sel_cursor = 
1793                         owner->buffer()->text->cursor;
1794                 break;
1795         }
1796         
1797         case LFUN_BREAKPARAGRAPH_SKIP:
1798         {
1799                 // When at the beginning of a paragraph, remove
1800                 // indentation and add a "defskip" at the top.
1801                 // Otherwise, do the same as LFUN_BREAKPARAGRAPH.
1802                 
1803                 LyXCursor cursor = owner->buffer()->text->cursor;
1804                 
1805                 BeforeChange();
1806                 if (cursor.pos == 0) {
1807                         if (cursor.par->added_space_top == VSpace(VSpace::NONE)) {
1808                                 owner->buffer()->text->SetParagraph
1809                                         (cursor.par->line_top,      
1810                                          cursor.par->line_bottom,
1811                                          cursor.par->pagebreak_top, 
1812                                          cursor.par->pagebreak_bottom,
1813                                          VSpace(VSpace::DEFSKIP), cursor.par->added_space_bottom,
1814                                          cursor.par->align, 
1815                                          cursor.par->labelwidthstring, 1);
1816                                 owner->buffer()->update(1);
1817                         } 
1818                 }
1819                 else {
1820                         owner->buffer()->text->BreakParagraph(0);
1821                         SmallUpdate(1);
1822                 }
1823                 SetUpdateTimer(0.01);
1824                 owner->buffer()->text->sel_cursor = cursor;
1825         }
1826         break;
1827         
1828         case LFUN_QUOTE:
1829                 BeforeChange();
1830                 owner->buffer()->text->InsertChar('\"');  // This " matches the single quote in the code
1831                 SmallUpdate(1);
1832                 SetUpdateTimer();
1833                 moveCursorUpdate(false);
1834                 break;
1835
1836         case LFUN_HTMLURL:
1837         case LFUN_URL:
1838         {
1839                 InsetCommand *new_inset;
1840                 if (action == LFUN_HTMLURL)
1841                         new_inset = new InsetUrl("htmlurl", "", "");
1842                 else
1843                         new_inset = new InsetUrl("url", "", "");
1844                 owner->buffer()->insertInset(new_inset);
1845                 new_inset->Edit(0, 0);
1846         }
1847         break;
1848
1849         // --- lyxserver commands ----------------------------
1850
1851         case LFUN_CHARATCURSOR:
1852         {
1853                 LyXParagraph::size_type pos = 
1854                   owner->buffer()->text->cursor.pos;
1855                 if(pos < owner->buffer()->text->cursor.par->size())
1856                         dispatch_buffer = owner->buffer()->text->
1857                                 cursor.par->text[pos];
1858                 else
1859                         dispatch_buffer = "EOF";
1860         }
1861         break;
1862         
1863         case LFUN_GETXY:
1864                 dispatch_buffer = 
1865                          tostr(owner->buffer()->text->cursor.x) + ' '
1866                         + tostr(owner->buffer()->text->cursor.y);
1867                 break;
1868                 
1869         case LFUN_SETXY:
1870         {
1871                 int  x;
1872                 long y;
1873                 sscanf(argument.c_str(), " %d %ld", &x, &y);
1874                 owner->buffer()->text->SetCursorFromCoordinates(x, y);
1875         }
1876         break;
1877         
1878         case LFUN_GETLAYOUT:
1879                 dispatch_buffer =  
1880                         tostr(owner->buffer()->text->cursor.par->layout);
1881                 break;
1882                         
1883         case LFUN_GETFONT:
1884         {
1885                 LyXFont *font = &(owner->buffer()->text->current_font);
1886                 if(font->shape() == LyXFont::ITALIC_SHAPE)
1887                         dispatch_buffer = 'E';
1888                 else if(font->shape() == LyXFont::SMALLCAPS_SHAPE)
1889                         dispatch_buffer = 'N';
1890                 else
1891                         dispatch_buffer = '0';
1892
1893         }
1894         break;
1895
1896         case LFUN_GETLATEX:
1897         {
1898                 LyXFont *font = &(owner->buffer()->text->current_font);
1899                 if(font->latex() == LyXFont::ON)
1900                         dispatch_buffer = 'L';
1901                 else
1902                         dispatch_buffer = '0';
1903         }
1904         break;
1905
1906         case LFUN_GETNAME:
1907                 setMessage(owner->buffer()->getFileName());
1908                 lyxerr.debug() << "FNAME["
1909                                << owner->buffer()->getFileName()
1910                                << "] " << endl;
1911                 break;
1912                 
1913         case LFUN_NOTIFY:
1914         {
1915                 char buf[100];
1916                 keyseq.print(buf, 100);
1917                 dispatch_buffer = buf;
1918                 lyxserver->notifyClient(dispatch_buffer);
1919         }
1920         break;
1921
1922         case LFUN_GOTOFILEROW:
1923         {
1924                 char file_name[100];
1925                 int  row;
1926                 sscanf(argument.c_str(), " %s %d", file_name, &row);
1927
1928                 // Must replace extension of the file to be .lyx and get full path
1929                 string s = ChangeExtension(string(file_name), ".lyx", false);
1930
1931                 // Either change buffer or load the file
1932                 if (bufferlist.exists(s))
1933                         owner->currentView()->buffer(bufferlist.getBuffer(s));
1934                 else
1935                         owner->currentView()->buffer(bufferlist.loadLyXFile(s));
1936
1937                 // Set the cursor  
1938                 owner->buffer()->setCursorFromRow(row);
1939
1940                 // Recenter screen
1941                 BeforeChange();
1942                 if (owner->buffer()->text->cursor.y >
1943                     owner->currentView()->getWorkArea()->h / 2) {
1944                         owner->currentView()->getScreen()->
1945                                 Draw(owner->buffer()->text->cursor.y -
1946                                      owner->currentView()->getWorkArea()->h/2);
1947                 } else { // <= 
1948                         owner->currentView()->getScreen()->
1949                                 Draw(0);
1950                 }
1951                 owner->buffer()->update(0);
1952                 owner->currentView()->redraw();
1953         }
1954         break;
1955
1956         case LFUN_APROPOS:
1957         case LFUN_GETTIP:
1958         {
1959                 int qa = lyxaction.LookupFunc(argument.c_str());
1960                 setMessage(lyxaction.helpText((kb_action)qa));
1961         }
1962         break;
1963
1964         // --- accented characters ---------------------------
1965                 
1966         case LFUN_UMLAUT:
1967         case LFUN_CIRCUMFLEX:
1968         case LFUN_GRAVE:
1969         case LFUN_ACUTE:
1970         case LFUN_TILDE:
1971         case LFUN_CEDILLA:
1972         case LFUN_MACRON:
1973         case LFUN_DOT:
1974         case LFUN_UNDERDOT:
1975         case LFUN_UNDERBAR:
1976         case LFUN_CARON:
1977         case LFUN_SPECIAL_CARON:
1978         case LFUN_BREVE:
1979         case LFUN_TIE:
1980         case LFUN_HUNG_UMLAUT:
1981         case LFUN_CIRCLE:
1982         case LFUN_OGONEK:
1983         {
1984                 char c;
1985                 
1986                 if (keyseq.length == -1 && keyseq.getiso()!= 0) 
1987                         c= keyseq.getiso();
1988                 else
1989                         c= 0;
1990                 
1991                 owner->getIntl()->getTrans()->
1992                         deadkey(c, get_accent(action).accent, 
1993                                 owner->buffer()->text);
1994                 
1995                 // Need to reset, in case the minibuffer calls these
1996                 // actions
1997                 keyseq.reset();
1998                 keyseq.length= 0;
1999                 
2000                 // copied verbatim from do_accent_char
2001                 SmallUpdate(1);
2002                 SetUpdateTimer();
2003                 owner->buffer()->text->sel_cursor = 
2004                         owner->buffer()->text->cursor;
2005         }   
2006         break;
2007         
2008         // --- toolbar ----------------------------------
2009         case LFUN_PUSH_TOOLBAR:
2010         {
2011                 int nth = strToInt(argument);
2012                 if (lyxerr.debugging(Debug::TOOLBAR)) {
2013                         lyxerr << "LFUN_PUSH_TOOLBAR: argument = `"
2014                                << argument << "'\n"
2015                                << "LFUN_PUSH_TOOLBAR: nth = `"
2016                                << nth << "'" << endl;
2017                 }
2018                 
2019                 if (nth <= 0) {
2020                         LyXBell();
2021                         setErrorMessage(N_("Push-toolbar needs argument > 0"));
2022                 } else {
2023                         owner->getToolbar()->push(nth);
2024                 }
2025         }
2026         break;
2027         
2028         case LFUN_ADD_TO_TOOLBAR:
2029         {
2030                 if (lyxerr.debugging(Debug::TOOLBAR)) {
2031                         lyxerr << "LFUN_ADD_TO_TOOLBAR:"
2032                                 "argument = `" << argument << '\'' << endl;
2033                 }
2034                 string tmp(argument);
2035                 //lyxerr <<string("Argument: ") + argument);
2036                 //lyxerr <<string("Tmp     : ") + tmp);
2037                 if (tmp.empty()) {
2038                         LyXBell();
2039                         setErrorMessage(N_("Usage: toolbar-add-to <LyX command>"));
2040                 } else {
2041                         owner->getToolbar()->add(argument, false);
2042                         owner->getToolbar()->set();
2043                 }
2044         }
2045         break;
2046         
2047         // --- insert characters ----------------------------------------
2048 #if 0
2049         case LFUN_INSERT_INSET_LATEX:
2050         {
2051                 Inset *new_inset = new InsetLatex(argument);
2052                 owner->buffer()->insertInset(new_inset);
2053         }
2054         break;
2055 #endif
2056         // ---  Mathed stuff. If we are here, there is no locked inset yet.
2057         
2058         // Greek mode     
2059         case LFUN_GREEK:
2060         {
2061                 if (!greek_kb_flag) {
2062                         greek_kb_flag = 1;
2063                         setMessage(N_("Math greek mode on"));
2064                 } else
2065                         greek_kb_flag = 0;
2066         }  
2067         break;
2068       
2069         // Greek keyboard      
2070         case LFUN_GREEK_TOGGLE:
2071         {
2072                 greek_kb_flag = (greek_kb_flag) ? 0: 2;
2073                 if (greek_kb_flag) {
2074                         setMessage(N_("Math greek keyboard on"));
2075                 } else {
2076                         setMessage(N_("Math greek keyboard off"));
2077                 }
2078         }
2079         break;
2080         
2081         case LFUN_MATH_DELIM:     
2082         case LFUN_INSERT_MATRIX:
2083         {          
2084                 if (owner->currentView()->available()) { 
2085                         owner->buffer()->
2086                                 open_new_inset(new InsetFormula(false));
2087                         owner->buffer()->
2088                                 the_locking_inset->LocalDispatch(action, argument.c_str());
2089                 }
2090         }          
2091         break;
2092                
2093         case LFUN_INSERT_MATH:
2094         {
2095                 math_insert_symbol(argument.c_str());
2096         }
2097         break;
2098         
2099         case LFUN_MATH_DISPLAY:
2100         {
2101                 if (owner->currentView()->available())
2102                         owner->buffer()->open_new_inset(new InsetFormula(true));
2103                 break;
2104         }
2105                     
2106         case LFUN_MATH_MACRO:
2107         {
2108                 if (owner->currentView()->available()) {
2109                         string s(argument);
2110                         if (s.empty())
2111                             setErrorMessage(N_("Missing argument"));
2112                         else {
2113                             string s1 = token(s, ' ', 1);
2114                             int na = s1.empty() ? 0: atoi(s1.c_str());
2115                             owner->buffer()->
2116                               open_new_inset(new InsetFormulaMacro(token(s, ' ', 0), na));
2117                         }
2118                 }
2119         }
2120         break;
2121
2122         case LFUN_MATH_MODE:   // Open or create a math inset
2123         {
2124                 
2125                 if (owner->currentView()->available())
2126                         owner->buffer()->open_new_inset(new InsetFormula);
2127                 setMessage(N_("Math editor mode"));
2128         }
2129         break;
2130           
2131         case LFUN_MATH_NUMBER:
2132         case LFUN_MATH_LIMITS:
2133         {
2134                 setErrorMessage(N_("This is only allowed in math mode!"));
2135         }
2136         break;
2137         
2138         case LFUN_INSERT_CITATION:
2139         {   
2140                 InsetCitation * new_inset = new InsetCitation();
2141                 // ale970405
2142                 // The note, if any, must be after the key, delimited
2143                 // by a | so both key and remark can have spaces.
2144                 if (!argument.empty()) {
2145                         string lsarg(argument);
2146                         if (contains(lsarg, "|")) {
2147                                 new_inset->setContents(token(lsarg, '|', 0));
2148                                 new_inset->setOptions(token(lsarg, '|', 1));
2149                         } else
2150                                 new_inset->setContents(lsarg);
2151                         owner->buffer()->insertInset(new_inset);
2152                 } else {
2153                         owner->buffer()->insertInset(new_inset);
2154                         new_inset->Edit(0, 0);
2155                 }
2156         }
2157         break;
2158                     
2159         case LFUN_INSERT_BIBTEX:
2160         {   
2161                 // ale970405+lasgoutt970425
2162                 // The argument can be up to two tokens separated 
2163                 // by a space. The first one is the bibstyle.
2164                 string lsarg(argument);
2165                 string bibstyle = token(lsarg, ' ', 1);
2166                 if (bibstyle.empty())
2167                         bibstyle = "plain";
2168                 InsetBibtex * new_inset 
2169                         = new InsetBibtex(token(lsarg, ' ', 0),
2170                                           bibstyle,
2171                                           owner->buffer());
2172                 
2173                 owner->buffer()->insertInset(new_inset);
2174                 if (lsarg.empty()) {
2175                         new_inset->Edit(0, 0);
2176                 }
2177         }
2178         break;
2179                 
2180         // BibTeX data bases
2181         case LFUN_BIBDB_ADD:
2182         {
2183                 InsetBibtex * inset = 
2184                         static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2185                 if (inset) {
2186                         inset->addDatabase(argument);
2187                 }
2188         }
2189         break;
2190                     
2191         case LFUN_BIBDB_DEL:
2192         {
2193                 InsetBibtex * inset = 
2194                         static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2195                 if (inset) {
2196                         inset->delDatabase(argument);
2197                 }
2198         }
2199         break;
2200         
2201         case LFUN_BIBTEX_STYLE:
2202         {
2203                 InsetBibtex * inset = 
2204                         static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2205                 if (inset) {
2206                         inset->setOptions(argument);
2207                 }
2208         }
2209         break;
2210                 
2211         case LFUN_INDEX_INSERT:
2212         case LFUN_INDEX_INSERT_LAST:
2213         {
2214                 InsetIndex * new_inset = new InsetIndex();
2215                 if (!argument.empty()) {
2216                         string lsarg(argument);
2217                         new_inset->setContents(lsarg);
2218                         owner->buffer()->insertInset(new_inset);
2219                 } else {
2220                   //reh 98/09/21
2221                   //get the current word for an argument
2222                   
2223                   
2224                   // grab a word
2225
2226                   LyXParagraph::size_type lastpos = 
2227                           owner->buffer()->text->cursor.pos - 1;
2228                   // If this can't happen, let's make sure that it really don't
2229                   Assert(owner->buffer()->text->cursor.pos - 1 >= 0);
2230                   // get the current word
2231                   // note that this must be done before 
2232                   // inserting the inset, or the inset will break
2233                   // the word
2234                   string curstring(owner->buffer()
2235                                    ->text->cursor.par->GetWord(lastpos));
2236
2237                   //make the new inset and write the current word into it
2238                   InsetIndex * new_inset = new InsetIndex();
2239
2240                   new_inset->setContents(curstring);
2241
2242                   //don't edit it if the call was to INSERT_LAST
2243                   if(action!= LFUN_INDEX_INSERT_LAST) {
2244                       new_inset->Edit(0, 0);
2245                   } else {
2246                       //it looks blank on the screen unless
2247                       //we do  something.  put it here.
2248
2249                       // move the cursor to the returned value of lastpos
2250                       // but only for the auto-insert
2251                       owner->buffer()->text->cursor.pos= lastpos;
2252                   }
2253
2254                   //put the new inset into the buffer.
2255                   // there should be some way of knowing the user
2256                   //cancelled & avoiding this, but i don't know how
2257                   owner->buffer()->insertInset(new_inset);
2258                 }
2259         }
2260         break;
2261
2262         case LFUN_INDEX_PRINT:
2263         {
2264                 Inset * new_inset = new InsetPrintIndex(owner->buffer());
2265                 owner->buffer()->insertInset(new_inset, "Standard", true);
2266         }
2267         break;
2268
2269         case LFUN_PARENTINSERT:
2270         {
2271                 lyxerr << "arg " << argument << endl;
2272                 Inset * new_inset = new InsetParent(argument, owner->buffer());
2273                 owner->buffer()->insertInset(new_inset, "Standard", true);
2274         }
2275         break;
2276
2277         case LFUN_CHILDINSERT:
2278         {
2279                 Inset * new_inset = new InsetInclude(argument,
2280                                                      owner->buffer());
2281                 owner->buffer()->insertInset(new_inset, "Standard", true);
2282                 new_inset->Edit(0, 0);
2283         }
2284         break;
2285
2286         case LFUN_CHILDOPEN:
2287         {
2288                 string filename =
2289                         MakeAbsPath(argument, 
2290                                     OnlyPath(owner->buffer()->getFileName()));
2291                 setMessage(N_("Opening child document ") +
2292                            MakeDisplayPath(filename) + "...");
2293                 owner->currentView()->savePosition();
2294                 if (bufferlist.exists(filename))
2295                   owner->currentView()->buffer(bufferlist.getBuffer(filename));
2296                 else
2297                   owner->currentView()->buffer(bufferlist.loadLyXFile(filename));
2298         }
2299         break;
2300
2301         case LFUN_INSERT_NOTE:
2302                 NoteCB();
2303                 break;
2304                 
2305         case LFUN_INSERTFOOTNOTE: 
2306         {
2307                 LyXParagraph::footnote_kind kind;
2308                 if (argument == "footnote")
2309                         { kind = LyXParagraph::FOOTNOTE; }
2310                 else if (argument == "margin")
2311                         { kind = LyXParagraph::MARGIN; }
2312                 else if (argument == "figure")
2313                         { kind = LyXParagraph::FIG; }
2314                 else if (argument == "table")
2315                         { kind = LyXParagraph::TAB; }
2316                 else if (argument == "wide-fig")
2317                         { kind = LyXParagraph::WIDE_FIG; }
2318                 else if (argument == "wide-tab")
2319                         { kind = LyXParagraph::WIDE_TAB; }
2320                 else if (argument == "algorithm")
2321                         { kind = LyXParagraph::ALGORITHM; }
2322                 else {
2323                         setErrorMessage(N_("Unknown kind of footnote"));
2324                         break;
2325                 }
2326                 owner->buffer()->text->InsertFootnoteEnvironment(kind);
2327                 owner->buffer()->update(1);
2328         }
2329         break;
2330         
2331         case LFUN_BUFFERBULLETSSELECT:
2332                 bulletForm();
2333                 break;
2334                 
2335         case LFUN_TOGGLECURSORFOLLOW:
2336                 cursor_follows_scrollbar = !cursor_follows_scrollbar;
2337                 break;
2338                 
2339         case LFUN_KMAP_OFF:             // keymap off
2340                 owner->getIntl()->KeyMapOn(false);
2341                 break;
2342                 
2343         case LFUN_KMAP_PRIM:    // primary keymap
2344                 owner->getIntl()->KeyMapPrim();
2345                 break;
2346                 
2347         case LFUN_KMAP_SEC:             // secondary keymap
2348                 owner->getIntl()->KeyMapSec();
2349                 break;
2350                 
2351         case LFUN_KMAP_TOGGLE:  // toggle keymap
2352                 owner->getIntl()->ToggleKeyMap();
2353                 break;
2354
2355         case LFUN_SELFINSERT:
2356         {
2357                 for (string::size_type i = 0; i < argument.length(); ++i) {
2358                         owner->buffer()->text->InsertChar(argument[i]);
2359                         // This needs to be in the loop, or else we
2360                         // won't break lines correctly. (Asger)
2361                         SmallUpdate(1);
2362                 }
2363                 SetUpdateTimer();
2364                 owner->buffer()->text->sel_cursor = 
2365                         owner->buffer()->text->cursor;
2366                 moveCursorUpdate(false);
2367         }
2368         break;
2369
2370         case LFUN_SEQUENCE: 
2371         {
2372                 // argument contains ';'-terminated commands
2373                 while (argument.find(';') != string::npos) {
2374                         string first;
2375                         argument = split(argument, first, ';');
2376                         Dispatch(first);
2377                 }
2378         }
2379         break;
2380
2381         case LFUN_UNKNOWN_ACTION:
2382         {
2383                 if (owner->buffer()->isReadonly()) {
2384                         LyXBell();
2385                         setErrorMessage(N_("Document is read only"));
2386                         break;
2387                 }
2388                          
2389                 if (!argument.empty()) {
2390                         
2391                         /* Automatically delete the currently selected
2392                          * text and replace it with what is being
2393                          * typed in now. Depends on lyxrc settings
2394                          * "auto_region_delete", which defaults to
2395                          * true (on). */
2396                 
2397                         if ( lyxrc->auto_region_delete ) {
2398                                 if (owner->buffer()->text->selection){
2399                                         owner->buffer()->text->CutSelection(false);
2400                                         owner->buffer()->update(-1);
2401                                 }
2402                         }
2403                         
2404                         BeforeChange();
2405                         for (string::size_type i = 0;
2406                              i < argument.length(); ++i) {
2407                                 if (greek_kb_flag) {
2408                                         if (!math_insert_greek(argument[i]))
2409                                                 owner->getIntl()->getTrans()->TranslateAndInsert(argument[i], owner->buffer()->text);
2410                                 } else
2411                                         owner->getIntl()->getTrans()->TranslateAndInsert(argument[i], owner->buffer()->text);
2412                         }
2413                         
2414                         SmallUpdate(1);
2415                         SetUpdateTimer();
2416
2417                         owner->buffer()->text->sel_cursor = 
2418                                 owner->buffer()->text->cursor;
2419                         moveCursorUpdate(false);
2420                         return string();
2421                 } else {
2422                         // why is an "Unknown action" with empty
2423                         // argument even dispatched in the first
2424                         // place? I`ll probably change that. (Lgb)
2425                         LyXBell();
2426                         setErrorMessage(N_("Unknown action"));
2427                 }
2428                 break;
2429         default:
2430                 lyxerr << "A truly unknown func!" << endl;
2431                 break;
2432         }
2433         } // end of switch
2434   exit_with_message:
2435
2436         string res= getMessage();
2437
2438         if (res.empty()) {
2439                 if (!commandshortcut.empty()) {
2440                         string newbuf = owner->getMiniBuffer()->GetText();
2441                         if (newbuf != commandshortcut) {
2442                                 owner->getMiniBuffer()->Set(newbuf
2443                                                             + " " +
2444                                                             commandshortcut);
2445                         }
2446                 }
2447         } else {
2448                 owner->getMiniBuffer()->Set(string(_(res.c_str()))
2449                                             + " " + commandshortcut);
2450         }
2451
2452         return getMessage();
2453 }
2454             
2455
2456 void LyXFunc::setupLocalKeymap()
2457 {
2458         keyseq.stdmap = keyseq.curmap = toplevel_keymap;
2459         cancel_meta_seq.stdmap = cancel_meta_seq.curmap = toplevel_keymap;
2460 }
2461
2462
2463 void LyXFunc::MenuNew(bool fromTemplate)
2464 {
2465         string fname, initpath = lyxrc->document_path;
2466         LyXFileDlg fileDlg;
2467
2468         if (owner->currentView()->available()) {
2469                 string trypath = owner->buffer()->filepath;
2470                 // If directory is writeable, use this as default.
2471                 if (IsDirWriteable(trypath) == 1)
2472                         initpath = trypath;
2473         }
2474
2475         ProhibitInput();
2476         fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2477         fileDlg.SetButton(1, _("Templates"), lyxrc->template_path);
2478         fname = fileDlg.Select(_("Enter Filename for new document"), 
2479                                initpath, "*.lyx", _("newfile"));
2480         AllowInput();
2481         
2482         if (fname.empty()) {
2483                 owner->getMiniBuffer()->Set(_("Canceled."));
2484                 lyxerr.debug() << "New Document Cancelled." << endl;
2485                 return;
2486         }
2487         
2488         // get absolute path of file and make sure the filename ends
2489         // with .lyx
2490         string s = MakeAbsPath(fname);
2491         if (!IsLyXFilename(s))
2492                 s += ".lyx";
2493
2494         // Check if the document already is open
2495         if (bufferlist.exists(s)){
2496                 switch(AskConfirmation(_("Document is already open:"), 
2497                                        MakeDisplayPath(s, 50),
2498                                        _("Do you want to close that document now?\n"
2499                                          "('No' will just switch to the open version)")))
2500                 {
2501                 case 1: // Yes: close the document
2502                         if (!bufferlist.close(bufferlist.getBuffer(s)))
2503                                 // If close is canceled, we cancel here too.
2504                                 return;
2505                         break;
2506                 case 2: // No: switch to the open document
2507                         owner->currentView()->buffer(bufferlist.getBuffer(s));
2508                         return;
2509                 case 3: // Cancel: Do nothing
2510                         owner->getMiniBuffer()->Set(_("Canceled."));
2511                         return;
2512                 }
2513         }
2514         
2515         // Check whether the file already exists
2516         if (IsLyXFilename(s)) {
2517                 FilePtr myfile(s, FilePtr::read);
2518                 if (myfile() &&
2519                     AskQuestion(_("File already exists:"), 
2520                                 MakeDisplayPath(s, 50),
2521                                 _("Do you want to open the document?"))) {
2522                         // loads document
2523                         owner->getMiniBuffer()->Set(_("Opening document"), 
2524                                                     MakeDisplayPath(s), "...");
2525                         XFlush(fl_display);
2526                         owner->currentView()->buffer(
2527                                 bufferlist.loadLyXFile(s));
2528                         owner->getMiniBuffer()->Set(_("Document"),
2529                                                     MakeDisplayPath(s),
2530                                                     _("opened."));
2531                         return;
2532                 }
2533         }
2534
2535         // The template stuff
2536         string templname;
2537         if (fromTemplate) {
2538                 ProhibitInput();
2539                 fname = fileDlg.Select(_("Choose template"),
2540                                        lyxrc->template_path,
2541                                        "*.lyx");
2542                 templname = fname;
2543                 AllowInput();
2544         }
2545   
2546         // find a free buffer
2547         lyxerr.debug() << "Find a free buffer." << endl;
2548         owner->currentView()->buffer(bufferlist.newFile(s, templname));
2549 }
2550
2551
2552 void LyXFunc::MenuOpen()
2553 {
2554         string initpath = lyxrc->document_path;
2555         LyXFileDlg fileDlg;
2556   
2557         if (owner->currentView()->available()) {
2558                 string trypath = owner->buffer()->filepath;
2559                 // If directory is writeable, use this as default.
2560                 if (IsDirWriteable(trypath) == 1)
2561                         initpath = trypath;
2562         }
2563
2564         // launches dialog
2565         ProhibitInput();
2566         fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2567         fileDlg.SetButton(1, _("Examples"), 
2568                           AddPath(system_lyxdir, "examples"));
2569         string filename = fileDlg.Select(_("Select Document to Open"),
2570                                           initpath, "*.lyx");
2571         AllowInput();
2572  
2573         // check selected filename
2574         if (filename.empty()) {
2575                 owner->getMiniBuffer()->Set(_("Canceled."));
2576                 return;
2577         }
2578
2579         // get absolute path of file and make sure the filename ends
2580         // with .lyx
2581         filename = MakeAbsPath(filename);
2582         if (!IsLyXFilename(filename))
2583                 filename += ".lyx";
2584
2585         // loads document
2586         owner->getMiniBuffer()->Set(_("Opening document"),
2587                                     MakeDisplayPath(filename), "...");
2588         Buffer * openbuf = bufferlist.loadLyXFile(filename);
2589         if (openbuf) {
2590                 owner->currentView()->buffer(openbuf);
2591                 owner->getMiniBuffer()->Set(_("Document"),
2592                                             MakeDisplayPath(filename),
2593                                             _("opened."));
2594         } else {
2595                 owner->getMiniBuffer()->Set(_("Could not open document"),
2596                                             MakeDisplayPath(filename));
2597         }
2598 }
2599
2600
2601 void LyXFunc::doImportASCII(bool linorpar)
2602 {
2603         string initpath = lyxrc->document_path;
2604         LyXFileDlg fileDlg;
2605   
2606         if (owner->currentView()->available()) {
2607                 string trypath = owner->buffer()->filepath;
2608                 // If directory is writeable, use this as default.
2609                 if (IsDirWriteable(trypath) == 1)
2610                         initpath = trypath;
2611         }
2612
2613         // launches dialog
2614         ProhibitInput();
2615         fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2616         fileDlg.SetButton(1, _("Examples"), 
2617                           AddPath(system_lyxdir, "examples"));
2618         string filename = fileDlg.Select(_("Select ASCII file to Import"),
2619                                           initpath, "*.txt");
2620         AllowInput();
2621  
2622         // check selected filename
2623         if (filename.empty()) {
2624                 owner->getMiniBuffer()->Set(_("Canceled."));
2625                 return;
2626         }
2627
2628         // get absolute path of file
2629         filename = MakeAbsPath(filename);
2630
2631         string s = ChangeExtension(filename, ".lyx", false);
2632
2633         // Check if the document already is open
2634         if (bufferlist.exists(s)){
2635                 switch(AskConfirmation(_("Document is already open:"), 
2636                                        MakeDisplayPath(s, 50),
2637                                        _("Do you want to close that document now?\n"
2638                                          "('No' will just switch to the open version)")))
2639                 {
2640                 case 1: // Yes: close the document
2641                         if (!bufferlist.close(bufferlist.getBuffer(s)))
2642                                 // If close is canceled, we cancel here too.
2643                                 return;
2644                         break;
2645                 case 2: // No: switch to the open document
2646                         owner->currentView()->buffer(bufferlist.getBuffer(s));
2647                         return;
2648                 case 3: // Cancel: Do nothing
2649                         owner->getMiniBuffer()->Set(_("Canceled."));
2650                         return;
2651                 }
2652         }
2653
2654         // Check if a LyX document by the same root exists in filesystem
2655         FileInfo f(s, true);
2656         if (f.exist() && !AskQuestion(_("A document by the name"), 
2657                                       MakeDisplayPath(s),
2658                                       _("already exists. Overwrite?"))) {
2659                 owner->getMiniBuffer()->Set(_("Canceled."));
2660                 return;
2661         }
2662
2663         owner->currentView()->buffer(bufferlist.newFile(s, string()));
2664         owner->getMiniBuffer()->Set(_("Importing ASCII file"),
2665                                     MakeDisplayPath(filename), "...");
2666         // Insert ASCII file
2667         InsertAsciiFile(filename, linorpar);
2668         owner->getMiniBuffer()->Set(_("ASCII file "),
2669                                     MakeDisplayPath(filename),
2670                                     _("imported."));
2671 }
2672
2673
2674 void LyXFunc::doImportLaTeX(bool isnoweb)
2675 {
2676         string initpath = lyxrc->document_path;
2677         LyXFileDlg fileDlg;
2678   
2679         if (owner->currentView()->available()) {
2680                 string trypath = owner->buffer()->filepath;
2681                 // If directory is writeable, use this as default.
2682                 if (IsDirWriteable(trypath) == 1)
2683                         initpath = trypath;
2684         }
2685
2686         // launches dialog
2687         ProhibitInput();
2688         fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2689         fileDlg.SetButton(1, _("Examples"), 
2690                           AddPath(system_lyxdir, "examples"));
2691         string filename;
2692         if (isnoweb) {
2693                 filename = fileDlg.Select(_("Select Noweb file to Import"),
2694                                           initpath, "*.nw");
2695         } else {
2696                 filename = fileDlg.Select(_("Select LaTeX file to Import"),
2697                                           initpath, "*.tex");
2698         }
2699         
2700         AllowInput();
2701  
2702         // check selected filename
2703         if (filename.empty()) {
2704                 owner->getMiniBuffer()->Set(_("Canceled."));
2705                 return;
2706         }
2707
2708         // get absolute path of file
2709         filename = MakeAbsPath(filename);
2710
2711         // Check if the document already is open
2712         string LyXfilename = ChangeExtension(filename, ".lyx", false);
2713         if (bufferlist.exists(LyXfilename)){
2714                 switch(AskConfirmation(_("Document is already open:"), 
2715                                        MakeDisplayPath(LyXfilename, 50),
2716                                        _("Do you want to close that document now?\n"
2717                                          "('No' will just switch to the open version)")))
2718                 {
2719                 case 1: // Yes: close the document
2720                         if (!bufferlist.close(bufferlist.getBuffer(LyXfilename)))
2721                                 // If close is canceled, we cancel here too.
2722                                 return;
2723                         break;
2724                 case 2: // No: switch to the open document
2725                         owner->currentView()->buffer(
2726                                 bufferlist.getBuffer(LyXfilename));
2727                         return;
2728                 case 3: // Cancel: Do nothing
2729                         owner->getMiniBuffer()->Set(_("Canceled."));
2730                         return;
2731                 }
2732         }
2733
2734         // Check if a LyX document by the same root exists in filesystem
2735         FileInfo f(LyXfilename, true);
2736         if (f.exist() && !AskQuestion(_("A document by the name"), 
2737                                       MakeDisplayPath(LyXfilename),
2738                                       _("already exists. Overwrite?"))) {
2739                 owner->getMiniBuffer()->Set(_("Canceled."));
2740                 return;
2741         }
2742
2743         // loads document
2744         Buffer * openbuf;
2745         if (!isnoweb) {
2746                 owner->getMiniBuffer()->Set(_("Importing LaTeX file"),
2747                                             MakeDisplayPath(filename), "...");
2748                 ImportLaTeX myImport(filename);
2749                 openbuf = myImport.run();
2750         } else {
2751                 owner->getMiniBuffer()->Set(_("Importing Noweb file"),
2752                                             MakeDisplayPath(filename), "...");
2753                 ImportNoweb myImport(filename);
2754                 openbuf = myImport.run();
2755         }
2756         if (openbuf) {
2757                 owner->currentView()->buffer(openbuf);
2758                 owner->getMiniBuffer()->Set(isnoweb ?
2759                                             _("Noweb file ") : _("LateX file "),
2760                                             MakeDisplayPath(filename),
2761                                             _("imported."));
2762         } else {
2763                 owner->getMiniBuffer()->Set(isnoweb ?
2764                                             _("Could not import Noweb file") :
2765                                             _("Could not import LaTeX file"),
2766                                             MakeDisplayPath(filename));
2767         }
2768 }
2769
2770
2771 void LyXFunc::MenuInsertLyXFile(string const & filen)
2772 {
2773         string filename = filen;
2774
2775         if (filename.empty()) {
2776                 // Launch a file browser
2777                 string initpath = lyxrc->document_path;
2778                 LyXFileDlg fileDlg;
2779
2780                 if (owner->currentView()->available()) {
2781                         string trypath = owner->buffer()->filepath;
2782                         // If directory is writeable, use this as default.
2783                         if (IsDirWriteable(trypath) == 1)
2784                                 initpath = trypath;
2785                 }
2786
2787                 // launches dialog
2788                 ProhibitInput();
2789                 fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2790                 fileDlg.SetButton(1, _("Examples"), 
2791                                   AddPath(system_lyxdir, "examples"));
2792                 filename = fileDlg.Select(_("Select Document to Insert"),
2793                                           initpath, "*.lyx");
2794                 AllowInput();
2795
2796                 // check selected filename
2797                 if (filename.empty()) {
2798                         owner->getMiniBuffer()->Set(_("Canceled."));
2799                         return;
2800                 }
2801         } 
2802
2803         // get absolute path of file and make sure the filename ends
2804         // with .lyx
2805         filename = MakeAbsPath(filename);
2806         if (!IsLyXFilename(filename))
2807                 filename += ".lyx";
2808
2809         // Inserts document
2810         owner->getMiniBuffer()->Set(_("Inserting document"),
2811                                     MakeDisplayPath(filename), "...");
2812         bool res = owner->buffer()->insertLyXFile(filename);
2813         if (res) {
2814                 owner->getMiniBuffer()->Set(_("Document"),
2815                                             MakeDisplayPath(filename),
2816                                             _("inserted."));
2817         } else {
2818                 owner->getMiniBuffer()->Set(_("Could not insert document"),
2819                                             MakeDisplayPath(filename));
2820         }
2821 }
2822
2823
2824 void LyXFunc::reloadBuffer()
2825 {
2826         string fn = owner->buffer()->getFileName();
2827         if (bufferlist.close(owner->buffer()))
2828                 owner->currentView()->buffer(bufferlist.loadLyXFile(fn));
2829 }
2830
2831
2832 void LyXFunc::CloseBuffer()
2833 {
2834         if (bufferlist.close(owner->buffer()) && !quitting) {
2835                 if (bufferlist.empty()) {
2836                         // need this otherwise SEGV may occur while trying to
2837                         // set variables that don't exist
2838                         // since there's no current buffer
2839                         CloseAllBufferRelatedPopups();
2840                 }
2841                 else {
2842                         owner->currentView()->buffer(bufferlist.first());
2843                 }
2844         }
2845 }
2846
2847
2848 Inset * LyXFunc::getInsetByCode(Inset::Code code)
2849 {
2850         bool found = false;
2851         Inset * inset = 0;
2852         LyXCursor cursor = owner->buffer()->text->cursor;
2853         LyXParagraph::size_type pos = cursor.pos;
2854         LyXParagraph * par = cursor.par;
2855         
2856         while (par && !found) {
2857                 while ((inset = par->ReturnNextInsetPointer(pos))){
2858                         if (inset->LyxCode() == code) {
2859                                 found = true;
2860                                 break;
2861                         }
2862                         pos++;
2863                 } 
2864                 par = par->next;
2865         }
2866         return (found) ? inset: 0;
2867 }
2868
2869
2870 // Each "owner" should have it's own message method. lyxview and
2871 // the minibuffer would use the minibuffer, but lyxserver would
2872 // send an ERROR signal to its client.  Alejandro 970603
2873 // This func is bit problematic when it comes to NLS, to make the
2874 // lyx servers client be language indepenent we must not translate
2875 // strings sent to this func.
2876 void LyXFunc::setErrorMessage(string const &m) 
2877 {
2878         dispatch_buffer = m;
2879         errorstat = true;
2880 }
2881
2882
2883 void LyXFunc::setMessage(string const & m)
2884 {
2885         dispatch_buffer = m;
2886 }