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