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