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