X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetert.C;h=9daea852d7b7aee8c56c8d537e6cb369fef6ae35;hb=4a5b7a5952ad2381fcdf4830511293e184c7c5a1;hp=386dbd26adb247dc16e53b086854fd032ca82cdf;hpb=ba5e47f1a92c3688d16f76f654fd3768672ebb50;p=lyx.git diff --git a/src/insets/insetert.C b/src/insets/insetert.C index 386dbd26ad..9daea852d7 100644 --- a/src/insets/insetert.C +++ b/src/insets/insetert.C @@ -16,178 +16,661 @@ #include "insetert.h" #include "gettext.h" #include "lyxfont.h" -#include "Painter.h" +#include "language.h" +#include "buffer.h" #include "lyx_gui_misc.h" +#include "BufferView.h" +#include "LyXView.h" +#include "lyxtext.h" +#include "debug.h" +#include "lyxtextclasslist.h" +#include "insets/insettext.h" -InsetERT::InsetERT(Buffer * bf) - : InsetText(bf) +#include "frontends/Dialogs.h" +#include "frontends/Alert.h" + +#include "support/LOstream.h" + + +using std::ostream; +using std::min; +using std::endl; + +using lyx::pos_type; + + +void InsetERT::init() { - closed = true; - nomotion = false; + setButtonLabel(); + labelfont = LyXFont(LyXFont::ALL_SANE); + labelfont.decSize(); + labelfont.decSize(); + labelfont.setColor(LColor::latex); + setInsetName("ERT"); } -Inset * InsetERT::Clone() const +InsetERT::InsetERT(bool collapsed) + : InsetCollapsable(collapsed) { - InsetERT * result = new InsetERT(buffer); - return result; + if (collapsed) + status_ = Collapsed; + else + status_ = Open; + init(); } -void InsetERT::Write(ostream & os) const +InsetERT::InsetERT(InsetERT const & in, bool same_id) + : InsetCollapsable(in, same_id), status_(in.status_) { - os << "ERT\n"; - WriteParagraphData(os); + init(); } -int InsetERT::ascent_closed(Painter & pain, LyXFont const & f) const +Inset * InsetERT::clone(Buffer const &, bool same_id) const { - int width, ascent, descent; - LyXFont font(LyXFont::ALL_SANE); - font.setSize(f.size()); - font.decSize(); - font.decSize(); - pain.buttonText(0, 0, _("ERT"), font, false, width, ascent, descent); - return ascent; + return new InsetERT(*const_cast(this), same_id); } -int InsetERT::descent_closed(Painter & pain, LyXFont const & f) const +InsetERT::InsetERT(string const & contents, bool collapsed) + : InsetCollapsable(collapsed) { - int width, ascent, descent; - LyXFont font(LyXFont::ALL_SANE); - font.setSize(f.size()); - font.decSize(); - font.decSize(); - pain.buttonText(0, 0, _("ERT"), font, false, width, ascent, descent); - return descent; + if (collapsed) + status_ = Collapsed; + else + status_ = Open; +#ifndef INHERIT_LANG + LyXFont font(LyXFont::ALL_INHERIT, latex_language); +#else + LyXFont font(LyXFont::ALL_INHERIT); +#endif + font.setFamily(LyXFont::TYPEWRITER_FAMILY); + font.setColor(LColor::latex); + string::const_iterator cit = contents.begin(); + string::const_iterator end = contents.end(); + pos_type pos = 0; + for (; cit != end; ++cit) { + inset.paragraph()->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(); +} + + +InsetERT::~InsetERT() +{ + hideDialog(); } -int InsetERT::width_closed(Painter & pain, LyXFont const & f) const +void InsetERT::read(Buffer const * buf, LyXLex & lex) { - int width, ascent, descent; - LyXFont font(LyXFont::ALL_SANE); - font.setSize(f.size()); - font.decSize(); - font.decSize(); - pain.buttonText(TEXT_TO_INSET_OFFSET, 0, _("ERT"), font, false, - width, ascent, descent); - return width + (2*TEXT_TO_INSET_OFFSET); + 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(0, Inlined); + } else if (tmp_token == "Collapsed") { + status(0, Collapsed); + } else { + // leave this as default! + status(0, Open); + } + + token_found = true; + } else { + lyxerr << "InsetERT::Read: Missing 'status'-tag!" + << endl; + // take countermeasures + lex.pushToken(token); + } + } +#if 0 +#warning this should be really short lived only for compatibility to +#warning files written 07/08/2001 so this has to go before 1.2.0! (Jug) + if (lex.isOK()) { + lex.next(); + string const token = lex.getString(); + if (token == "collapsed") { + lex.next(); + collapsed_ = lex.getBool(); + } else { + // Take countermeasures + lex.pushToken(token); + } + } +#endif + inset.read(buf, lex); + +#ifndef INHERIT_LANG + LyXFont font(LyXFont::ALL_INHERIT, latex_language); +#else + LyXFont font(LyXFont::ALL_INHERIT); +#endif + + font.setFamily(LyXFont::TYPEWRITER_FAMILY); + font.setColor(LColor::latex); + Paragraph * par = inset.paragraph(); + while (par) { + pos_type siz = par->size(); + for (pos_type i = 0; i < siz; ++i) { + par->setFont(i, font); + } + par = par->next(); + } + + if (!token_found) { + if (collapsed_) { + status(0, Collapsed); + } else { + status(0, Open); + } + } + setButtonLabel(); } -int InsetERT::ascent(Painter & pain, LyXFont const & font) const +void InsetERT::write(Buffer const * buf, ostream & os) const { - if (closed) - return ascent_closed(pain, font); - else - return InsetText::ascent(pain, font); + string st; + + 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 = + textclasslist.NameOfLayout(buf->params.textclass, 0); + Paragraph * par = inset.paragraph(); + while (par) { + os << "\n\\layout " << layout << "\n"; + 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: + case Paragraph::META_HFILL: + lyxerr << "Element is not allowed in insertERT" + << endl; + case Paragraph::META_NEWLINE: + os << "\n\\newline \n"; + break; + case '\\': + os << "\n\\backslash \n"; + break; + default: + os << c; + break; + } + } + par = par->next(); + } } -int InsetERT::descent(Painter & pain, LyXFont const & font) const +string const InsetERT::editMessage() const { + return _("Opened ERT Inset"); +} + - if (closed) - return descent_closed(pain, font); - else - return InsetText::descent(pain, font); +bool InsetERT::insertInset(BufferView *, Inset *) +{ + return false; } -int InsetERT::width(Painter & pain, LyXFont const & font) const +void InsetERT::setFont(BufferView *, LyXFont const &, bool, bool selectall) { - if (closed) - return width_closed(pain, font); - else - return InsetText::width(pain, font); + // if selectall is activated then the fontchange was an outside general + // fontchange and this messages is not needed + if (!selectall) + Alert::alert(_("Impossible Operation!"), + _("Not permitted to change font-types inside ERT-insets!"), + _("Sorry.")); } -void InsetERT::draw_closed(Painter & pain, LyXFont const & f, - int baseline, float & x) const +void InsetERT::updateStatus(BufferView * bv, bool swap) const { - LyXFont font(LyXFont::ALL_SANE); - font.setSize(f.size()); - font.decSize(); - font.decSize(); - font.setColor(LColor::ert); - int width; - pain.buttonText(int(x) + TEXT_TO_INSET_OFFSET, baseline, - _("ERT"), font, true, width); - x += width + (2 * TEXT_TO_INSET_OFFSET); + if (status_ != Inlined) { + if (collapsed_) { + status(bv, swap ? Open : Collapsed); + } else { + status(bv, swap ? Collapsed : Open); + } + } +} + + +void InsetERT::edit(BufferView * bv, int x, int y, unsigned int button) +{ + if (button == 3) + return; + + if (status_ == Inlined) { + if (!bv->lockInset(this)) + return; + inset.edit(bv, x, y, button); + } else { + InsetCollapsable::edit(bv, x, y, button); + } + set_latex_font(bv); + updateStatus(bv); } -void InsetERT::draw(Painter & pain, LyXFont const & f, - int baseline, float & x) const +Inset::EDITABLE InsetERT::editable() const { - if (closed) { - top_x = int(x); - top_baseline = baseline; - draw_closed(pain, f, baseline, x); - } else { - InsetText::draw(pain, f, baseline, x); - } -// resetPos(bv); + if (status_ == Collapsed) + return IS_EDITABLE; + return HIGHLY_EDITABLE; +} + + +void InsetERT::edit(BufferView * bv, bool front) +{ + InsetCollapsable::edit(bv, front); + updateStatus(0); + set_latex_font(bv); +} + + + + +void InsetERT::insetButtonPress(BufferView * bv, + int x, int y, int button) +{ + if (status_ == Inlined) { + inset.insetButtonPress(bv, x, y, button); + } else { + InsetCollapsable::insetButtonPress(bv, x, y, button); + } +} + + +bool InsetERT::insetButtonRelease(BufferView * bv, int x, int y, int button) +{ + if (button == 3) { + showInsetDialog(bv); + return true; + } + + if (status_ != Inlined && (x >= 0) && (x < button_length) && + (y >= button_top_y) && (y <= button_bottom_y)) { + updateStatus(bv, true); + } else { + LyXFont font(LyXFont::ALL_SANE); + int yy = ascent(bv, font) + y - inset.ascent(bv, font); + + // inlined is special - the text appears above + // button_bottom_y + if (status_ == Inlined) { + inset.insetButtonRelease(bv, x, yy, button); + } else if (!collapsed_ && (y > button_bottom_y)) { + yy -= (ascent_collapsed() + descent_collapsed()); + inset.insetButtonRelease(bv, x, yy, button); + } + } + return false; +} + + +void InsetERT::insetMotionNotify(BufferView * bv, + int x, int y, int state) +{ + if (status_ == Inlined) { + inset.insetMotionNotify(bv, x, y, state); + } else { + InsetCollapsable::insetMotionNotify(bv, x, y, state); + } +} + + +int InsetERT::latex(Buffer const *, ostream & os, bool /*fragile*/, + bool /*free_spc*/) const +{ + Paragraph * par = inset.paragraph(); + int lines = 0; + while (par) { + 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_NEWLINE: + os << '\n'; + ++lines; + break; + default: + os << c; + break; + } + } + par = par->next(); + if (par) { + os << "\n\n"; + lines += 2; + } + } + + return lines; } -void InsetERT::InsetButtonRelease(BufferView * bv, int x, int y, int button) +int InsetERT::ascii(Buffer const *, + ostream &, int /*linelen*/) const { - nomotion = false; - InsetText::InsetButtonRelease(bv, x, y, button); + return 0; } -void InsetERT::InsetButtonPress(BufferView * bv, int x, int y, int button) +int InsetERT::linuxdoc(Buffer const *, ostream & os) const { - nomotion = false; - InsetText::InsetButtonPress(bv, x, y, button); + Paragraph * par = inset.paragraph(); + int lines = 0; + while (par) { + 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_NEWLINE: + os << '\n'; + ++lines; + break; + default: + os << c; + break; + } + } + par = par->next(); + if (par) { + os << "\n"; + lines ++; + } + } + + return lines; +} + + +int InsetERT::docbook(Buffer const *, ostream & os) const +{ + Paragraph * par = inset.paragraph(); + int lines = 0; + while (par) { + 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_NEWLINE: + os << '\n'; + ++lines; + break; + default: + os << c; + break; + } + } + par = par->next(); + if (par) { + os << "\n"; + lines ++; + } + } + + return lines; +} + + +UpdatableInset::RESULT +InsetERT::localDispatch(BufferView * bv, kb_action action, string const & arg) +{ + UpdatableInset::RESULT result = DISPATCHED_NOUPDATE; + + if (!inset.paragraph()->size()) { + set_latex_font(bv); + } + + switch (action) { + case LFUN_LAYOUT: + bv->owner()->setLayout(inset.paragraph()->getLayout()); + break; + default: + result = InsetCollapsable::localDispatch(bv, action, arg); + } + switch (action) { + 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: + set_latex_font(bv); + break; + + default: + break; + } + return result; +} + + +string const InsetERT::get_new_label() const +{ + string la; + pos_type const max_length = 15; + pos_type const p_siz = inset.paragraph()->size(); + pos_type const n = min(max_length, p_siz); + int i = 0; + int j = 0; + for(; i < n && j < p_siz; ++j) { + if (inset.paragraph()->isInset(j)) + continue; + la += inset.paragraph()->getChar(j); + ++i; + } + if (i > 0 && j < p_siz) { + la += "..."; + } + if (la.empty()) { + la = _("ERT"); + } + return la; +} + + +void InsetERT::setButtonLabel() const +{ + if (status_ == Collapsed) { + setLabel(get_new_label()); + } else { + setLabel(_("ERT")); + } +} + + +bool InsetERT::checkInsertChar(LyXFont & font) +{ +#ifndef INHERIT_LANG + LyXFont f(LyXFont::ALL_INHERIT, latex_language); +#else + LyXFont f(LyXFont::ALL_INHERIT); +#endif + font = f; + font.setFamily(LyXFont::TYPEWRITER_FAMILY); + font.setColor(LColor::latex); + return true; +} + + +int InsetERT::ascent(BufferView * bv, LyXFont const & font) const +{ + if (!inlined()) + return InsetCollapsable::ascent(bv, font); + + return inset.ascent(bv, font); +} + + +int InsetERT::descent(BufferView * bv, LyXFont const & font) const +{ + if (!inlined()) + return InsetCollapsable::descent(bv, font); + + return inset.descent(bv, font); +} + + +int InsetERT::width(BufferView * bv, LyXFont const & font) const +{ + if (!inlined()) + return InsetCollapsable::width(bv, font); + + return inset.width(bv, font); +} + + +void InsetERT::draw(BufferView * bv, LyXFont const & f, + int baseline, float & x, bool cleared) const +{ + Painter & pain = bv->painter(); + + button_length = width_collapsed(); + button_top_y = -ascent(bv, f); + button_bottom_y = -ascent(bv, f) + ascent_collapsed() + + descent_collapsed(); + + if (!isOpen()) { + draw_collapsed(pain, baseline, x); + x += TEXT_TO_INSET_OFFSET; + return; + } + + float old_x = x; + + if (!owner()) + x += static_cast(scroll()); + + if (!cleared && (inset.need_update == InsetText::FULL || + inset.need_update == InsetText::INIT || + top_x != int(x) || + top_baseline != baseline)) + { + // we don't need anymore to clear here we just have to tell + // the underlying LyXText that it should do the RowClear! + inset.setUpdateStatus(bv, InsetText::FULL); + bv->text->status(bv, LyXText::CHANGED_IN_DRAW); + return; + } + + top_x = int(x); + topx_set = true; + top_baseline = baseline; + + int const bl = baseline - ascent(bv, f) + ascent_collapsed(); + + if (inlined()) { + inset.draw(bv, f, baseline, x, cleared); + } else { + draw_collapsed(pain, bl, old_x); + inset.draw(bv, f, + bl + descent_collapsed() + inset.ascent(bv, f), + x, cleared); + } + need_update = NONE; +} + + +void InsetERT::set_latex_font(BufferView * bv) +{ +#ifndef INHERIT_LANG + LyXFont font(LyXFont::ALL_INHERIT, latex_language); +#else + LyXFont font(LyXFont::ALL_INHERIT); +#endif + + font.setFamily(LyXFont::TYPEWRITER_FAMILY); + font.setColor(LColor::latex); + inset.getLyXText(bv)->setFont(bv, font, false); } -void InsetERT::InsetMotionNotify(BufferView * bv, int x, int y, int button) +void InsetERT::status(BufferView * bv, ERTStatus const st) const { - if (nomotion) - return; - InsetText::InsetMotionNotify(bv, x, y, button); + if (st != status_) { + status_ = st; + switch (st) { + case Inlined: + inset.setAutoBreakRows(false); + break; + case Open: + inset.setAutoBreakRows(true); + collapsed_ = false; + need_update = FULL; + setButtonLabel(); + break; + case Collapsed: + inset.setAutoBreakRows(true); + collapsed_ = true; + need_update = FULL; + setButtonLabel(); + if (bv) + bv->unlockInset(const_cast(this)); + break; + } + if (bv) + bv->updateInset(const_cast(this), false); + } } -void InsetERT::Edit(BufferView * bv, int x, int y, unsigned int button) +bool InsetERT::showInsetDialog(BufferView * bv) const { - closed = false; - nomotion = true; - LyXFont font(LyXFont::ALL_SANE); - font.setLatex (LyXFont::ON); - InsetText::Edit(bv, (x > (width_closed(bv->getPainter(),font)-5) ? - width(bv->getPainter(), font) : 0), y, button); - real_current_font = current_font = font; - bv->updateInset(this, false); + bv->owner()->getDialogs()->showERT(const_cast(this)); + return true; } -void InsetERT::InsetUnlock(BufferView * bv) +void InsetERT::open(BufferView * bv) { - closed = true; - InsetText::InsetUnlock(bv); - bv->updateInset(this, false); + if (!collapsed_) + return; + status(bv, Open); } -bool InsetERT::InsertInset(Inset *) +void InsetERT::close(BufferView * bv) const { - return false; + if (collapsed_) + return; + status(bv, Collapsed); } -void InsetERT::SetFont(LyXFont const &, bool) +string const InsetERT::selectNextWordToSpellcheck(BufferView * bv,float &) const { - WriteAlert(_("Impossible Operation!"), - _("Not permitted to change font-types inside ERT-insets!"), - _("Sorry.")); + bv->unlockInset(const_cast(this)); + return string(); }