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