X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetcollapsable.C;h=59857a0a1bb1ef63b29663450ebaf7715080ac89;hb=62e4adaef2e2434781204df1da791757e54e4431;hp=1732465503c77c327d291f708ff4512e31987f9e;hpb=50d4d2bd7e78cc20c323d4d7adcfe164c01e0d15;p=lyx.git diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index 1732465503..59857a0a1b 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -13,126 +13,140 @@ #include #include "insetcollapsable.h" -#include "insettext.h" +#include "buffer.h" #include "BufferView.h" +#include "cursor.h" #include "debug.h" -#include "dimension.h" -#include "gettext.h" -#include "lyxfont.h" +#include "dispatchresult.h" +#include "LColor.h" #include "lyxlex.h" -#include "lyxtext.h" -#include "WordLangTuple.h" #include "funcrequest.h" -#include "buffer.h" #include "metricsinfo.h" +#include "paragraph.h" #include "frontends/font_metrics.h" #include "frontends/Painter.h" #include "frontends/LyXView.h" -#include "support/LAssert.h" -#include "support/LOstream.h" -using namespace lyx::support; -using namespace lyx::graphics; +using lyx::graphics::PreviewLoader; -using std::vector; -using std::ostream; using std::endl; +using std::string; using std::max; +using std::min; +using std::ostream; -InsetCollapsable::InsetCollapsable(BufferParams const & bp, bool collapsed) - : UpdatableInset(), collapsed_(collapsed), inset(bp), - button_dim(0, 0, 0, 0), label("Label"), -#if 0 - autocollapse(false), -#endif - in_update(false), first_after_edit(false) +InsetCollapsable::InsetCollapsable(BufferParams const & bp, + CollapseStatus status) + : inset(bp), label("Label"), status_(status) { inset.setOwner(this); inset.setAutoBreakRows(true); inset.setDrawFrame(InsetText::ALWAYS); inset.setFrameColor(LColor::collapsableframe); setInsetName("Collapsable"); + setButtonLabel(); } InsetCollapsable::InsetCollapsable(InsetCollapsable const & in) - : UpdatableInset(in), collapsed_(in.collapsed_), - framecolor(in.framecolor), labelfont(in.labelfont), inset(in.inset), - button_dim(0, 0, 0, 0), label(in.label), -#if 0 - autocollapse(in.autocollapse), -#endif - in_update(false), first_after_edit(false) -{ - inset.init(&(in.inset)); - inset.setOwner(this); -} - - -bool InsetCollapsable::insertInset(BufferView * bv, InsetOld * in) + : UpdatableInset(in), inset(in.inset), + labelfont_(in.labelfont_), label(in.label), status_(in.status_) { - if (!insetAllowed(in->lyxCode())) { - lyxerr << "InsetCollapsable::InsertInset: " - "Unable to insert inset." << endl; - return false; - } - return inset.insertInset(bv, in); + inset.setOwner(this); + setButtonLabel(); } void InsetCollapsable::write(Buffer const & buf, ostream & os) const { - os << "collapsed " << (collapsed_ ? "true" : "false") << "\n"; - inset.writeParagraphData(buf, os); + os << "status "; + switch (status_) { + case Open: + os << "open"; + break; + case Collapsed: + os << "collapsed"; + break; + case Inlined: + os << "inlined"; + break; + } + os << "\n"; + inset.text_.write(buf, os); } void InsetCollapsable::read(Buffer const & buf, LyXLex & lex) { + bool token_found = false; if (lex.isOK()) { lex.next(); string const token = lex.getString(); - if (token == "collapsed") { + if (token == "status") { lex.next(); - collapsed_ = lex.getBool(); + string const tmp_token = lex.getString(); + + if (tmp_token == "inlined") { + status_ = Inlined; + token_found = true; + } else if (tmp_token == "collapsed") { + status_ = Collapsed; + token_found = true; + } else if (tmp_token == "open") { + status_ = Open; + token_found = true; + } else { + lyxerr << "InsetCollapsable::read: Missing status!" + << endl; + // Take countermeasures + lex.pushToken(token); + } } else { - lyxerr << "InsetCollapsable::Read: Missing collapsed!" - << endl; - // Take countermeasures + lyxerr << "InsetCollapsable::Read: Missing 'status'-tag!" + << endl; + // take countermeasures lex.pushToken(token); } } inset.read(buf, lex); + + if (!token_found) + status_ = isOpen() ? Open : Collapsed; + + setButtonLabel(); } void InsetCollapsable::dimension_collapsed(Dimension & dim) const { - font_metrics::buttonText(label, labelfont, dim.wid, dim.asc, dim.des); + font_metrics::buttonText(label, labelfont_, dim.wid, dim.asc, dim.des); } int InsetCollapsable::height_collapsed() const { Dimension dim; - font_metrics::buttonText(label, labelfont, dim.wid, dim.asc, dim.des); + font_metrics::buttonText(label, labelfont_, dim.wid, dim.asc, dim.des); return dim.asc + dim.des; } void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const { - //lyxerr << "InsetCollapsable::metrics: width: " << mi.base.textwidth << endl; - dimension_collapsed(dim); - if (!collapsed_) { - Dimension insetdim; - inset.metrics(mi, insetdim); - dim.des += insetdim.height() + TEXT_TO_BOTTOM_OFFSET; - dim.wid = max(dim.wid, insetdim.wid); + if (status_ == Inlined) { + inset.metrics(mi, dim); + } else { + dimension_collapsed(dim); + if (status_ == Open) { + Dimension insetdim; + inset.metrics(mi, insetdim); + dim.des += insetdim.height() + TEXT_TO_BOTTOM_OFFSET; + dim.wid = max(dim.wid, insetdim.wid); + } } dim_ = dim; } @@ -140,139 +154,106 @@ void InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const void InsetCollapsable::draw_collapsed(PainterInfo & pi, int x, int y) const { - pi.pain.buttonText(x, y, label, labelfont); + pi.pain.buttonText(x, y, label, labelfont_); } -void InsetCollapsable::draw(PainterInfo & pi, int x, int y, bool inlined) const +void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const { - Assert(pi.base.bv); - cache(pi.base.bv); - - Dimension dim_collapsed; - dimension_collapsed(dim_collapsed); - - int const aa = ascent(); - button_dim.x1 = 0; - button_dim.x2 = dim_collapsed.width(); - button_dim.y1 = -aa; - button_dim.y2 = -aa + dim_collapsed.height(); - - if (!isOpen()) { - draw_collapsed(pi, x, y); - return; - } - - int old_x = x; - - if (!owner()) - x += scroll(); - - top_x = x; - top_baseline = y; + setPosCache(pi, x, y); - int const bl = y - aa + dim_collapsed.ascent(); - - if (inlined) { + if (status_ == Inlined) { inset.draw(pi, x, y); } else { - draw_collapsed(pi, old_x, bl); - inset.draw(pi, x, bl + dim_collapsed.descent() + inset.ascent()); - } -} - + Dimension dimc; + dimension_collapsed(dimc); + int const aa = ascent(); + button_dim.x1 = x + 0; + button_dim.x2 = x + dimc.width(); + button_dim.y1 = y - aa; + button_dim.y2 = y - aa + dimc.height(); -void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const -{ - // by default, we are not inlined-drawing - draw(pi, x, y, false); + draw_collapsed(pi, x, y); + if (status_ == Open) { + if (!owner()) + x += scroll(); + inset.draw(pi, x, y - aa + dimc.height() + inset.ascent()); + } + } } InsetOld::EDITABLE InsetCollapsable::editable() const { - return collapsed_ ? IS_EDITABLE : HIGHLY_EDITABLE; -} - - -void InsetCollapsable::insetUnlock(BufferView * bv) -{ -#if 0 - if (autocollapse) { - if (change_label_with_text) { - draw_label = get_new_label(); - } else { - draw_label = label; - } - collapsed_ = true; - } -#endif - inset.insetUnlock(bv); - if (scroll()) - scroll(bv, 0.0F); - bv->updateInset(this); + return status_ != Collapsed ? HIGHLY_EDITABLE : IS_EDITABLE; } -FuncRequest InsetCollapsable::adjustCommand(FuncRequest const & cmd) +bool InsetCollapsable::descendable() const { - FuncRequest cmd1 = cmd; - cmd1.y = ascent() + cmd.y - (height_collapsed() + inset.ascent()); - return cmd1; + return status_ != Collapsed; } -void InsetCollapsable::lfunMouseRelease(FuncRequest const & cmd) +DispatchResult +InsetCollapsable::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd) { - bool ret = false; - BufferView * bv = cmd.view(); - - if (collapsed_ && cmd.button() != mouse_button::button3) { - collapsed_ = false; - bv->updateInset(this); - bv->buffer()->markDirty(); - return; + if (cmd.button() == mouse_button::button3) { + lyxerr << "InsetCollapsable::lfunMouseRelease 0" << endl; + showInsetDialog(&cur.bv()); + return DispatchResult(true, true); } - if (cmd.button() != mouse_button::button3 && hitButton(cmd)) { - if (collapsed_) { - collapsed_ = false; - } else { - collapsed_ = true; - bv->unlockInset(this); + switch (status_) { + case Collapsed: + lyxerr << "InsetCollapsable::lfunMouseRelease 1" << endl; + setStatus(Open); + edit(cur, true); + return DispatchResult(true, true); + + case Open: + if (hitButton(cmd)) { + lyxerr << "InsetCollapsable::lfunMouseRelease 2" << endl; + setStatus(Collapsed); + return DispatchResult(false, FINISHED_RIGHT); } - bv->updateInset(this); - bv->buffer()->markDirty(); - } else if (!collapsed_ && cmd.y > button_dim.y2) { - ret = inset.localDispatch(adjustCommand(cmd)) == DISPATCHED; + lyxerr << "InsetCollapsable::lfunMouseRelease 3" << endl; + return inset.dispatch(cur, cmd); + + case Inlined: + return inset.dispatch(cur, cmd); } - if (cmd.button() == mouse_button::button3 && !ret) - showInsetDialog(bv); + BOOST_ASSERT(false); + // shut up compiler + return DispatchResult(true, true); } int InsetCollapsable::latex(Buffer const & buf, ostream & os, - LatexRunParams const & runparams) const + OutputParams const & runparams) const { return inset.latex(buf, os, runparams); } -int InsetCollapsable::ascii(Buffer const & buf, ostream & os, int ll) const +int InsetCollapsable::plaintext(Buffer const & buf, ostream & os, + OutputParams const & runparams) const { - return inset.ascii(buf, os, ll); + return inset.plaintext(buf, os, runparams); } -int InsetCollapsable::linuxdoc(Buffer const & buf, ostream & os) const +int InsetCollapsable::linuxdoc(Buffer const & buf, ostream & os, + OutputParams const & runparams) const { - return inset.linuxdoc(buf, os); + return inset.linuxdoc(buf, os, runparams); } -int InsetCollapsable::docbook(Buffer const & buf, ostream & os, bool mixcont) const +int InsetCollapsable::docbook(Buffer const & buf, ostream & os, + OutputParams const & runparams) const { - return inset.docbook(buf, os, mixcont); + return inset.docbook(buf, os, runparams); } @@ -282,171 +263,109 @@ bool InsetCollapsable::hitButton(FuncRequest const & cmd) const } -InsetOld::RESULT InsetCollapsable::localDispatch(FuncRequest const & cmd) +string const InsetCollapsable::getNewLabel(string const & l) const { - //lyxerr << "InsetCollapsable::localDispatch: " - // << cmd.action << " '" << cmd.argument << "'\n"; - BufferView * bv = cmd.view(); - switch (cmd.action) { - case LFUN_INSET_EDIT: { - if (!cmd.argument.empty()) { - UpdatableInset::localDispatch(cmd); - if (collapsed_) { - lyxerr << "branch collapsed_" << endl; - collapsed_ = false; - if (bv->lockInset(this)) { - bv->updateInset(this); - bv->buffer()->markDirty(); - inset.localDispatch(cmd); - first_after_edit = true; - } - } else { - lyxerr << "branch not collapsed_" << endl; - if (bv->lockInset(this)) - inset.localDispatch(cmd); - } - return DISPATCHED; - } - -#ifdef WITH_WARNINGS -#warning Fix this properly in BufferView_pimpl::workAreaButtonRelease -#endif - if (cmd.button() == mouse_button::button3) - return DISPATCHED; - - UpdatableInset::localDispatch(cmd); - - if (collapsed_) { - collapsed_ = false; - // set this only here as it should be recollapsed only if - // it was already collapsed! - first_after_edit = true; - if (!bv->lockInset(this)) - return DISPATCHED; - bv->updateInset(this); - bv->buffer()->markDirty(); - inset.localDispatch(cmd); - } else { - FuncRequest cmd1 = cmd; - if (!bv->lockInset(this)) - return DISPATCHED; - if (cmd.y <= button_dim.y2) { - cmd1.y = 0; - } else { - cmd1.y = ascent() + cmd.y - (height_collapsed() + inset.ascent()); - } - inset.localDispatch(cmd); - } - return DISPATCHED; - } - - case LFUN_MOUSE_PRESS: - if (!collapsed_ && cmd.y > button_dim.y2) - inset.localDispatch(adjustCommand(cmd)); - return DISPATCHED; - - case LFUN_MOUSE_MOTION: - if (!collapsed_ && cmd.y > button_dim.y2) - inset.localDispatch(adjustCommand(cmd)); - return DISPATCHED; - - case LFUN_MOUSE_RELEASE: - lfunMouseRelease(cmd); - return DISPATCHED; - - default: - UpdatableInset::RESULT result = inset.localDispatch(cmd); - if (result >= FINISHED) - bv->unlockInset(this); - first_after_edit = false; - return result; + 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; } -} - - -bool InsetCollapsable::lockInsetInInset(BufferView * bv, UpdatableInset * in) -{ - if (&inset == in) - return true; - return inset.lockInsetInInset(bv, in); -} - - -bool InsetCollapsable::unlockInsetInInset(BufferView * bv, UpdatableInset * in, - bool lr) -{ - if (&inset == in) { - bv->unlockInset(this); - return true; + if (inset.paragraphs().size() > 1 || (i > 0 && j < p_siz)) { + la += "..."; } - return inset.unlockInsetInInset(bv, in, lr); + return la.empty() ? l : la; } -int InsetCollapsable::insetInInsetY() const +void InsetCollapsable::edit(LCursor & cur, bool left) { - return inset.insetInInsetY() - (top_baseline - inset.y()); + //lyxerr << "InsetCollapsable: edit left/right" << endl; + cur.push(this); + inset.edit(cur, left); + open(); } -void InsetCollapsable::validate(LaTeXFeatures & features) const +void InsetCollapsable::edit(LCursor & cur, int x, int y) { - inset.validate(features); -} - - -void InsetCollapsable::getCursor(BufferView & bv, int & x, int & y) const -{ - inset.getCursor(bv, x, y); -} - - -void InsetCollapsable::getCursorPos(BufferView * bv, int & x, int & y) const -{ - inset.getCursorPos(bv, x , y); + cur.push(this); + //lyxerr << "InsetCollapsable: edit xy" << endl; + if (status_ == Collapsed) { + setStatus(Open); + } else { + if (y <= button_dim.y2) + y = 0; + else + y += inset.ascent() - height_collapsed(); + } + inset.edit(cur, x, y); } -UpdatableInset * InsetCollapsable::getLockingInset() const +DispatchResult +InsetCollapsable::priv_dispatch(LCursor & cur, FuncRequest const & cmd) { - UpdatableInset * in = inset.getLockingInset(); - if (&inset == in) - return const_cast(this); - return in; -} - + lyxerr << "\nInsetCollapsable::priv_dispatch (begin): cmd: " << cmd + << " button y: " << button_dim.y2 << endl; + switch (cmd.action) { + case LFUN_MOUSE_PRESS: + if (status_ == Inlined) + inset.dispatch(cur, cmd); + else if (status_ == Open && cmd.y > button_dim.y2) + inset.dispatch(cur, cmd); + return DispatchResult(true, true); -UpdatableInset * InsetCollapsable::getFirstLockingInsetOfType(InsetOld::Code c) -{ - if (c == lyxCode()) - return this; - return inset.getFirstLockingInsetOfType(c); -} + case LFUN_MOUSE_MOTION: + if (status_ == Inlined) + inset.dispatch(cur, cmd); + else if (status_ == Open && cmd.y > button_dim.y2) + inset.dispatch(cur, cmd); + return DispatchResult(true, true); + case LFUN_MOUSE_RELEASE: + return lfunMouseRelease(cur, cmd); + + case LFUN_INSET_TOGGLE: + if (inset.text_.toggleInset()) + return DispatchResult(true, true); + if (status_ == Open) { + setStatus(Inlined); + return DispatchResult(true, true); + } else { + setStatus(Collapsed); + return DispatchResult(false, FINISHED_RIGHT); + } -void InsetCollapsable::setFont(BufferView * bv, LyXFont const & font, - bool toggleall, bool selectall) -{ - inset.setFont(bv, font, toggleall, selectall); + default: + return inset.dispatch(cur, cmd); + } } -LyXText * InsetCollapsable::getLyXText(BufferView const * bv, - bool const recursive) const +void InsetCollapsable::validate(LaTeXFeatures & features) const { - return inset.getLyXText(bv, recursive); + inset.validate(features); } -void InsetCollapsable::deleteLyXText(BufferView * bv, bool recursive) const +void InsetCollapsable::getCursorPos(CursorSlice const & cur, + int & x, int & y) const { - inset.deleteLyXText(bv, recursive); + inset.getCursorPos(cur, x, y); } -void InsetCollapsable::getLabelList(std::vector & list) const +void InsetCollapsable::getLabelList(Buffer const & buffer, + std::vector & list) const { - inset.getLabelList(list); + inset.getLabelList(buffer, list); } @@ -455,55 +374,47 @@ int InsetCollapsable::scroll(bool recursive) const int sx = UpdatableInset::scroll(false); if (recursive) - sx += inset.scroll(recursive); + sx += inset.scroll(false); return sx; } -ParagraphList * InsetCollapsable::getParagraphs(int i) const +int InsetCollapsable::numParagraphs() const { - return inset.getParagraphs(i); + return inset.numParagraphs(); } -LyXCursor const & InsetCollapsable::cursor(BufferView * bv) const +LyXText * InsetCollapsable::getText(int i) const { - return inset.cursor(bv); + return inset.getText(i); } -InsetOld * InsetCollapsable::getInsetFromID(int id_arg) const +void InsetCollapsable::open() { - if (id_arg == id()) - return const_cast(this); - return inset.getInsetFromID(id_arg); + if (status_ == Collapsed) // ...but not inlined + setStatus(Open); } -void InsetCollapsable::open(BufferView * bv) +void InsetCollapsable::close() { - if (!collapsed_) - return; - - collapsed_ = false; - bv->updateInset(this); + setStatus(Collapsed); } -void InsetCollapsable::close(BufferView * bv) const +void InsetCollapsable::setLabel(string const & l) { - if (collapsed_) - return; - - collapsed_ = true; - bv->updateInset(this); + label = l; } -void InsetCollapsable::setLabel(string const & l) const +void InsetCollapsable::setStatus(CollapseStatus st) { - label = l; + status_ = st; + setButtonLabel(); } @@ -513,66 +424,44 @@ void InsetCollapsable::markErased() } -bool InsetCollapsable::nextChange(BufferView * bv, lyx::pos_type & length) +void InsetCollapsable::addPreview(PreviewLoader & loader) const { - bool found = inset.nextChange(bv, length); - - if (first_after_edit && !found) - close(bv); - else if (!found) - first_after_edit = false; - return found; + inset.addPreview(loader); } -bool InsetCollapsable::searchForward(BufferView * bv, string const & str, - bool cs, bool mw) +bool InsetCollapsable::insetAllowed(InsetOld::Code code) const { - bool found = inset.searchForward(bv, str, cs, mw); - if (first_after_edit && !found) - close(bv); - else if (!found) - first_after_edit = false; - return found; + return inset.insetAllowed(code); } -bool InsetCollapsable::searchBackward(BufferView * bv, string const & str, - bool cs, bool mw) +void InsetCollapsable::setLabelFont(LyXFont & font) { - bool found = inset.searchBackward(bv, str, cs, mw); - if (first_after_edit && !found) - close(bv); - else if (!found) - first_after_edit = false; - return found; + labelfont_ = font; } -WordLangTuple const -InsetCollapsable::selectNextWordToSpellcheck(BufferView * bv, float & value) const +void InsetCollapsable::scroll(BufferView & bv, float sx) const { - WordLangTuple word = inset.selectNextWordToSpellcheck(bv, value); - if (first_after_edit && word.word().empty()) - close(bv); - first_after_edit = false; - return word; + UpdatableInset::scroll(bv, sx); } -void InsetCollapsable::addPreview(PreviewLoader & loader) const +void InsetCollapsable::scroll(BufferView & bv, int offset) const { - inset.addPreview(loader); + UpdatableInset::scroll(bv, offset); } -void InsetCollapsable::cache(BufferView * bv) const +Box const & InsetCollapsable::buttonDim() const { - view_ = bv->owner()->view(); + return button_dim; } -BufferView * InsetCollapsable::view() const +void InsetCollapsable::setBackgroundColor(LColor_color color) { - return view_.lock().get(); + InsetOld::setBackgroundColor(color); + inset.setBackgroundColor(color); }