X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetert.C;h=15e936c5d201310f9aa7f5b120d24ff2615ae09a;hb=e28331ed63062dea10d0a21b9ec12034b4b17b9a;hp=5c5a8b3e7f19269e5735732742a41b3e62205caf;hpb=0ca871014add94c501cb423d8dc65c1405f4d141;p=lyx.git diff --git a/src/insets/insetert.C b/src/insets/insetert.C index 5c5a8b3e7f..15e936c5d2 100644 --- a/src/insets/insetert.C +++ b/src/insets/insetert.C @@ -16,31 +16,38 @@ #include "buffer.h" #include "bufferparams.h" #include "BufferView.h" +#include "cursor.h" #include "debug.h" #include "dispatchresult.h" #include "funcrequest.h" +#include "FuncStatus.h" #include "gettext.h" #include "language.h" #include "LColor.h" +#include "LyXAction.h" #include "lyxlex.h" +#include "lyxtextclass.h" #include "metricsinfo.h" +#include "ParagraphParameters.h" #include "paragraph.h" #include "frontends/Alert.h" -#include "frontends/LyXView.h" -#include "support/tostr.h" +#include -using lyx::pos_type; -using lyx::support::split; -using lyx::support::strToInt; +namespace lyx { + +using support::token; using std::endl; using std::min; -using std::string; + using std::auto_ptr; +using std::istringstream; using std::ostream; +using std::ostringstream; +using std::string; void InsetERT::init() @@ -52,54 +59,46 @@ void InsetERT::init() font.decSize(); font.setColor(LColor::latex); setLabelFont(font); + text_.current_font.setLanguage(latex_language); + text_.real_current_font.setLanguage(latex_language); - setInsetName("ERT"); + setInsetName(from_ascii("ERT")); } -InsetERT::InsetERT(BufferParams const & bp, bool collapsed) - : InsetCollapsable(bp, collapsed) +InsetERT::InsetERT(BufferParams const & bp, CollapseStatus status) + : InsetCollapsable(bp, status) { - status_ = collapsed ? Collapsed : Open; init(); } InsetERT::InsetERT(InsetERT const & in) - : InsetCollapsable(in), status_(in.status_) + : InsetCollapsable(in) { init(); } -auto_ptr InsetERT::clone() const +auto_ptr InsetERT::doClone() const { return auto_ptr(new InsetERT(*this)); } +#if 0 InsetERT::InsetERT(BufferParams const & bp, - Language const * l, string const & contents, bool collapsed) - : InsetCollapsable(bp, collapsed) + Language const *, string const & contents, CollapseStatus status) + : InsetCollapsable(bp, status) { - status_ = collapsed ? Collapsed : Open; - - LyXFont font(LyXFont::ALL_INHERIT, l); -#ifdef SET_HARD_FONT - font.setFamily(LyXFont::TYPEWRITER_FAMILY); - font.setColor(LColor::latex); -#endif + LyXFont font(LyXFont::ALL_INHERIT, latex_language); + paragraphs().begin()->insert(0, contents, font); - string::const_iterator cit = contents.begin(); - string::const_iterator end = contents.end(); - pos_type pos = 0; - for (; cit != end; ++cit) { - inset.paragraphs.begin()->insertChar(pos++, *cit, font); - } // the init has to be after the initialization of the paragraph // because of the label settings (draw_label for ert insets). init(); } +#endif InsetERT::~InsetERT() @@ -108,211 +107,58 @@ InsetERT::~InsetERT() } -void InsetERT::read(Buffer const & buf, LyXLex & lex) +void InsetERT::write(Buffer const & buf, ostream & os) const { - bool token_found = false; - if (lex.isOK()) { - lex.next(); - string const token = lex.getString(); - if (token == "status") { - lex.next(); - string const tmp_token = lex.getString(); - - if (tmp_token == "Inlined") { - status(Inlined); - } else if (tmp_token == "Collapsed") { - status(Collapsed); - } else { - // leave this as default! - status(Open); - } - - token_found = true; - } else { - lyxerr << "InsetERT::Read: Missing 'status'-tag!" - << endl; - // take countermeasures - lex.pushToken(token); - } - } - inset.read(buf, lex); - -#ifdef SET_HARD_FONT - LyXFont font(LyXFont::ALL_INHERIT, latex_language); - font.setFamily(LyXFont::TYPEWRITER_FAMILY); - font.setColor(LColor::latex); - - ParagraphList::iterator pit = inset.paragraphs.begin(); - ParagraphList::iterator pend = inset.paragraphs.end(); - for (; pit != pend; ++pit) { - pos_type siz = pit->size(); - for (pos_type i = 0; i < siz; ++i) { - pit->setFont(i, font); - } - } -#endif - - if (!token_found) { - if (isOpen()) - status(Open); - else - status(Collapsed); - } - setButtonLabel(); + os << "ERT" << "\n"; + InsetCollapsable::write(buf, os); } -void InsetERT::write(Buffer const & buf, ostream & os) const +void InsetERT::read(Buffer const & buf, LyXLex & lex) { - string st; + InsetCollapsable::read(buf, lex); - switch (status_) { - case Open: - st = "Open"; - break; - case Collapsed: - st = "Collapsed"; - break; - case Inlined: - st = "Inlined"; - break; - } - - os << getInsetName() << "\n" << "status "<< st << "\n"; - - //inset.writeParagraphData(buf, os); - string const layout(buf.params().getLyXTextClass().defaultLayoutName()); - ParagraphList::iterator par = inset.paragraphs.begin(); - ParagraphList::iterator end = inset.paragraphs.end(); - for (; par != end; ++par) { - os << "\n\\begin_layout " << layout << "\n"; + // Force default font + // This avoids paragraphs in buffer language that would have a + // foreign language after a document langauge change, and it ensures + // that all new text in ERT gets the "latex" language, since new text + // inherits the language from the last position of the existing text. + // As a side effect this makes us also robust against bugs in LyX + // that might lead to font changes in ERT in .lyx files. + LyXFont font(LyXFont::ALL_INHERIT, latex_language); + ParagraphList::iterator par = paragraphs().begin(); + ParagraphList::iterator const end = paragraphs().end(); + while (par != end) { pos_type siz = par->size(); - for (pos_type i = 0; i < siz; ++i) { - Paragraph::value_type c = par->getChar(i); - switch (c) { - case Paragraph::META_INSET: - if (par->getInset(i)->lyxCode() != InsetOld::NEWLINE_CODE) { - lyxerr << "Element is not allowed in insertERT" - << endl; - } else { - par->getInset(i)->write(buf, os); - } - break; - - case '\\': - os << "\n\\backslash \n"; - break; - default: - os << c; - break; - } + for (pos_type i = 0; i <= siz; ++i) { + par->setFont(i, font); } - os << "\n\\end_layout\n"; + ++par; } } -string const InsetERT::editMessage() const +docstring const InsetERT::editMessage() const { return _("Opened ERT Inset"); } -bool InsetERT::insertInset(BufferView *, InsetOld *) -{ - return false; -} - - -void InsetERT::updateStatus(bool swap) const -{ - if (status_ != Inlined) { - if (isOpen()) - status(swap ? Collapsed : Open); - else - status(swap ? Open : Collapsed); - } -} - - -InsetOld::EDITABLE InsetERT::editable() const -{ - return (status_ == Collapsed) ? IS_EDITABLE : HIGHLY_EDITABLE; -} - - -void InsetERT::lfunMousePress(FuncRequest const & cmd) -{ - if (status_ == Inlined) - inset.dispatch(cmd); - else { - idx_type idx = 0; - pos_type pos = 0; - InsetCollapsable::priv_dispatch(cmd, idx, pos); - } -} - - -bool InsetERT::lfunMouseRelease(FuncRequest const & cmd) -{ - BufferView * bv = cmd.view(); - - if (cmd.button() == mouse_button::button3) { - showInsetDialog(bv); - return true; - } - - if (status_ != Inlined && hitButton(cmd)) { - updateStatus(true); - } else { - FuncRequest cmd1 = cmd; -#warning metrics? - cmd1.y = ascent() + cmd.y - inset.ascent(); - - // inlined is special - the text appears above - if (status_ == Inlined) - inset.dispatch(cmd1); - else if (isOpen() && cmd.y > buttonDim().y2) { - cmd1.y -= height_collapsed(); - inset.dispatch(cmd1); - } - } - return false; -} - - -void InsetERT::lfunMouseMotion(FuncRequest const & cmd) -{ - if (status_ == Inlined) - inset.dispatch(cmd); - else { - idx_type idx = 0; - pos_type pos = 0; - InsetCollapsable::priv_dispatch(cmd, idx, pos); - } -} - - -int InsetERT::latex(Buffer const &, ostream & os, +int InsetERT::latex(Buffer const &, odocstream & os, OutputParams const &) const { - ParagraphList::iterator par = inset.paragraphs.begin(); - ParagraphList::iterator end = inset.paragraphs.end(); + ParagraphList::const_iterator par = paragraphs().begin(); + ParagraphList::const_iterator end = paragraphs().end(); int lines = 0; while (par != end) { pos_type siz = par->size(); for (pos_type i = 0; i < siz; ++i) { // ignore all struck out text - if (isDeletedText(*par, i)) + if (par->isDeleted(i)) continue; - if (par->isNewline(i)) { - os << '\n'; - ++lines; - } else { - os << par->getChar(i); - } + os.put(par->getChar(i)); } ++par; if (par != end) { @@ -325,62 +171,28 @@ int InsetERT::latex(Buffer const &, ostream & os, } -int InsetERT::plaintext(Buffer const &, ostream &, +int InsetERT::plaintext(Buffer const &, odocstream &, OutputParams const & /*runparams*/) const { return 0; } -int InsetERT::linuxdoc(Buffer const &, ostream & os, - OutputParams const &)const -{ - ParagraphList::iterator par = inset.paragraphs.begin(); - ParagraphList::iterator end = inset.paragraphs.end(); - - int lines = 0; - while (par != end) { - pos_type siz = par->size(); - for (pos_type i = 0; i < siz; ++i) { - if (par->isNewline(i)) { - os << '\n'; - ++lines; - } else { - os << par->getChar(i); - } - } - ++par; - if (par != end) { - os << "\n"; - lines ++; - } - } - - return lines; -} - - -int InsetERT::docbook(Buffer const &, ostream & os, +int InsetERT::docbook(Buffer const &, odocstream & os, OutputParams const &) const { - ParagraphList::iterator par = inset.paragraphs.begin(); - ParagraphList::iterator end = inset.paragraphs.end(); + ParagraphList::const_iterator par = paragraphs().begin(); + ParagraphList::const_iterator end = paragraphs().end(); int lines = 0; while (par != end) { pos_type siz = par->size(); - for (pos_type i = 0; i < siz; ++i) { - if (par->isNewline(i)) { - os << '\n'; - ++lines; - } else { - os << par->getChar(i); - } - } + for (pos_type i = 0; i < siz; ++i) + os.put(par->getChar(i)); ++par; if (par != end) { os << "\n"; - lines ++; + ++lines; } } @@ -388,161 +200,223 @@ int InsetERT::docbook(Buffer const &, ostream & os, } -void InsetERT::edit(BufferView * bv, bool left) +void InsetERT::doDispatch(LCursor & cur, FuncRequest & cmd) { - if (status_ == Inlined) { - inset.edit(bv, left); - } else { - InsetCollapsable::edit(bv, left); - } - setLatexFont(bv); - updateStatus(); -} - - -DispatchResult -InsetERT::priv_dispatch(FuncRequest const & cmd, idx_type & idx, pos_type & pos) -{ - BufferView * bv = cmd.view(); - - if (inset.paragraphs.begin()->empty()) - setLatexFont(bv); - + //lyxerr << "\nInsetERT::doDispatch (begin): cmd: " << cmd << endl; switch (cmd.action) { + case LFUN_QUOTE_INSERT: { + // We need to bypass the fancy quotes in LyXText + FuncRequest f(LFUN_SELF_INSERT, "\""); + dispatch(cur, f); + break; + } case LFUN_INSET_MODIFY: { - InsetERT::ERTStatus status_; - InsetERTMailer::string2params(cmd.argument, status_); - status(status_); - bv->update(); - return DispatchResult(true, true); + InsetCollapsable::CollapseStatus st; + InsetERTMailer::string2params(to_utf8(cmd.argument()), st); + setStatus(cur, st); + break; + } + case LFUN_PASTE: + case LFUN_CLIPBOARD_PASTE: + case LFUN_PRIMARY_SELECTION_PASTE: { + InsetCollapsable::doDispatch(cur, cmd); + + // Since we can only store plain text, we must reset all + // attributes. + // FIXME: Change only the pasted paragraphs + + BufferParams const & bp = cur.buffer().params(); + LyXLayout_ptr const layout = + bp.getLyXTextClass().defaultLayout(); + LyXFont font = layout->font; + // ERT contents has always latex_language + font.setLanguage(latex_language); + ParagraphList::iterator const end = paragraphs().end(); + for (ParagraphList::iterator par = paragraphs().begin(); + par != end; ++par) { + // in case par had a manual label + par->setBeginOfBody(); + pos_type const siz = par->size(); + for (pos_type i = 0; i < siz; ++i) { + par->setFont(i, font); + } + par->params().clear(); + } + break; } - - case LFUN_MOUSE_PRESS: - lfunMousePress(cmd); - return DispatchResult(true, true); - - case LFUN_MOUSE_MOTION: - lfunMouseMotion(cmd); - return DispatchResult(true, true); - - case LFUN_MOUSE_RELEASE: - lfunMouseRelease(cmd); - return DispatchResult(true, true); - - case LFUN_LAYOUT: - bv->owner()->setLayout(inset.paragraphs.begin()->layout()->name()); - return DispatchResult(true); - - case LFUN_BREAKPARAGRAPH: - case LFUN_BREAKPARAGRAPHKEEPLAYOUT: - case LFUN_BACKSPACE: - case LFUN_BACKSPACE_SKIP: - case LFUN_DELETE: - case LFUN_DELETE_SKIP: - case LFUN_DELETE_LINE_FORWARD: - case LFUN_CUT: - setLatexFont(bv); - return InsetCollapsable::priv_dispatch(cmd, idx, pos); - default: - return InsetCollapsable::priv_dispatch(cmd, idx, pos); + // Force any new text to latex_language + // FIXME: This should only be necessary in init(), but + // new paragraphs that are created by pressing enter at the + // start of an existing paragraph get the buffer language + // and not latex_language, so we take this brute force + // approach. + text_.current_font.setLanguage(latex_language); + text_.real_current_font.setLanguage(latex_language); + + InsetCollapsable::doDispatch(cur, cmd); + break; } } -string const InsetERT::getNewLabel() const +bool InsetERT::getStatus(LCursor & cur, FuncRequest const & cmd, + FuncStatus & status) const { - string la; - pos_type const max_length = 15; - pos_type const p_siz = inset.paragraphs.begin()->size(); - pos_type const n = min(max_length, p_siz); - pos_type i = 0; - pos_type j = 0; - for( ; i < n && j < p_siz; ++j) { - if (inset.paragraphs.begin()->isInset(j)) - continue; - la += inset.paragraphs.begin()->getChar(j); - ++i; - } - if (inset.paragraphs.size() > 1 || (i > 0 && j < p_siz)) { - la += "..."; - } - if (la.empty()) { - la = _("ERT"); + switch (cmd.action) { + // suppress these + case LFUN_ACCENT_ACUTE: + case LFUN_ACCENT_BREVE: + case LFUN_ACCENT_CARON: + case LFUN_ACCENT_CEDILLA: + case LFUN_ACCENT_CIRCLE: + case LFUN_ACCENT_CIRCUMFLEX: + case LFUN_ACCENT_DOT: + case LFUN_ACCENT_GRAVE: + case LFUN_ACCENT_HUNGARIAN_UMLAUT: + case LFUN_ACCENT_MACRON: + case LFUN_ACCENT_OGONEK: + case LFUN_ACCENT_SPECIAL_CARON: + case LFUN_ACCENT_TIE: + case LFUN_ACCENT_TILDE: + case LFUN_ACCENT_UMLAUT: + case LFUN_ACCENT_UNDERBAR: + case LFUN_ACCENT_UNDERDOT: + case LFUN_APPENDIX: + case LFUN_BREAK_LINE: + case LFUN_CAPTION_INSERT: + case LFUN_DEPTH_DECREMENT: + case LFUN_DEPTH_INCREMENT: + case LFUN_DOTS_INSERT: + case LFUN_END_OF_SENTENCE_PERIOD_INSERT: + case LFUN_ENVIRONMENT_INSERT: + case LFUN_ERT_INSERT: + case LFUN_FILE_INSERT: + case LFUN_FLOAT_INSERT: + case LFUN_FLOAT_WIDE_INSERT: + case LFUN_WRAP_INSERT: + case LFUN_FONT_BOLD: + case LFUN_FONT_CODE: + case LFUN_FONT_DEFAULT: + case LFUN_FONT_EMPH: + case LFUN_FONT_FREE_APPLY: + case LFUN_FONT_FREE_UPDATE: + case LFUN_FONT_NOUN: + case LFUN_FONT_ROMAN: + case LFUN_FONT_SANS: + case LFUN_FONT_FRAK: + case LFUN_FONT_ITAL: + case LFUN_FONT_SIZE: + case LFUN_FONT_STATE: + case LFUN_FONT_UNDERLINE: + case LFUN_FOOTNOTE_INSERT: + case LFUN_HFILL_INSERT: + case LFUN_HTML_INSERT: + case LFUN_HYPHENATION_POINT_INSERT: + case LFUN_LIGATURE_BREAK_INSERT: + case LFUN_INDEX_INSERT: + case LFUN_INDEX_PRINT: + case LFUN_LABEL_INSERT: + case LFUN_OPTIONAL_INSERT: + case LFUN_BIBITEM_INSERT: + case LFUN_LINE_INSERT: + case LFUN_PAGEBREAK_INSERT: + case LFUN_CLEARPAGE_INSERT: + case LFUN_CLEARDOUBLEPAGE_INSERT: + case LFUN_LANGUAGE: + case LFUN_LAYOUT: + case LFUN_LAYOUT_PARAGRAPH: + case LFUN_LAYOUT_TABULAR: + case LFUN_MARGINALNOTE_INSERT: + case LFUN_MATH_DISPLAY: + case LFUN_MATH_INSERT: + case LFUN_MATH_MATRIX: + case LFUN_MATH_MODE: + case LFUN_MENU_OPEN: + case LFUN_MENU_SEPARATOR_INSERT: + case LFUN_BRANCH_INSERT: + case LFUN_CHARSTYLE_INSERT: + case LFUN_NOTE_INSERT: + case LFUN_BOX_INSERT: + case LFUN_NOTE_NEXT: + case LFUN_PARAGRAPH_SPACING: + case LFUN_LABEL_GOTO: + case LFUN_REFERENCE_NEXT: + case LFUN_SPACE_INSERT: + case LFUN_SERVER_GOTO_FILE_ROW: + case LFUN_SERVER_NOTIFY: + case LFUN_SERVER_SET_XY: + case LFUN_TABULAR_INSERT: + case LFUN_TOC_INSERT: + case LFUN_URL_INSERT: + case LFUN_FLOAT_LIST: + case LFUN_INSET_INSERT: + case LFUN_PARAGRAPH_PARAMS_APPLY: + case LFUN_PARAGRAPH_UPDATE: + case LFUN_NOMENCL_INSERT: + case LFUN_NOMENCL_PRINT: + case LFUN_NOACTION: + status.enabled(false); + return true; + + case LFUN_QUOTE_INSERT: + case LFUN_INSET_MODIFY: + case LFUN_PASTE: + case LFUN_CLIPBOARD_PASTE: + case LFUN_PRIMARY_SELECTION_PASTE: + status.enabled(true); + return true; + + // this one is difficult to get right. As a half-baked + // solution, we consider only the first action of the sequence + case LFUN_COMMAND_SEQUENCE: { + // argument contains ';'-terminated commands + string const firstcmd = token(to_utf8(cmd.argument()), ';', 0); + FuncRequest func(lyxaction.lookupFunc(firstcmd)); + func.origin = cmd.origin; + return getStatus(cur, func, status); + } + + default: + return InsetCollapsable::getStatus(cur, cmd, status); } - return la; } -void InsetERT::setButtonLabel() const +void InsetERT::setButtonLabel() { - setLabel(status_ == Collapsed ? getNewLabel() : _("ERT")); + // FIXME UNICODE + setLabel(isOpen() ? _("ERT") : getNewLabel(_("ERT"))); } -bool InsetERT::checkInsertChar(LyXFont & /* font */) +bool InsetERT::insetAllowed(InsetBase::Code /* code */) const { -#ifdef SET_HARD_FONT - LyXFont font(LyXFont::ALL_INHERIT, latex_language); - font.setFamily(LyXFont::TYPEWRITER_FAMILY); - font.setColor(LColor::latex); -#endif - return true; + return false; } -void InsetERT::metrics(MetricsInfo & mi, Dimension & dim) const +bool InsetERT::metrics(MetricsInfo & mi, Dimension & dim) const { - setButtonLabel(); - if (inlined()) - inset.metrics(mi, dim); - else - InsetCollapsable::metrics(mi, dim); - // Make it stand out on its own as it is code, not part of running - // text: - if (isOpen() && !inlined()) - dim.wid = mi.base.textwidth; + LyXFont tmpfont = mi.base.font; + getDrawFont(mi.base.font); + mi.base.font.realize(tmpfont); + InsetCollapsable::metrics(mi, dim); + mi.base.font = tmpfont; + bool const changed = dim_ != dim; dim_ = dim; + return changed; } void InsetERT::draw(PainterInfo & pi, int x, int y) const { - InsetCollapsable::draw(pi, x, y, inlined()); -} - - -void InsetERT::setLatexFont(BufferView * /*bv*/) -{ -#ifdef SET_HARD_FONT - LyXFont font(LyXFont::ALL_INHERIT, latex_language); - font.setFamily(LyXFont::TYPEWRITER_FAMILY); - font.setColor(LColor::latex); - inset.text_.setFont(bv, font, false); -#endif -} - - -void InsetERT::status(ERTStatus const st) const -{ - if (st == status_) - return; - - status_ = st; - - switch (st) { - case Inlined: - break; - case Open: - setCollapsed(false); - setButtonLabel(); - break; - case Collapsed: - setCollapsed(true); - setButtonLabel(); - break; - } + LyXFont tmpfont = pi.base.font; + getDrawFont(pi.base.font); + pi.base.font.realize(tmpfont); + InsetCollapsable::draw(pi, x, y); + pi.base.font = tmpfont; } @@ -553,22 +427,6 @@ bool InsetERT::showInsetDialog(BufferView * bv) const } -void InsetERT::open() -{ - if (!isOpen()) - status(Open); -} - - -void InsetERT::close() const -{ - if (status_ == Collapsed || status_ == Inlined) - return; - - status(Collapsed); -} - - void InsetERT::getDrawFont(LyXFont & font) const { font = LyXFont(LyXFont::ALL_INHERIT, latex_language); @@ -591,21 +449,35 @@ string const InsetERTMailer::inset2string(Buffer const &) const void InsetERTMailer::string2params(string const & in, - InsetERT::ERTStatus & status) + InsetCollapsable::CollapseStatus & status) { - status = InsetERT::Collapsed; + status = InsetCollapsable::Collapsed; + if (in.empty()) + return; - string name; - string body = split(in, name, ' '); + istringstream data(in); + LyXLex lex(0,0); + lex.setStream(data); - if (body.empty()) - return; + string name; + lex >> name; + if (name != name_) + return print_mailer_error("InsetERTMailer", in, 1, name_); - status = static_cast(strToInt(body)); + int s; + lex >> s; + if (lex) + status = static_cast(s); } -string const InsetERTMailer::params2string(InsetERT::ERTStatus status) +string const +InsetERTMailer::params2string(InsetCollapsable::CollapseStatus status) { - return name_ + ' ' + tostr(status); + ostringstream data; + data << name_ << ' ' << status; + return data.str(); } + + +} // namespace lyx