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