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