1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-1999 The LyX Team.
9 * ====================================================== */
18 #pragma implementation
21 #include "lyxlookup.h"
24 #include "bufferlist.h"
25 #include "lyxserver.h"
30 #include "LyXAction.h"
32 #include "insets/insetlatex.h"
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"
47 #include "spellchecker.h" // RVDK_PATCH_5
48 #include "minibuffer.h"
52 #include "lyx_gui_misc.h"
53 #include "support/filetools.h"
54 #include "support/FileInfo.h"
55 #include "support/syscall.h"
56 #include "support/lstrings.h"
57 #include "support/path.h"
58 #include "lyxscreen.h"
63 #include "trans_mgr.h"
64 #include "ImportLaTeX.h"
65 #include "ImportNoweb.h"
68 extern bool cursor_follows_scrollbar;
70 extern void InsertAsciiFile(string const &, bool);
71 extern void math_insert_symbol(char const *);
72 extern Bool math_insert_greek(char const); // why "Bool"?
73 extern BufferList bufferlist;
74 extern LyXServer * lyxserver;
75 extern short greek_kb_flag;
76 extern FD_form_toc * fd_form_toc;
77 extern bool selection_possible;
79 extern kb_keymap * toplevel_keymap;
81 extern void MenuWrite(Buffer *);
82 extern void MenuWriteAs(Buffer *);
83 extern int MenuRunLaTeX(Buffer *);
84 extern int MenuBuildProg(Buffer *);
85 extern int MenuRunChktex(Buffer *);
86 extern bool MenuRunDvips(Buffer *, bool);
87 extern void MenuPrint(Buffer *);
88 extern void MenuSendto();
89 extern void QuitLyX();
90 extern void MenuFax(Buffer *);
91 extern void MenuExport(Buffer *, string const &);
92 extern void MenuPasteSelection(char at);
93 extern LyXAction lyxaction;
95 extern tex_accent_struct get_accent(kb_action action);
97 extern void AutoSave();
98 extern void MenuSearch();
100 extern void CopyEnvironmentCB();
101 extern void PasteEnvironmentCB();
102 extern void GotoNote();
103 extern void NoteCB();
104 extern void OpenStuff();
105 extern void HyphenationPoint();
107 extern void EndOfSentenceDot();
108 extern void MenuSeparator();
110 extern void MenuUndo();
111 extern void MenuRedo();
112 extern void SetUpdateTimer(float timer = 0.3);
113 extern void FreeUpdateTimer();
114 extern bool MenuPreview(Buffer *);
115 extern bool MenuPreviewPS(Buffer *);
116 extern void MenuInsertLabel(char const *);
117 extern void MenuInsertRef();
118 extern void MenuLayoutCharacter();
119 extern void MenuLayoutParagraph();
120 extern void MenuLayoutDocument();
121 extern void MenuLayoutPaper();
122 extern void MenuLayoutTable(int flag);
123 extern void MenuLayoutQuotes();
124 extern void MenuLayoutPreamble();
125 extern void MenuLayoutSave();
126 extern void bulletForm();
128 extern Buffer * NewLyxFile(string const &);
129 extern void LoadLyXFile(string const &);
130 extern void Reconfigure();
132 extern int current_layout;
133 extern int getISOCodeFromLaTeX(char *);
135 extern int UnlockInset(UpdatableInset *);
137 extern void ShowLatexLog();
139 extern void UpdateInset(Inset * inset, bool mark_dirty = true);
141 /* === globals =========================================================== */
143 bool LyXFunc::show_sc = true;
146 LyXFunc::LyXFunc(LyXView * o)
150 lyx_dead_action = LFUN_NOACTION;
151 lyx_calling_dead_action = LFUN_NOACTION;
156 // I changed this func slightly. I commented out the ...FinishUndo(),
157 // this means that all places that used to have a moveCursorUpdate, now
158 // have a ...FinishUndo() as the preceeding statement. I have also added
159 // a moveCursorUpdate to some of the functions that updated the cursor, but
160 // that did not show its new position.
162 void LyXFunc::moveCursorUpdate(bool selecting)
164 if (selecting || owner->view()->text->mark_set) {
165 owner->view()->text->SetSelection();
166 owner->view()->getScreen()->ToggleToggle();
167 owner->view()->update(0);
169 owner->view()->update(-2); // this IS necessary
173 owner->view()->getScreen()->ShowCursor();
175 /* ---> Everytime the cursor is moved, show the current font state. */
176 // should this too me moved out of this func?
177 //owner->getMiniBuffer()->Set(CurrentState());
181 int LyXFunc::processKeyEvent(XEvent * ev)
186 XKeyEvent * keyevent = &ev->xkey;
187 KeySym keysym_return;
189 int num_bytes = LyXLookupString(ev, s_r, 10, &keysym_return);
191 if (lyxerr.debugging(Debug::KEY)) {
192 lyxerr << "KeySym is "
193 << XKeysymToString(keysym_return)
195 << keysym_return << "]"
196 << " and num_bytes is "
198 << " the string returned is \""
199 << s_r << '\"' << endl;
201 // Do nothing if we have nothing (JMarc)
202 if (num_bytes == 0 && keysym_return == NoSymbol) {
203 lyxerr[Debug::KEY] << "Empty kbd action (probably composing)"
208 // this function should be used always [asierra060396]
209 if (owner->view()->available() &&
210 owner->view()->the_locking_inset &&
211 keysym_return == XK_Escape) {
212 UnlockInset(owner->view()->the_locking_inset);
213 owner->view()->text->CursorRight();
217 // Can we be sure that this will work for all X-Windows
218 // implementations? (Lgb)
219 // This code snippet makes lyx ignore some keys. Perhaps
220 // all of them should be explictly mentioned?
221 if((keysym_return >= XK_Shift_L && keysym_return <= XK_Hyper_R)
222 || keysym_return == XK_Mode_switch || keysym_return == 0x0)
225 // Do a one-deep top-level lookup for
226 // cancel and meta-fake keys. RVDK_PATCH_5
227 cancel_meta_seq.reset();
229 int action = cancel_meta_seq.addkey(keysym_return, keyevent->state
230 &(ShiftMask|ControlMask
233 // When not cancel or meta-fake, do the normal lookup.
234 // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards.
235 // Mostly, meta_fake_bit = 0. RVDK_PATCH_5.
236 if ( (action != LFUN_CANCEL) && (action != LFUN_META_FAKE) ) {
238 // remove Caps Lock and Mod2 as a modifiers
239 action = keyseq.addkey(keysym_return,
240 (keyevent->state | meta_fake_bit)
241 &(ShiftMask|ControlMask
244 // Dont remove this unless you know what you are doing.
247 if (action == 0) action = LFUN_PREFIX;
249 if (lyxerr.debugging(Debug::KEY)) {
255 << num_bytes << "]" << endl;
258 // already here we know if it any point in going further
259 // why not return already here if action == -1 and
260 // num_bytes == 0? (Lgb)
262 if(keyseq.length > 1 || keyseq.length < -1){
265 owner->getMiniBuffer()->Set(buf);
269 if (keyseq.length < -1) { // unknown key sequence...
273 owner->getMiniBuffer()->Set(_("Unknown sequence:"), buf);
277 char isochar = keyseq.getiso();
278 if (!(keyevent->state&ControlMask) &&
279 !(keyevent->state&Mod1Mask) &&
280 (isochar && keysym_return < 0xF000)) {
283 if (argument.empty()) {
284 lyxerr.debug() << "Empty argument!" << endl;
285 // This can`t possibly be of any use
286 // so we`ll skip the dispatch.
290 if (action == LFUN_SELFINSERT) {
294 bool tmp_sc = show_sc;
296 Dispatch(action, argument.c_str());
303 LyXFunc::func_status LyXFunc::getStatus(int ac) const
306 func_status flag = LyXFunc::OK;
308 Buffer * buf = owner->buffer();
310 if (lyxaction.isPseudoAction(ac))
311 action = lyxaction.retrieveActionArg(ac, argument);
313 action = static_cast<kb_action>(ac);
315 if (action == LFUN_UNKNOWN_ACTION) {
316 setErrorMessage(N_("Unknown action"));
317 return LyXFunc::Unknown;
320 // Check whether we need a buffer
321 if (!lyxaction.funcHasFlag(action, LyXAction::NoBuffer)) {
322 // Yes we need a buffer, do we have one?
325 // Can we use a readonly buffer?
326 if (buf->isReadonly() &&
327 !lyxaction.funcHasFlag(action,
328 LyXAction::ReadOnly)) {
330 setErrorMessage(N_("Document is read-only"));
331 flag |= LyXFunc::Disabled;
335 setErrorMessage(N_("Command not allowed with"
336 "out any document open"));
337 flag |= LyXFunc::Disabled;
341 if (flag & LyXFunc::Disabled)
344 // I would really like to avoid having this switch and rather try to
345 // encode this in the function itself.
346 static bool noLaTeX = lyxrc->latex_command == "none";
347 bool disable = false;
350 disable = noLaTeX || lyxrc->view_dvi_command == "none";
353 disable = noLaTeX || lyxrc->view_ps_command == "none";
360 disable = noLaTeX || lyxrc->print_command == "none";
363 disable = noLaTeX || lyxrc->fax_command == "none";
366 if (argument == "latex")
367 disable = lyxrc->relyx_command == "none";
370 if (argument == "dvi" || argument == "postscript")
372 if (argument == "html")
373 disable = lyxrc->html_command == "none";
376 disable = buf->undostack.empty();
379 disable = buf->redostack.empty();
381 case LFUN_SPELLCHECK:
382 disable = lyxrc->isp_command == "none";
385 disable = lyxrc->chktex_command == "none";
387 case LFUN_LAYOUT_TABLE:
388 disable = ! owner->view()->text->cursor.par->table;
394 flag |= LyXFunc::Disabled;
397 func_status box = LyXFunc::ToggleOff;
398 LyXFont font = owner->view()->text->real_current_font;
401 if (font.emph() == LyXFont::ON)
402 box = LyXFunc::ToggleOn;
405 if (font.noun() == LyXFont::ON)
406 box = LyXFunc::ToggleOn;
409 if (font.series() == LyXFont::BOLD_SERIES)
410 box = LyXFunc::ToggleOn;
413 if (font.latex() == LyXFont::ON)
414 box = LyXFunc::ToggleOn;
427 string LyXFunc::Dispatch(string const & s)
429 // Split command string into command and argument
430 string cmd, line = frontStrip(s);
431 string arg = strip(frontStrip(split(line, cmd, ' ')));
433 return Dispatch(lyxaction.LookupFunc(cmd.c_str()), arg.c_str());
437 string LyXFunc::Dispatch(int ac,
438 char const * do_not_use_this_arg)
443 FL_OBJECT * ob = 0; // This will disapear soon
445 // we have not done anything wrong yet.
447 dispatch_buffer.clear();
449 // if action is a pseudo-action, we need the real action
450 if (lyxaction.isPseudoAction(ac)) {
452 action = static_cast<kb_action>
453 (lyxaction.retrieveActionArg(ac, tmparg));
457 action = static_cast<kb_action>(ac);
458 if (do_not_use_this_arg)
459 argument = do_not_use_this_arg; // except here
462 selection_possible = false;
464 if (owner->view()->available()
465 && owner->view()->getScreen())
466 owner->view()->getScreen()->HideCursor();
468 // We cannot use this function here
469 if (getStatus(action) & Disabled)
470 goto exit_with_message;
472 commandshortcut.clear();
474 if (lyxrc->display_shortcuts && show_sc) {
475 if (action != LFUN_SELFINSERT) {
476 // Put name of command and list of shortcuts
477 // for it in minibuffer
478 string comname = lyxaction.getActionName(action);
480 int pseudoaction = action;
481 bool argsadded = false;
483 if (!argument.empty()) {
484 // If we have the command with argument,
487 lyxaction.searchActionArg(action,
490 if (pseudoaction == -1) {
491 pseudoaction = action;
493 comname += " " + argument;
498 string shortcuts = toplevel_keymap->findbinding(pseudoaction);
500 if (!shortcuts.empty()) {
501 comname += ": " + shortcuts;
502 } else if (!argsadded) {
503 comname += " " + argument;
506 if (!comname.empty()) {
507 comname = strip(comname);
508 commandshortcut = "(" + comname + ')';
509 owner->getMiniBuffer()->Set(commandshortcut);
510 // Here we could even add a small pause,
511 // to annoy the user and make him learn
513 // No! That will just annoy, not teach
514 // anything. The user will read the messages
515 // if they are interested. (Asger)
520 // If in math mode pass the control to
521 // the math inset [asierra060396]
522 if (owner->view()->available() &&
523 owner->view()->the_locking_inset) {
525 || (action == LFUN_UNKNOWN_ACTION
526 && keyseq.length >= -1)) {
527 if (action == LFUN_UNKNOWN_ACTION
528 && argument.empty()) {
529 argument = keyseq.getiso();
531 // Undo/Redo pre 0.13 is a bit tricky for insets.
532 if (action == LFUN_UNDO) {
534 UpdatableInset * inset =
535 owner->view()->the_locking_inset;
536 inset->GetCursorPos(slx, sly);
539 inset = static_cast<UpdatableInset*>(owner->view()->text->cursor.par->GetInset(owner->view()->text->cursor.pos));
541 inset->Edit(slx, sly);
544 if (action == LFUN_REDO) {
546 UpdatableInset * inset = owner->view()->the_locking_inset;
547 inset->GetCursorPos(slx, sly);
550 inset = static_cast<UpdatableInset*>(owner->view()->text->cursor.par->GetInset(owner->view()->text->cursor.pos));
552 inset->Edit(slx, sly);
555 if (owner->view()->the_locking_inset->LocalDispatch(action, argument.c_str()))
558 setMessage(N_("Text mode"));
559 if (action == LFUN_RIGHT || action == -1)
560 owner->view()->text->CursorRight();
561 if (action == LFUN_LEFT || action == LFUN_RIGHT)
568 // --- Misc -------------------------------------------
569 case LFUN_WORDFINDFORWARD :
570 case LFUN_WORDFINDBACKWARD : {
571 static string last_search;
572 string searched_string;
574 if (!argument.empty()) {
575 last_search = argument;
576 searched_string = argument;
578 searched_string = last_search;
581 LyXText * ltCur = owner->view()->text ;
583 if (!searched_string.empty() &&
584 ((action == LFUN_WORDFINDBACKWARD) ?
585 ltCur->SearchBackward(searched_string.c_str()) :
586 ltCur->SearchForward(searched_string.c_str()))) {
588 // ??? What is that ???
589 owner->view()->update(-2);
592 // clear the selection (if there is any)
593 owner->view()->getScreen()->ToggleSelection();
594 owner->view()->text->ClearSelection();
596 // Move cursor so that successive C-s 's will not stand in place.
597 if( action == LFUN_WORDFINDFORWARD )
598 owner->view()->text->CursorRightOneWord();
599 owner->view()->text->FinishUndo();
600 moveCursorUpdate(false);
603 // set the new selection
604 // SetSelectionOverLenChars(owner->view()->currentBuffer()->text, iLenSelected);
605 owner->view()->getScreen()->ToggleSelection(false);
609 // REMOVED : if (owner->view()->getWorkArea()->focus)
610 owner->view()->getScreen()->ShowCursor();
616 if (owner->view()->available()
617 && owner->view()->getScreen()) {
618 owner->view()->update(-2);
621 keyseq.print(buf, true);
622 owner->getMiniBuffer()->Set(buf, string(), string(), 1);
626 // --- Misc -------------------------------------------
627 case LFUN_EXEC_COMMAND:
628 owner->getMiniBuffer()->ExecCommand();
631 case LFUN_CANCEL: // RVDK_PATCH_5
634 if(owner->view()->available())
635 // cancel any selection
636 Dispatch(LFUN_MARK_OFF, 0);
637 setMessage(N_("Cancel"));
640 case LFUN_META_FAKE: // RVDK_PATCH_5
642 meta_fake_bit = Mod1Mask;
644 keyseq.print(buf, true);
645 string res = string("M-") + buf;
646 setMessage(buf); // RVDK_PATCH_5
650 case LFUN_READ_ONLY_TOGGLE:
651 if (owner->buffer()->lyxvc.inUse()) {
652 owner->buffer()->lyxvc.toggleReadOnly();
654 owner->buffer()->setReadonly(
655 !owner->buffer()->isReadonly());
659 case LFUN_CENTER: // this is center and redraw.
660 owner->view()->beforeChange();
661 if (owner->view()->text->cursor.y >
662 owner->view()->getWorkArea()->h / 2) {
663 owner->view()->getScreen()->
664 Draw(owner->view()->text->cursor.y -
665 owner->view()->getWorkArea()->h / 2);
667 owner->view()->getScreen()->
670 owner->view()->update(0);
671 owner->view()->redraw();
675 if (owner->view()->available()) {
676 owner->view()->text->toggleAppendix();
677 owner->view()->update(1);
681 // --- Menus -----------------------------------------------
686 case LFUN_MENUNEWTMPLT:
694 case LFUN_CLOSEBUFFER:
699 MenuWrite(owner->buffer());
702 case LFUN_MENUWRITEAS:
703 MenuWriteAs(owner->buffer());
706 case LFUN_MENURELOAD:
711 MenuPreview(owner->buffer());
715 MenuPreviewPS(owner->buffer());
719 MenuRunLaTeX(owner->buffer());
723 MenuBuildProg(owner->buffer());
727 MenuRunChktex(owner->buffer());
731 MenuRunDvips(owner->buffer(), false);
735 MenuPrint(owner->buffer());
739 MenuFax(owner->buffer());
743 MenuExport(owner->buffer(), argument);
748 //needs argument as string
749 string imtyp = argument;
752 if (imtyp == "latex") {
753 doImportLaTeX(false);
756 else if (imtyp == "ascii") {
757 doImportASCII(false);
758 } else if (imtyp == "asciiparagraph") {
761 } else if (imtyp == "noweb") {
764 setErrorMessage(string(N_("Unknown import type: "))
776 if (fd_form_toc->form_toc->visible) {
777 fl_raise_form(fd_form_toc->form_toc);
779 static int ow = -1, oh;
780 fl_show_form(fd_form_toc->form_toc,
782 FL_FREE_SIZE, FL_FULLBORDER,
783 _("Table of Contents"));
785 ow = fd_form_toc->form_toc->w;
786 oh = fd_form_toc->form_toc->h;
788 fl_set_form_minsize(fd_form_toc->form_toc, ow, oh);
792 case LFUN_TOC_INSERT:
794 Inset * new_inset = new InsetTOC(owner->buffer());
795 owner->buffer()->insertInset(new_inset, "Standard", true);
799 case LFUN_LOF_INSERT:
801 Inset * new_inset = new InsetLOF(owner->buffer());
802 owner->buffer()->insertInset(new_inset, "Standard", true);
806 case LFUN_LOA_INSERT:
808 Inset * new_inset = new InsetLOA(owner->buffer());
809 owner->buffer()->insertInset(new_inset, "Standard", true);
813 case LFUN_LOT_INSERT:
815 Inset * new_inset = new InsetLOT(owner->buffer());
816 owner->buffer()->insertInset(new_inset, "Standard", true);
840 case LFUN_MENUSEARCH:
848 case LFUN_PASTESELECTION:
851 if (argument == "paragraph") asPara = true;
852 MenuPasteSelection(asPara);
864 case LFUN_LAYOUT_COPY:
868 case LFUN_LAYOUT_PASTE:
869 PasteEnvironmentCB();
873 owner->view()->gotoError();
876 case LFUN_REMOVEERRORS:
877 if (owner->buffer()->removeAutoInsets()) {
878 owner->view()->redraw();
879 owner->view()->fitCursor();
880 owner->view()->updateScrollbar();
892 case LFUN_HYPHENATION:
900 case LFUN_END_OF_SENTENCE:
904 case LFUN_MENU_SEPARATOR:
920 case LFUN_DEPTH_PLUS:
936 case LFUN_RECONFIGURE:
941 if (owner->view()->available()
942 && !owner->view()->text->selection
943 && owner->view()->text->cursor.par->footnoteflag
944 != LyXParagraph::NO_FOOTNOTE)
945 { // only melt footnotes with FOOTMELT, not margins etc
946 if(owner->view()->text->cursor.par->footnotekind == LyXParagraph::FOOTNOTE)
953 case LFUN_MARGINMELT:
954 if (owner->view()->available()
955 && !owner->view()->text->selection
956 && owner->view()->text->cursor.par->footnoteflag
957 != LyXParagraph::NO_FOOTNOTE) {
959 if(owner->view()->text->cursor.par->footnotekind == LyXParagraph::MARGIN)
966 // --- version control -------------------------------
967 case LFUN_VC_REGISTER:
969 if (!owner->buffer()->lyxvc.inUse())
970 owner->buffer()->lyxvc.registrer();
974 case LFUN_VC_CHECKIN:
976 if (owner->buffer()->lyxvc.inUse()
977 && !owner->buffer()->isReadonly())
978 owner->buffer()->lyxvc.checkIn();
982 case LFUN_VC_CHECKOUT:
984 if (owner->buffer()->lyxvc.inUse()
985 && owner->buffer()->isReadonly())
986 owner->buffer()->lyxvc.checkOut();
992 owner->buffer()->lyxvc.revert();
998 owner->buffer()->lyxvc.undoLast();
1002 case LFUN_VC_HISTORY:
1004 owner->buffer()->lyxvc.showLog();
1008 // --- buffers ----------------------------------------
1009 case LFUN_PREVBUFFER:
1010 #ifdef WITH_WARNINGS
1011 #warning fix this please
1013 // it is the LyXView or the BufferView that should
1014 // remember the previous buffer, not bufferlist.
1015 // if (owner->view()->available()){
1016 // owner->view()->beforeChange();
1017 // owner->buffer()->update(-2);
1019 // owner->view()->setBuffer(bufferlist.prev());
1022 // resizeCurrentBufferPseudoExpose();
1025 case LFUN_FILE_INSERT:
1027 MenuInsertLyXFile(argument);
1031 case LFUN_FILE_INSERT_ASCII:
1033 bool asPara = (argument == "paragraph");
1034 InsertAsciiFile(string(), asPara);
1040 // servercmd: argument must be <file>:<template>
1041 Buffer * tmpbuf = NewLyxFile(argument);
1043 owner->view()->buffer(tmpbuf);
1047 case LFUN_FILE_OPEN:
1048 owner->view()->buffer(bufferlist.loadLyXFile(argument));
1051 case LFUN_LATEX_LOG:
1057 lyxerr.debug() << "LFUN_LAYOUTNO: (arg) " << argument << endl;
1058 int sel = strToInt(argument);
1059 lyxerr.debug() << "LFUN_LAYOUTNO: (sel) "<< sel << endl;
1061 // Should this give a setMessage instead?
1063 return string(); // illegal argument
1065 sel--; // sel 1..., but layout 0...
1067 // Pretend we got the name instead.
1068 Dispatch(int(LFUN_LAYOUT),
1069 textclasslist.NameOfLayout(owner->view()->
1078 lyxerr.debug() << "LFUN_LAYOUT: (arg) "
1079 << argument << endl;
1081 // Derive layout number from given argument (string)
1082 // and current buffer's textclass (number). */
1084 textclasslist.NumberOfLayout(owner->
1090 // see if we found the layout number:
1091 if (layoutno == -1) {
1092 setErrorMessage(string(N_("Layout ")) + argument +
1097 if (current_layout != layoutno) {
1098 owner->view()->getScreen()->HideCursor();
1099 current_layout = layoutno;
1100 owner->view()->update(-2);
1101 owner->view()->text->
1102 SetLayout(layoutno);
1103 owner->getToolbar()->combox->
1104 select(owner->view()->
1107 owner->view()->update(1);
1112 case LFUN_LAYOUT_DOCUMENT:
1113 MenuLayoutDocument();
1116 case LFUN_LAYOUT_PARAGRAPH:
1117 MenuLayoutParagraph();
1120 case LFUN_LAYOUT_CHARACTER:
1121 MenuLayoutCharacter();
1124 case LFUN_LAYOUT_TABLE:
1127 if (argument == "true") flag = 1;
1128 MenuLayoutTable(flag);
1132 case LFUN_LAYOUT_PAPER:
1136 case LFUN_LAYOUT_QUOTES:
1140 case LFUN_LAYOUT_PREAMBLE:
1141 MenuLayoutPreamble();
1144 case LFUN_LAYOUT_SAVE_DEFAULT:
1148 case LFUN_DROP_LAYOUTS_CHOICE:
1149 owner->getToolbar()->combox->Show();
1180 case LFUN_UNDERLINE:
1184 case LFUN_FONT_SIZE:
1185 FontSizeCB(argument);
1188 case LFUN_FONT_STATE:
1189 setMessage(CurrentState());
1192 case LFUN_UPCASE_WORD:
1193 owner->view()->update(-2);
1195 owner->view()->text->ChangeWordCase(LyXText::text_uppercase);
1196 owner->view()->update(1);
1200 case LFUN_LOWCASE_WORD:
1201 owner->view()->update(-2);
1203 owner->view()->text->ChangeWordCase(LyXText::text_lowercase);
1204 owner->view()->update(1);
1208 case LFUN_CAPITALIZE_WORD:
1209 owner->view()->update(-2);
1211 owner->view()->text->ChangeWordCase(LyXText::text_capitalization);
1212 owner->view()->update(1);
1216 case LFUN_INSERT_LABEL:
1217 MenuInsertLabel(argument.c_str());
1220 case LFUN_INSERT_REF:
1224 case LFUN_REFTOGGLE:
1227 static_cast<InsetRef*>(getInsetByCode(Inset::REF_CODE));
1229 if (inset->getFlag() == InsetRef::REF)
1230 inset->setFlag(InsetRef::PAGE_REF);
1232 inset->setFlag(InsetRef::REF);
1235 setErrorMessage(N_("No cross-reference to toggle"));
1242 owner->view()->restorePosition();
1248 string label(argument);
1249 if (label.empty()) {
1251 static_cast<InsetRef*>(getInsetByCode(Inset::REF_CODE));
1253 label = inset->getContents();
1256 if (!label.empty()) {
1257 owner->view()->savePosition();
1258 owner->buffer()->gotoLabel(label.c_str());
1263 case LFUN_MENU_OPEN_BY_NAME:
1264 owner->getMenus()->openByName(argument);
1265 break; // RVDK_PATCH_5
1267 case LFUN_SPELLCHECK:
1268 if (lyxrc->isp_command != "none")
1270 break; // RVDK_PATCH_5
1272 // --- Cursor Movements -----------------------------
1275 LyXText * tmptext = owner->view()->text;
1276 if(!tmptext->mark_set)
1277 owner->view()->beforeChange();
1278 owner->view()->update(-2);
1279 if (tmptext->cursor.pos < tmptext->cursor.par->Last()
1280 && tmptext->cursor.par->GetChar(tmptext->cursor.pos)
1281 == LyXParagraph::META_INSET
1282 && tmptext->cursor.par->GetInset(tmptext->cursor.pos)
1283 && tmptext->cursor.par->GetInset(tmptext->cursor.pos)->Editable() == 2){
1284 Inset * tmpinset = tmptext->cursor.par->GetInset(tmptext->cursor.pos);
1285 setMessage(tmpinset->EditMessage());
1286 tmpinset->Edit(0, 0);
1289 tmptext->CursorRight();
1290 owner->view()->text->FinishUndo();
1291 moveCursorUpdate(false);
1292 owner->getMiniBuffer()->Set(CurrentState());
1298 // This is soooo ugly. Isn`t it possible to make
1299 // it simpler? (Lgb)
1300 LyXText * txt = owner->view()->text;
1301 if(!txt->mark_set) owner->view()->beforeChange();
1302 owner->view()->update(-2);
1304 if (txt->cursor.pos < txt->cursor.par->Last()
1305 && txt->cursor.par->GetChar(txt->cursor.pos)
1306 == LyXParagraph::META_INSET
1307 && txt->cursor.par->GetInset(txt->cursor.pos)
1308 && txt->cursor.par->GetInset(txt->cursor.pos)->Editable() == 2) {
1309 Inset * tmpinset = txt->cursor.par->GetInset(txt->cursor.pos);
1310 setMessage(tmpinset->EditMessage());
1311 tmpinset->Edit(tmpinset->Width(txt->GetFont(txt->cursor.par,
1312 txt->cursor.pos)), 0);
1315 owner->view()->text->FinishUndo();
1316 moveCursorUpdate(false);
1317 owner->getMiniBuffer()->Set(CurrentState());
1322 if(!owner->view()->text->mark_set) owner->view()->beforeChange();
1323 owner->view()->update(-3);
1324 owner->view()->text->CursorUp();
1325 owner->view()->text->FinishUndo();
1326 moveCursorUpdate(false);
1327 owner->getMiniBuffer()->Set(CurrentState());
1331 if(!owner->view()->text->mark_set)
1332 owner->view()->beforeChange();
1333 owner->view()->update(-3);
1334 owner->view()->text->CursorDown();
1335 owner->view()->text->FinishUndo();
1336 moveCursorUpdate(false);
1337 owner->getMiniBuffer()->Set(CurrentState());
1340 case LFUN_UP_PARAGRAPH:
1341 if(!owner->view()->text->mark_set)
1342 owner->view()->beforeChange();
1343 owner->view()->update(-3);
1344 owner->view()->text->CursorUpParagraph();
1345 owner->view()->text->FinishUndo();
1346 moveCursorUpdate(false);
1347 owner->getMiniBuffer()->Set(CurrentState());
1350 case LFUN_DOWN_PARAGRAPH:
1351 if(!owner->view()->text->mark_set)
1352 owner->view()->beforeChange();
1353 owner->view()->update(-3);
1354 owner->view()->text->CursorDownParagraph();
1355 owner->view()->text->FinishUndo();
1356 moveCursorUpdate(false);
1357 owner->getMiniBuffer()->Set(CurrentState());
1361 if(!owner->view()->text->mark_set)
1362 owner->view()->beforeChange();
1363 owner->view()->update(-3);
1364 owner->view()->cursorPrevious();
1365 owner->view()->text->FinishUndo();
1366 moveCursorUpdate(false);
1367 owner->getMiniBuffer()->Set(CurrentState());
1371 if(!owner->view()->text->mark_set)
1372 owner->view()->beforeChange();
1373 owner->view()->update(-3);
1374 owner->view()->cursorNext();
1375 owner->view()->text->FinishUndo();
1376 moveCursorUpdate(false);
1377 owner->getMiniBuffer()->Set(CurrentState());
1381 if(!owner->view()->text->mark_set)
1382 owner->view()->beforeChange();
1383 owner->view()->update(-2);
1384 owner->view()->text->CursorHome();
1385 owner->view()->text->FinishUndo();
1386 moveCursorUpdate(false);
1387 owner->getMiniBuffer()->Set(CurrentState());
1391 if(!owner->view()->text->mark_set)
1392 owner->view()->beforeChange();
1393 owner->view()->update(-2);
1394 owner->view()->text->CursorEnd();
1395 owner->view()->text->FinishUndo();
1396 moveCursorUpdate(false);
1397 owner->getMiniBuffer()->Set(CurrentState());
1401 if(!owner->view()->text->mark_set)
1402 owner->view()->beforeChange();
1403 owner->view()->update(-2);
1404 owner->view()->text->CursorTab();
1405 owner->view()->text->FinishUndo();
1406 moveCursorUpdate(false);
1407 owner->getMiniBuffer()->Set(CurrentState());
1410 case LFUN_WORDRIGHT:
1411 if(!owner->view()->text->mark_set)
1412 owner->view()->beforeChange();
1413 owner->view()->update(-2);
1414 owner->view()->text->CursorRightOneWord();
1415 owner->view()->text->FinishUndo();
1416 moveCursorUpdate(false);
1417 owner->getMiniBuffer()->Set(CurrentState());
1421 if(!owner->view()->text->mark_set)
1422 owner->view()->beforeChange();
1423 owner->view()->update(-2);
1424 owner->view()->text->CursorLeftOneWord();
1425 owner->view()->text->FinishUndo();
1426 moveCursorUpdate(false);
1427 owner->getMiniBuffer()->Set(CurrentState());
1430 case LFUN_BEGINNINGBUF:
1431 if(!owner->view()->text->mark_set)
1432 owner->view()->beforeChange();
1433 owner->view()->update(-2);
1434 owner->view()->text->CursorTop();
1435 owner->view()->text->FinishUndo();
1436 moveCursorUpdate(false);
1437 owner->getMiniBuffer()->Set(CurrentState());
1441 if(!owner->view()->text->mark_set)
1442 owner->view()->beforeChange();
1443 owner->view()->update(-2);
1444 owner->view()->text->CursorBottom();
1445 owner->view()->text->FinishUndo();
1446 moveCursorUpdate(false);
1447 owner->getMiniBuffer()->Set(CurrentState());
1451 /* cursor selection ---------------------------- */
1453 owner->view()->update(-2);
1454 owner->view()->text->CursorRight();
1455 owner->view()->text->FinishUndo();
1456 moveCursorUpdate(true);
1457 owner->getMiniBuffer()->Set(CurrentState());
1461 owner->view()->update(-2);
1462 owner->view()->text->CursorLeft();
1463 owner->view()->text->FinishUndo();
1464 moveCursorUpdate(true);
1465 owner->getMiniBuffer()->Set(CurrentState());
1469 owner->view()->update(-2);
1470 owner->view()->text->CursorUp();
1471 owner->view()->text->FinishUndo();
1472 moveCursorUpdate(true);
1473 owner->getMiniBuffer()->Set(CurrentState());
1477 owner->view()->update(-2);
1478 owner->view()->text->CursorDown();
1479 owner->view()->text->FinishUndo();
1480 moveCursorUpdate(true);
1481 owner->getMiniBuffer()->Set(CurrentState());
1484 case LFUN_UP_PARAGRAPHSEL:
1485 owner->view()->update(-2);
1486 owner->view()->text->CursorUpParagraph();
1487 owner->view()->text->FinishUndo();
1488 moveCursorUpdate(true);
1489 owner->getMiniBuffer()->Set(CurrentState());
1492 case LFUN_DOWN_PARAGRAPHSEL:
1493 owner->view()->update(-2);
1494 owner->view()->text->CursorDownParagraph();
1495 owner->view()->text->FinishUndo();
1496 moveCursorUpdate(true);
1497 owner->getMiniBuffer()->Set(CurrentState());
1501 owner->view()->update(-2);
1502 owner->view()->cursorPrevious();
1503 owner->view()->text->FinishUndo();
1504 moveCursorUpdate(true);
1505 owner->getMiniBuffer()->Set(CurrentState());
1509 owner->view()->update(-2);
1510 owner->view()->cursorNext();
1511 owner->view()->text->FinishUndo();
1512 moveCursorUpdate(true);
1513 owner->getMiniBuffer()->Set(CurrentState());
1517 owner->view()->update(-2);
1518 owner->view()->text->CursorHome();
1519 owner->view()->text->FinishUndo();
1520 moveCursorUpdate(true);
1521 owner->getMiniBuffer()->Set(CurrentState());
1525 owner->view()->update(-2);
1526 owner->view()->text->CursorEnd();
1527 owner->view()->text->FinishUndo();
1528 moveCursorUpdate(true);
1529 owner->getMiniBuffer()->Set(CurrentState());
1532 case LFUN_WORDRIGHTSEL:
1533 owner->view()->update(-2);
1534 owner->view()->text->CursorRightOneWord();
1535 owner->view()->text->FinishUndo();
1536 moveCursorUpdate(true);
1537 owner->getMiniBuffer()->Set(CurrentState());
1540 case LFUN_WORDLEFTSEL:
1541 owner->view()->update(-2);
1542 owner->view()->text->CursorLeftOneWord();
1543 owner->view()->text->FinishUndo();
1544 moveCursorUpdate(true);
1545 owner->getMiniBuffer()->Set(CurrentState());
1548 case LFUN_BEGINNINGBUFSEL:
1549 owner->view()->update(-2);
1550 owner->view()->text->CursorTop();
1551 owner->view()->text->FinishUndo();
1552 moveCursorUpdate(true);
1553 owner->getMiniBuffer()->Set(CurrentState());
1556 case LFUN_ENDBUFSEL:
1557 owner->view()->update(-2);
1558 owner->view()->text->CursorBottom();
1559 owner->view()->text->FinishUndo();
1560 moveCursorUpdate(true);
1561 owner->getMiniBuffer()->Set(CurrentState());
1564 // --- text changing commands ------------------------
1565 case LFUN_BREAKLINE:
1566 owner->view()->beforeChange();
1567 owner->view()->text->InsertChar(LyXParagraph::META_NEWLINE);
1568 owner->view()->smallUpdate(1);
1569 SetUpdateTimer(0.01);
1570 moveCursorUpdate(false);
1573 case LFUN_PROTECTEDSPACE:
1574 owner->view()->beforeChange();
1575 owner->view()->text->
1576 InsertChar(LyXParagraph::META_PROTECTED_SEPARATOR);
1577 owner->view()->smallUpdate(1);
1579 moveCursorUpdate(false);
1583 if(owner->view()->text->mark_set) {
1584 owner->view()->beforeChange();
1585 owner->view()->update(0);
1586 setMessage(N_("Mark removed"));
1588 owner->view()->beforeChange();
1589 owner->view()->text->mark_set = 1;
1590 owner->view()->update(0);
1591 setMessage(N_("Mark set"));
1593 owner->view()->text->sel_cursor =
1594 owner->view()->text->cursor;
1599 if (!owner->view()->text->selection) {
1600 owner->view()->text->Delete();
1601 owner->view()->text->sel_cursor =
1602 owner->view()->text->cursor;
1603 owner->view()->smallUpdate(1);
1604 // It is possible to make it a lot faster still
1605 // just comment out the lone below...
1606 owner->view()->getScreen()->ShowCursor();
1613 case LFUN_DELETE_SKIP:
1615 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
1617 LyXCursor cursor = owner->view()->text->cursor;
1620 if (!owner->view()->text->selection) {
1621 if (cursor.pos == cursor.par->Last()) {
1622 owner->view()->text->CursorRight();
1623 cursor = owner->view()->text->cursor;
1625 && !(cursor.par->added_space_top
1626 == VSpace (VSpace::NONE))) {
1627 owner->view()->text->SetParagraph
1628 (cursor.par->line_top,
1629 cursor.par->line_bottom,
1630 cursor.par->pagebreak_top,
1631 cursor.par->pagebreak_bottom,
1632 VSpace(VSpace::NONE),
1633 cursor.par->added_space_bottom,
1635 cursor.par->labelwidthstring, 0);
1636 owner->view()->text->CursorLeft();
1637 owner->view()->update (1);
1639 owner->view()->text->CursorLeft();
1640 owner->view()->text->Delete();
1641 owner->view()->text->sel_cursor =
1642 owner->view()->text->cursor;
1643 owner->view()->smallUpdate(1);
1646 owner->view()->text->Delete();
1647 owner->view()->text->sel_cursor =
1648 owner->view()->text->cursor;
1649 owner->view()->smallUpdate(1);
1658 /* -------> Delete word forward. */
1659 case LFUN_DELETE_WORD_FORWARD:
1660 owner->view()->update(-2);
1662 owner->view()->text->DeleteWordForward();
1663 owner->view()->update( 1 );
1665 moveCursorUpdate(false);
1668 /* -------> Delete word backward. */
1669 case LFUN_DELETE_WORD_BACKWARD:
1670 owner->view()->update(-2);
1672 owner->view()->text->DeleteWordBackward();
1673 owner->view()->update( 1 );
1675 moveCursorUpdate(false);
1678 /* -------> Kill to end of line. */
1679 case LFUN_DELETE_LINE_FORWARD:
1681 owner->view()->update(-2);
1682 owner->view()->text->DeleteLineForward();
1683 owner->view()->update( 1 );
1685 moveCursorUpdate(false);
1688 /* -------> Set mark off. */
1690 owner->view()->beforeChange();
1691 owner->view()->update(0);
1692 owner->view()->text->sel_cursor =
1693 owner->view()->text->cursor;
1694 setMessage(N_("Mark off"));
1697 /* -------> Set mark on. */
1699 owner->view()->beforeChange();
1700 owner->view()->text->mark_set = 1;
1701 owner->view()->update( 0 );
1702 owner->view()->text->sel_cursor =
1703 owner->view()->text->cursor;
1704 setMessage(N_("Mark on"));
1707 case LFUN_BACKSPACE:
1710 if (!owner->view()->text->selection) {
1711 if (owner->getIntl()->getTrans()->backspace()) {
1712 owner->view()->text->Backspace();
1713 owner->view()->text->sel_cursor =
1714 owner->view()->text->cursor;
1715 owner->view()->smallUpdate(1);
1716 // It is possible to make it a lot faster still
1717 // just comment out the lone below...
1718 owner->view()->getScreen()->ShowCursor();
1727 case LFUN_BACKSPACE_SKIP:
1729 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
1731 LyXCursor cursor = owner->view()->text->cursor;
1734 if (!owner->view()->text->selection) {
1736 && !(cursor.par->added_space_top
1737 == VSpace (VSpace::NONE))) {
1738 owner->view()->text->SetParagraph
1739 (cursor.par->line_top,
1740 cursor.par->line_bottom,
1741 cursor.par->pagebreak_top,
1742 cursor.par->pagebreak_bottom,
1743 VSpace(VSpace::NONE), cursor.par->added_space_bottom,
1745 cursor.par->labelwidthstring, 0);
1746 owner->view()->update (1);
1748 owner->view()->text->Backspace();
1749 owner->view()->text->sel_cursor
1751 owner->view()->smallUpdate (1);
1759 case LFUN_BREAKPARAGRAPH:
1761 owner->view()->beforeChange();
1762 owner->view()->text->BreakParagraph(0);
1763 owner->view()->smallUpdate(1);
1764 SetUpdateTimer(0.01);
1765 owner->view()->text->sel_cursor =
1766 owner->view()->text->cursor;
1770 case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
1772 owner->view()->beforeChange();
1773 owner->view()->text->BreakParagraph(1);
1774 owner->view()->smallUpdate(1);
1775 SetUpdateTimer(0.01);
1776 owner->view()->text->sel_cursor =
1777 owner->view()->text->cursor;
1781 case LFUN_BREAKPARAGRAPH_SKIP:
1783 // When at the beginning of a paragraph, remove
1784 // indentation and add a "defskip" at the top.
1785 // Otherwise, do the same as LFUN_BREAKPARAGRAPH.
1787 LyXCursor cursor = owner->view()->text->cursor;
1789 owner->view()->beforeChange();
1790 if (cursor.pos == 0) {
1791 if (cursor.par->added_space_top == VSpace(VSpace::NONE)) {
1792 owner->view()->text->SetParagraph
1793 (cursor.par->line_top,
1794 cursor.par->line_bottom,
1795 cursor.par->pagebreak_top,
1796 cursor.par->pagebreak_bottom,
1797 VSpace(VSpace::DEFSKIP), cursor.par->added_space_bottom,
1799 cursor.par->labelwidthstring, 1);
1800 owner->view()->update(1);
1804 owner->view()->text->BreakParagraph(0);
1805 owner->view()->smallUpdate(1);
1807 SetUpdateTimer(0.01);
1808 owner->view()->text->sel_cursor = cursor;
1813 owner->view()->beforeChange();
1814 owner->view()->text->InsertChar('\"'); // This " matches the single quote in the code
1815 owner->view()->smallUpdate(1);
1817 moveCursorUpdate(false);
1823 InsetCommand * new_inset;
1824 if (action == LFUN_HTMLURL)
1825 new_inset = new InsetUrl("htmlurl", "", "");
1827 new_inset = new InsetUrl("url", "", "");
1828 owner->buffer()->insertInset(new_inset);
1829 new_inset->Edit(0, 0);
1833 // --- lyxserver commands ----------------------------
1835 case LFUN_CHARATCURSOR:
1837 LyXParagraph::size_type pos =
1838 owner->view()->text->cursor.pos;
1839 if(pos < owner->view()->text->cursor.par->size())
1840 dispatch_buffer = owner->view()->text->
1841 cursor.par->text[pos];
1843 dispatch_buffer = "EOF";
1849 tostr(owner->view()->text->cursor.x) + ' '
1850 + tostr(owner->view()->text->cursor.y);
1857 sscanf(argument.c_str(), " %d %ld", &x, &y);
1858 owner->view()->text->SetCursorFromCoordinates(x, y);
1862 case LFUN_GETLAYOUT:
1864 tostr(owner->view()->text->cursor.par->layout);
1869 LyXFont * font = &(owner->view()->text->current_font);
1870 if(font->shape() == LyXFont::ITALIC_SHAPE)
1871 dispatch_buffer = 'E';
1872 else if(font->shape() == LyXFont::SMALLCAPS_SHAPE)
1873 dispatch_buffer = 'N';
1875 dispatch_buffer = '0';
1882 LyXFont * font = &(owner->view()->text->current_font);
1883 if(font->latex() == LyXFont::ON)
1884 dispatch_buffer = 'L';
1886 dispatch_buffer = '0';
1891 setMessage(owner->buffer()->fileName());
1892 lyxerr.debug() << "FNAME["
1893 << owner->buffer()->fileName()
1901 dispatch_buffer = buf;
1902 lyxserver->notifyClient(dispatch_buffer);
1906 case LFUN_GOTOFILEROW:
1908 char file_name[100];
1910 sscanf(argument.c_str(), " %s %d", file_name, &row);
1912 // Must replace extension of the file to be .lyx and get full path
1913 string s = ChangeExtension(string(file_name), ".lyx", false);
1915 // Either change buffer or load the file
1916 if (bufferlist.exists(s))
1917 owner->view()->buffer(bufferlist.getBuffer(s));
1919 owner->view()->buffer(bufferlist.loadLyXFile(s));
1922 owner->buffer()->setCursorFromRow(row);
1925 owner->view()->beforeChange();
1926 if (owner->view()->text->cursor.y >
1927 owner->view()->getWorkArea()->h / 2) {
1928 owner->view()->getScreen()->
1929 Draw(owner->view()->text->cursor.y -
1930 owner->view()->getWorkArea()->h/2);
1932 owner->view()->getScreen()->
1935 owner->view()->update(0);
1936 owner->view()->redraw();
1943 int qa = lyxaction.LookupFunc(argument.c_str());
1944 setMessage(lyxaction.helpText(static_cast<kb_action>(qa)));
1948 // --- accented characters ---------------------------
1951 case LFUN_CIRCUMFLEX:
1961 case LFUN_SPECIAL_CARON:
1964 case LFUN_HUNG_UMLAUT:
1970 if (keyseq.length == -1 && keyseq.getiso() != 0)
1971 c = keyseq.getiso();
1975 owner->getIntl()->getTrans()->
1976 deadkey(c, get_accent(action).accent,
1977 owner->view()->text);
1979 // Need to reset, in case the minibuffer calls these
1984 // copied verbatim from do_accent_char
1985 owner->view()->smallUpdate(1);
1987 owner->view()->text->sel_cursor =
1988 owner->view()->text->cursor;
1992 // --- toolbar ----------------------------------
1993 case LFUN_PUSH_TOOLBAR:
1995 int nth = strToInt(argument);
1996 if (lyxerr.debugging(Debug::TOOLBAR)) {
1997 lyxerr << "LFUN_PUSH_TOOLBAR: argument = `"
1998 << argument << "'\n"
1999 << "LFUN_PUSH_TOOLBAR: nth = `"
2000 << nth << "'" << endl;
2005 setErrorMessage(N_("Push-toolbar needs argument > 0"));
2007 owner->getToolbar()->push(nth);
2012 case LFUN_ADD_TO_TOOLBAR:
2014 if (lyxerr.debugging(Debug::TOOLBAR)) {
2015 lyxerr << "LFUN_ADD_TO_TOOLBAR:"
2016 "argument = `" << argument << '\'' << endl;
2018 string tmp(argument);
2019 //lyxerr <<string("Argument: ") + argument);
2020 //lyxerr <<string("Tmp : ") + tmp);
2023 setErrorMessage(N_("Usage: toolbar-add-to <LyX command>"));
2025 owner->getToolbar()->add(argument, false);
2026 owner->getToolbar()->set();
2031 // --- insert characters ----------------------------------------
2033 case LFUN_INSERT_INSET_LATEX:
2035 Inset * new_inset = new InsetLatex(argument);
2036 owner->buffer()->insertInset(new_inset);
2040 // --- Mathed stuff. If we are here, there is no locked inset yet.
2045 if (!greek_kb_flag) {
2047 setMessage(N_("Math greek mode on"));
2054 case LFUN_GREEK_TOGGLE:
2056 greek_kb_flag = greek_kb_flag ? 0 : 2;
2057 if (greek_kb_flag) {
2058 setMessage(N_("Math greek keyboard on"));
2060 setMessage(N_("Math greek keyboard off"));
2065 case LFUN_MATH_DELIM:
2066 case LFUN_INSERT_MATRIX:
2068 if (owner->view()->available()) {
2070 open_new_inset(new InsetFormula(false));
2072 the_locking_inset->LocalDispatch(action, argument.c_str());
2077 case LFUN_INSERT_MATH:
2079 math_insert_symbol(argument.c_str());
2083 case LFUN_MATH_DISPLAY:
2085 if (owner->view()->available())
2086 owner->buffer()->open_new_inset(new InsetFormula(true));
2090 case LFUN_MATH_MACRO:
2092 if (owner->view()->available()) {
2095 setErrorMessage(N_("Missing argument"));
2097 string s1 = token(s, ' ', 1);
2098 int na = s1.empty() ? 0: atoi(s1.c_str());
2100 open_new_inset(new InsetFormulaMacro(token(s, ' ', 0), na));
2106 case LFUN_MATH_MODE: // Open or create a math inset
2109 if (owner->view()->available())
2110 owner->buffer()->open_new_inset(new InsetFormula);
2111 setMessage(N_("Math editor mode"));
2115 case LFUN_MATH_NUMBER:
2116 case LFUN_MATH_LIMITS:
2118 setErrorMessage(N_("This is only allowed in math mode!"));
2122 case LFUN_INSERT_CITATION:
2124 InsetCitation * new_inset = new InsetCitation();
2126 // The note, if any, must be after the key, delimited
2127 // by a | so both key and remark can have spaces.
2128 if (!argument.empty()) {
2129 string lsarg(argument);
2130 if (contains(lsarg, "|")) {
2131 new_inset->setContents(token(lsarg, '|', 0));
2132 new_inset->setOptions(token(lsarg, '|', 1));
2134 new_inset->setContents(lsarg);
2135 owner->buffer()->insertInset(new_inset);
2137 owner->buffer()->insertInset(new_inset);
2138 new_inset->Edit(0, 0);
2143 case LFUN_INSERT_BIBTEX:
2145 // ale970405+lasgoutt970425
2146 // The argument can be up to two tokens separated
2147 // by a space. The first one is the bibstyle.
2148 string lsarg(argument);
2149 string bibstyle = token(lsarg, ' ', 1);
2150 if (bibstyle.empty())
2152 InsetBibtex * new_inset
2153 = new InsetBibtex(token(lsarg, ' ', 0),
2157 owner->buffer()->insertInset(new_inset);
2158 if (lsarg.empty()) {
2159 new_inset->Edit(0, 0);
2164 // BibTeX data bases
2165 case LFUN_BIBDB_ADD:
2167 InsetBibtex * inset =
2168 static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2170 inset->addDatabase(argument);
2175 case LFUN_BIBDB_DEL:
2177 InsetBibtex * inset =
2178 static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2180 inset->delDatabase(argument);
2185 case LFUN_BIBTEX_STYLE:
2187 InsetBibtex * inset =
2188 static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2190 inset->setOptions(argument);
2195 case LFUN_INDEX_INSERT:
2196 case LFUN_INDEX_INSERT_LAST:
2198 // Can't do that at the beginning of a paragraph.
2199 if (owner->view()->text->cursor.pos - 1 < 0)
2202 InsetIndex * new_inset = new InsetIndex();
2203 if (!argument.empty()) {
2204 string lsarg(argument);
2205 new_inset->setContents(lsarg);
2206 owner->buffer()->insertInset(new_inset);
2209 //get the current word for an argument
2210 LyXParagraph::size_type lastpos =
2211 owner->view()->text->cursor.pos - 1;
2212 // Get the current word. note that this must be done
2213 // before inserting the inset, or the inset will
2215 string curstring(owner->view()
2216 ->text->cursor.par->GetWord(lastpos));
2218 //make the new inset and write the current word into it
2219 InsetIndex * new_inset = new InsetIndex();
2221 new_inset->setContents(curstring);
2223 //don't edit it if the call was to INSERT_LAST
2224 if(action != LFUN_INDEX_INSERT_LAST) {
2225 new_inset->Edit(0, 0);
2227 //it looks blank on the screen unless
2228 //we do something. put it here.
2230 // move the cursor to the returned value of lastpos
2231 // but only for the auto-insert
2232 owner->view()->text->cursor.pos = lastpos;
2235 //put the new inset into the buffer.
2236 // there should be some way of knowing the user
2237 //cancelled & avoiding this, but i don't know how
2238 owner->buffer()->insertInset(new_inset);
2243 case LFUN_INDEX_PRINT:
2245 Inset * new_inset = new InsetPrintIndex(owner->buffer());
2246 owner->buffer()->insertInset(new_inset, "Standard", true);
2250 case LFUN_PARENTINSERT:
2252 lyxerr << "arg " << argument << endl;
2253 Inset * new_inset = new InsetParent(argument, owner->buffer());
2254 owner->buffer()->insertInset(new_inset, "Standard", true);
2258 case LFUN_CHILDINSERT:
2260 Inset * new_inset = new InsetInclude(argument,
2262 owner->buffer()->insertInset(new_inset, "Standard", true);
2263 new_inset->Edit(0, 0);
2267 case LFUN_CHILDOPEN:
2270 MakeAbsPath(argument,
2271 OnlyPath(owner->buffer()->fileName()));
2272 setMessage(N_("Opening child document ") +
2273 MakeDisplayPath(filename) + "...");
2274 owner->view()->savePosition();
2275 if (bufferlist.exists(filename))
2276 owner->view()->buffer(bufferlist.getBuffer(filename));
2278 owner->view()->buffer(bufferlist.loadLyXFile(filename));
2282 case LFUN_INSERT_NOTE:
2286 case LFUN_INSERTFOOTNOTE:
2288 LyXParagraph::footnote_kind kind;
2289 if (argument == "footnote")
2290 { kind = LyXParagraph::FOOTNOTE; }
2291 else if (argument == "margin")
2292 { kind = LyXParagraph::MARGIN; }
2293 else if (argument == "figure")
2294 { kind = LyXParagraph::FIG; }
2295 else if (argument == "table")
2296 { kind = LyXParagraph::TAB; }
2297 else if (argument == "wide-fig")
2298 { kind = LyXParagraph::WIDE_FIG; }
2299 else if (argument == "wide-tab")
2300 { kind = LyXParagraph::WIDE_TAB; }
2301 else if (argument == "algorithm")
2302 { kind = LyXParagraph::ALGORITHM; }
2304 setErrorMessage(N_("Unknown kind of footnote"));
2307 owner->view()->text->InsertFootnoteEnvironment(kind);
2308 owner->view()->update(1);
2312 case LFUN_BUFFERBULLETSSELECT:
2316 case LFUN_TOGGLECURSORFOLLOW:
2317 cursor_follows_scrollbar = !cursor_follows_scrollbar;
2320 case LFUN_KMAP_OFF: // keymap off
2321 owner->getIntl()->KeyMapOn(false);
2324 case LFUN_KMAP_PRIM: // primary keymap
2325 owner->getIntl()->KeyMapPrim();
2328 case LFUN_KMAP_SEC: // secondary keymap
2329 owner->getIntl()->KeyMapSec();
2332 case LFUN_KMAP_TOGGLE: // toggle keymap
2333 owner->getIntl()->ToggleKeyMap();
2336 case LFUN_SELFINSERT:
2338 for (string::size_type i = 0; i < argument.length(); ++i) {
2339 owner->view()->text->InsertChar(argument[i]);
2340 // This needs to be in the loop, or else we
2341 // won't break lines correctly. (Asger)
2342 owner->view()->smallUpdate(1);
2345 owner->view()->text->sel_cursor =
2346 owner->view()->text->cursor;
2347 moveCursorUpdate(false);
2353 // argument contains ';'-terminated commands
2354 while (argument.find(';') != string::npos) {
2356 argument = split(argument, first, ';');
2362 case LFUN_SAVEPREFERENCES:
2364 Path p(user_lyxdir);
2365 lyxrc->write("preferences");
2369 case LFUN_UNKNOWN_ACTION:
2371 if(!owner->buffer()) {
2373 setErrorMessage(N_("No document open"));
2377 if (owner->buffer()->isReadonly()) {
2379 setErrorMessage(N_("Document is read only"));
2383 if (!argument.empty()) {
2385 /* Automatically delete the currently selected
2386 * text and replace it with what is being
2387 * typed in now. Depends on lyxrc settings
2388 * "auto_region_delete", which defaults to
2391 if ( lyxrc->auto_region_delete ) {
2392 if (owner->view()->text->selection){
2393 owner->view()->text->CutSelection(false);
2394 owner->view()->update(-1);
2398 owner->view()->beforeChange();
2399 for (string::size_type i = 0;
2400 i < argument.length(); ++i) {
2401 if (greek_kb_flag) {
2402 if (!math_insert_greek(argument[i]))
2403 owner->getIntl()->getTrans()->TranslateAndInsert(argument[i], owner->view()->text);
2405 owner->getIntl()->getTrans()->TranslateAndInsert(argument[i], owner->view()->text);
2408 owner->view()->smallUpdate(1);
2411 owner->view()->text->sel_cursor =
2412 owner->view()->text->cursor;
2413 moveCursorUpdate(false);
2416 // why is an "Unknown action" with empty
2417 // argument even dispatched in the first
2418 // place? I`ll probably change that. (Lgb)
2420 setErrorMessage(N_("Unknown action"));
2424 lyxerr << "A truly unknown func!" << endl;
2430 string res = getMessage();
2433 if (!commandshortcut.empty()) {
2434 string newbuf = owner->getMiniBuffer()->GetText();
2435 if (newbuf != commandshortcut) {
2436 owner->getMiniBuffer()->Set(newbuf
2442 owner->getMiniBuffer()->Set(string(_(res.c_str()))
2443 + " " + commandshortcut);
2450 void LyXFunc::setupLocalKeymap()
2452 keyseq.stdmap = keyseq.curmap = toplevel_keymap;
2453 cancel_meta_seq.stdmap = cancel_meta_seq.curmap = toplevel_keymap;
2457 void LyXFunc::MenuNew(bool fromTemplate)
2459 string fname, initpath = lyxrc->document_path;
2462 if (owner->view()->available()) {
2463 string trypath = owner->buffer()->filepath;
2464 // If directory is writeable, use this as default.
2465 if (IsDirWriteable(trypath) == 1)
2470 fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2471 fileDlg.SetButton(1, _("Templates"), lyxrc->template_path);
2472 fname = fileDlg.Select(_("Enter Filename for new document"),
2473 initpath, "*.lyx", _("newfile"));
2476 if (fname.empty()) {
2477 owner->getMiniBuffer()->Set(_("Canceled."));
2478 lyxerr.debug() << "New Document Cancelled." << endl;
2482 // get absolute path of file and make sure the filename ends
2484 string s = MakeAbsPath(fname);
2485 if (!IsLyXFilename(s))
2488 // Check if the document already is open
2489 if (bufferlist.exists(s)){
2490 switch(AskConfirmation(_("Document is already open:"),
2491 MakeDisplayPath(s, 50),
2492 _("Do you want to close that document now?\n"
2493 "('No' will just switch to the open version)")))
2495 case 1: // Yes: close the document
2496 if (!bufferlist.close(bufferlist.getBuffer(s)))
2497 // If close is canceled, we cancel here too.
2500 case 2: // No: switch to the open document
2501 owner->view()->buffer(bufferlist.getBuffer(s));
2503 case 3: // Cancel: Do nothing
2504 owner->getMiniBuffer()->Set(_("Canceled."));
2509 // Check whether the file already exists
2510 if (IsLyXFilename(s)) {
2512 if (fi.readable() &&
2513 AskQuestion(_("File already exists:"),
2514 MakeDisplayPath(s, 50),
2515 _("Do you want to open the document?"))) {
2517 owner->getMiniBuffer()->Set(_("Opening document"),
2518 MakeDisplayPath(s), "...");
2520 owner->view()->buffer(
2521 bufferlist.loadLyXFile(s));
2522 owner->getMiniBuffer()->Set(_("Document"),
2529 // The template stuff
2533 fname = fileDlg.Select(_("Choose template"),
2534 lyxrc->template_path,
2540 // find a free buffer
2541 lyxerr.debug() << "Find a free buffer." << endl;
2542 owner->view()->buffer(bufferlist.newFile(s, templname));
2546 void LyXFunc::MenuOpen()
2548 string initpath = lyxrc->document_path;
2551 if (owner->view()->available()) {
2552 string trypath = owner->buffer()->filepath;
2553 // If directory is writeable, use this as default.
2554 if (IsDirWriteable(trypath) == 1)
2560 fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2561 fileDlg.SetButton(1, _("Examples"),
2562 AddPath(system_lyxdir, "examples"));
2563 string filename = fileDlg.Select(_("Select Document to Open"),
2567 // check selected filename
2568 if (filename.empty()) {
2569 owner->getMiniBuffer()->Set(_("Canceled."));
2573 // get absolute path of file and make sure the filename ends
2575 filename = MakeAbsPath(filename);
2576 if (!IsLyXFilename(filename))
2580 owner->getMiniBuffer()->Set(_("Opening document"),
2581 MakeDisplayPath(filename), "...");
2582 Buffer * openbuf = bufferlist.loadLyXFile(filename);
2584 owner->view()->buffer(openbuf);
2585 owner->getMiniBuffer()->Set(_("Document"),
2586 MakeDisplayPath(filename),
2589 owner->getMiniBuffer()->Set(_("Could not open document"),
2590 MakeDisplayPath(filename));
2595 void LyXFunc::doImportASCII(bool linorpar)
2597 string initpath = lyxrc->document_path;
2600 if (owner->view()->available()) {
2601 string trypath = owner->buffer()->filepath;
2602 // If directory is writeable, use this as default.
2603 if (IsDirWriteable(trypath) == 1)
2609 fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2610 fileDlg.SetButton(1, _("Examples"),
2611 AddPath(system_lyxdir, "examples"));
2612 string filename = fileDlg.Select(_("Select ASCII file to Import"),
2616 // check selected filename
2617 if (filename.empty()) {
2618 owner->getMiniBuffer()->Set(_("Canceled."));
2622 // get absolute path of file
2623 filename = MakeAbsPath(filename);
2625 string s = ChangeExtension(filename, ".lyx", false);
2627 // Check if the document already is open
2628 if (bufferlist.exists(s)) {
2629 switch(AskConfirmation(_("Document is already open:"),
2630 MakeDisplayPath(s, 50),
2631 _("Do you want to close that document now?\n"
2632 "('No' will just switch to the open version)")))
2634 case 1: // Yes: close the document
2635 if (!bufferlist.close(bufferlist.getBuffer(s)))
2636 // If close is canceled, we cancel here too.
2639 case 2: // No: switch to the open document
2640 owner->view()->buffer(bufferlist.getBuffer(s));
2642 case 3: // Cancel: Do nothing
2643 owner->getMiniBuffer()->Set(_("Canceled."));
2648 // Check if a LyX document by the same root exists in filesystem
2649 FileInfo f(s, true);
2650 if (f.exist() && !AskQuestion(_("A document by the name"),
2652 _("already exists. Overwrite?"))) {
2653 owner->getMiniBuffer()->Set(_("Canceled."));
2657 owner->view()->buffer(bufferlist.newFile(s, string()));
2658 owner->getMiniBuffer()->Set(_("Importing ASCII file"),
2659 MakeDisplayPath(filename), "...");
2660 // Insert ASCII file
2661 InsertAsciiFile(filename, linorpar);
2662 owner->getMiniBuffer()->Set(_("ASCII file "),
2663 MakeDisplayPath(filename),
2668 void LyXFunc::doImportLaTeX(bool isnoweb)
2670 string initpath = lyxrc->document_path;
2673 if (owner->view()->available()) {
2674 string trypath = owner->buffer()->filepath;
2675 // If directory is writeable, use this as default.
2676 if (IsDirWriteable(trypath) == 1)
2682 fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2683 fileDlg.SetButton(1, _("Examples"),
2684 AddPath(system_lyxdir, "examples"));
2687 filename = fileDlg.Select(_("Select Noweb file to Import"),
2690 filename = fileDlg.Select(_("Select LaTeX file to Import"),
2696 // check selected filename
2697 if (filename.empty()) {
2698 owner->getMiniBuffer()->Set(_("Canceled."));
2702 // get absolute path of file
2703 filename = MakeAbsPath(filename);
2705 // Check if the document already is open
2706 string LyXfilename = ChangeExtension(filename, ".lyx", false);
2707 if (bufferlist.exists(LyXfilename)){
2708 switch(AskConfirmation(_("Document is already open:"),
2709 MakeDisplayPath(LyXfilename, 50),
2710 _("Do you want to close that document now?\n"
2711 "('No' will just switch to the open version)")))
2713 case 1: // Yes: close the document
2714 if (!bufferlist.close(bufferlist.getBuffer(LyXfilename)))
2715 // If close is canceled, we cancel here too.
2718 case 2: // No: switch to the open document
2719 owner->view()->buffer(
2720 bufferlist.getBuffer(LyXfilename));
2722 case 3: // Cancel: Do nothing
2723 owner->getMiniBuffer()->Set(_("Canceled."));
2728 // Check if a LyX document by the same root exists in filesystem
2729 FileInfo f(LyXfilename, true);
2730 if (f.exist() && !AskQuestion(_("A document by the name"),
2731 MakeDisplayPath(LyXfilename),
2732 _("already exists. Overwrite?"))) {
2733 owner->getMiniBuffer()->Set(_("Canceled."));
2740 owner->getMiniBuffer()->Set(_("Importing LaTeX file"),
2741 MakeDisplayPath(filename), "...");
2742 ImportLaTeX myImport(filename);
2743 openbuf = myImport.run();
2745 owner->getMiniBuffer()->Set(_("Importing Noweb file"),
2746 MakeDisplayPath(filename), "...");
2747 ImportNoweb myImport(filename);
2748 openbuf = myImport.run();
2751 owner->view()->buffer(openbuf);
2752 owner->getMiniBuffer()->Set(isnoweb ?
2753 _("Noweb file ") : _("LateX file "),
2754 MakeDisplayPath(filename),
2757 owner->getMiniBuffer()->Set(isnoweb ?
2758 _("Could not import Noweb file") :
2759 _("Could not import LaTeX file"),
2760 MakeDisplayPath(filename));
2765 void LyXFunc::MenuInsertLyXFile(string const & filen)
2767 string filename = filen;
2769 if (filename.empty()) {
2770 // Launch a file browser
2771 string initpath = lyxrc->document_path;
2774 if (owner->view()->available()) {
2775 string trypath = owner->buffer()->filepath;
2776 // If directory is writeable, use this as default.
2777 if (IsDirWriteable(trypath) == 1)
2783 fileDlg.SetButton(0, _("Documents"), lyxrc->document_path);
2784 fileDlg.SetButton(1, _("Examples"),
2785 AddPath(system_lyxdir, "examples"));
2786 filename = fileDlg.Select(_("Select Document to Insert"),
2790 // check selected filename
2791 if (filename.empty()) {
2792 owner->getMiniBuffer()->Set(_("Canceled."));
2797 // get absolute path of file and make sure the filename ends
2799 filename = MakeAbsPath(filename);
2800 if (!IsLyXFilename(filename))
2804 owner->getMiniBuffer()->Set(_("Inserting document"),
2805 MakeDisplayPath(filename), "...");
2806 bool res = owner->buffer()->insertLyXFile(filename);
2808 owner->getMiniBuffer()->Set(_("Document"),
2809 MakeDisplayPath(filename),
2812 owner->getMiniBuffer()->Set(_("Could not insert document"),
2813 MakeDisplayPath(filename));
2818 void LyXFunc::reloadBuffer()
2820 string fn = owner->buffer()->fileName();
2821 if (bufferlist.close(owner->buffer()))
2822 owner->view()->buffer(bufferlist.loadLyXFile(fn));
2826 void LyXFunc::CloseBuffer()
2828 if (bufferlist.close(owner->buffer()) && !quitting) {
2829 if (bufferlist.empty()) {
2830 // need this otherwise SEGV may occur while trying to
2831 // set variables that don't exist
2832 // since there's no current buffer
2833 CloseAllBufferRelatedPopups();
2836 owner->view()->buffer(bufferlist.first());
2842 Inset * LyXFunc::getInsetByCode(Inset::Code code)
2846 LyXCursor cursor = owner->view()->text->cursor;
2847 LyXParagraph::size_type pos = cursor.pos;
2848 LyXParagraph * par = cursor.par;
2850 while (par && !found) {
2851 while ((inset = par->ReturnNextInsetPointer(pos))){
2852 if (inset->LyxCode() == code) {
2860 return found ? inset : 0;
2864 // Each "owner" should have it's own message method. lyxview and
2865 // the minibuffer would use the minibuffer, but lyxserver would
2866 // send an ERROR signal to its client. Alejandro 970603
2867 // This func is bit problematic when it comes to NLS, to make the
2868 // lyx servers client be language indepenent we must not translate
2869 // strings sent to this func.
2870 void LyXFunc::setErrorMessage(string const & m) const
2872 dispatch_buffer = m;
2877 void LyXFunc::setMessage(string const & m)
2879 dispatch_buffer = m;