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