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