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