X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftext3.C;h=9fb01eda4f153259b3307df1a09148b06d5424b3;hb=35204f8f33d7400a5fefeffea533fb4cb4097211;hp=d0e57a3e3873672b37ee1f6771acbb17b5810288;hpb=8a424f8382d3c0b72077d0e5ab54d16d56897456;p=lyx.git diff --git a/src/text3.C b/src/text3.C index d0e57a3e38..9fb01eda4f 100644 --- a/src/text3.C +++ b/src/text3.C @@ -136,7 +136,7 @@ namespace { void mathDispatch(LCursor & cur, FuncRequest const & cmd, bool display) { recordUndo(cur); - string sel = to_utf8(cur.selectionAsString(false)); + docstring sel = cur.selectionAsString(false); //lyxerr << "selection is: '" << sel << "'" << endl; // It may happen that sel is empty but there is a selection @@ -162,11 +162,11 @@ namespace { // create a macro if we see "\\newcommand" // somewhere, and an ordinary formula // otherwise - istringstream is(sel); - if (sel.find("\\newcommand") == string::npos - && sel.find("\\def") == string::npos) + if (sel.find(from_ascii("\\newcommand")) == string::npos + && sel.find(from_ascii("\\def")) == string::npos) { InsetMathHull * formula = new InsetMathHull; + istringstream is(to_utf8(sel)); LyXLex lex(0, 0); lex.setStream(is); formula->read(cur.buffer(), lex); @@ -175,8 +175,9 @@ namespace { // delimiters are left out formula->mutate(hullSimple); cur.insert(formula); - } else - cur.insert(new MathMacroTemplate(is)); + } else { + cur.insert(new MathMacroTemplate(sel)); + } } cur.message(from_utf8(N_("Math editor mode"))); } @@ -283,14 +284,6 @@ bool doInsertInset(LCursor & cur, LyXText * text, } -void update(LCursor & cur) -{ - //we don't call update(true, false) directly to save a metrics call - if (cur.bv().fitCursor()) - cur.bv().update(Update::Force); -} - - } // anon namespace @@ -302,9 +295,9 @@ void LyXText::number(LCursor & cur) } -bool LyXText::isRTL(Paragraph const & par) const +bool LyXText::isRTL(Buffer const & buffer, Paragraph const & par) const { - return par.isRightToLeftPar(bv()->buffer()->params()); + return par.isRightToLeftPar(buffer.params()); } @@ -312,6 +305,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) { lyxerr[Debug::ACTION] << "LyXText::dispatch: cmd: " << cmd << endl; + // FIXME: We use the update flag to indicates wether a singlePar or a + // full screen update is needed. We reset it here but shall we restore it + // at the end? + cur.noUpdate(); + BOOST_ASSERT(cur.text() == this); BufferView * bv = &cur.bv(); CursorSlice oldTopSlice = cur.top(); @@ -331,7 +329,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_PARAGRAPH_MOVE_DOWN: { pit_type const pit = cur.pit(); - recUndo(pit, pit + 1); + recUndo(cur, pit, pit + 1); finishUndo(); std::swap(pars_[pit], pars_[pit + 1]); @@ -346,7 +344,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_PARAGRAPH_MOVE_UP: { pit_type const pit = cur.pit(); - recUndo(pit - 1, pit); + recUndo(cur, pit - 1, pit); finishUndo(); std::swap(pars_[pit], pars_[pit - 1]); @@ -370,7 +368,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) // ensure that we have only one start_of_appendix in this document for (pit_type tmp = 0, end = pars_.size(); tmp != end; ++tmp) { if (pars_[tmp].params().startOfAppendix()) { - recUndo(tmp); + recUndo(cur, tmp); pars_[tmp].params().startOfAppendix(false); break; } @@ -404,7 +402,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_BUFFER_BEGIN: case LFUN_BUFFER_BEGIN_SELECT: - cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_BEGIN_SELECT); if (cur.depth() == 1) { needsUpdate |= cursorTop(cur); } else { @@ -414,7 +412,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_BUFFER_END: case LFUN_BUFFER_END_SELECT: - cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_BUFFER_END_SELECT); if (cur.depth() == 1) { needsUpdate |= cursorBottom(cur); } else { @@ -426,8 +424,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_CHAR_FORWARD_SELECT: //lyxerr << BOOST_CURRENT_FUNCTION // << " LFUN_CHAR_FORWARD[SEL]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT); - if (isRTL(cur.paragraph())) + needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_FORWARD_SELECT); + if (isRTL(*cur.bv().buffer(), cur.paragraph())) needsUpdate |= cursorLeft(cur); else needsUpdate |= cursorRight(cur); @@ -442,8 +440,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_CHAR_BACKWARD: case LFUN_CHAR_BACKWARD_SELECT: //lyxerr << "handle LFUN_CHAR_BACKWARD[_SELECT]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT); - if (isRTL(cur.paragraph())) + needsUpdate |= cur.selHandle(cmd.action == LFUN_CHAR_BACKWARD_SELECT); + if (isRTL(*cur.bv().buffer(), cur.paragraph())) needsUpdate |= cursorRight(cur); else needsUpdate |= cursorLeft(cur); @@ -457,11 +455,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_UP: case LFUN_UP_SELECT: - update(cur); //lyxerr << "handle LFUN_UP[SEL]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_UP_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_UP_SELECT); needsUpdate |= cursorUp(cur); + if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { cur.undispatched(); @@ -471,10 +469,10 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_DOWN: case LFUN_DOWN_SELECT: - update(cur); //lyxerr << "handle LFUN_DOWN[SEL]:\n" << cur << endl; - cur.selHandle(cmd.action == LFUN_DOWN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_DOWN_SELECT); needsUpdate |= cursorDown(cur); + if (!needsUpdate && oldTopSlice == cur.top() && cur.boundary() == oldBoundary) { @@ -485,20 +483,19 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_PARAGRAPH_UP: case LFUN_PARAGRAPH_UP_SELECT: - cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_UP_SELECT); needsUpdate |= cursorUpParagraph(cur); break; case LFUN_PARAGRAPH_DOWN: case LFUN_PARAGRAPH_DOWN_SELECT: - cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_PARAGRAPH_DOWN_SELECT); needsUpdate |= cursorDownParagraph(cur); break; case LFUN_SCREEN_UP: case LFUN_SCREEN_UP_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_SCREEN_UP_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_UP_SELECT); if (cur.pit() == 0 && cur.textRow().pos() == 0) { cur.undispatched(); cmd = FuncRequest(LFUN_FINISHED_UP); @@ -509,8 +506,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_SCREEN_DOWN: case LFUN_SCREEN_DOWN_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_SCREEN_DOWN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_SCREEN_DOWN_SELECT); if (cur.pit() == cur.lastpit() && cur.textRow().endpos() == cur.lastpos()) { cur.undispatched(); @@ -522,22 +518,20 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_LINE_BEGIN: case LFUN_LINE_BEGIN_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_BEGIN_SELECT); needsUpdate |= cursorHome(cur); break; case LFUN_LINE_END: case LFUN_LINE_END_SELECT: - update(cur); - cur.selHandle(cmd.action == LFUN_LINE_END_SELECT); + needsUpdate |= cur.selHandle(cmd.action == LFUN_LINE_END_SELECT); needsUpdate |= cursorEnd(cur); break; case LFUN_WORD_FORWARD: case LFUN_WORD_FORWARD_SELECT: - cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT); - if (isRTL(cur.paragraph())) + needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_FORWARD_SELECT); + if (isRTL(*cur.bv().buffer(), cur.paragraph())) needsUpdate |= cursorLeftOneWord(cur); else needsUpdate |= cursorRightOneWord(cur); @@ -545,8 +539,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_WORD_BACKWARD: case LFUN_WORD_BACKWARD_SELECT: - cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT); - if (isRTL(cur.paragraph())) + needsUpdate |= cur.selHandle(cmd.action == LFUN_WORD_BACKWARD_SELECT); + if (isRTL(*cur.bv().buffer(), cur.paragraph())) needsUpdate |= cursorRightOneWord(cur); else needsUpdate |= cursorLeftOneWord(cur); @@ -759,7 +753,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; case LFUN_CHARS_TRANSPOSE: - recordUndo(cur); + charsTranspose(cur); break; case LFUN_PASTE: @@ -789,8 +783,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) case LFUN_SERVER_GET_XY: cur.message(from_utf8( - convert(cursorX(cur.top(), cur.boundary())) + ' ' - + convert(cursorY(cur.top(), cur.boundary())))); + convert(cursorX(cur.buffer(), cur.top(), cur.boundary())) + + ' ' + convert(cursorY(cur.top(), cur.boundary())))); break; case LFUN_SERVER_SET_XY: { @@ -820,24 +814,15 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; case LFUN_LAYOUT: { - lyxerr[Debug::INFO] << "LFUN_LAYOUT: (arg) " - << to_utf8(cmd.argument()) << endl; - - // This is not the good solution to the empty argument - // problem, but it will hopefully suffice for 1.2.0. - // The correct solution would be to augument the - // function list/array with information about what - // functions needs arguments and their type. - if (cmd.argument().empty()) { - cur.errorMessage(_("LyX function 'layout' needs an argument.")); - break; - } + string layout = to_ascii(cmd.argument()); + lyxerr[Debug::INFO] << "LFUN_LAYOUT: (arg) " << layout << endl; // Derive layout number from given argument (string) // and current buffer's textclass (number) LyXTextClass const & tclass = bv->buffer()->params().getLyXTextClass(); - bool hasLayout = tclass.hasLayout(to_utf8(cmd.argument())); - string layout = to_utf8(cmd.argument()); + if (layout.empty()) + layout = tclass.defaultLayoutName(); + bool hasLayout = tclass.hasLayout(layout); // If the entry is obsolete, use the new one instead. if (hasLayout) { @@ -904,6 +889,21 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; } + case LFUN_UNICODE_INSERT: { + if (cmd.argument().empty()) + break; + docstring hexstring = cmd.argument(); + if (lyx::support::isHex(hexstring)) { + char_type c = lyx::support::hexToInt(hexstring); + if (c > 32 && c < 0x10ffff) { + lyxerr << "Inserting c: " << c << endl; + docstring s = docstring(1, c); + lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, s)); + } + } + break; + } + case LFUN_QUOTE_INSERT: { cap::replaceSelection(cur); Paragraph & par = cur.paragraph(); @@ -993,6 +993,11 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) lyx::dispatch(FuncRequest(LFUN_PRIMARY_SELECTION_PASTE, "paragraph")); } + if (cmd.button() == mouse_button::button1) { + needsUpdate = false; + cur.noUpdate(); + } + break; } @@ -1042,8 +1047,12 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; // finish selection - if (cmd.button() == mouse_button::button1) - theSelection().haveSelection(cur.selection()); + if (cmd.button() == mouse_button::button1) { + if (cur.selection()) + theSelection().haveSelection(cur.selection()); + needsUpdate = false; + cur.noUpdate(); + } bv->switchKeyMap(); break; @@ -1101,8 +1110,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) InsetCommandParams p("label"); // Try to generate a valid label p["name"] = (cmd.argument().empty()) ? - // FIXME UNICODE - from_utf8(cur.getPossibleLabel()) : + cur.getPossibleLabel() : cmd.argument(); string const data = InsetCommandMailer::params2string("label", p); @@ -1156,7 +1164,8 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.dispatch(FuncRequest(LFUN_LAYOUT, "Caption")); break; - case LFUN_INDEX_INSERT: { + case LFUN_INDEX_INSERT: + case LFUN_NOMENCL_INSERT: { InsetBase * inset = createInset(&cur.bv(), cmd); if (!inset) break; @@ -1165,11 +1174,17 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) cur.clearSelection(); insertInset(cur, inset); inset->edit(cur, true); + // Show the dialog for the nomenclature entry, since the + // description entry still needs to be filled in. + if (cmd.action == LFUN_NOMENCL_INSERT) + InsetCommandMailer("nomenclature", + *reinterpret_cast(inset)).showDialog(&cur.bv()); cur.posRight(); break; } case LFUN_INDEX_PRINT: + case LFUN_NOMENCL_PRINT: case LFUN_TOC_INSERT: case LFUN_HFILL_INSERT: case LFUN_LINE_INSERT: @@ -1209,7 +1224,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) int const nargs = s1.empty() ? 0 : convert(s1); string const s2 = token(s, ' ', 2); string const type = s2.empty() ? "newcommand" : s2; - cur.insert(new MathMacroTemplate(token(s, ' ', 0), nargs, type)); + cur.insert(new MathMacroTemplate(from_utf8(token(s, ' ', 0)), nargs, from_utf8(type))); //cur.nextInset()->edit(cur, true); } break; @@ -1384,7 +1399,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) if (!cmd.argument().empty()) // FIXME: Are all these characters encoded in one byte in utf8? bv->getIntl().getTransManager() - .translateAndInsert(cmd.argument()[0], this); + .translateAndInsert(cmd.argument()[0], this, cur); break; case LFUN_FLOAT_LIST: { @@ -1401,7 +1416,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) } setLayout(cur, tclass.defaultLayoutName()); - setParagraph(cur, Spacing(), LYX_ALIGN_LAYOUT, string(), 0); + setParagraph(cur, Spacing(), LYX_ALIGN_LAYOUT, docstring(), 0); insertInset(cur, new InsetFloatList(to_utf8(cmd.argument()))); cur.posRight(); } else { @@ -1445,11 +1460,10 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) lex.setStream(is); ParagraphParameters params; params.read(lex); - // FIXME UNICODE setParagraph(cur, params.spacing(), params.align(), - to_ascii(params.labelWidthString()), + params.labelWidthString(), params.noindent()); cur.message(_("Paragraph layout set")); break; @@ -1473,26 +1487,40 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; } + needsUpdate |= (cur.pos() != cur.lastpos()) && cur.selection(); + + // FIXME: The cursor flag is reset two lines below + // so we need to check here if some of the LFUN did touch that. + // for now only LyXText::erase() and LyXText::backspace() do that. + // The plan is to verify all the LFUNs and then to remove this + // singleParUpdate boolean altogether. + if (cur.result().update() & Update::Force) { + singleParUpdate = false; + needsUpdate = true; + } + + // FIXME: the following code should go in favor of fine grained + // update flag treatment. if (singleParUpdate) // Inserting characters does not change par height if (cur.bottom().paragraph().dim().height() == olddim.height()) { // if so, update _only_ this paragraph - cur.bv().update(Update::SinglePar | - Update::FitCursor | - Update::MultiParSel); - cur.noUpdate(); + cur.updateFlags(Update::SinglePar | + Update::FitCursor | + Update::MultiParSel); return; } else needsUpdate = true; + if (!needsUpdate && &oldTopSlice.inset() == &cur.inset() && oldTopSlice.idx() == cur.idx() - && !sel + && !sel // sel is a backup of cur.selection() at the biginning of the function. && !cur.selection()) cur.noUpdate(); else - cur.needsUpdate(); + cur.updateFlags(Update::Force | Update::FitCursor); } @@ -1546,6 +1574,8 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, code = InsetBase::INCLUDE_CODE; else if (cmd.argument() == "index") code = InsetBase::INDEX_CODE; + else if (cmd.argument() == "nomenclature") + code = InsetBase::NOMENCL_CODE; else if (cmd.argument() == "label") code = InsetBase::LABEL_CODE; else if (cmd.argument() == "note") @@ -1628,6 +1658,12 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, case LFUN_INDEX_PRINT: code = InsetBase::INDEX_PRINT_CODE; break; + case LFUN_NOMENCL_INSERT: + code = InsetBase::NOMENCL_CODE; + break; + case LFUN_NOMENCL_PRINT: + code = InsetBase::NOMENCL_PRINT_CODE; + break; case LFUN_TOC_INSERT: code = InsetBase::TOC_CODE; break; @@ -1703,7 +1739,7 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, break; case LFUN_INSET_DISSOLVE: - enable = !isMainText() && cur.inset().nargs() == 1; + enable = !isMainText(*cur.bv().buffer()) && cur.inset().nargs() == 1; break; case LFUN_CHANGE_ACCEPT: @@ -1805,6 +1841,7 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, case LFUN_BUFFER_BEGIN: case LFUN_BUFFER_BEGIN_SELECT: case LFUN_BUFFER_END_SELECT: + case LFUN_UNICODE_INSERT: // these are handled in our dispatch() enable = true; break;