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