From aedfb81808d837df00947e8ac86f8941045e538c Mon Sep 17 00:00:00 2001 From: Vincent van Ravesteijn Date: Sat, 21 Feb 2009 16:27:00 +0000 Subject: [PATCH] Fix bug 4346: http://bugzilla.lyx.org/show_bug.cgi?id=4346. Synchronizing insets asserts with two views open It changes the autoOpen_ member of InsetCollapsable into a map, such that an autoOpen value can be specified for each bufferView. Now, the assertion is avoided and insetCollapsable can be open in one bufferview and be closed in the other in very special cases that the cursor end up in a closed inset. Compare with the MathMacro::editing_ member. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@28573 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/insets/InsetBranch.cpp | 12 +++--- src/insets/InsetBranch.h | 2 +- src/insets/InsetCollapsable.cpp | 71 +++++++++++++++++---------------- src/insets/InsetCollapsable.h | 16 ++++---- src/insets/InsetERT.cpp | 6 +-- src/insets/InsetERT.h | 2 +- src/insets/InsetFloat.cpp | 2 +- src/insets/InsetFoot.cpp | 2 +- src/insets/InsetListings.cpp | 4 +- src/insets/InsetListings.h | 2 +- src/insets/InsetWrap.cpp | 2 +- 11 files changed, 62 insertions(+), 59 deletions(-) diff --git a/src/insets/InsetBranch.cpp b/src/insets/InsetBranch.cpp index d28ba0deea..4bc330b3ad 100644 --- a/src/insets/InsetBranch.cpp +++ b/src/insets/InsetBranch.cpp @@ -81,7 +81,7 @@ docstring InsetBranch::toolTip(BufferView const &, int, int) const } -void InsetBranch::setButtonLabel() +void InsetBranch::setButtonLabel(BufferView const & bv) { docstring s = _("Branch: ") + params_.branch; if (!params_.branch.empty()) { @@ -91,7 +91,7 @@ void InsetBranch::setButtonLabel() s = _("Undef: ") + s; } if (decoration() == InsetLayout::CLASSIC) - setLabel(isOpen() ? s : getNewLabel(s) ); + setLabel(isOpen(bv) ? s : getNewLabel(s) ); else setLabel(params_.branch + ": " + getNewLabel(s)); } @@ -143,12 +143,12 @@ void InsetBranch::doDispatch(Cursor & cur, FuncRequest & cmd) if (cmd.argument() == "assign") { // The branch inset uses "assign". if (isBranchSelected()) { - if (status() != Open) + if (status(cur.bv()) != Open) setStatus(cur, Open); else cur.undispatched(); } else { - if (status() != Collapsed) + if (status(cur.bv()) != Collapsed) setStatus(cur, Collapsed); else cur.undispatched(); @@ -180,9 +180,9 @@ bool InsetBranch::getStatus(Cursor & cur, FuncRequest const & cmd, flag.setEnabled(true); else if (cmd.argument() == "assign" || cmd.argument().empty()) { if (isBranchSelected()) - flag.setEnabled(status() != Open); + flag.setEnabled(status(cur.bv()) != Open); else - flag.setEnabled(status() != Collapsed); + flag.setEnabled(status(cur.bv()) != Collapsed); } else flag.setEnabled(true); break; diff --git a/src/insets/InsetBranch.h b/src/insets/InsetBranch.h index 67fde95cf8..71591a127a 100644 --- a/src/insets/InsetBranch.h +++ b/src/insets/InsetBranch.h @@ -62,7 +62,7 @@ private: /// void read(Lexer & lex); /// - void setButtonLabel(); + void setButtonLabel(BufferView const & bv); /// ColorCode backgroundColor() const; /// diff --git a/src/insets/InsetCollapsable.cpp b/src/insets/InsetCollapsable.cpp index 31e3daf33c..6c5a44bbef 100644 --- a/src/insets/InsetCollapsable.cpp +++ b/src/insets/InsetCollapsable.cpp @@ -46,27 +46,27 @@ using namespace std; namespace lyx { -InsetCollapsable::CollapseStatus InsetCollapsable::status() const +InsetCollapsable::CollapseStatus InsetCollapsable::status(BufferView const & bv) const { if (decoration() == InsetLayout::CONGLOMERATE) return status_; - return autoOpen_ ? Open : status_; + return auto_open_[&bv] ? Open : status_; } -InsetCollapsable::Geometry InsetCollapsable::geometry() const +InsetCollapsable::Geometry InsetCollapsable::geometry(BufferView const & bv) const { switch (decoration()) { case InsetLayout::CLASSIC: - if (status() == Open) + if (status(bv) == Open) return openinlined_ ? LeftButton : TopButton; return ButtonOnly; case InsetLayout::MINIMALISTIC: - return status() == Open ? NoButton : ButtonOnly ; + return status(bv) == Open ? NoButton : ButtonOnly ; case InsetLayout::CONGLOMERATE: - return status() == Open ? SubLabel : Corners ; + return status(bv) == Open ? SubLabel : Corners ; case InsetLayout::DEFAULT: break; // this shouldn't happen @@ -80,7 +80,7 @@ InsetCollapsable::Geometry InsetCollapsable::geometry() const InsetCollapsable::InsetCollapsable(Buffer const & buf) : InsetText(buf), status_(Inset::Open), - openinlined_(false), autoOpen_(false), mouse_hover_(false) + openinlined_(false), mouse_hover_(false) { DocumentClass const & dc = buf.params().documentClass(); setLayout(&dc); @@ -98,7 +98,7 @@ InsetCollapsable::InsetCollapsable(InsetCollapsable const & rhs) labelstring_(rhs.labelstring_), button_dim(rhs.button_dim), openinlined_(rhs.openinlined_), - autoOpen_(rhs.autoOpen_), + auto_open_(rhs.auto_open_), // the sole purpose of this copy constructor mouse_hover_(false) { @@ -108,9 +108,9 @@ InsetCollapsable::InsetCollapsable(InsetCollapsable const & rhs) docstring InsetCollapsable::toolTip(BufferView const & bv, int x, int y) const { Dimension dim = dimensionCollapsed(); - if (geometry() == NoButton) + if (geometry(bv) == NoButton) return translateIfPossible(layout_->labelstring()); - if (x > xo(bv) + dim.wid || y > yo(bv) + dim.des || isOpen()) + if (x > xo(bv) + dim.wid || y > yo(bv) + dim.des || isOpen(bv)) return docstring(); OutputParams rp(&buffer().params().encoding()); @@ -201,13 +201,13 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const { LASSERT(layout_, /**/); - autoOpen_ = 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 = layout_->font(); mi.base.font.realize(tmpfont); - switch (geometry()) { + switch (geometry(*mi.base.bv)) { case NoButton: InsetText::metrics(mi, dim); break; @@ -234,7 +234,8 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const case LeftButton: case ButtonOnly: dim = dimensionCollapsed(); - if (geometry() == TopButton || geometry() == LeftButton) { + if (geometry(*mi.base.bv) == TopButton + || geometry(*mi.base.bv) == LeftButton) { Dimension textdim; InsetText::metrics(mi, textdim); openinlined_ = (textdim.wid + dim.wid) < mi.base.textwidth; @@ -266,7 +267,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const { LASSERT(layout_, /**/); - autoOpen_ = pi.base.bv->cursor().isInside(this); + auto_open_[pi.base.bv] = pi.base.bv->cursor().isInside(this); FontInfo tmpfont = pi.base.font; pi.base.font = layout_->font(); @@ -275,9 +276,9 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const // Draw button first -- top, left or only Dimension dimc = dimensionCollapsed(); - if (geometry() == TopButton || - geometry() == LeftButton || - geometry() == ButtonOnly) { + if (geometry(*pi.base.bv) == TopButton || + geometry(*pi.base.bv) == LeftButton || + geometry(*pi.base.bv) == ButtonOnly) { button_dim.x1 = x + 0; button_dim.x2 = x + dimc.width(); button_dim.y1 = y - dimc.asc; @@ -295,7 +296,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const Dimension const textdim = InsetText::dimension(*pi.base.bv); int const baseline = y; int textx, texty; - switch (geometry()) { + switch (geometry(*pi.base.bv)) { case LeftButton: textx = x + dimc.width(); texty = baseline; @@ -322,7 +323,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const const_cast(this)->setDrawFrame(true); int desc = textdim.descent(); - if (geometry() == Corners) + if (geometry(*pi.base.bv) == Corners) desc -= 3; const int xx1 = x + TEXT_TO_INSET_OFFSET - 1; @@ -347,7 +348,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const y + desc - 4, layout_->labelfont().color()); // the label below the text. Can be toggled. - if (geometry() == SubLabel) { + if (geometry(*pi.base.bv) == SubLabel) { FontInfo font(layout_->labelfont()); font.realize(sane_font); font.decSize(); @@ -384,14 +385,14 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const void InsetCollapsable::cursorPos(BufferView const & bv, CursorSlice const & sl, bool boundary, int & x, int & y) const { - if (geometry() == ButtonOnly) + if (geometry(bv) == ButtonOnly) status_ = Open; - LASSERT(geometry() != ButtonOnly, /**/); + LASSERT(geometry(bv) != ButtonOnly, /**/); InsetText::cursorPos(bv, sl, boundary, x, y); Dimension const textdim = InsetText::dimension(bv); - switch (geometry()) { + switch (geometry(bv)) { case LeftButton: x += dimensionCollapsed().wid; break; @@ -411,15 +412,15 @@ void InsetCollapsable::cursorPos(BufferView const & bv, } -Inset::EDITABLE InsetCollapsable::editable() const +Inset::EDITABLE InsetCollapsable::editable(BufferView const & bv) const { - return geometry() != ButtonOnly ? HIGHLY_EDITABLE : IS_EDITABLE; + return geometry(bv) != ButtonOnly ? HIGHLY_EDITABLE : IS_EDITABLE; } -bool InsetCollapsable::descendable() const +bool InsetCollapsable::descendable(BufferView const & bv) const { - return geometry() != ButtonOnly; + return geometry(bv) != ButtonOnly; } @@ -461,9 +462,9 @@ void InsetCollapsable::edit(Cursor & cur, bool front, EntryDirection entry_from) Inset * InsetCollapsable::editXY(Cursor & cur, int x, int y) { //lyxerr << "InsetCollapsable: edit xy" << endl; - if (geometry() == ButtonOnly + if (geometry(cur.bv()) == ButtonOnly || (button_dim.contains(x, y) - && geometry() != NoButton)) + && geometry(cur.bv()) != NoButton)) return this; cur.push(*this); return InsetText::editXY(cur, x, y); @@ -493,7 +494,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) cur.noUpdate(); break; } - } else if (geometry() != ButtonOnly) + } else if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); else cur.undispatched(); @@ -504,7 +505,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MOUSE_TRIPLE: if (hitButton(cmd)) cur.noUpdate(); - else if (geometry() != ButtonOnly) + else if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); else cur.undispatched(); @@ -513,7 +514,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MOUSE_RELEASE: if (!hitButton(cmd)) { // The mouse click has to be within the inset! - if (geometry() != ButtonOnly) + if (geometry(cur.bv()) != ButtonOnly) InsetText::doDispatch(cur, cmd); else cur.undispatched(); @@ -532,7 +533,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) // toggle the inset visual state. cur.dispatched(); cur.updateFlags(Update::Force | Update::FitCursor); - if (geometry() == ButtonOnly) { + if (geometry(cur.bv()) == ButtonOnly) { setStatus(cur, Open); edit(cur, true); } @@ -549,7 +550,7 @@ void InsetCollapsable::doDispatch(Cursor & cur, FuncRequest & cmd) else if (cmd.argument() == "toggle" || cmd.argument().empty()) if (status_ == Open) { setStatus(cur, Collapsed); - if (geometry() == ButtonOnly) + if (geometry(cur.bv()) == ButtonOnly) cur.top().forwardPos(); } else setStatus(cur, Open); @@ -867,7 +868,7 @@ docstring InsetCollapsable::contextMenu(BufferView const & bv, int x, if (decoration() == InsetLayout::CONGLOMERATE) return from_ascii("context-conglomerate"); - if (geometry() == NoButton) + if (geometry(bv) == NoButton) return from_ascii("context-collapsable"); Dimension dim = dimensionCollapsed(); diff --git a/src/insets/InsetCollapsable.h b/src/insets/InsetCollapsable.h index 8610516002..88055b4ba0 100644 --- a/src/insets/InsetCollapsable.h +++ b/src/insets/InsetCollapsable.h @@ -78,17 +78,18 @@ public: /// docstring const getNewLabel(docstring const & l) const; /// - EDITABLE editable() const; + EDITABLE editable(BufferView const & bv) const; /// can we go further down on mouse click? - bool descendable() const; + bool descendable(BufferView const & bv) const; /// void setLabel(docstring const & l); /// virtual void setButtonLabel() {} /// - bool isOpen() const { return geometry() != ButtonOnly; } + bool isOpen(BufferView const & bv) const + { return geometry(bv) != ButtonOnly; } /// - CollapseStatus status() const; + CollapseStatus status(BufferView const & bv) const; /** Of the old CollapseStatus we only keep the values * Open and Collapsed. * We define a list of possible inset decoration @@ -122,7 +123,7 @@ public: /// Returns the geometry based on CollapseStatus /// (status_), autoOpen_ and openinlined_, and of /// course decoration(). - Geometry geometry() const; + Geometry geometry(BufferView const & bv) const; /// Allow spellchecking, except for insets with latex_language bool allowSpellCheck() const { return !forceLTR(); } /// @@ -190,8 +191,9 @@ private: mutable Box button_dim; /// a substatus of the Open status, determined automatically in metrics mutable bool openinlined_; - /// the inset will automatically open when the cursor is inside - mutable bool autoOpen_; + /// the inset will automatically open when the cursor is inside. This is + /// dependent on the bufferview, compare with MathMacro::editing_. + mutable std::map auto_open_; /// changes color when mouse enters/leaves this inset bool mouse_hover_; }; diff --git a/src/insets/InsetERT.cpp b/src/insets/InsetERT.cpp index bc4756a5d8..de911557c7 100644 --- a/src/insets/InsetERT.cpp +++ b/src/insets/InsetERT.cpp @@ -162,10 +162,10 @@ bool InsetERT::getStatus(Cursor & cur, FuncRequest const & cmd, } -void InsetERT::setButtonLabel() +void InsetERT::setButtonLabel(BufferView const & bv) { if (decoration() == InsetLayout::CLASSIC) - setLabel(isOpen() ? _("ERT") : getNewLabel(_("ERT"))); + setLabel(isOpen(bv) ? _("ERT") : getNewLabel(_("ERT"))); else setLabel(getNewLabel(_("ERT"))); } @@ -179,7 +179,7 @@ bool InsetERT::insetAllowed(InsetCode /* code */) const bool InsetERT::showInsetDialog(BufferView * bv) const { - bv->showDialog("ert", params2string(status()), + bv->showDialog("ert", params2string(status(*bv)), const_cast(this)); return true; } diff --git a/src/insets/InsetERT.h b/src/insets/InsetERT.h index 1a81775ac4..2df001b3e0 100644 --- a/src/insets/InsetERT.h +++ b/src/insets/InsetERT.h @@ -69,7 +69,7 @@ private: /// Inset * clone() const { return new InsetERT(*this); } /// - void setButtonLabel(); + void setButtonLabel(BufferView const & bv); /// bool allowSpellCheck() const { return false; } }; diff --git a/src/insets/InsetFloat.cpp b/src/insets/InsetFloat.cpp index 0dfe34326b..37a247af44 100644 --- a/src/insets/InsetFloat.cpp +++ b/src/insets/InsetFloat.cpp @@ -135,7 +135,7 @@ docstring InsetFloat::name() const docstring InsetFloat::toolTip(BufferView const & bv, int x, int y) const { - if (InsetCollapsable::toolTip(bv, x, y).empty() || isOpen()) + if (InsetCollapsable::toolTip(bv, x, y).empty() || isOpen(bv)) return docstring(); OutputParams rp(&buffer().params().encoding()); diff --git a/src/insets/InsetFoot.cpp b/src/insets/InsetFoot.cpp index 615171d0e2..66654e6cb7 100644 --- a/src/insets/InsetFoot.cpp +++ b/src/insets/InsetFoot.cpp @@ -81,7 +81,7 @@ void InsetFoot::addToToc(DocIterator const & cpit) docstring InsetFoot::toolTip(BufferView const & bv, int x, int y) const { docstring default_tip = InsetCollapsable::toolTip(bv, x, y); - if (!isOpen()) + if (!isOpen(bv)) return custom_label_ + ": " + default_tip; return default_tip; } diff --git a/src/insets/InsetListings.cpp b/src/insets/InsetListings.cpp index 647d401386..035da731f2 100644 --- a/src/insets/InsetListings.cpp +++ b/src/insets/InsetListings.cpp @@ -397,11 +397,11 @@ bool InsetListings::getStatus(Cursor & cur, FuncRequest const & cmd, } -void InsetListings::setButtonLabel() +void InsetListings::setButtonLabel(BufferView const & bv) { // FIXME UNICODE if (decoration() == InsetLayout::CLASSIC) - setLabel(isOpen() ? _("Listing") : getNewLabel(_("Listing"))); + setLabel(isOpen(bv) ? _("Listing") : getNewLabel(_("Listing"))); else setLabel(getNewLabel(_("Listing"))); } diff --git a/src/insets/InsetListings.h b/src/insets/InsetListings.h index a1eeeda315..09d1ac7300 100644 --- a/src/insets/InsetListings.h +++ b/src/insets/InsetListings.h @@ -73,7 +73,7 @@ private: /// Inset * clone() const { return new InsetListings(*this); } /// - void setButtonLabel(); + void setButtonLabel(BufferView const & bv); /// docstring getCaption(OutputParams const &) const; diff --git a/src/insets/InsetWrap.cpp b/src/insets/InsetWrap.cpp index 566ba91d73..c21d222507 100644 --- a/src/insets/InsetWrap.cpp +++ b/src/insets/InsetWrap.cpp @@ -71,7 +71,7 @@ docstring InsetWrap::toolTip(BufferView const & bv, int x, int y) const OutputParams rp(&buffer().params().encoding()); docstring default_tip = InsetCollapsable::toolTip(bv, x, y); docstring caption_tip = getCaptionText(rp); - if (!isOpen() && !caption_tip.empty()) + if (!isOpen(bv) && !caption_tip.empty()) return caption_tip + '\n' + default_tip; return default_tip; }