/* This file is part of * ====================================================== * * LyX, The Document Processor * * Copyright 1998 The LyX Team. * *======================================================*/ #include #ifdef __GNUG__ #pragma implementation #endif #include "insetert.h" #include "gettext.h" #include "lyxfont.h" #include "buffer.h" #include "insets/insettext.h" #include "support/LOstream.h" #include "lyx_gui_misc.h" #include "BufferView.h" #include "LyXView.h" #include "lyxtext.h" #include "frontends/Dialogs.h" #include "debug.h" using std::ostream; void InsetERT::init() { setButtonLabel(); labelfont = LyXFont(LyXFont::ALL_SANE); labelfont.decSize(); labelfont.decSize(); labelfont.setColor(LColor::latex); setInsetName("ERT"); } InsetERT::InsetERT(bool collapsed) : InsetCollapsable(collapsed) { if (collapsed) status_ = Collapsed; else status_ = Open; init(); } InsetERT::InsetERT(InsetERT const & in, bool same_id) : InsetCollapsable(in, same_id), status_(in.status_) { init(); } Inset * InsetERT::clone(Buffer const &, bool same_id) const { return new InsetERT(*const_cast(this), same_id); } InsetERT::InsetERT(string const & contents, bool collapsed) : InsetCollapsable(collapsed) { LyXFont font(LyXFont::ALL_INHERIT); font.setFamily(LyXFont::TYPEWRITER_FAMILY); font.setColor(LColor::latex); string::const_iterator cit = contents.begin(); string::const_iterator end = contents.end(); Paragraph::size_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(); } void InsetERT::read(Buffer const * buf, LyXLex & lex) { 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!" << std::endl; // take countermeasures lex.pushToken(token); } } InsetCollapsable::read(buf, lex); if (!token_found) { if (collapsed_) { status_ = Collapsed; } else { status_ = Open; } } setButtonLabel(); } void InsetERT::write(Buffer const * buf, ostream & os) const { 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"; InsetCollapsable::write(buf, os); } string const InsetERT::editMessage() const { return _("Opened ERT Inset"); } bool InsetERT::insertInset(BufferView *, Inset *) { return false; } void InsetERT::setFont(BufferView *, LyXFont const &, bool, bool selectall) { // if selectall is activated then the fontchange was an outside general // fontchange and this messages is not needed if (!selectall) WriteAlert(_("Impossible Operation!"), _("Not permitted to change font-types inside ERT-insets!"), _("Sorry.")); } void InsetERT::edit(BufferView * bv, int x, int y, unsigned int button) { InsetCollapsable::edit(bv, x, y, button); set_latex_font(bv); } Inset::EDITABLE InsetERT::editable() const { if (status_ == Collapsed) return IS_EDITABLE; return HIGHLY_EDITABLE; } void InsetERT::edit(BufferView * bv, bool front) { InsetCollapsable::edit(bv, front); set_latex_font(bv); } void InsetERT::insetButtonRelease(BufferView * bv, int x, int y, int button) { if (button == 3) { showInsetDialog(bv); return; } if ((x >= 0) && (x < button_length) && (y >= button_top_y) && (y <= button_bottom_y)) { // if (collapsed_) { // setLabel(_("ERT")); // } else { // setLabel(get_new_label()); // } if (collapsed_) { status(bv, Open); // collapsed_ = false; // inset.insetButtonRelease(bv, 0, 0, button); // inset.setUpdateStatus(bv, InsetText::FULL); // bv->updateInset(this, true); } else { status(bv, Collapsed); // collapsed_ = true; // bv->unlockInset(this); // bv->updateInset(this, true); } } else if (!collapsed_ && (y > button_bottom_y)) { LyXFont font(LyXFont::ALL_SANE); int yy = ascent(bv, font) + y - (ascent_collapsed() + descent_collapsed() + inset.ascent(bv, font)); inset.insetButtonRelease(bv, x, yy, button); } } int InsetERT::latex(Buffer const *, std::ostream & os, bool /*fragile*/, bool /*free_spc*/) const { Paragraph * par = inset.paragraph(); while (par) { Paragraph::size_type siz = inset.paragraph()->size(); for (Paragraph::size_type i = 0; i != siz; ++i) { char c = inset.paragraph()->getChar(i); switch (c) { case Paragraph::META_NEWLINE: os << '\n'; break; default: os << c; break; } } par = par->next(); } return 1; } int InsetERT::ascii(Buffer const *, std::ostream &, int /*linelen*/) const { return 0; } int InsetERT::linuxdoc(Buffer const *, std::ostream &) const { return 0; } int InsetERT::docBook(Buffer const *, std::ostream &) const { return 0; } 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: set_latex_font(bv); break; default: break; } return result; } string const InsetERT::get_new_label() const { string la; Paragraph::size_type const max_length = 15; Paragraph::size_type const p_siz = inset.paragraph()->size(); Paragraph::size_type const n = std::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() { if (status_ == Collapsed) { setLabel(get_new_label()); } else { setLabel(_("ERT")); } } bool InsetERT::checkInsertChar(LyXFont & font) { LyXFont f(LyXFont::ALL_INHERIT); 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); 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) { LyXFont font(LyXFont::ALL_INHERIT); font.setFamily(LyXFont::TYPEWRITER_FAMILY); font.setColor(LColor::latex); inset.getLyXText(bv)->setFont(bv, font, false); } void InsetERT::status(BufferView * bv, ERTStatus const st) { 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(); bv->unlockInset(this); break; } bv->updateInset(this, true); } } bool InsetERT::showInsetDialog(BufferView * bv) const { bv->owner()->getDialogs()->showERT(const_cast(this)); return true; } void InsetERT::open(BufferView * bv) { if (!collapsed_) return; status(bv, Open); } void InsetERT::close(BufferView * bv) { if (collapsed_) return; status(bv, Collapsed); }