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