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