1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2000 The LyX Team.
9 * ====================================================== */
15 using std::istringstream;
28 #pragma implementation
31 #include "lyxlookup.h"
34 #include "bufferlist.h"
35 #include "ColorHandler.h"
36 #include "lyxserver.h"
41 #include "LyXAction.h"
42 #include "insets/inseturl.h"
43 #include "insets/insetlatexaccent.h"
44 #include "insets/insettoc.h"
45 #include "insets/insetlof.h"
46 #include "insets/insetloa.h"
47 #include "insets/insetlot.h"
48 #include "insets/insetref.h"
49 #include "insets/insetparent.h"
50 #include "insets/insetindex.h"
51 #include "insets/insetinclude.h"
52 #include "insets/insetbib.h"
53 #include "insets/insetcite.h"
54 #include "insets/insettext.h"
55 #include "insets/insetert.h"
56 #include "insets/insetexternal.h"
57 #include "insets/insetgraphics.h"
58 #include "insets/insetfoot.h"
59 #include "insets/insetmarginal.h"
60 #include "insets/insetminipage.h"
61 #include "insets/insetfloat.h"
62 #include "insets/insetlist.h"
63 #include "insets/insettabular.h"
64 #include "mathed/formulamacro.h"
66 #include "spellchecker.h" // RVDK_PATCH_5
67 #include "minibuffer.h"
71 #include "lyx_gui_misc.h"
72 #include "support/filetools.h"
73 #include "support/FileInfo.h"
74 #include "support/syscall.h"
75 #include "support/lstrings.h"
76 #include "support/path.h"
81 #include "trans_mgr.h"
82 #include "ImportLaTeX.h"
83 #include "ImportNoweb.h"
88 #include "bufferview_funcs.h"
89 #include "frontends/Dialogs.h"
94 extern bool cursor_follows_scrollbar;
96 extern void InsertAsciiFile(BufferView *, string const &, bool);
97 extern void math_insert_symbol(char const *);
98 extern Bool math_insert_greek(char const); // why "Bool"?
99 extern BufferList bufferlist;
100 extern LyXServer * lyxserver;
101 extern short greek_kb_flag;
102 extern FD_form_toc * fd_form_toc;
103 extern bool selection_possible;
105 extern kb_keymap * toplevel_keymap;
107 extern void MenuWrite(Buffer *);
108 extern void MenuWriteAs(Buffer *);
109 extern int MenuRunLaTeX(Buffer *);
110 extern int MenuBuildProg(Buffer *);
111 extern int MenuRunChktex(Buffer *);
112 extern bool CreatePostscript(Buffer *, bool);
113 extern void MenuPrint(Buffer *);
114 extern void MenuSendto();
115 extern void QuitLyX();
116 extern void MenuFax(Buffer *);
117 extern void MenuExport(Buffer *, string const &);
119 extern LyXAction lyxaction;
121 extern tex_accent_struct get_accent(kb_action action);
123 extern void AutoSave(BufferView *);
124 extern bool PreviewDVI(Buffer *);
125 extern bool PreviewPostscript(Buffer *);
126 extern void MenuInsertLabel(char const *);
127 extern void MenuInsertRef();
128 extern void MenuLayoutCharacter();
129 extern void MenuLayoutParagraph();
130 extern void MenuLayoutDocument();
131 extern void MenuLayoutPaper();
132 extern void MenuLayoutTable(int flag);
133 extern void MenuLayoutQuotes();
134 extern void MenuLayoutPreamble();
135 extern void MenuLayoutSave();
136 extern void bulletForm();
138 extern Buffer * NewLyxFile(string const &);
139 extern void LoadLyXFile(string const &);
140 extern void Reconfigure(BufferView *);
142 extern LyXTextClass::size_type current_layout;
143 extern int getISOCodeFromLaTeX(char *);
145 extern void ShowLatexLog();
147 /* === globals =========================================================== */
149 bool LyXFunc::show_sc = true;
152 LyXFunc::LyXFunc(LyXView * o)
156 lyx_dead_action = LFUN_NOACTION;
157 lyx_calling_dead_action = LFUN_NOACTION;
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.
168 void LyXFunc::moveCursorUpdate(bool selecting)
170 if (selecting || owner->view()->text->mark_set) {
171 owner->view()->text->SetSelection();
172 owner->view()->toggleToggle();
174 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
175 owner->view()->showCursor();
177 /* ---> Everytime the cursor is moved, show the current font state. */
178 // should this too me moved out of this func?
179 //owner->getMiniBuffer()->Set(CurrentState());
180 owner->view()->setState();
184 int LyXFunc::processKeyEvent(XEvent * ev)
188 XKeyEvent * keyevent = &ev->xkey;
189 KeySym keysym_return = 0;
191 int num_bytes = LyXLookupString(ev, s_r, 10, &keysym_return);
192 s_r[num_bytes] = '\0';
194 if (lyxerr.debugging(Debug::KEY)) {
195 char * tmp = XKeysymToString(keysym_return);
196 string stm = (tmp ? tmp : "");
197 lyxerr << "KeySym is "
200 << keysym_return << "]"
201 << " and num_bytes is "
203 << " the string returned is \""
204 << s_r << '\"' << endl;
206 // Do nothing if we have nothing (JMarc)
207 if (num_bytes == 0 && keysym_return == NoSymbol) {
208 lyxerr[Debug::KEY] << "Empty kbd action (probably composing)"
213 // this function should be used always [asierra060396]
214 UpdatableInset * tli = owner->view()->the_locking_inset;
215 if (owner->view()->available() && tli && (keysym_return==XK_Escape)) {
216 if (tli == tli->GetLockingInset()) {
217 owner->view()->unlockInset(tli);
218 owner->view()->text->CursorRight(owner->view());
219 moveCursorUpdate(false);
220 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
222 tli->UnlockInsetInInset(owner->view(),
223 tli->GetLockingInset(),true);
228 // Can we be sure that this will work for all X-Windows
229 // implementations? (Lgb)
230 // This code snippet makes lyx ignore some keys. Perhaps
231 // all of them should be explictly mentioned?
232 if((keysym_return >= XK_Shift_L && keysym_return <= XK_Hyper_R)
233 || keysym_return == XK_Mode_switch || keysym_return == 0x0)
236 // Do a one-deep top-level lookup for
237 // cancel and meta-fake keys. RVDK_PATCH_5
238 cancel_meta_seq.reset();
240 int action = cancel_meta_seq.addkey(keysym_return, keyevent->state
241 &(ShiftMask|ControlMask
244 // When not cancel or meta-fake, do the normal lookup.
245 // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards.
246 // Mostly, meta_fake_bit = 0. RVDK_PATCH_5.
247 if ( (action != LFUN_CANCEL) && (action != LFUN_META_FAKE) ) {
249 // remove Caps Lock and Mod2 as a modifiers
250 action = keyseq.addkey(keysym_return,
251 (keyevent->state | meta_fake_bit)
252 &(ShiftMask|ControlMask
255 // Dont remove this unless you know what you are doing.
258 if (action == 0) action = LFUN_PREFIX;
260 if (lyxerr.debugging(Debug::KEY)) {
266 << num_bytes << "]" << endl;
269 // already here we know if it any point in going further
270 // why not return already here if action == -1 and
271 // num_bytes == 0? (Lgb)
273 if(keyseq.length > 1 || keyseq.length < -1) {
276 owner->getMiniBuffer()->Set(buf);
280 if (keyseq.length < -1) { // unknown key sequence...
284 owner->getMiniBuffer()->Set(_("Unknown sequence:"), buf);
288 char isochar = keyseq.getiso();
289 if (!(keyevent->state&ControlMask) &&
290 !(keyevent->state&Mod1Mask) &&
291 (isochar && keysym_return < 0xF000)) {
294 if (argument.empty()) {
295 lyxerr.debug() << "Empty argument!" << endl;
296 // This can`t possibly be of any use
297 // so we`ll skip the dispatch.
301 if (action == LFUN_SELFINSERT) {
305 bool tmp_sc = show_sc;
307 Dispatch(action, argument.c_str());
314 LyXFunc::func_status LyXFunc::getStatus(int ac) const
317 func_status flag = LyXFunc::OK;
319 Buffer * buf = owner->buffer();
321 if (lyxaction.isPseudoAction(ac))
322 action = lyxaction.retrieveActionArg(ac, argument);
324 action = static_cast<kb_action>(ac);
326 if (action == LFUN_UNKNOWN_ACTION) {
327 setErrorMessage(N_("Unknown action"));
328 return LyXFunc::Unknown;
331 // Check whether we need a buffer
332 if (!lyxaction.funcHasFlag(action, LyXAction::NoBuffer)) {
333 // Yes we need a buffer, do we have one?
336 // Can we use a readonly buffer?
337 if (buf->isReadonly() &&
338 !lyxaction.funcHasFlag(action,
339 LyXAction::ReadOnly)) {
341 setErrorMessage(N_("Document is read-only"));
342 flag |= LyXFunc::Disabled;
346 setErrorMessage(N_("Command not allowed with"
347 "out any document open"));
348 flag |= LyXFunc::Disabled;
352 if (flag & LyXFunc::Disabled)
355 // I would really like to avoid having this switch and rather try to
356 // encode this in the function itself.
357 static bool noLaTeX = lyxrc.latex_command == "none";
358 bool disable = false;
361 disable = noLaTeX || lyxrc.view_dvi_command == "none";
364 disable = noLaTeX || lyxrc.view_ps_command == "none";
371 disable = noLaTeX || lyxrc.print_command == "none";
374 disable = noLaTeX || lyxrc.fax_command == "none";
377 if (argument == "latex")
378 disable = lyxrc.relyx_command == "none";
379 if (argument == "linuxdoc")
380 disable = lyxrc.linuxdoc_to_lyx_command == "none";
383 if (argument == "dvi" || argument == "postscript")
385 if (argument == "html")
386 disable = lyxrc.html_command == "none";
387 if (argument == "html-linuxdoc")
388 disable = lyxrc.linuxdoc_to_html_command == "none";
389 if (argument == "html-docbook")
390 disable = lyxrc.docbook_to_html_command == "none";
393 disable = buf->undostack.empty();
396 disable = buf->redostack.empty();
398 case LFUN_SPELLCHECK:
399 disable = lyxrc.isp_command == "none";
402 disable = lyxrc.chktex_command == "none";
404 case LFUN_LAYOUT_TABLE:
405 disable = ! owner->view()->text->cursor.par()->table;
411 flag |= LyXFunc::Disabled;
414 func_status box = LyXFunc::ToggleOff;
415 LyXFont font = owner->view()->text->real_current_font;
418 if (font.emph() == LyXFont::ON)
419 box = LyXFunc::ToggleOn;
422 if (font.noun() == LyXFont::ON)
423 box = LyXFunc::ToggleOn;
426 if (font.series() == LyXFont::BOLD_SERIES)
427 box = LyXFunc::ToggleOn;
430 if (font.latex() == LyXFont::ON)
431 box = LyXFunc::ToggleOn;
444 string LyXFunc::Dispatch(string const & s)
446 // Split command string into command and argument
447 string cmd, line = frontStrip(s);
448 string arg = strip(frontStrip(split(line, cmd, ' ')));
450 return Dispatch(lyxaction.LookupFunc(cmd.c_str()), arg.c_str());
454 string LyXFunc::Dispatch(int ac,
455 char const * do_not_use_this_arg)
460 // we have not done anything wrong yet.
462 dispatch_buffer.erase();
464 // if action is a pseudo-action, we need the real action
465 if (lyxaction.isPseudoAction(ac)) {
467 action = static_cast<kb_action>
468 (lyxaction.retrieveActionArg(ac, tmparg));
472 action = static_cast<kb_action>(ac);
473 if (do_not_use_this_arg)
474 argument = do_not_use_this_arg; // except here
477 selection_possible = false;
479 if (owner->view()->available())
480 owner->view()->hideCursor();
482 // We cannot use this function here
483 if (getStatus(action) & Disabled)
484 goto exit_with_message;
486 commandshortcut.erase();
488 if (lyxrc.display_shortcuts && show_sc) {
489 if (action != LFUN_SELFINSERT) {
490 // Put name of command and list of shortcuts
491 // for it in minibuffer
492 string comname = lyxaction.getActionName(action);
494 int pseudoaction = action;
495 bool argsadded = false;
497 if (!argument.empty()) {
498 // If we have the command with argument,
501 lyxaction.searchActionArg(action,
504 if (pseudoaction == -1) {
505 pseudoaction = action;
507 comname += " " + argument;
512 string shortcuts = toplevel_keymap->findbinding(pseudoaction);
514 if (!shortcuts.empty()) {
515 comname += ": " + shortcuts;
516 } else if (!argsadded) {
517 comname += " " + argument;
520 if (!comname.empty()) {
521 comname = strip(comname);
522 commandshortcut = "(" + comname + ')';
523 owner->getMiniBuffer()->Set(commandshortcut);
524 // Here we could even add a small pause,
525 // to annoy the user and make him learn
527 // No! That will just annoy, not teach
528 // anything. The user will read the messages
529 // if they are interested. (Asger)
534 // If in math mode pass the control to
535 // the math inset [asierra060396]
536 if (owner->view()->available() &&
537 owner->view()->the_locking_inset) {
538 UpdatableInset::RESULT result;
539 if ((action > 1) || ((action == LFUN_UNKNOWN_ACTION) &&
540 (keyseq.length >= -1)))
542 if ((action==LFUN_UNKNOWN_ACTION) && argument.empty()){
543 argument = keyseq.getiso();
545 // Undo/Redo pre 0.13 is a bit tricky for insets.
546 if (action == LFUN_UNDO) {
548 UpdatableInset * inset =
549 owner->view()->the_locking_inset;
550 inset->GetCursorPos(owner->view(), slx, sly);
551 owner->view()->unlockInset(inset);
552 owner->view()->menuUndo();
553 if (owner->view()->text->cursor.par()->
554 IsInset(owner->view()->text->cursor.pos())) {
555 inset = static_cast<UpdatableInset*>(
556 owner->view()->text->cursor.par()->
557 GetInset(owner->view()->text->
563 inset->Edit(owner->view(),slx,sly,0);
565 } else if (action == LFUN_REDO) {
567 UpdatableInset * inset = owner->view()->
569 inset->GetCursorPos(owner->view(), slx, sly);
570 owner->view()->unlockInset(inset);
571 owner->view()->menuRedo();
572 inset = static_cast<UpdatableInset*>(
573 owner->view()->text->cursor.par()->
574 GetInset(owner->view()->text->
577 inset->Edit(owner->view(),slx,sly,0);
579 } else if (((result=owner->view()->the_locking_inset->
580 LocalDispatch(owner->view(), action,
582 UpdatableInset::DISPATCHED) ||
583 (result == UpdatableInset::DISPATCHED_NOUPDATE))
586 setMessage(N_("Text mode"));
588 case LFUN_UNKNOWN_ACTION:
589 case LFUN_BREAKPARAGRAPH:
591 owner->view()->text->CursorRight(owner->view());
592 owner->view()->setState();
593 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
596 if (!owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params)) {
597 owner->view()->text->CursorRight(owner->view());
598 moveCursorUpdate(false);
599 owner->getMiniBuffer()->
600 Set(CurrentState(owner->view()));
604 if (owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params)) {
605 owner->view()->text->CursorRight(owner->view());
606 moveCursorUpdate(false);
607 owner->getMiniBuffer()->
608 Set(CurrentState(owner->view()));
612 owner->view()->text->CursorDown(owner->view());
613 moveCursorUpdate(false);
614 owner->getMiniBuffer()->
615 Set(CurrentState(owner->view()));
625 // --- Misc -------------------------------------------
626 case LFUN_WORDFINDFORWARD :
627 case LFUN_WORDFINDBACKWARD : {
628 static string last_search;
629 string searched_string;
631 if (!argument.empty()) {
632 last_search = argument;
633 searched_string = argument;
635 searched_string = last_search;
638 LyXText * ltCur = owner->view()->text ;
640 if (!searched_string.empty() &&
641 ((action == LFUN_WORDFINDBACKWARD) ?
642 ltCur->SearchBackward(owner->view(), searched_string.c_str()) :
643 ltCur->SearchForward(owner->view(), searched_string.c_str()))) {
645 // ??? What is that ???
646 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
649 // clear the selection (if there is any)
650 owner->view()->toggleSelection();
651 owner->view()->text->ClearSelection();
653 // Move cursor so that successive C-s 's will not stand in place.
654 if( action == LFUN_WORDFINDFORWARD )
655 owner->view()->text->CursorRightOneWord(owner->view());
656 owner->view()->text->FinishUndo();
657 moveCursorUpdate(false);
660 // set the new selection
661 // SetSelectionOverLenChars(owner->view()->currentBuffer()->text, iLenSelected);
662 owner->view()->toggleSelection(false);
666 // REMOVED : if (owner->view()->getWorkArea()->focus)
667 owner->view()->showCursor();
673 if (owner->view()->available()) {
674 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
677 keyseq.print(buf, true);
678 owner->getMiniBuffer()->Set(buf, string(), string(), 1);
682 // --- Misc -------------------------------------------
683 case LFUN_EXEC_COMMAND:
684 owner->getMiniBuffer()->ExecCommand();
687 case LFUN_CANCEL: // RVDK_PATCH_5
690 if(owner->view()->available())
691 // cancel any selection
692 Dispatch(LFUN_MARK_OFF, 0);
693 setMessage(N_("Cancel"));
696 case LFUN_META_FAKE: // RVDK_PATCH_5
698 meta_fake_bit = Mod1Mask;
700 keyseq.print(buf, true);
701 string res = string("M-") + buf;
702 setMessage(buf); // RVDK_PATCH_5
706 case LFUN_READ_ONLY_TOGGLE:
707 if (owner->buffer()->lyxvc.inUse()) {
708 owner->buffer()->lyxvc.toggleReadOnly();
710 owner->buffer()->setReadonly(
711 !owner->buffer()->isReadonly());
715 case LFUN_CENTER: // this is center and redraw.
716 owner->view()->center();
720 if (owner->view()->available()) {
721 owner->view()->text->toggleAppendix(owner->view());
722 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
726 // --- Menus -----------------------------------------------
731 case LFUN_MENUNEWTMPLT:
739 case LFUN_CLOSEBUFFER:
744 owner->getMiniBuffer()->Set(_("Saving document"),
745 MakeDisplayPath(owner->buffer()->fileName()),
747 MenuWrite(owner->buffer());
748 //owner->getMiniBuffer()-> {
749 // Set(_("Document saved as"),
750 // MakeDisplayPath(owner->buffer()->fileName()));
752 //owner->getMiniBuffer()->Set(_("Save failed!"));
756 case LFUN_MENUWRITEAS:
757 MenuWriteAs(owner->buffer());
760 case LFUN_MENURELOAD:
765 PreviewDVI(owner->buffer());
769 PreviewPostscript(owner->buffer());
773 MenuRunLaTeX(owner->buffer());
777 MenuBuildProg(owner->buffer());
781 MenuRunChktex(owner->buffer());
785 CreatePostscript(owner->buffer(), false);
789 owner->getDialogs()->showPrint();
793 MenuFax(owner->buffer());
797 MenuExport(owner->buffer(), argument);
813 Buffer::TocType type = Buffer::TOC_TOC;
814 if (action == LFUN_LOFVIEW)
815 type = Buffer::TOC_LOF;
816 else if (action == LFUN_LOTVIEW)
817 type = Buffer::TOC_LOT;
818 else if (action == LFUN_LOAVIEW)
819 type = Buffer::TOC_LOA;
820 fl_set_choice(fd_form_toc->toctype,type + 1);
822 if (fd_form_toc->form_toc->visible) {
823 fl_raise_form(fd_form_toc->form_toc);
825 static int ow = -1, oh;
826 fl_show_form(fd_form_toc->form_toc,
828 FL_FREE_SIZE, FL_FULLBORDER,
829 _("Table of Contents"));
831 ow = fd_form_toc->form_toc->w;
832 oh = fd_form_toc->form_toc->h;
834 fl_set_form_minsize(fd_form_toc->form_toc, ow, oh);
838 case LFUN_TOC_INSERT:
840 Inset * new_inset = new InsetTOC(owner->buffer());
841 if (!owner->view()->insertInset(new_inset, "Standard", true))
846 case LFUN_LOF_INSERT:
848 Inset * new_inset = new InsetLOF(owner->buffer());
849 if (!owner->view()->insertInset(new_inset, "Standard", true))
854 case LFUN_LOA_INSERT:
856 Inset * new_inset = new InsetLOA(owner->buffer());
857 if (!owner->view()->insertInset(new_inset, "Standard", true))
862 case LFUN_LOT_INSERT:
864 Inset * new_inset = new InsetLOT(owner->buffer());
865 if (!owner->view()->insertInset(new_inset, "Standard", true))
878 case LFUN_INSERT_GRAPHICS:
880 Inset * new_inset = new InsetGraphics;
881 if (!owner->view()->insertInset(new_inset))
887 AutoSave(owner->view());
891 owner->view()->menuUndo();
895 owner->view()->menuRedo();
898 case LFUN_MENUSEARCH:
900 // Ok this is one _very_ bad solution, but I think that some
901 // of this will be rewritten as part of GUI indep anyway.
903 static LyXFindReplace FR_;
904 FR_.StartSearch(owner->view());
909 owner->view()->paste();
910 owner->view()->setState();
913 case LFUN_PASTESELECTION:
916 if (argument == "paragraph") asPara = true;
917 owner->view()->pasteClipboard(asPara);
922 owner->view()->cut();
926 owner->view()->copy();
929 case LFUN_LAYOUT_COPY:
930 owner->view()->copyEnvironment();
933 case LFUN_LAYOUT_PASTE:
934 owner->view()->pasteEnvironment();
935 owner->view()->setState();
939 owner->view()->gotoError();
942 case LFUN_REMOVEERRORS:
943 if (owner->view()->removeAutoInsets()) {
944 owner->view()->redraw();
945 owner->view()->fitCursor();
946 //owner->view()->updateScrollbar();
951 owner->view()->gotoNote();
955 owner->view()->openStuff();
958 case LFUN_HYPHENATION:
959 owner->view()->hyphenationPoint();
963 owner->view()->ldots();
966 case LFUN_END_OF_SENTENCE:
967 owner->view()->endOfSentenceDot();
970 case LFUN_MENU_SEPARATOR:
971 owner->view()->menuSeparator();
975 owner->view()->hfill();
979 changeDepth(owner->view(), 0);
983 changeDepth(owner->view(), -1);
986 case LFUN_DEPTH_PLUS:
987 changeDepth(owner->view(), 1);
992 owner->view()->setState();
993 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
998 owner->view()->setState();
999 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1003 Melt(owner->view());
1006 case LFUN_RECONFIGURE:
1007 Reconfigure(owner->view());
1011 if (owner->view()->available()
1012 && !owner->view()->text->selection
1013 && owner->view()->text->cursor.par()->footnoteflag
1014 != LyXParagraph::NO_FOOTNOTE)
1015 { // only melt footnotes with FOOTMELT, not margins etc
1016 if(owner->view()->text->cursor.par()->footnotekind == LyXParagraph::FOOTNOTE)
1017 Melt(owner->view());
1020 Foot(owner->view());
1021 owner->view()->setState();
1024 case LFUN_MARGINMELT:
1025 if (owner->view()->available()
1026 && !owner->view()->text->selection
1027 && owner->view()->text->cursor.par()->footnoteflag
1028 != LyXParagraph::NO_FOOTNOTE) {
1029 // only melt margins
1030 if(owner->view()->text->cursor.par()->footnotekind == LyXParagraph::MARGIN)
1031 Melt(owner->view());
1033 Margin(owner->view());
1034 owner->view()->setState();
1037 case LFUN_HELP_COPYRIGHT:
1038 owner->getDialogs()->showCopyright();
1041 // --- version control -------------------------------
1042 case LFUN_VC_REGISTER:
1044 if (!owner->buffer()->lyxvc.inUse())
1045 owner->buffer()->lyxvc.registrer();
1049 case LFUN_VC_CHECKIN:
1051 if (owner->buffer()->lyxvc.inUse()
1052 && !owner->buffer()->isReadonly())
1053 owner->buffer()->lyxvc.checkIn();
1057 case LFUN_VC_CHECKOUT:
1059 if (owner->buffer()->lyxvc.inUse()
1060 && owner->buffer()->isReadonly())
1061 owner->buffer()->lyxvc.checkOut();
1065 case LFUN_VC_REVERT:
1067 owner->buffer()->lyxvc.revert();
1073 owner->buffer()->lyxvc.undoLast();
1077 case LFUN_VC_HISTORY:
1079 owner->buffer()->lyxvc.showLog();
1083 // --- buffers ----------------------------------------
1085 case LFUN_FILE_INSERT:
1087 MenuInsertLyXFile(argument);
1091 case LFUN_FILE_INSERT_ASCII:
1093 bool asPara = (argument == "paragraph");
1094 InsertAsciiFile(owner->view(), string(), asPara);
1100 // servercmd: argument must be <file>:<template>
1101 Buffer * tmpbuf = NewLyxFile(argument);
1103 owner->view()->buffer(tmpbuf);
1107 case LFUN_FILE_OPEN:
1108 owner->view()->buffer(bufferlist.loadLyXFile(argument));
1111 case LFUN_LATEX_LOG:
1117 lyxerr.debug() << "LFUN_LAYOUTNO: (arg) " << argument << endl;
1118 int sel = strToInt(argument);
1119 lyxerr.debug() << "LFUN_LAYOUTNO: (sel) "<< sel << endl;
1121 // Should this give a setMessage instead?
1123 return string(); // illegal argument
1125 --sel; // sel 1..., but layout 0...
1127 // Pretend we got the name instead.
1128 Dispatch(int(LFUN_LAYOUT),
1129 textclasslist.NameOfLayout(owner->view()
1130 ->buffer()->params.textclass,
1137 lyxerr.debug() << "LFUN_LAYOUT: (arg) "
1138 << argument << endl;
1140 // Derive layout number from given argument (string)
1141 // and current buffer's textclass (number). */
1142 LyXTextClassList::ClassList::size_type tclass =
1143 owner->view()->buffer()->params.textclass;
1144 pair <bool, LyXTextClass::size_type> layout =
1145 textclasslist.NumberOfLayout(tclass, argument);
1147 // If the entry is obsolete, use the new one instead.
1149 string obs = textclasslist.Style(tclass,layout.second)
1153 textclasslist.NumberOfLayout(tclass, obs);
1156 // see if we found the layout number:
1157 if (!layout.first) {
1158 setErrorMessage(string(N_("Layout ")) + argument +
1163 if (current_layout != layout.second) {
1164 owner->view()->hideCursor();
1165 current_layout = layout.second;
1166 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1167 owner->view()->text->
1168 SetLayout(owner->view(), layout.second);
1169 owner->getToolbar()->combox->
1170 select(owner->view()->
1171 text->cursor.par()->
1173 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1174 owner->view()->setState();
1179 case LFUN_LAYOUT_DOCUMENT:
1180 MenuLayoutDocument();
1183 case LFUN_LAYOUT_PARAGRAPH:
1184 MenuLayoutParagraph();
1187 case LFUN_LAYOUT_CHARACTER:
1188 MenuLayoutCharacter();
1191 case LFUN_LAYOUT_TABLE:
1194 if (argument == "true") flag = 1;
1195 MenuLayoutTable(flag);
1199 case LFUN_LAYOUT_PAPER:
1203 case LFUN_LAYOUT_QUOTES:
1207 case LFUN_LAYOUT_PREAMBLE:
1208 MenuLayoutPreamble();
1211 case LFUN_LAYOUT_SAVE_DEFAULT:
1215 case LFUN_DROP_LAYOUTS_CHOICE:
1216 owner->getToolbar()->combox->Show();
1220 Lang(owner->view(), argument);
1221 owner->view()->setState();
1222 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1226 Emph(owner->view());
1227 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1231 Bold(owner->view());
1232 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1236 Noun(owner->view());
1237 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1241 Code(owner->view());
1242 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1246 Sans(owner->view());
1247 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1251 Roman(owner->view());
1252 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1256 StyleReset(owner->view());
1257 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1260 case LFUN_UNDERLINE:
1261 Underline(owner->view());
1262 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1265 case LFUN_FONT_SIZE:
1266 FontSize(owner->view(), argument);
1267 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1270 case LFUN_FONT_STATE:
1271 setMessage(CurrentState(owner->view()));
1274 case LFUN_UPCASE_WORD:
1275 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1276 owner->view()->text->ChangeWordCase(owner->view(),
1277 LyXText::text_uppercase);
1278 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1281 case LFUN_LOWCASE_WORD:
1282 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1283 owner->view()->text->ChangeWordCase(owner->view(),
1284 LyXText::text_lowercase);
1285 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1288 case LFUN_CAPITALIZE_WORD:
1289 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1290 owner->view()->text->ChangeWordCase(owner->view(),
1291 LyXText::text_capitalization);
1292 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1295 case LFUN_INSERT_LABEL:
1296 MenuInsertLabel(argument.c_str());
1299 case LFUN_INSERT_REF:
1303 case LFUN_REFTOGGLE:
1306 static_cast<InsetRef*>(getInsetByCode(Inset::REF_CODE));
1309 owner->view()->updateInset(inset, true);
1311 setErrorMessage(N_("No cross-reference to toggle"));
1318 owner->view()->restorePosition();
1324 string label(argument);
1325 if (label.empty()) {
1327 static_cast<InsetRef*>(getInsetByCode(Inset::REF_CODE));
1329 label = inset->getContents();
1332 if (!label.empty()) {
1333 owner->view()->savePosition();
1334 if (!owner->view()->gotoLabel(label))
1335 WriteAlert(_("Error"),
1336 _("Couldn't find this label"),
1337 _("in current document."));
1342 case LFUN_MENU_OPEN_BY_NAME:
1343 owner->getMenus()->openByName(argument);
1344 break; // RVDK_PATCH_5
1346 case LFUN_SPELLCHECK:
1347 if (lyxrc.isp_command != "none")
1348 ShowSpellChecker(owner->view());
1349 break; // RVDK_PATCH_5
1351 // --- Cursor Movements -----------------------------
1354 LyXText * tmptext = owner->view()->text;
1355 bool is_rtl = tmptext->cursor.par()->isRightToLeftPar(owner->buffer()->params);
1356 if(!tmptext->mark_set)
1357 owner->view()->beforeChange();
1358 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1360 tmptext->CursorLeft(owner->view(), false);
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() == Inset::HIGHLY_EDITABLE){
1366 Inset * tmpinset = tmptext->cursor.par()->GetInset(tmptext->cursor.pos());
1367 setMessage(tmpinset->EditMessage());
1368 tmpinset->Edit(owner->view(), 0, 0, 0);
1372 tmptext->CursorRight(owner->view(), false);
1373 owner->view()->text->FinishUndo();
1374 moveCursorUpdate(false);
1375 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1381 // This is soooo ugly. Isn`t it possible to make
1382 // it simpler? (Lgb)
1383 LyXText * txt = owner->view()->text;
1384 bool is_rtl = txt->cursor.par()->isRightToLeftPar(owner->buffer()->params);
1385 if(!txt->mark_set) owner->view()->beforeChange();
1386 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1388 txt->CursorLeft(owner->view(), false);
1389 if (txt->cursor.pos() < txt->cursor.par()->Last()
1390 && txt->cursor.par()->GetChar(txt->cursor.pos())
1391 == LyXParagraph::META_INSET
1392 && txt->cursor.par()->GetInset(txt->cursor.pos())
1393 && txt->cursor.par()->GetInset(txt->cursor.pos())->Editable() == Inset::HIGHLY_EDITABLE) {
1394 Inset * tmpinset = txt->cursor.par()->GetInset(txt->cursor.pos());
1395 setMessage(tmpinset->EditMessage());
1396 LyXFont font = txt->GetFont(owner->view()->buffer(),
1399 tmpinset->Edit(owner->view(),
1400 tmpinset->x() + tmpinset->width(owner->view()->painter(),font),
1401 tmpinset->descent(owner->view()->painter(),font),
1406 txt->CursorRight(owner->view(), false);
1408 owner->view()->text->FinishUndo();
1409 moveCursorUpdate(false);
1410 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1415 if(!owner->view()->text->mark_set) owner->view()->beforeChange();
1416 owner->view()->update(BufferView::UPDATE);
1417 owner->view()->text->CursorUp(owner->view());
1418 owner->view()->text->FinishUndo();
1419 moveCursorUpdate(false);
1420 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1424 if(!owner->view()->text->mark_set)
1425 owner->view()->beforeChange();
1426 owner->view()->update(BufferView::UPDATE);
1427 owner->view()->text->CursorDown(owner->view());
1428 owner->view()->text->FinishUndo();
1429 moveCursorUpdate(false);
1430 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1433 case LFUN_UP_PARAGRAPH:
1434 if(!owner->view()->text->mark_set)
1435 owner->view()->beforeChange();
1436 owner->view()->update(BufferView::UPDATE);
1437 owner->view()->text->CursorUpParagraph(owner->view());
1438 owner->view()->text->FinishUndo();
1439 moveCursorUpdate(false);
1440 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1443 case LFUN_DOWN_PARAGRAPH:
1444 if(!owner->view()->text->mark_set)
1445 owner->view()->beforeChange();
1446 owner->view()->update(BufferView::UPDATE);
1447 owner->view()->text->CursorDownParagraph(owner->view());
1448 owner->view()->text->FinishUndo();
1449 moveCursorUpdate(false);
1450 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1454 if(!owner->view()->text->mark_set)
1455 owner->view()->beforeChange();
1456 owner->view()->update(BufferView::UPDATE);
1457 owner->view()->cursorPrevious();
1458 owner->view()->text->FinishUndo();
1459 moveCursorUpdate(false);
1460 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1464 if(!owner->view()->text->mark_set)
1465 owner->view()->beforeChange();
1466 owner->view()->update(BufferView::UPDATE);
1467 owner->view()->cursorNext();
1468 owner->view()->text->FinishUndo();
1469 moveCursorUpdate(false);
1470 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1474 if(!owner->view()->text->mark_set)
1475 owner->view()->beforeChange();
1476 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1477 owner->view()->text->CursorHome(owner->view());
1478 owner->view()->text->FinishUndo();
1479 moveCursorUpdate(false);
1480 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1484 if(!owner->view()->text->mark_set)
1485 owner->view()->beforeChange();
1486 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1487 owner->view()->text->CursorEnd(owner->view());
1488 owner->view()->text->FinishUndo();
1489 moveCursorUpdate(false);
1490 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1493 case LFUN_SHIFT_TAB:
1495 if(!owner->view()->text->mark_set)
1496 owner->view()->beforeChange();
1497 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1498 owner->view()->text->CursorTab(owner->view());
1499 owner->view()->text->FinishUndo();
1500 moveCursorUpdate(false);
1501 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1504 case LFUN_WORDRIGHT:
1505 if(!owner->view()->text->mark_set)
1506 owner->view()->beforeChange();
1507 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1508 if (owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params))
1509 owner->view()->text->CursorLeftOneWord(owner->view());
1511 owner->view()->text->CursorRightOneWord(owner->view());
1512 owner->view()->text->FinishUndo();
1513 moveCursorUpdate(false);
1514 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1518 if(!owner->view()->text->mark_set)
1519 owner->view()->beforeChange();
1520 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1521 if (owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params))
1522 owner->view()->text->CursorRightOneWord(owner->view());
1524 owner->view()->text->CursorLeftOneWord(owner->view());
1525 owner->view()->text->FinishUndo();
1526 moveCursorUpdate(false);
1527 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1530 case LFUN_BEGINNINGBUF:
1531 if(!owner->view()->text->mark_set)
1532 owner->view()->beforeChange();
1533 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1534 owner->view()->text->CursorTop(owner->view());
1535 owner->view()->text->FinishUndo();
1536 moveCursorUpdate(false);
1537 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1541 if(!owner->view()->text->mark_set)
1542 owner->view()->beforeChange();
1543 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1544 owner->view()->text->CursorBottom(owner->view());
1545 owner->view()->text->FinishUndo();
1546 moveCursorUpdate(false);
1547 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1551 /* cursor selection ---------------------------- */
1553 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1554 if (owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params))
1555 owner->view()->text->CursorLeft(owner->view());
1557 owner->view()->text->CursorRight(owner->view());
1558 owner->view()->text->FinishUndo();
1559 moveCursorUpdate(true);
1560 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1564 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1565 if (owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params))
1566 owner->view()->text->CursorRight(owner->view());
1568 owner->view()->text->CursorLeft(owner->view());
1569 owner->view()->text->FinishUndo();
1570 moveCursorUpdate(true);
1571 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1575 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1576 owner->view()->text->CursorUp(owner->view());
1577 owner->view()->text->FinishUndo();
1578 moveCursorUpdate(true);
1579 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1583 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1584 owner->view()->text->CursorDown(owner->view());
1585 owner->view()->text->FinishUndo();
1586 moveCursorUpdate(true);
1587 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1590 case LFUN_UP_PARAGRAPHSEL:
1591 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1592 owner->view()->text->CursorUpParagraph(owner->view());
1593 owner->view()->text->FinishUndo();
1594 moveCursorUpdate(true);
1595 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1598 case LFUN_DOWN_PARAGRAPHSEL:
1599 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1600 owner->view()->text->CursorDownParagraph(owner->view());
1601 owner->view()->text->FinishUndo();
1602 moveCursorUpdate(true);
1603 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1607 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1608 owner->view()->cursorPrevious();
1609 owner->view()->text->FinishUndo();
1610 moveCursorUpdate(true);
1611 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1615 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1616 owner->view()->cursorNext();
1617 owner->view()->text->FinishUndo();
1618 moveCursorUpdate(true);
1619 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1623 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1624 owner->view()->text->CursorHome(owner->view());
1625 owner->view()->text->FinishUndo();
1626 moveCursorUpdate(true);
1627 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1631 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1632 owner->view()->text->CursorEnd(owner->view());
1633 owner->view()->text->FinishUndo();
1634 moveCursorUpdate(true);
1635 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1638 case LFUN_WORDRIGHTSEL:
1639 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1640 if (owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params))
1641 owner->view()->text->CursorLeftOneWord(owner->view());
1643 owner->view()->text->CursorRightOneWord(owner->view());
1644 owner->view()->text->FinishUndo();
1645 moveCursorUpdate(true);
1646 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1649 case LFUN_WORDLEFTSEL:
1650 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1651 if (owner->view()->text->cursor.par()->isRightToLeftPar(owner->buffer()->params))
1652 owner->view()->text->CursorRightOneWord(owner->view());
1654 owner->view()->text->CursorLeftOneWord(owner->view());
1655 owner->view()->text->FinishUndo();
1656 moveCursorUpdate(true);
1657 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1660 case LFUN_BEGINNINGBUFSEL:
1661 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1662 owner->view()->text->CursorTop(owner->view());
1663 owner->view()->text->FinishUndo();
1664 moveCursorUpdate(true);
1665 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1668 case LFUN_ENDBUFSEL:
1669 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1670 owner->view()->text->CursorBottom(owner->view());
1671 owner->view()->text->FinishUndo();
1672 moveCursorUpdate(true);
1673 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1676 // --- text changing commands ------------------------
1677 case LFUN_BREAKLINE:
1678 owner->view()->beforeChange();
1679 owner->view()->text->InsertChar(owner->view(), LyXParagraph::META_NEWLINE);
1680 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1681 moveCursorUpdate(false);
1684 case LFUN_PROTECTEDSPACE:
1686 LyXLayout const & style =
1687 textclasslist.Style(owner->view()->buffer()->params.textclass,
1688 owner->view()->text->cursor.par()->GetLayout());
1690 if (style.free_spacing) {
1691 owner->view()->text->InsertChar(owner->view(), ' ');
1692 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1694 owner->view()->protectedBlank();
1696 moveCursorUpdate(false);
1701 if(owner->view()->text->mark_set) {
1702 owner->view()->beforeChange();
1703 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1704 setMessage(N_("Mark removed"));
1706 owner->view()->beforeChange();
1707 owner->view()->text->mark_set = 1;
1708 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1709 setMessage(N_("Mark set"));
1711 owner->view()->text->sel_cursor =
1712 owner->view()->text->cursor;
1716 if (!owner->view()->text->selection) {
1717 owner->view()->text->Delete(owner->view());
1718 owner->view()->text->sel_cursor =
1719 owner->view()->text->cursor;
1720 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1721 // It is possible to make it a lot faster still
1722 // just comment out the lone below...
1723 owner->view()->showCursor();
1725 owner->view()->cut();
1727 moveCursorUpdate(false);
1728 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1729 owner->view()->setState();
1732 case LFUN_DELETE_SKIP:
1734 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
1736 LyXCursor cursor = owner->view()->text->cursor;
1738 if (!owner->view()->text->selection) {
1739 if (cursor.pos() == cursor.par()->Last()) {
1740 owner->view()->text->CursorRight(owner->view());
1741 cursor = owner->view()->text->cursor;
1742 if (cursor.pos() == 0
1743 && !(cursor.par()->added_space_top
1744 == VSpace (VSpace::NONE))) {
1745 owner->view()->text->SetParagraph
1747 cursor.par()->line_top,
1748 cursor.par()->line_bottom,
1749 cursor.par()->pagebreak_top,
1750 cursor.par()->pagebreak_bottom,
1751 VSpace(VSpace::NONE),
1752 cursor.par()->added_space_bottom,
1753 cursor.par()->align,
1754 cursor.par()->labelwidthstring, 0);
1755 owner->view()->text->CursorLeft(owner->view());
1756 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1758 owner->view()->text->CursorLeft(owner->view());
1759 owner->view()->text->Delete(owner->view());
1760 owner->view()->text->sel_cursor =
1761 owner->view()->text->cursor;
1762 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1765 owner->view()->text->Delete(owner->view());
1766 owner->view()->text->sel_cursor =
1767 owner->view()->text->cursor;
1768 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1771 owner->view()->cut();
1776 /* -------> Delete word forward. */
1777 case LFUN_DELETE_WORD_FORWARD:
1778 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1779 owner->view()->text->DeleteWordForward(owner->view());
1780 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1781 moveCursorUpdate(false);
1782 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1785 /* -------> Delete word backward. */
1786 case LFUN_DELETE_WORD_BACKWARD:
1787 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1788 owner->view()->text->DeleteWordBackward(owner->view());
1789 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1790 moveCursorUpdate(false);
1791 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1794 /* -------> Kill to end of line. */
1795 case LFUN_DELETE_LINE_FORWARD:
1796 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1797 owner->view()->text->DeleteLineForward(owner->view());
1798 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1799 moveCursorUpdate(false);
1802 /* -------> Set mark off. */
1804 owner->view()->beforeChange();
1805 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1806 owner->view()->text->sel_cursor =
1807 owner->view()->text->cursor;
1808 setMessage(N_("Mark off"));
1811 /* -------> Set mark on. */
1813 owner->view()->beforeChange();
1814 owner->view()->text->mark_set = 1;
1815 owner->view()->update(BufferView::SELECT|BufferView::FITCUR);
1816 owner->view()->text->sel_cursor =
1817 owner->view()->text->cursor;
1818 setMessage(N_("Mark on"));
1821 case LFUN_BACKSPACE:
1823 if (!owner->view()->text->selection) {
1824 if (owner->getIntl()->getTrans()->backspace()) {
1825 owner->view()->text->Backspace(owner->view());
1826 owner->view()->text->sel_cursor =
1827 owner->view()->text->cursor;
1828 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1829 // It is possible to make it a lot faster still
1830 // just comment out the lone below...
1831 owner->view()->showCursor();
1834 owner->view()->cut();
1836 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1837 owner->view()->setState();
1841 case LFUN_BACKSPACE_SKIP:
1843 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
1845 LyXCursor cursor = owner->view()->text->cursor;
1847 if (!owner->view()->text->selection) {
1848 if (cursor.pos() == 0
1849 && !(cursor.par()->added_space_top
1850 == VSpace (VSpace::NONE))) {
1851 owner->view()->text->SetParagraph
1853 cursor.par()->line_top,
1854 cursor.par()->line_bottom,
1855 cursor.par()->pagebreak_top,
1856 cursor.par()->pagebreak_bottom,
1857 VSpace(VSpace::NONE), cursor.par()->added_space_bottom,
1858 cursor.par()->align,
1859 cursor.par()->labelwidthstring, 0);
1860 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1862 owner->view()->text->Backspace(owner->view());
1863 owner->view()->text->sel_cursor
1865 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1868 owner->view()->cut();
1872 case LFUN_BREAKPARAGRAPH:
1874 owner->view()->beforeChange();
1875 owner->view()->text->BreakParagraph(owner->view(), 0);
1876 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1877 owner->view()->text->sel_cursor =
1878 owner->view()->text->cursor;
1879 owner->view()->setState();
1880 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1884 case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
1886 owner->view()->beforeChange();
1887 owner->view()->text->BreakParagraph(owner->view(), 1);
1888 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1889 owner->view()->text->sel_cursor =
1890 owner->view()->text->cursor;
1891 owner->view()->setState();
1892 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1896 case LFUN_BREAKPARAGRAPH_SKIP:
1898 // When at the beginning of a paragraph, remove
1899 // indentation and add a "defskip" at the top.
1900 // Otherwise, do the same as LFUN_BREAKPARAGRAPH.
1902 LyXCursor cursor = owner->view()->text->cursor;
1904 owner->view()->beforeChange();
1905 if (cursor.pos() == 0) {
1906 if (cursor.par()->added_space_top == VSpace(VSpace::NONE)) {
1907 owner->view()->text->SetParagraph
1909 cursor.par()->line_top,
1910 cursor.par()->line_bottom,
1911 cursor.par()->pagebreak_top,
1912 cursor.par()->pagebreak_bottom,
1913 VSpace(VSpace::DEFSKIP), cursor.par()->added_space_bottom,
1914 cursor.par()->align,
1915 cursor.par()->labelwidthstring, 1);
1916 //owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1920 owner->view()->text->BreakParagraph(owner->view(), 0);
1921 //owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1924 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1925 owner->view()->text->sel_cursor = cursor;
1926 owner->view()->setState();
1927 owner->getMiniBuffer()->Set(CurrentState(owner->view()));
1931 case LFUN_PARAGRAPH_SPACING:
1933 LyXParagraph * par = owner->view()->text->cursor.par();
1934 Spacing::Space cur_spacing = par->spacing.getSpace();
1935 float cur_value = 1.0;
1936 if (cur_spacing == Spacing::Other) {
1937 cur_value = par->spacing.getValue();
1941 istringstream istr(argument);
1943 istrstream istr(argument.c_str());
1947 Spacing::Space new_spacing = cur_spacing;
1948 float new_value = cur_value;
1950 lyxerr << "Missing argument to `paragraph-spacing'"
1952 } else if (tmp == "single") {
1953 new_spacing = Spacing::Single;
1954 } else if (tmp == "onehalf") {
1955 new_spacing = Spacing::Onehalf;
1956 } else if (tmp == "double") {
1957 new_spacing = Spacing::Double;
1958 } else if (tmp == "other") {
1959 new_spacing = Spacing::Other;
1962 lyxerr << "new_value = " << tmpval << endl;
1965 } else if (tmp == "default") {
1966 new_spacing = Spacing::Default;
1968 lyxerr << _("Unknown spacing argument: ")
1969 << argument << endl;
1971 if (cur_spacing != new_spacing || cur_value != new_value) {
1972 par->spacing.set(new_spacing, new_value);
1973 owner->view()->text->RedoParagraph(owner->view());
1974 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1980 owner->view()->beforeChange();
1981 owner->view()->text->InsertChar(owner->view(), '\"'); // This " matches the single quote in the code
1982 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
1983 moveCursorUpdate(false);
1989 InsetCommand * new_inset;
1990 if (action == LFUN_HTMLURL)
1991 new_inset = new InsetUrl("htmlurl", "", "");
1993 new_inset = new InsetUrl("url", "", "");
1994 if (owner->view()->insertInset(new_inset))
1995 new_inset->Edit(owner->view(), 0, 0, 0);
2001 case LFUN_INSET_TEXT:
2003 InsetText * new_inset = new InsetText;
2004 if (owner->view()->insertInset(new_inset))
2005 new_inset->Edit(owner->view(), 0, 0, 0);
2011 case LFUN_INSET_ERT:
2013 InsetERT * new_inset = new InsetERT;
2014 if (owner->view()->insertInset(new_inset))
2015 new_inset->Edit(owner->view(), 0, 0, 0);
2021 case LFUN_INSET_EXTERNAL:
2023 InsetExternal * new_inset = new InsetExternal;
2024 if (owner->view()->insertInset(new_inset))
2025 new_inset->Edit(owner->view(), 0, 0, 0);
2031 case LFUN_INSET_FOOTNOTE:
2033 InsetFoot * new_inset = new InsetFoot;
2034 if (owner->view()->insertInset(new_inset))
2035 new_inset->Edit(owner->view(), 0, 0, 0);
2041 case LFUN_INSET_MARGINAL:
2043 InsetMarginal * new_inset = new InsetMarginal;
2044 if (owner->view()->insertInset(new_inset))
2045 new_inset->Edit(owner->view(), 0, 0, 0);
2051 case LFUN_INSET_MINIPAGE:
2053 InsetMinipage * new_inset = new InsetMinipage;
2054 if (owner->view()->insertInset(new_inset))
2055 new_inset->Edit(owner->view(), 0, 0, 0);
2061 case LFUN_INSET_FLOAT:
2063 InsetFloat * new_inset = new InsetFloat;
2064 if (owner->view()->insertInset(new_inset))
2065 new_inset->Edit(owner->view(), 0, 0, 0);
2071 case LFUN_INSET_LIST:
2073 InsetList * new_inset = new InsetList;
2074 if (owner->view()->insertInset(new_inset))
2075 new_inset->Edit(owner->view(), 0, 0, 0);
2081 case LFUN_INSET_TABULAR:
2084 if (!argument.empty())
2085 sscanf(argument.c_str(),"%d%d",&r,&c);
2086 InsetTabular * new_inset = new InsetTabular(owner->buffer(),r,c);
2087 if (owner->view()->insertInset(new_inset))
2088 new_inset->Edit(owner->view(), 0, 0, 0);
2094 // --- lyxserver commands ----------------------------
2096 case LFUN_CHARATCURSOR:
2098 LyXParagraph::size_type pos =
2099 owner->view()->text->cursor.pos();
2100 if(pos < owner->view()->text->cursor.par()->size())
2101 //dispatch_buffer = owner->view()->text->
2102 // cursor.par()->text[pos];
2104 owner->view()->text->
2105 cursor.par()->GetChar(pos);
2107 dispatch_buffer = "EOF";
2113 tostr(owner->view()->text->cursor.x()) + ' '
2114 + tostr(owner->view()->text->cursor.y());
2121 sscanf(argument.c_str(), " %d %ld", &x, &y);
2122 owner->view()->text->SetCursorFromCoordinates(owner->view(), x, y);
2126 case LFUN_GETLAYOUT:
2128 tostr(owner->view()->text->cursor.par()->layout);
2133 LyXFont & font = owner->view()->text->current_font;
2134 if(font.shape() == LyXFont::ITALIC_SHAPE)
2135 dispatch_buffer = 'E';
2136 else if(font.shape() == LyXFont::SMALLCAPS_SHAPE)
2137 dispatch_buffer = 'N';
2139 dispatch_buffer = '0';
2146 LyXFont & font = owner->view()->text->current_font;
2147 if(font.latex() == LyXFont::ON)
2148 dispatch_buffer = 'L';
2150 dispatch_buffer = '0';
2155 setMessage(owner->buffer()->fileName());
2156 lyxerr.debug() << "FNAME["
2157 << owner->buffer()->fileName()
2165 dispatch_buffer = buf;
2166 lyxserver->notifyClient(dispatch_buffer);
2170 case LFUN_GOTOFILEROW:
2172 char file_name[100];
2174 sscanf(argument.c_str(), " %s %d", file_name, &row);
2176 // Must replace extension of the file to be .lyx and get full path
2177 string s = ChangeExtension(string(file_name), ".lyx");
2179 // Either change buffer or load the file
2180 if (bufferlist.exists(s))
2181 owner->view()->buffer(bufferlist.getBuffer(s));
2183 owner->view()->buffer(bufferlist.loadLyXFile(s));
2186 owner->view()->setCursorFromRow(row);
2189 owner->view()->center();
2196 int qa = lyxaction.LookupFunc(argument.c_str());
2197 setMessage(lyxaction.helpText(static_cast<kb_action>(qa)));
2201 // --- accented characters ---------------------------
2204 case LFUN_CIRCUMFLEX:
2214 case LFUN_SPECIAL_CARON:
2217 case LFUN_HUNG_UMLAUT:
2223 if (keyseq.length == -1 && keyseq.getiso() != 0)
2224 c = keyseq.getiso();
2226 owner->getIntl()->getTrans()->
2227 deadkey(c, get_accent(action).accent,
2228 owner->view()->text);
2230 // Need to reset, in case the minibuffer calls these
2235 // copied verbatim from do_accent_char
2236 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2238 owner->view()->text->sel_cursor =
2239 owner->view()->text->cursor;
2243 // --- toolbar ----------------------------------
2244 case LFUN_PUSH_TOOLBAR:
2246 int nth = strToInt(argument);
2247 if (lyxerr.debugging(Debug::TOOLBAR)) {
2248 lyxerr << "LFUN_PUSH_TOOLBAR: argument = `"
2249 << argument << "'\n"
2250 << "LFUN_PUSH_TOOLBAR: nth = `"
2251 << nth << "'" << endl;
2256 setErrorMessage(N_("Push-toolbar needs argument > 0"));
2258 owner->getToolbar()->push(nth);
2263 case LFUN_ADD_TO_TOOLBAR:
2265 if (lyxerr.debugging(Debug::TOOLBAR)) {
2266 lyxerr << "LFUN_ADD_TO_TOOLBAR:"
2267 "argument = `" << argument << '\'' << endl;
2269 string tmp(argument);
2270 //lyxerr <<string("Argument: ") + argument);
2271 //lyxerr <<string("Tmp : ") + tmp);
2274 setErrorMessage(N_("Usage: toolbar-add-to <LyX command>"));
2276 owner->getToolbar()->add(argument, false);
2277 owner->getToolbar()->set();
2282 // --- insert characters ----------------------------------------
2284 // --- Mathed stuff. If we are here, there is no locked inset yet.
2289 if (!greek_kb_flag) {
2291 setMessage(N_("Math greek mode on"));
2298 case LFUN_GREEK_TOGGLE:
2300 greek_kb_flag = greek_kb_flag ? 0 : 2;
2301 if (greek_kb_flag) {
2302 setMessage(N_("Math greek keyboard on"));
2304 setMessage(N_("Math greek keyboard off"));
2309 case LFUN_MATH_DELIM:
2310 case LFUN_INSERT_MATRIX:
2312 if (owner->view()->available()) {
2314 open_new_inset(new InsetFormula(false));
2317 ->LocalDispatch(owner->view(),
2324 case LFUN_INSERT_MATH:
2326 math_insert_symbol(argument.c_str());
2330 case LFUN_MATH_DISPLAY:
2332 if (owner->view()->available())
2333 owner->view()->open_new_inset(new InsetFormula(true));
2337 case LFUN_MATH_MACRO:
2339 if (owner->view()->available()) {
2342 setErrorMessage(N_("Missing argument"));
2344 string s1 = token(s, ' ', 1);
2345 int na = s1.empty() ? 0: atoi(s1.c_str());
2347 open_new_inset(new InsetFormulaMacro(token(s, ' ', 0), na));
2353 case LFUN_MATH_MODE: // Open or create a math inset
2356 if (owner->view()->available())
2357 owner->view()->open_new_inset(new InsetFormula);
2358 setMessage(N_("Math editor mode"));
2362 case LFUN_MATH_NUMBER:
2363 case LFUN_MATH_LIMITS:
2365 setErrorMessage(N_("This is only allowed in math mode!"));
2369 case LFUN_INSERT_CITATION:
2371 InsetCitation * new_inset = new InsetCitation();
2373 // The note, if any, must be after the key, delimited
2374 // by a | so both key and remark can have spaces.
2375 if (!argument.empty()) {
2376 string lsarg(argument);
2377 if (contains(lsarg, "|")) {
2378 new_inset->setContents(token(lsarg, '|', 0));
2379 new_inset->setOptions(token(lsarg, '|', 1));
2381 new_inset->setContents(lsarg);
2382 if (!owner->view()->insertInset(new_inset))
2385 if (owner->view()->insertInset(new_inset))
2386 new_inset->Edit(owner->view(), 0, 0, 0);
2393 case LFUN_INSERT_BIBTEX:
2395 // ale970405+lasgoutt970425
2396 // The argument can be up to two tokens separated
2397 // by a space. The first one is the bibstyle.
2398 string lsarg(argument);
2399 string bibstyle = token(lsarg, ' ', 1);
2400 if (bibstyle.empty())
2402 InsetBibtex * new_inset
2403 = new InsetBibtex(token(lsarg, ' ', 0),
2407 if (owner->view()->insertInset(new_inset)) {
2409 new_inset->Edit(owner->view(), 0, 0, 0);
2415 // BibTeX data bases
2416 case LFUN_BIBDB_ADD:
2418 InsetBibtex * inset =
2419 static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2421 inset->addDatabase(argument);
2426 case LFUN_BIBDB_DEL:
2428 InsetBibtex * inset =
2429 static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2431 inset->delDatabase(argument);
2436 case LFUN_BIBTEX_STYLE:
2438 InsetBibtex * inset =
2439 static_cast<InsetBibtex*>(getInsetByCode(Inset::BIBTEX_CODE));
2441 inset->setOptions(argument);
2446 case LFUN_INDEX_INSERT:
2447 case LFUN_INDEX_INSERT_LAST:
2449 // Can't do that at the beginning of a paragraph.
2450 if (owner->view()->text->cursor.pos() - 1 < 0)
2453 InsetIndex * new_inset = new InsetIndex();
2454 if (!argument.empty()) {
2455 string lsarg(argument);
2456 new_inset->setContents(lsarg);
2457 if (!owner->view()->insertInset(new_inset))
2461 //get the current word for an argument
2462 LyXParagraph::size_type lastpos =
2463 owner->view()->text->cursor.pos() - 1;
2464 // Get the current word. note that this must be done
2465 // before inserting the inset, or the inset will
2467 string curstring(owner->view()
2468 ->text->cursor.par()->GetWord(lastpos));
2470 //make the new inset and write the current word into it
2471 InsetIndex * new_inset = new InsetIndex();
2473 new_inset->setContents(curstring);
2475 //don't edit it if the call was to INSERT_LAST
2476 if(action != LFUN_INDEX_INSERT_LAST) {
2477 new_inset->Edit(owner->view(), 0, 0, 0);
2479 //it looks blank on the screen unless
2480 //we do something. put it here.
2482 // move the cursor to the returned value of lastpos
2483 // but only for the auto-insert
2484 owner->view()->text->cursor.pos(lastpos);
2487 //put the new inset into the buffer.
2488 // there should be some way of knowing the user
2489 //cancelled & avoiding this, but i don't know how
2490 if (!owner->view()->insertInset(new_inset))
2496 case LFUN_INDEX_PRINT:
2498 Inset * new_inset = new InsetPrintIndex(owner->buffer());
2499 if (!owner->view()->insertInset(new_inset, "Standard", true))
2504 case LFUN_PARENTINSERT:
2506 lyxerr << "arg " << argument << endl;
2507 Inset * new_inset = new InsetParent(argument, owner->buffer());
2508 if (!owner->view()->insertInset(new_inset, "Standard", true))
2513 case LFUN_CHILDINSERT:
2515 Inset * new_inset = new InsetInclude(argument,
2517 if (owner->view()->insertInset(new_inset, "Standard", true))
2518 new_inset->Edit(owner->view(), 0, 0, 0);
2524 case LFUN_CHILDOPEN:
2527 MakeAbsPath(argument,
2528 OnlyPath(owner->buffer()->fileName()));
2529 setMessage(N_("Opening child document ") +
2530 MakeDisplayPath(filename) + "...");
2531 owner->view()->savePosition();
2532 if (bufferlist.exists(filename))
2533 owner->view()->buffer(bufferlist.getBuffer(filename));
2535 owner->view()->buffer(bufferlist.loadLyXFile(filename));
2539 case LFUN_INSERT_NOTE:
2540 owner->view()->insertNote();
2543 case LFUN_INSERTFOOTNOTE:
2545 LyXParagraph::footnote_kind kind;
2546 if (argument == "footnote")
2547 { kind = LyXParagraph::FOOTNOTE; }
2548 else if (argument == "margin")
2549 { kind = LyXParagraph::MARGIN; }
2550 else if (argument == "figure")
2551 { kind = LyXParagraph::FIG; }
2552 else if (argument == "table")
2553 { kind = LyXParagraph::TAB; }
2554 else if (argument == "wide-fig")
2555 { kind = LyXParagraph::WIDE_FIG; }
2556 else if (argument == "wide-tab")
2557 { kind = LyXParagraph::WIDE_TAB; }
2558 else if (argument == "algorithm")
2559 { kind = LyXParagraph::ALGORITHM; }
2561 setErrorMessage(N_("Unknown kind of footnote"));
2564 owner->view()->text->InsertFootnoteEnvironment(owner->view(), kind);
2565 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2566 owner->view()->setState();
2570 case LFUN_BUFFERBULLETSSELECT:
2574 case LFUN_TOGGLECURSORFOLLOW:
2575 cursor_follows_scrollbar = !cursor_follows_scrollbar;
2578 case LFUN_KMAP_OFF: // keymap off
2579 owner->getIntl()->KeyMapOn(false);
2582 case LFUN_KMAP_PRIM: // primary keymap
2583 owner->getIntl()->KeyMapPrim();
2586 case LFUN_KMAP_SEC: // secondary keymap
2587 owner->getIntl()->KeyMapSec();
2590 case LFUN_KMAP_TOGGLE: // toggle keymap
2591 owner->getIntl()->ToggleKeyMap();
2594 case LFUN_SELFINSERT:
2596 for (string::size_type i = 0; i < argument.length(); ++i) {
2597 owner->view()->text->InsertChar(owner->view(), argument[i]);
2598 // This needs to be in the loop, or else we
2599 // won't break lines correctly. (Asger)
2600 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2602 owner->view()->text->sel_cursor =
2603 owner->view()->text->cursor;
2604 moveCursorUpdate(false);
2610 // argument contains ';'-terminated commands
2611 while (argument.find(';') != string::npos) {
2613 argument = split(argument, first, ';');
2619 case LFUN_DATE_INSERT: // jdblair: date-insert cmd
2623 time_t now_time_t = time(NULL);
2624 now_tm = localtime(&now_time_t);
2625 setlocale(LC_TIME, "");
2627 if (!argument.empty())
2630 arg = lyxrc.date_insert_format;
2632 int datetmp_len = strftime(datetmp, 32, arg.c_str(), now_tm);
2633 for (int i = 0; i < datetmp_len; i++) {
2634 owner->view()->text->InsertChar(owner->view(), datetmp[i]);
2635 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2638 owner->view()->text->sel_cursor = owner->view()->text->cursor;
2639 moveCursorUpdate(false);
2643 case LFUN_SAVEPREFERENCES:
2645 Path p(user_lyxdir);
2646 lyxrc.write("preferences");
2650 case LFUN_SET_COLOR:
2652 string lyx_name, x11_name;
2653 x11_name = split(argument, lyx_name, ' ');
2654 if (lyx_name.empty() || x11_name.empty()) {
2656 setErrorMessage(N_("Syntax: set-color <lyx_name>"
2661 if (!lcolor.setColor(lyx_name, x11_name)) {
2662 static string err1 (N_("Set-color \""));
2663 static string err2 (N_("\" failed - color is undefined "
2664 "or may not be redefined"));
2666 setErrorMessage(err1 + lyx_name + err2);
2669 lyxColorHandler->updateColor(lcolor.getFromLyXName(lyx_name));
2670 owner->view()->redraw();
2674 case LFUN_UNKNOWN_ACTION:
2676 if(!owner->buffer()) {
2678 setErrorMessage(N_("No document open"));
2682 if (owner->buffer()->isReadonly()) {
2684 setErrorMessage(N_("Document is read only"));
2688 if (!argument.empty()) {
2690 /* Automatically delete the currently selected
2691 * text and replace it with what is being
2692 * typed in now. Depends on lyxrc settings
2693 * "auto_region_delete", which defaults to
2696 if ( lyxrc.auto_region_delete ) {
2697 if (owner->view()->text->selection){
2698 owner->view()->text->CutSelection(owner->view(), false);
2699 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2703 owner->view()->beforeChange();
2705 for (string::size_type i = 0;
2706 i < argument.length(); ++i) {
2707 if (greek_kb_flag) {
2708 if (!math_insert_greek(argument[i]))
2709 owner->getIntl()->getTrans()->TranslateAndInsert(argument[i], owner->view()->text);
2711 owner->getIntl()->getTrans()->TranslateAndInsert(argument[i], owner->view()->text);
2714 owner->view()->update(BufferView::SELECT|BufferView::FITCUR|BufferView::CHANGE);
2716 owner->view()->text->sel_cursor =
2717 owner->view()->text->cursor;
2718 moveCursorUpdate(false);
2721 // why is an "Unknown action" with empty
2722 // argument even dispatched in the first
2723 // place? I`ll probably change that. (Lgb)
2725 setErrorMessage(N_("Unknown action"));
2729 lyxerr << "A truly unknown func!" << endl;
2735 string res = getMessage();
2738 if (!commandshortcut.empty()) {
2739 string newbuf = owner->getMiniBuffer()->GetText();
2740 if (newbuf != commandshortcut) {
2741 owner->getMiniBuffer()->Set(newbuf
2747 owner->getMiniBuffer()->Set(string(_(res.c_str()))
2748 + " " + commandshortcut);
2755 void LyXFunc::setupLocalKeymap()
2757 keyseq.stdmap = keyseq.curmap = toplevel_keymap;
2758 cancel_meta_seq.stdmap = cancel_meta_seq.curmap = toplevel_keymap;
2762 void LyXFunc::MenuNew(bool fromTemplate)
2764 string fname, initpath = lyxrc.document_path;
2767 if (owner->view()->available()) {
2768 string trypath = owner->buffer()->filepath;
2769 // If directory is writeable, use this as default.
2770 if (IsDirWriteable(trypath) == 1)
2774 ProhibitInput(owner->view());
2775 fileDlg.SetButton(0, _("Documents"), lyxrc.document_path);
2776 fileDlg.SetButton(1, _("Templates"), lyxrc.template_path);
2777 fname = fileDlg.Select(_("Enter Filename for new document"),
2778 initpath, "*.lyx", _("newfile"));
2779 AllowInput(owner->view());
2781 if (fname.empty()) {
2782 owner->getMiniBuffer()->Set(_("Canceled."));
2783 lyxerr.debug() << "New Document Cancelled." << endl;
2787 // get absolute path of file and make sure the filename ends
2789 string s = MakeAbsPath(fname);
2790 if (!IsLyXFilename(s))
2793 // Check if the document already is open
2794 if (bufferlist.exists(s)){
2795 switch(AskConfirmation(_("Document is already open:"),
2796 MakeDisplayPath(s, 50),
2797 _("Do you want to close that document now?\n"
2798 "('No' will just switch to the open version)")))
2800 case 1: // Yes: close the document
2801 if (!bufferlist.close(bufferlist.getBuffer(s)))
2802 // If close is canceled, we cancel here too.
2805 case 2: // No: switch to the open document
2806 owner->view()->buffer(bufferlist.getBuffer(s));
2808 case 3: // Cancel: Do nothing
2809 owner->getMiniBuffer()->Set(_("Canceled."));
2814 // Check whether the file already exists
2815 if (IsLyXFilename(s)) {
2817 if (fi.readable() &&
2818 AskQuestion(_("File already exists:"),
2819 MakeDisplayPath(s, 50),
2820 _("Do you want to open the document?"))) {
2822 owner->getMiniBuffer()->Set(_("Opening document"),
2823 MakeDisplayPath(s), "...");
2825 owner->view()->buffer(
2826 bufferlist.loadLyXFile(s));
2827 owner->getMiniBuffer()->Set(_("Document"),
2834 // The template stuff
2837 ProhibitInput(owner->view());
2838 fname = fileDlg.Select(_("Choose template"),
2839 lyxrc.template_path,
2842 AllowInput(owner->view());
2845 // find a free buffer
2846 lyxerr.debug() << "Find a free buffer." << endl;
2847 owner->view()->buffer(bufferlist.newFile(s, templname));
2851 void LyXFunc::MenuOpen()
2853 string initpath = lyxrc.document_path;
2856 if (owner->view()->available()) {
2857 string trypath = owner->buffer()->filepath;
2858 // If directory is writeable, use this as default.
2859 if (IsDirWriteable(trypath) == 1)
2864 ProhibitInput(owner->view());
2865 fileDlg.SetButton(0, _("Documents"), lyxrc.document_path);
2866 fileDlg.SetButton(1, _("Examples"),
2867 AddPath(system_lyxdir, "examples"));
2868 string filename = fileDlg.Select(_("Select Document to Open"),
2870 AllowInput(owner->view());
2872 // check selected filename
2873 if (filename.empty()) {
2874 owner->getMiniBuffer()->Set(_("Canceled."));
2878 // get absolute path of file and make sure the filename ends
2880 filename = MakeAbsPath(filename);
2881 if (!IsLyXFilename(filename))
2885 owner->getMiniBuffer()->Set(_("Opening document"),
2886 MakeDisplayPath(filename), "...");
2887 Buffer * openbuf = bufferlist.loadLyXFile(filename);
2889 owner->view()->buffer(openbuf);
2890 owner->getMiniBuffer()->Set(_("Document"),
2891 MakeDisplayPath(filename),
2894 owner->getMiniBuffer()->Set(_("Could not open document"),
2895 MakeDisplayPath(filename));
2899 // returns filename if file must be imported,
2900 // empty string if either file not found or already loaded
2901 // checks for running without gui are missing.
2903 void LyXFunc::doImportHelper(
2904 string const & file, // filename (possibly empty)
2905 string const & text, // info when asking for filename
2906 string const & pattern, // filetype
2907 bool func(BufferView *, string const &) // the real import function
2910 string filename = file;
2912 if (filename.empty()) { // need user interaction
2913 string initpath = lyxrc.document_path;
2916 if (owner->view()->available()) {
2917 string trypath = owner->buffer()->filepath;
2918 // If directory is writeable, use this as default.
2919 if (IsDirWriteable(trypath) == 1)
2924 ProhibitInput(owner->view());
2925 fileDlg.SetButton(0, _("Documents"), lyxrc.document_path);
2926 fileDlg.SetButton(1, _("Examples"),
2927 AddPath(system_lyxdir, "examples"));
2928 filename = fileDlg.Select(text, initpath, pattern);
2929 AllowInput(owner->view());
2931 // check selected filename
2932 if (filename.empty())
2933 owner->getMiniBuffer()->Set(_("Canceled."));
2936 // still no filename? abort
2937 if (filename.empty())
2940 // get absolute path of file
2941 filename = MakeAbsPath(filename);
2943 string lyxfile = ChangeExtension(filename, ".lyx");
2945 // Check if the document already is open
2946 if (bufferlist.exists(lyxfile)) {
2947 switch(AskConfirmation(_("Document is already open:"),
2948 MakeDisplayPath(lyxfile, 50),
2949 _("Do you want to close that document now?\n"
2950 "('No' will just switch to the open version)")))
2952 case 1: // Yes: close the document
2953 if (!bufferlist.close(bufferlist.getBuffer(lyxfile)))
2954 // If close is canceled, we cancel here too.
2957 case 2: // No: switch to the open document
2958 owner->view()->buffer(bufferlist.getBuffer(lyxfile));
2960 case 3: // Cancel: Do nothing
2961 owner->getMiniBuffer()->Set(_("Canceled."));
2966 // Check if a LyX document by the same root exists in filesystem
2967 FileInfo f(lyxfile, true);
2968 if (f.exist() && !AskQuestion(_("A document by the name"),
2969 MakeDisplayPath(lyxfile),
2970 _("already exists. Overwrite?"))) {
2971 owner->getMiniBuffer()->Set(_("Canceled."));
2974 // filename should be valid now
2976 // notify user of import ahead
2977 string displaypath = MakeDisplayPath(filename);
2978 owner->getMiniBuffer()->Set(_("Importing"), displaypath, "...");
2980 // call real importer
2981 bool result = func(owner->view(), filename);
2985 owner->getMiniBuffer()->Set(displaypath, _("imported."));
2987 owner->getMiniBuffer()->Set(displaypath, _(": import failed."));
2991 bool doImportASCIIasLines(BufferView * view, string const & filename)
2993 view->buffer(bufferlist.newFile(filename, string()));
2994 InsertAsciiFile(view, filename, false);
2999 bool doImportASCIIasParagraphs(BufferView * view, string const & filename)
3001 view->buffer(bufferlist.newFile(filename, string()));
3002 InsertAsciiFile(view, filename, true);
3007 bool doImportLaTeX(BufferView * view, string const & filename)
3009 ImportLaTeX myImport(filename);
3010 Buffer * openbuf = myImport.run();
3012 view->buffer(openbuf);
3020 bool doImportNoweb(BufferView * view, string const & filename)
3022 ImportNoweb myImport(filename);
3023 Buffer * openbuf = myImport.run();
3025 view->buffer(openbuf);
3033 bool doImportLinuxDoc(BufferView *, string const & filename)
3036 string tmp = lyxrc.linuxdoc_to_lyx_command + filename;
3040 int result = one.startscript(Systemcalls::System, tmp);
3042 string filename = ChangeExtension(filename, ".lyx");
3043 // File was generated without problems. Load it.
3044 buf = bufferlist.loadLyXFile(filename);
3051 void LyXFunc::MenuInsertLyXFile(string const & filen)
3053 string filename = filen;
3055 if (filename.empty()) {
3056 // Launch a file browser
3057 string initpath = lyxrc.document_path;
3060 if (owner->view()->available()) {
3061 string trypath = owner->buffer()->filepath;
3062 // If directory is writeable, use this as default.
3063 if (IsDirWriteable(trypath) == 1)
3068 ProhibitInput(owner->view());
3069 fileDlg.SetButton(0, _("Documents"), lyxrc.document_path);
3070 fileDlg.SetButton(1, _("Examples"),
3071 AddPath(system_lyxdir, "examples"));
3072 filename = fileDlg.Select(_("Select Document to Insert"),
3074 AllowInput(owner->view());
3076 // check selected filename
3077 if (filename.empty()) {
3078 owner->getMiniBuffer()->Set(_("Canceled."));
3083 // get absolute path of file and make sure the filename ends
3085 filename = MakeAbsPath(filename);
3086 if (!IsLyXFilename(filename))
3090 owner->getMiniBuffer()->Set(_("Inserting document"),
3091 MakeDisplayPath(filename), "...");
3092 bool res = owner->view()->insertLyXFile(filename);
3094 owner->getMiniBuffer()->Set(_("Document"),
3095 MakeDisplayPath(filename),
3098 owner->getMiniBuffer()->Set(_("Could not insert document"),
3099 MakeDisplayPath(filename));
3103 void LyXFunc::doImport(string const & argument)
3106 string filename = split(argument, type, ' ');
3107 lyxerr.debug() << "LyXFunc::doImport: " << type
3108 << " file: " << filename << endl;
3110 if (type == "latex")
3111 doImportHelper(filename,
3112 _("Select LaTeX file to import"), "*.tex",
3114 else if (type == "ascii")
3115 doImportHelper(filename,
3116 _("Select ASCII file to import"), "*.txt",
3117 doImportASCIIasLines);
3118 else if (type == "asciiparagraph")
3119 doImportHelper(filename,
3120 _("Select ASCII file to import"), "*.txt",
3121 doImportASCIIasParagraphs);
3122 else if (type == "noweb")
3123 doImportHelper(filename,
3124 _("Select NoWeb file to import"), "*.nw",
3126 else if (type == "linuxdoc")
3127 doImportHelper(filename,
3128 _("Select LinuxDoc file to import"), "*.doc",
3131 setErrorMessage(string(N_("Unknown import type: ")) + type);
3134 void LyXFunc::reloadBuffer()
3136 string fn = owner->buffer()->fileName();
3137 if (bufferlist.close(owner->buffer()))
3138 owner->view()->buffer(bufferlist.loadLyXFile(fn));
3142 void LyXFunc::CloseBuffer()
3144 if (bufferlist.close(owner->buffer()) && !quitting) {
3145 if (bufferlist.empty()) {
3146 // need this otherwise SEGV may occur while trying to
3147 // set variables that don't exist
3148 // since there's no current buffer
3149 owner->getDialogs()->hideBufferDependent();
3152 owner->view()->buffer(bufferlist.first());
3158 Inset * LyXFunc::getInsetByCode(Inset::Code code)
3160 LyXCursor cursor = owner->view()->text->cursor;
3161 Buffer * buffer = owner->view()->buffer();
3162 for (Buffer::inset_iterator it = Buffer::inset_iterator(cursor.par(),
3164 it != buffer->inset_iterator_end(); ++it) {
3165 if ((*it)->LyxCode() == code)
3172 // Each "owner" should have it's own message method. lyxview and
3173 // the minibuffer would use the minibuffer, but lyxserver would
3174 // send an ERROR signal to its client. Alejandro 970603
3175 // This func is bit problematic when it comes to NLS, to make the
3176 // lyx servers client be language indepenent we must not translate
3177 // strings sent to this func.
3178 void LyXFunc::setErrorMessage(string const & m) const
3180 dispatch_buffer = m;
3185 void LyXFunc::setMessage(string const & m)
3187 dispatch_buffer = m;