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