X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetCollapsable.cpp;h=6e5051ef5fd90b141e9d618258fa46fd34f79dad;hb=c9d9309c1ecffa218dee04ce4f7991ed4fc0c9bb;hp=5a2e9b67dd58c7f651b024ff23fdf77de08f0582;hpb=ace4f7d3b868bab8ebcf32319ce70527073d87ae;p=lyx.git diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp index 5a2e9b67dd..6e5051ef5f 100644 --- a/src/insets/InsetCollapsable.cpp +++ b/src/insets/InsetCollapsable.cpp @@ -19,20 +19,13 @@ #include "BufferView.h" #include "Cursor.h" #include "Dimension.h" -#include "DispatchResult.h" #include "FloatList.h" #include "FuncRequest.h" #include "FuncStatus.h" #include "InsetLayout.h" -#include "InsetList.h" -#include "Language.h" #include "Lexer.h" #include "MetricsInfo.h" -#include "output_xhtml.h" #include "OutputParams.h" -#include "paragraph_funcs.h" -#include "ParagraphParameters.h" -#include "sgml.h" #include "TextClass.h" #include "frontends/FontMetrics.h" @@ -49,6 +42,35 @@ using namespace std; namespace lyx { +InsetCollapsable::InsetCollapsable(Buffer * buf, InsetText::UsePlain ltype) + : InsetText(buf, ltype), status_(Open), openinlined_(false) +{ + setDrawFrame(true); + setFrameColor(Color_collapsableframe); +} + + +// The sole purpose of this copy constructor is to make sure +// that the mouse_hover_ map is not copied and remains empty. +InsetCollapsable::InsetCollapsable(InsetCollapsable const & rhs) + : InsetText(rhs), + status_(rhs.status_), + labelstring_(rhs.labelstring_), + button_dim(rhs.button_dim), + openinlined_(rhs.openinlined_) +{} + + +InsetCollapsable::~InsetCollapsable() +{ + map::iterator it = mouse_hover_.begin(); + map::iterator end = mouse_hover_.end(); + for (; it != end; ++it) + if (it->second) + it->first->clearLastInset(this); +} + + InsetCollapsable::CollapseStatus InsetCollapsable::status(BufferView const & bv) const { if (decoration() == InsetLayout::CONGLOMERATE) @@ -105,42 +127,15 @@ InsetCollapsable::Geometry InsetCollapsable::geometry() const } -InsetCollapsable::InsetCollapsable(Buffer const & buf, InsetText::UsePlain ltype) - : InsetText(buf, ltype), status_(Inset::Open), - openinlined_(false), mouse_hover_(false) -{ - setAutoBreakRows(true); - setDrawFrame(true); - setFrameColor(Color_collapsableframe); -} - - -InsetCollapsable::InsetCollapsable(InsetCollapsable const & rhs) - : InsetText(rhs), - status_(rhs.status_), - labelstring_(rhs.labelstring_), - button_dim(rhs.button_dim), - openinlined_(rhs.openinlined_), - auto_open_(rhs.auto_open_), - // the sole purpose of this copy constructor - mouse_hover_(false) -{ -} - - docstring InsetCollapsable::toolTip(BufferView const & bv, int x, int y) const { - Dimension dim = dimensionCollapsed(bv); + Dimension const dim = dimensionCollapsed(bv); if (geometry(bv) == NoButton) return translateIfPossible(getLayout().labelstring()); if (x > xo(bv) + dim.wid || y > yo(bv) + dim.des || isOpen(bv)) return docstring(); - OutputParams rp(&buffer().params().encoding()); - odocstringstream ods; - InsetText::plaintext(ods, rp); - docstring const content_tip = ods.str(); - return support::wrapParas(content_tip, 4); + return toolTipText(); } @@ -156,7 +151,7 @@ void InsetCollapsable::write(ostream & os) const break; } os << "\n"; - text().write(buffer(), os); + text().write(os); } @@ -177,7 +172,9 @@ void InsetCollapsable::read(Lexer & lex) Dimension InsetCollapsable::dimensionCollapsed(BufferView const & bv) const { Dimension dim; - theFontMetrics(getLayout().labelfont()).buttonText( + FontInfo labelfont(getLabelfont()); + labelfont.realize(sane_font); + theFontMetrics(labelfont).buttonText( buttonLabel(bv), dim.wid, dim.asc, dim.des); return dim; } @@ -185,10 +182,10 @@ Dimension InsetCollapsable::dimensionCollapsed(BufferView const & bv) const void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const { - auto_open_[mi.base.bv] = mi.base.bv->cursor().isInside(this); + auto_open_[mi.base.bv] = mi.base.bv->cursor().isInside(this); FontInfo tmpfont = mi.base.font; - mi.base.font = getLayout().font(); + mi.base.font = getFont(); mi.base.font.realize(tmpfont); BufferView const & bv = *mi.base.bv; @@ -205,7 +202,7 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const case SubLabel: { InsetText::metrics(mi, dim); // consider width of the inset label - FontInfo font(getLayout().labelfont()); + FontInfo font(getLabelfont()); font.realize(sane_font); font.decSize(); font.decSize(); @@ -242,9 +239,10 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const } -bool InsetCollapsable::setMouseHover(bool mouse_hover) +bool InsetCollapsable::setMouseHover(BufferView const * bv, bool mouse_hover) + const { - mouse_hover_ = mouse_hover; + mouse_hover_[bv] = mouse_hover; return true; } @@ -253,27 +251,27 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const { BufferView const & bv = *pi.base.bv; - auto_open_[&bv] = bv.cursor().isInside(this); + auto_open_[&bv] = bv.cursor().isInside(this); FontInfo tmpfont = pi.base.font; - pi.base.font = getLayout().font(); + pi.base.font = getFont(); pi.base.font.realize(tmpfont); // Draw button first -- top, left or only Dimension dimc = dimensionCollapsed(bv); - if (geometry(*pi.base.bv) == TopButton || - geometry(*pi.base.bv) == LeftButton || - geometry(*pi.base.bv) == ButtonOnly) { + if (geometry(bv) == TopButton || + geometry(bv) == LeftButton || + geometry(bv) == ButtonOnly) { button_dim.x1 = x + 0; button_dim.x2 = x + dimc.width(); button_dim.y1 = y - dimc.asc; button_dim.y2 = y + dimc.des; - FontInfo labelfont = getLayout().labelfont(); + FontInfo labelfont = getLabelfont(); labelfont.setColor(labelColor()); pi.pain.buttonText(x, y, buttonLabel(bv), labelfont, - mouse_hover_); + mouse_hover_[&bv]); } else { button_dim.x1 = 0; button_dim.y1 = 0; @@ -318,26 +316,26 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const const int xx2 = x + textdim.wid - TEXT_TO_INSET_OFFSET + 1; pi.pain.line(xx1, y + desc - 4, xx1, y + desc, - labelColor()); + Color_foreground); if (status_ == Open) pi.pain.line(xx1, y + desc, xx2, y + desc, - labelColor()); + Color_foreground); else { // Make status_ value visible: pi.pain.line(xx1, y + desc, xx1 + 4, y + desc, - labelColor()); + Color_foreground); pi.pain.line(xx2 - 4, y + desc, xx2, y + desc, - labelColor()); + Color_foreground); } pi.pain.line(x + textdim.wid - 3, y + desc, x + textdim.wid - 3, - y + desc - 4, labelColor()); + y + desc - 4, Color_foreground); // the label below the text. Can be toggled. if (geometry(bv) == SubLabel) { - FontInfo font(getLayout().labelfont()); + FontInfo font(getLabelfont()); font.realize(sane_font); font.decSize(); font.decSize(); @@ -356,12 +354,10 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const if (cur.isInside(this)) { y -= textdim.asc; y += 3; - pi.pain.line(xx1, y + 4, xx1, y, labelColor()); - pi.pain.line(xx1 + 4, y, xx1, y, labelColor()); - pi.pain.line(xx2, y + 4, xx2, y, - labelColor()); - pi.pain.line(xx2 - 4, y, xx2, y, - labelColor()); + pi.pain.line(xx1, y + 4, xx1, y, Color_foreground); + pi.pain.line(xx1 + 4, y, xx1, y, Color_foreground); + pi.pain.line(xx2, y + 4, xx2, y, Color_foreground); + pi.pain.line(xx2 - 4, y, xx2, y, Color_foreground); } break; } @@ -375,7 +371,6 @@ void InsetCollapsable::cursorPos(BufferView const & bv, { if (geometry(bv) == ButtonOnly) status_ = Open; - LASSERT(geometry(bv) != ButtonOnly, /**/); InsetText::cursorPos(bv, sl, boundary, x, y); Dimension const textdim = InsetText::dimension(bv); @@ -406,15 +401,22 @@ bool InsetCollapsable::editable() const } -bool InsetCollapsable::descendable() const +bool InsetCollapsable::descendable(BufferView const & bv) const { - return geometry() != ButtonOnly; + return geometry(bv) != ButtonOnly; } bool InsetCollapsable::hitButton(FuncRequest const & cmd) const { - return button_dim.contains(cmd.x, cmd.y); + return button_dim.contains(cmd.x(), cmd.y()); +} + + +bool InsetCollapsable::clickable(int x, int y) const +{ + FuncRequest cmd(LFUN_NOACTION, x, y, mouse_button::none); + return hitButton(cmd); } @@ -464,7 +466,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) //lyxerr << "InsetCollapsable::doDispatch (begin): cmd: " << cmd // << " cur: " << cur << " bvcur: " << cur.bv().cursor() << endl; - switch (cmd.action) { + switch (cmd.action()) { case LFUN_MOUSE_PRESS: if (hitButton(cmd)) { switch (cmd.button()) { @@ -479,7 +481,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) case mouse_button::button4: case mouse_button::button5: // Nothing to do. - cur.noUpdate(); + cur.noScreenUpdate(); break; } } else if (geometry(cur.bv()) != ButtonOnly) @@ -492,7 +494,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MOUSE_DOUBLE: case LFUN_MOUSE_TRIPLE: if (hitButton(cmd)) - cur.noUpdate(); + cur.noScreenUpdate(); else if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); else @@ -510,7 +512,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) } if (cmd.button() != mouse_button::button1) { // Nothing to do. - cur.noUpdate(); + cur.noScreenUpdate(); break; } // if we are selecting, we do not want to @@ -520,7 +522,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) // Left button is clicked, the user asks to // toggle the inset visual state. cur.dispatched(); - cur.updateFlags(Update::Force | Update::FitCursor); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); if (geometry(cur.bv()) == ButtonOnly) { setStatus(cur, Open); edit(cur, true); @@ -536,11 +538,9 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) else if (cmd.argument() == "close") setStatus(cur, Collapsed); else if (cmd.argument() == "toggle" || cmd.argument().empty()) - if (status_ == Open) { + if (status_ == Open) setStatus(cur, Collapsed); - if (geometry(cur.bv()) == ButtonOnly) - cur.top().forwardPos(); - } else + else setStatus(cur, Open); else // if assign or anything else cur.undispatched(); @@ -557,7 +557,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) bool InsetCollapsable::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & flag) const { - switch (cmd.action) { + switch (cmd.action()) { case LFUN_INSET_TOGGLE: if (cmd.argument() == "open") flag.setEnabled(status_ != Open); @@ -582,9 +582,14 @@ void InsetCollapsable::setLabel(docstring const & l) } -docstring const InsetCollapsable::buttonLabel(BufferView const &) const +docstring const InsetCollapsable::buttonLabel(BufferView const & bv) const { - return labelstring_.empty() ? getLayout().labelstring() : labelstring_; + InsetLayout const & il = getLayout(); + docstring const label = labelstring_.empty() ? + translateIfPossible(il.labelstring()) : labelstring_; + if (!il.contentaslabel() || geometry(bv) != ButtonOnly) + return label; + return getNewLabel(label); } @@ -592,10 +597,8 @@ void InsetCollapsable::setStatus(Cursor & cur, CollapseStatus status) { status_ = status; setButtonLabel(); - if (status_ == Collapsed) { + if (status_ == Collapsed) cur.leaveInset(*this); - mouse_hover_ = false; - } } @@ -616,87 +619,35 @@ InsetLayout::InsetDecoration InsetCollapsable::decoration() const } -// FIXME It seems as if it ought to be possible to do this more simply, -// maybe by calling InsetText::docbook() in the middle there. -int InsetCollapsable::docbook(odocstream & os, OutputParams const & runparams) const -{ - ParagraphList::const_iterator const beg = paragraphs().begin(); - ParagraphList::const_iterator par = paragraphs().begin(); - ParagraphList::const_iterator const end = paragraphs().end(); - - if (!undefined()) - sgml::openTag(os, getLayout().latexname(), - par->getID(buffer(), runparams) + getLayout().latexparam()); - - for (; par != end; ++par) { - par->simpleDocBookOnePar(buffer(), os, runparams, - outerFont(distance(beg, par), - paragraphs())); - } - - if (!undefined()) - sgml::closeTag(os, getLayout().latexname()); - - return 0; -} - - -docstring InsetCollapsable::xhtml(odocstream & os, OutputParams const & runparams) const -{ - InsetLayout const & il = getLayout(); - if (undefined()) - return InsetText::xhtml(os, runparams); - - bool const opened = html::openTag(os, il.htmltag(), il.htmlattr()); - if (!il.counter().empty()) { - BufferParams const & bp = buffer().masterBuffer()->params(); - Counters & cntrs = bp.documentClass().counters(); - cntrs.step(il.counter()); - // FIXME: translate to paragraph language - if (!il.htmllabel().empty()) - os << cntrs.counterLabel(from_utf8(il.htmllabel()), bp.language->code()); - } - bool innertag_opened = false; - if (!il.htmlinnertag().empty()) - innertag_opened = html::openTag(os, il.htmlinnertag(), il.htmlinnerattr()); - docstring deferred = InsetText::xhtml(os, runparams); - if (innertag_opened) - html::closeTag(os, il.htmlinnertag()); - if (opened) - html::closeTag(os, il.htmltag()); - return deferred; -} - - -bool InsetCollapsable::undefined() const -{ - docstring const & n = getLayout().name(); - return n.empty() || n == DocumentClass::plainInsetLayout().name(); -} - - -docstring InsetCollapsable::contextMenu(BufferView const & bv, int x, +string InsetCollapsable::contextMenu(BufferView const & bv, int x, int y) const { + string context_menu = contextMenuName(); + string const it_context_menu = InsetText::contextMenuName(); if (decoration() == InsetLayout::CONGLOMERATE) - return from_ascii("context-conglomerate"); + return context_menu + ";" + it_context_menu; + + string const ic_context_menu = InsetCollapsable::contextMenuName(); + if (ic_context_menu != context_menu) + context_menu += ";" + ic_context_menu; if (geometry(bv) == NoButton) - return from_ascii("context-collapsable"); + return context_menu + ";" + it_context_menu; Dimension dim = dimensionCollapsed(bv); if (x < xo(bv) + dim.wid && y < yo(bv) + dim.des) - return from_ascii("context-collapsable"); + return context_menu; - return InsetText::contextMenu(bv, x, y); + return it_context_menu; } -void InsetCollapsable::tocString(odocstream & os) const + +string InsetCollapsable::contextMenuName() const { - if (!getLayout().isInToc()) - return; - os << text().asString(0, 1, AS_STR_LABEL | AS_STR_INSETS); + if (decoration() == InsetLayout::CONGLOMERATE) + return "context-conglomerate"; + else + return "context-collapsable"; } - } // namespace lyx