1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2002 The LyX Team.
9 * ====================================================== */
15 #include "paragraph.h"
16 #include "BufferView.h"
17 #include "funcrequest.h"
20 #include "bufferparams.h"
22 #include "ParagraphParameters.h"
27 #include "support/lstrings.h"
28 #include "frontends/LyXView.h"
29 #include "frontends/screen.h"
30 #include "frontends/WorkArea.h"
31 #include "insets/insetspecialchar.h"
32 #include "insets/insettext.h"
33 #include "insets/insetquotes.h"
34 #include "insets/insetcommand.h"
35 #include "undo_funcs.h"
42 extern string current_layout;
46 void moveCursorUpdate(BufferView * bv, bool selecting)
48 LyXText * lt = bv->getLyXText();
50 if (selecting || lt->selection.mark()) {
55 bv->updateInset(lt->inset_owner, false);
59 // bv->update(lt, BufferView::SELECT|BufferView::FITCUR);
61 bv->update(lt, BufferView::SELECT);
63 } else if (bv->text->status() != LyXText::UNCHANGED) {
64 bv->theLockingInset()->hideInsetCursor(bv);
65 bv->update(bv->text, BufferView::SELECT|BufferView::FITCUR);
69 if (!lt->selection.set())
70 bv->workarea().haveSelection(false);
76 void finishChange(BufferView * bv, bool selecting = false)
79 moveCursorUpdate(bv, selecting);
80 bv->owner()->view_state_changed();
86 bool LyXText::gotoNextInset(BufferView * bv,
87 vector<Inset::Code> const & codes, string const & contents) const
89 LyXCursor res = cursor;
92 if (res.pos() < res.par()->size() - 1) {
93 res.pos(res.pos() + 1);
95 res.par(res.par()->next());
100 !(res.par()->isInset(res.pos())
101 && (inset = res.par()->getInset(res.pos())) != 0
102 && find(codes.begin(), codes.end(), inset->lyxCode())
104 && (contents.empty() ||
105 static_cast<InsetCommand *>(
106 res.par()->getInset(res.pos()))->getContents()
110 setCursor(bv, res.par(), res.pos(), false);
117 void LyXText::gotoInset(BufferView * bv, vector<Inset::Code> const & codes,
121 bv->beforeChange(this);
125 if (same_content && cursor.par()->isInset(cursor.pos())) {
126 Inset const * inset = cursor.par()->getInset(cursor.pos());
127 if (find(codes.begin(), codes.end(), inset->lyxCode())
129 contents = static_cast<InsetCommand const *>(inset)->getContents();
132 if (!gotoNextInset(bv, codes, contents)) {
133 if (cursor.pos() || cursor.par() != ownerParagraph()) {
134 LyXCursor tmp = cursor;
135 cursor.par(ownerParagraph());
137 if (!gotoNextInset(bv, codes, contents)) {
139 bv->owner()->message(_("No more insets"));
142 bv->owner()->message(_("No more insets"));
146 selection.cursor = cursor;
150 void LyXText::gotoInset(BufferView * bv, Inset::Code code, bool same_content)
152 gotoInset(bv, vector<Inset::Code>(1, code), same_content);
156 void LyXText::cursorPrevious(BufferView * bv)
158 if (!cursor.row()->previous()) {
160 int new_y = bv->text->first_y - bv->workarea().workHeight();
161 bv->screen().draw(bv->text, bv, new_y < 0 ? 0 : new_y);
162 bv->updateScrollbar();
168 Row * cursorrow = cursor.row();
170 setCursorFromCoordinates(bv, cursor.x_fix(), y);
174 if (cursorrow == bv->text->cursor.row()) {
175 // we have a row which is higher than the workarea so we leave the
176 // cursor on the start of the row and move only the draw up as soon
177 // as we move the cursor or do something while inside the row (it may
178 // span several workarea-heights) we'll move to the top again, but this
179 // is better than just jump down and only display part of the row.
180 new_y = bv->text->first_y - bv->workarea().workHeight();
183 new_y = bv->text->cursor.iy()
184 + bv->theLockingInset()->insetInInsetY() + y
185 + cursor.row()->height()
186 - bv->workarea().workHeight() + 1;
189 - cursor.row()->baseline()
190 + cursor.row()->height()
191 - bv->workarea().workHeight() + 1;
194 bv->screen().draw(bv->text, bv, new_y < 0 ? 0 : new_y);
195 if (cursor.row()->previous()) {
197 setCursor(bv, cur, cursor.row()->previous()->par(),
198 cursor.row()->previous()->pos(), false);
199 if (cur.y() > first_y) {
203 bv->updateScrollbar();
207 void LyXText::cursorNext(BufferView * bv)
209 if (!cursor.row()->next()) {
210 int y = cursor.y() - cursor.row()->baseline() +
211 cursor.row()->height();
212 if (y > int(first_y + bv->workarea().workHeight())) {
213 bv->screen().draw(bv->text, bv,
214 bv->text->first_y + bv->workarea().workHeight());
215 bv->updateScrollbar();
220 int y = first_y + bv->workarea().workHeight();
221 if (inset_owner && !first_y) {
222 y -= (bv->text->cursor.iy()
224 + bv->theLockingInset()->insetInInsetY());
229 Row * cursorrow = cursor.row();
230 setCursorFromCoordinates(bv, cursor.x_fix(), y);
231 // + workarea().workHeight());
235 if (cursorrow == bv->text->cursor.row()) {
236 // we have a row which is higher than the workarea so we leave the
237 // cursor on the start of the row and move only the draw down as soon
238 // as we move the cursor or do something while inside the row (it may
239 // span several workarea-heights) we'll move to the top again, but this
240 // is better than just jump down and only display part of the row.
241 new_y = bv->text->first_y + bv->workarea().workHeight();
244 new_y = bv->text->cursor.iy()
245 + bv->theLockingInset()->insetInInsetY()
246 + y - cursor.row()->baseline();
248 new_y = cursor.y() - cursor.row()->baseline();
251 bv->screen().draw(bv->text, bv, new_y);
252 if (cursor.row()->next()) {
254 setCursor(bv, cur, cursor.row()->next()->par(),
255 cursor.row()->next()->pos(), false);
256 if (cur.y() < int(first_y + bv->workarea().workHeight())) {
257 cursorDown(bv, true);
260 bv->updateScrollbar();
264 void LyXText::update(BufferView * bv, bool changed)
266 BufferView::UpdateCodes c = BufferView::SELECT | BufferView::FITCUR;
268 bv->update(this, c | BufferView::CHANGE);
274 void specialChar(LyXText * lt, BufferView * bv, InsetSpecialChar::Kind kind)
278 InsetSpecialChar * new_inset = new InsetSpecialChar(kind);
279 if (!bv->insertInset(new_inset))
282 bv->updateInset(new_inset, true);
286 Inset::RESULT LyXText::dispatch(FuncRequest const & cmd)
288 lyxerr[Debug::ACTION] << "LyXFunc::dispatch: action[" << cmd.action
289 <<"] arg[" << cmd.argument << "]" << endl;
291 BufferView * bv = cmd.view();
293 switch (cmd.action) {
295 case LFUN_APPENDIX: {
296 Paragraph * par = cursor.par();
297 bool start = !par->params().startOfAppendix();
299 // ensure that we have only one start_of_appendix in this document
300 Paragraph * tmp = ownerParagraph();
301 for (; tmp; tmp = tmp->next())
302 tmp->params().startOfAppendix(false);
304 par->params().startOfAppendix(start);
306 // we can set the refreshing parameters now
307 status(cmd.view(), LyXText::NEED_MORE_REFRESH);
309 refresh_row = 0; // not needed for full update
310 updateCounters(cmd.view());
311 setCursor(cmd.view(), cursor.par(), cursor.pos());
316 case LFUN_DELETE_WORD_FORWARD:
317 bv->beforeChange(this);
319 deleteWordForward(bv);
324 case LFUN_DELETE_WORD_BACKWARD:
325 bv->beforeChange(this);
327 deleteWordBackward(bv);
332 case LFUN_DELETE_LINE_FORWARD:
333 bv->beforeChange(this);
335 deleteLineForward(bv);
342 if (!selection.mark())
343 bv->beforeChange(this);
350 if (!selection.mark())
351 bv->beforeChange(this);
353 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
354 cursorLeftOneWord(bv);
356 cursorRightOneWord(bv);
361 if (!selection.mark())
362 bv->beforeChange(this);
364 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
365 cursorRightOneWord(bv);
367 cursorLeftOneWord(bv);
371 case LFUN_BEGINNINGBUF:
372 if (!selection.mark())
373 bv->beforeChange(this);
380 if (selection.mark())
381 bv->beforeChange(this);
389 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
393 finishChange(bv, true);
398 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
402 finishChange(bv, true);
408 finishChange(bv, true);
413 cursorDown(bv, true);
414 finishChange(bv, true);
417 case LFUN_UP_PARAGRAPHSEL:
419 cursorUpParagraph(bv);
420 finishChange(bv, true);
423 case LFUN_DOWN_PARAGRAPHSEL:
425 cursorDownParagraph(bv);
426 finishChange(bv, true);
432 finishChange(bv, true);
438 finishChange(bv, true);
444 finishChange(bv, true);
450 finishChange(bv, true);
453 case LFUN_WORDRIGHTSEL:
455 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
456 cursorLeftOneWord(bv);
458 cursorRightOneWord(bv);
459 finishChange(bv, true);
462 case LFUN_WORDLEFTSEL:
464 if (cursor.par()->isRightToLeftPar(bv->buffer()->params))
465 cursorRightOneWord(bv);
467 cursorLeftOneWord(bv);
468 finishChange(bv, true);
472 bool is_rtl = cursor.par()->isRightToLeftPar(bv->buffer()->params);
473 if (!selection.mark())
474 bv->beforeChange(this);
477 cursorLeft(bv, false);
478 if (cursor.pos() < cursor.par()->size()
479 && cursor.par()->isInset(cursor.pos())
480 && isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) {
481 Inset * tmpinset = cursor.par()->getInset(cursor.pos());
482 cmd.message(tmpinset->editMessage());
483 tmpinset->edit(bv, !is_rtl);
487 cursorRight(bv, false);
493 // This is soooo ugly. Isn`t it possible to make
495 bool const is_rtl = cursor.par()->isRightToLeftPar(bv->buffer()->params);
496 if (!selection.mark())
497 bv->beforeChange(this);
499 LyXCursor const cur = cursor;
501 cursorLeft(bv, false);
502 if ((is_rtl || cur != cursor) && // only if really moved!
503 cursor.pos() < cursor.par()->size() &&
504 cursor.par()->isInset(cursor.pos()) &&
505 isHighlyEditableInset(cursor.par()->getInset(cursor.pos()))) {
506 Inset * tmpinset = cursor.par()->getInset(cursor.pos());
507 cmd.message(tmpinset->editMessage());
508 tmpinset->edit(bv, is_rtl);
512 cursorRight(bv, false);
518 if (!selection.mark())
519 bv->beforeChange(this);
520 bv->update(this, BufferView::UPDATE);
526 if (!selection.mark())
527 bv->beforeChange(this);
528 bv->update(this, BufferView::UPDATE);
533 case LFUN_UP_PARAGRAPH:
534 if (!selection.mark())
535 bv->beforeChange(this);
536 bv->update(this, BufferView::UPDATE);
537 cursorUpParagraph(bv);
541 case LFUN_DOWN_PARAGRAPH:
542 if (!selection.mark())
543 bv->beforeChange(this);
544 bv->update(this, BufferView::UPDATE);
545 cursorDownParagraph(bv);
546 finishChange(bv, false);
550 if (!selection.mark())
551 bv->beforeChange(this);
552 bv->update(this, BufferView::UPDATE);
554 finishChange(bv, false);
557 // moveCursorUpdate(bv, false, false);
558 // owner_->view_state_changed();
562 if (!selection.mark())
563 bv->beforeChange(this);
564 bv->update(this, BufferView::UPDATE);
566 finishChange(bv, false);
570 if (!selection.mark())
571 bv->beforeChange(this);
574 finishChange(bv, false);
578 if (!selection.mark())
579 bv->beforeChange(this);
582 finishChange(bv, false);
586 bv->beforeChange(this);
587 insertChar(bv, Paragraph::META_NEWLINE);
589 setCursor(bv, cursor.par(), cursor.pos());
590 moveCursorUpdate(bv, false);
594 if (!selection.set()) {
596 selection.cursor = cursor;
598 // It is possible to make it a lot faster still
599 // just comment out the line below...
603 cutSelection(bv, true);
606 moveCursorUpdate(bv, false);
607 bv->owner()->view_state_changed();
611 case LFUN_DELETE_SKIP:
612 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
613 if (!selection.set()) {
614 LyXCursor cur = cursor;
615 if (cur.pos() == cur.par()->size()) {
619 && !(cur.par()->params().spaceTop()
620 == VSpace (VSpace::NONE))) {
622 cur.par()->params().lineTop(),
623 cur.par()->params().lineBottom(),
624 cur.par()->params().pagebreakTop(),
625 cur.par()->params().pagebreakBottom(),
626 VSpace(VSpace::NONE),
627 cur.par()->params().spaceBottom(),
628 cur.par()->params().spacing(),
629 cur.par()->params().align(),
630 cur.par()->params().labelWidthString(), 0);
636 selection.cursor = cursor;
640 selection.cursor = cursor;
644 cutSelection(bv, true);
651 if (!selection.set()) {
652 if (bv->owner()->getIntl().getTransManager().backspace()) {
654 selection.cursor = cursor;
656 // It is possible to make it a lot faster still
657 // just comment out the line below...
662 cutSelection(bv, true);
665 bv->owner()->view_state_changed();
669 case LFUN_BACKSPACE_SKIP:
670 // Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
671 if (!selection.set()) {
672 LyXCursor cur = cursor;
674 && !(cur.par()->params().spaceTop()
675 == VSpace (VSpace::NONE))) {
677 cur.par()->params().lineTop(),
678 cur.par()->params().lineBottom(),
679 cur.par()->params().pagebreakTop(),
680 cur.par()->params().pagebreakBottom(),
681 VSpace(VSpace::NONE), cur.par()->params().spaceBottom(),
682 cur.par()->params().spacing(),
683 cur.par()->params().align(),
684 cur.par()->params().labelWidthString(), 0);
687 selection.cursor = cur;
691 cutSelection(bv, true);
696 case LFUN_BREAKPARAGRAPH:
697 bv->beforeChange(this);
698 breakParagraph(bv, 0);
700 selection.cursor = cursor;
702 bv->owner()->view_state_changed();
705 case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
706 bv->beforeChange(this);
707 breakParagraph(bv, 1);
709 selection.cursor = cursor;
711 bv->owner()->view_state_changed();
714 case LFUN_BREAKPARAGRAPH_SKIP: {
715 // When at the beginning of a paragraph, remove
716 // indentation and add a "defskip" at the top.
717 // Otherwise, do the same as LFUN_BREAKPARAGRAPH.
718 LyXCursor cur = cursor;
719 bv->beforeChange(this);
720 if (cur.pos() == 0) {
721 if (cur.par()->params().spaceTop() == VSpace(VSpace::NONE)) {
723 cur.par()->params().lineTop(),
724 cur.par()->params().lineBottom(),
725 cur.par()->params().pagebreakTop(),
726 cur.par()->params().pagebreakBottom(),
727 VSpace(VSpace::DEFSKIP), cur.par()->params().spaceBottom(),
728 cur.par()->params().spacing(),
729 cur.par()->params().align(),
730 cur.par()->params().labelWidthString(), 1);
735 breakParagraph(bv, 0);
739 selection.cursor = cur;
741 bv->owner()->view_state_changed();
745 case LFUN_PARAGRAPH_SPACING: {
746 Paragraph * par = cursor.par();
747 Spacing::Space cur_spacing = par->params().spacing().getSpace();
748 float cur_value = 1.0;
749 if (cur_spacing == Spacing::Other)
750 cur_value = par->params().spacing().getValue();
752 istringstream is(cmd.argument.c_str());
755 Spacing::Space new_spacing = cur_spacing;
756 float new_value = cur_value;
758 lyxerr << "Missing argument to `paragraph-spacing'"
760 } else if (tmp == "single") {
761 new_spacing = Spacing::Single;
762 } else if (tmp == "onehalf") {
763 new_spacing = Spacing::Onehalf;
764 } else if (tmp == "double") {
765 new_spacing = Spacing::Double;
766 } else if (tmp == "other") {
767 new_spacing = Spacing::Other;
770 lyxerr << "new_value = " << tmpval << endl;
773 } else if (tmp == "default") {
774 new_spacing = Spacing::Default;
776 lyxerr << _("Unknown spacing argument: ")
777 << cmd.argument << endl;
779 if (cur_spacing != new_spacing || cur_value != new_value) {
780 par->params().spacing(Spacing(new_spacing, new_value));
787 case LFUN_INSET_TOGGLE:
789 bv->beforeChange(this);
796 case LFUN_PROTECTEDSPACE:
797 if (cursor.par()->layout()->free_spacing) {
801 specialChar(this, bv, InsetSpecialChar::PROTECTED_SEPARATOR);
803 moveCursorUpdate(bv, false);
806 case LFUN_HYPHENATION:
807 specialChar(this, bv, InsetSpecialChar::HYPHENATION);
810 case LFUN_LIGATURE_BREAK:
811 specialChar(this, bv, InsetSpecialChar::LIGATURE_BREAK);
815 specialChar(this, bv, InsetSpecialChar::LDOTS);
821 insertChar(bv, Paragraph::META_HFILL);
825 case LFUN_END_OF_SENTENCE:
826 specialChar(this, bv, InsetSpecialChar::END_OF_SENTENCE);
829 case LFUN_MENU_SEPARATOR:
830 specialChar(this, bv, InsetSpecialChar::MENU_SEPARATOR);
834 bv->beforeChange(this);
836 selection.cursor = cursor;
837 cmd.message(N_("Mark off"));
841 bv->beforeChange(this);
842 selection.mark(true);
844 selection.cursor = cursor;
845 cmd.message(N_("Mark on"));
849 bv->beforeChange(this);
850 if (selection.mark()) {
852 cmd.message(N_("Mark removed"));
854 selection.mark(true);
856 cmd.message(N_("Mark set"));
858 selection.cursor = cursor;
861 case LFUN_UPCASE_WORD:
863 changeCase(bv, LyXText::text_uppercase);
865 bv->updateInset(inset_owner, true);
869 case LFUN_LOWCASE_WORD:
871 changeCase(bv, LyXText::text_lowercase);
873 bv->updateInset(inset_owner, true);
877 case LFUN_CAPITALIZE_WORD:
879 changeCase(bv, LyXText::text_capitalization);
881 bv->updateInset(inset_owner, true);
885 case LFUN_TRANSPOSE_CHARS:
889 bv->updateInset(inset_owner, true);
894 cmd.message(_("Paste"));
896 // clear the selection
897 bv->toggleSelection();
901 clearSelection(); // bug 393
910 cutSelection(bv, true);
912 cmd.message(_("Cut"));
917 cmd.message(_("Copy"));
920 case LFUN_BEGINNINGBUFSEL:
922 return Inset::UNDISPATCHED;
925 finishChange(bv, true);
930 return Inset::UNDISPATCHED;
933 finishChange(bv, true);
937 cmd.message(tostr(cursor.x()) + ' ' + tostr(cursor.y()));
943 istringstream is(cmd.argument.c_str());
946 lyxerr << "SETXY: Could not parse coordinates in '"
947 << cmd.argument << std::endl;
949 setCursorFromCoordinates(bv, x, y);
954 if (current_font.shape() == LyXFont::ITALIC_SHAPE)
956 else if (current_font.shape() == LyXFont::SMALLCAPS_SHAPE)
963 cmd.message(tostr(cursor.par()->layout()));
967 lyxerr[Debug::INFO] << "LFUN_LAYOUT: (arg) "
968 << cmd.argument << endl;
970 // This is not the good solution to the empty argument
971 // problem, but it will hopefully suffice for 1.2.0.
972 // The correct solution would be to augument the
973 // function list/array with information about what
974 // functions needs arguments and their type.
975 if (cmd.argument.empty()) {
976 cmd.errorMessage(_("LyX function 'layout' needs an argument."));
980 // Derive layout number from given argument (string)
981 // and current buffer's textclass (number)
982 LyXTextClass const & tclass = bv->buffer()->params.getLyXTextClass();
983 bool hasLayout = tclass.hasLayout(cmd.argument);
984 string layout = cmd.argument;
986 // If the entry is obsolete, use the new one instead.
988 string const & obs = tclass[layout]->obsoleted_by();
994 cmd.errorMessage(string(N_("Layout ")) + cmd.argument +
999 bool change_layout = (current_layout != layout);
1000 if (!change_layout && selection.set() &&
1001 selection.start.par() != selection.end.par())
1003 Paragraph * spar = selection.start.par();
1004 Paragraph * epar = selection.end.par()->next();
1005 while (spar != epar) {
1006 if (spar->layout()->name() != current_layout) {
1007 change_layout = true;
1012 if (change_layout) {
1014 current_layout = layout;
1016 setLayout(bv, layout);
1017 bv->owner()->setLayout(layout);
1024 case LFUN_PASTESELECTION: {
1028 // this was originally a beforeChange(bv->text), i.e
1029 // the outermost LyXText!
1030 bv->beforeChange(this);
1031 string const clip = bv->workarea().getClipboard();
1032 if (!clip.empty()) {
1033 if (cmd.argument == "paragraph")
1034 insertStringAsParagraphs(bv, clip);
1036 insertStringAsLines(bv, clip);
1043 case LFUN_GOTOERROR:
1044 gotoInset(bv, Inset::ERROR_CODE, false);
1048 gotoInset(bv, Inset::NOTE_CODE, false);
1051 case LFUN_REFERENCE_GOTO:
1053 vector<Inset::Code> tmp;
1054 tmp.push_back(Inset::LABEL_CODE);
1055 tmp.push_back(Inset::REF_CODE);
1056 gotoInset(bv, tmp, true);
1061 case LFUN_INSET_LIST:
1062 case LFUN_INSET_THEOREM:
1064 case LFUN_INSERT_NOTE:
1065 case LFUN_INSET_ERT:
1066 case LFUN_INSET_EXTERNAL:
1067 case LFUN_INSET_FLOAT:
1068 case LFUN_INSET_FOOTNOTE:
1069 case LFUN_INSET_MARGINAL:
1070 case LFUN_INSET_MINIPAGE:
1071 case LFUN_INSET_OPTARG:
1072 case LFUN_INSET_WIDE_FLOAT: {
1073 Inset * inset = createInset(cmd);
1075 bool gotsel = false;
1076 if (selection.set()) {
1077 cutSelection(bv, true, false);
1080 if (bv->insertInset(inset)) {
1083 bv->owner()->dispatch(FuncRequest(LFUN_PASTESELECTION));
1092 Paragraph const * par = cursor.par();
1093 lyx::pos_type pos = cursor.pos();
1097 else if (par->isInset(pos - 1) && par->getInset(pos - 1)->isSpace())
1100 c = par->getChar(pos - 1);
1103 LyXLayout_ptr const & style = par->layout();
1105 if (style->pass_thru ||
1106 par->getFontSettings(bv->buffer()->params,
1107 pos).language()->lang() == "hebrew" ||
1108 (!bv->insertInset(new InsetQuotes(c, bv->buffer()->params))))
1109 bv->owner()->dispatch(FuncRequest(LFUN_SELFINSERT, "\""));
1113 case LFUN_DATE_INSERT: { // jdblair: date-insert cmd
1114 time_t now_time_t = time(NULL);
1115 struct tm * now_tm = localtime(&now_time_t);
1116 setlocale(LC_TIME, "");
1118 if (!cmd.argument.empty())
1121 arg = lyxrc.date_insert_format;
1123 int const datetmp_len =
1124 ::strftime(datetmp, 32, arg.c_str(), now_tm);
1126 for (int i = 0; i < datetmp_len; i++) {
1127 insertChar(bv, datetmp[i]);
1130 selection.cursor = cursor;
1131 moveCursorUpdate(bv, false);
1135 case LFUN_SELFINSERT: {
1136 if (cmd.argument.empty())
1139 // Automatically delete the currently selected
1140 // text and replace it with what is being
1141 // typed in now. Depends on lyxrc settings
1142 // "auto_region_delete", which defaults to
1145 if (lyxrc.auto_region_delete) {
1146 if (selection.set()) {
1147 cutSelection(bv, false, false);
1150 bv->workarea().haveSelection(false);
1153 bv->beforeChange(this);
1154 LyXFont const old_font(real_current_font);
1156 string::const_iterator cit = cmd.argument.begin();
1157 string::const_iterator end = cmd.argument.end();
1158 for (; cit != end; ++cit)
1159 bv->owner()->getIntl().getTransManager().
1160 TranslateAndInsert(*cit, this);
1163 selection.cursor = cursor;
1164 moveCursorUpdate(bv, false);
1166 // real_current_font.number can change so we need to
1167 // update the minibuffer
1168 if (old_font != real_current_font)
1169 bv->owner()->view_state_changed();
1174 return Inset::UNDISPATCHED;
1177 return Inset::DISPATCHED;