3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Lars Gullik Bjønnes
9 * Full author contact details are available in file CREDITS
14 #include "insettext.h"
17 #include "BufferView.h"
19 #include "funcrequest.h"
26 #include "WordLangTuple.h"
28 #include "frontends/Alert.h"
29 #include "frontends/Dialogs.h"
30 #include "frontends/LyXView.h"
32 #include "support/LOstream.h"
33 #include "support/LAssert.h"
34 #include "support/tostr.h"
47 labelfont = LyXFont(LyXFont::ALL_SANE);
50 labelfont.setColor(LColor::latex);
55 InsetERT::InsetERT(BufferParams const & bp, bool collapsed)
56 : InsetCollapsable(bp, collapsed)
66 InsetERT::InsetERT(InsetERT const & in)
67 : InsetCollapsable(in), status_(in.status_)
73 // InsetERT::InsetERT(InsetERT const & in, bool same_id)
74 // : InsetCollapsable(in, same_id), status_(in.status_)
80 Inset * InsetERT::clone(Buffer const &) const
82 return new InsetERT(*const_cast<InsetERT *>(this));
86 // Inset * InsetERT::clone(Buffer const &, bool same_id) const
88 // return new InsetERT(*const_cast<InsetERT *>(this), same_id);
92 InsetERT::InsetERT(BufferParams const & bp,
93 Language const * l, string const & contents, bool collapsed)
94 : InsetCollapsable(bp, collapsed)
101 LyXFont font(LyXFont::ALL_INHERIT, l);
103 font.setFamily(LyXFont::TYPEWRITER_FAMILY);
104 font.setColor(LColor::latex);
107 string::const_iterator cit = contents.begin();
108 string::const_iterator end = contents.end();
110 for (; cit != end; ++cit) {
111 inset.paragraphs.begin()->insertChar(pos++, *cit, font);
113 // the init has to be after the initialization of the paragraph
114 // because of the label settings (draw_label for ert insets).
119 InsetERT::~InsetERT()
121 InsetERTMailer mailer(*this);
126 void InsetERT::read(Buffer const * buf, LyXLex & lex)
128 bool token_found = false;
131 string const token = lex.getString();
132 if (token == "status") {
134 string const tmp_token = lex.getString();
136 if (tmp_token == "Inlined") {
138 } else if (tmp_token == "Collapsed") {
139 status(0, Collapsed);
141 // leave this as default!
147 lyxerr << "InsetERT::Read: Missing 'status'-tag!"
149 // take countermeasures
150 lex.pushToken(token);
154 #warning this should be really short lived only for compatibility to
155 #warning files written 07/08/2001 so this has to go before 1.2.0! (Jug)
158 string const token = lex.getString();
159 if (token == "collapsed") {
161 collapsed_ = lex.getBool();
163 // Take countermeasures
164 lex.pushToken(token);
168 inset.read(buf, lex);
171 LyXFont font(LyXFont::ALL_INHERIT, latex_language);
172 font.setFamily(LyXFont::TYPEWRITER_FAMILY);
173 font.setColor(LColor::latex);
175 ParagraphList::iterator pit = inset.paragraphs.begin();
176 ParagraphList::iterator pend = inset.paragraphs.end();
177 for (; pit != pend; ++pit) {
178 pos_type siz = pit->size();
179 for (pos_type i = 0; i < siz; ++i) {
180 pit->setFont(i, font);
187 status(0, Collapsed);
196 void InsetERT::write(Buffer const * buf, ostream & os) const
212 os << getInsetName() << "\n"
213 << "status "<< st << "\n";
215 //inset.writeParagraphData(buf, os);
216 string const layout(buf->params.getLyXTextClass().defaultLayoutName());
217 ParagraphList::iterator par = inset.paragraphs.begin();
218 ParagraphList::iterator end = inset.paragraphs.end();
219 for (; par != end; ++par) {
220 os << "\n\\layout " << layout << "\n";
221 pos_type siz = par->size();
222 for (pos_type i = 0; i < siz; ++i) {
223 Paragraph::value_type c = par->getChar(i);
225 case Paragraph::META_INSET:
226 if (par->getInset(i)->lyxCode() != Inset::NEWLINE_CODE) {
227 lyxerr << "Element is not allowed in insertERT"
230 par->getInset(i)->write(buf, os);
235 os << "\n\\backslash \n";
246 string const InsetERT::editMessage() const
248 return _("Opened ERT Inset");
252 bool InsetERT::insertInset(BufferView *, Inset *)
258 void InsetERT::setFont(BufferView *, LyXFont const &, bool, bool selectall)
261 #warning FIXME. More UI stupidity...
263 // if selectall is activated then the fontchange was an outside general
264 // fontchange and this messages is not needed
266 Alert::error(_("Cannot change font"),
267 _("You cannot change font settings inside TeX code."));
271 void InsetERT::updateStatus(BufferView * bv, bool swap) const
273 if (status_ != Inlined) {
275 status(bv, swap ? Open : Collapsed);
277 status(bv, swap ? Collapsed : Open);
283 Inset::EDITABLE InsetERT::editable() const
285 if (status_ == Collapsed)
287 return HIGHLY_EDITABLE;
291 void InsetERT::lfunMousePress(FuncRequest const & cmd)
293 if (status_ == Inlined)
294 inset.localDispatch(cmd);
296 InsetCollapsable::localDispatch(cmd);
300 bool InsetERT::lfunMouseRelease(FuncRequest const & cmd)
302 BufferView * bv = cmd.view();
304 if (cmd.button() == mouse_button::button3) {
309 if (status_ != Inlined && (cmd.x >= 0) && (cmd.x < button_length) &&
310 (cmd.y >= button_top_y) && (cmd.y <= button_bottom_y)) {
311 updateStatus(bv, true);
313 LyXFont font(LyXFont::ALL_SANE);
314 FuncRequest cmd1 = cmd;
315 cmd1.y = ascent(bv, font) + cmd.y - inset.ascent(bv, font);
317 // inlined is special - the text appears above
319 if (status_ == Inlined)
320 inset.localDispatch(cmd1);
321 else if (!collapsed_ && (cmd.y > button_bottom_y)) {
322 cmd1.y -= height_collapsed();
323 inset.localDispatch(cmd1);
330 void InsetERT::lfunMouseMotion(FuncRequest const & cmd)
332 if (status_ == Inlined)
333 inset.localDispatch(cmd);
335 InsetCollapsable::localDispatch(cmd);
339 int InsetERT::latex(Buffer const *, ostream & os,
340 LatexRunParams const &) const
342 ParagraphList::iterator par = inset.paragraphs.begin();
343 ParagraphList::iterator end = inset.paragraphs.end();
347 pos_type siz = par->size();
348 for (pos_type i = 0; i < siz; ++i) {
349 // ignore all struck out text
350 if (isDeletedText(*par, i))
353 if (par->isNewline(i)) {
357 os << par->getChar(i);
371 int InsetERT::ascii(Buffer const *, ostream &, int /*linelen*/) const
377 int InsetERT::linuxdoc(Buffer const *, ostream & os) const
379 ParagraphList::iterator par = inset.paragraphs.begin();
380 ParagraphList::iterator end = inset.paragraphs.end();
384 pos_type siz = par->size();
385 for (pos_type i = 0; i < siz; ++i) {
386 if (par->isNewline(i)) {
390 os << par->getChar(i);
404 int InsetERT::docbook(Buffer const *, ostream & os, bool) const
406 ParagraphList::iterator par = inset.paragraphs.begin();
407 ParagraphList::iterator end = inset.paragraphs.end();
411 pos_type siz = par->size();
412 for (pos_type i = 0; i < siz; ++i) {
413 if (par->isNewline(i)) {
417 os << par->getChar(i);
431 Inset::RESULT InsetERT::localDispatch(FuncRequest const & cmd)
433 Inset::RESULT result = UNDISPATCHED;
434 BufferView * bv = cmd.view();
436 if (inset.paragraphs.begin()->empty()) {
440 switch (cmd.action) {
442 case LFUN_INSET_EDIT:
443 if (cmd.button() == mouse_button::button3)
445 if (status_ == Inlined) {
446 if (!bv->lockInset(this))
448 result = inset.localDispatch(cmd);
450 result = InsetCollapsable::localDispatch(cmd);
456 case LFUN_INSET_MODIFY: {
457 InsetERT::ERTStatus status_;
458 InsetERTMailer::string2params(cmd.argument, status_);
462 /* FIXME: I refuse to believe we have to live
463 * with ugliness like this ! Note that this
464 * rebreak *is* needed. Consider a change from
465 * Open (needfullrow) to Inlined (only the space
466 * taken by the text).
468 LyXText * t = inset.getLyXText(cmd.view());
469 t->need_break_row = t->rows().begin();
471 t->setCursorIntern(t->cursor.par(), t->cursor.pos());
472 inset.update(cmd.view(), true);
473 bv->updateInset(this);
478 case LFUN_MOUSE_PRESS:
483 case LFUN_MOUSE_MOTION:
484 lfunMouseMotion(cmd);
488 case LFUN_MOUSE_RELEASE:
489 lfunMouseRelease(cmd);
494 bv->owner()->setLayout(inset.paragraphs.begin()->layout()->name());
495 result = DISPATCHED_NOUPDATE;
499 result = InsetCollapsable::localDispatch(cmd);
502 switch (cmd.action) {
503 case LFUN_BREAKPARAGRAPH:
504 case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
506 case LFUN_BACKSPACE_SKIP:
508 case LFUN_DELETE_SKIP:
509 case LFUN_DELETE_LINE_FORWARD:
521 string const InsetERT::get_new_label() const
524 pos_type const max_length = 15;
525 pos_type const p_siz = inset.paragraphs.begin()->size();
526 pos_type const n = min(max_length, p_siz);
529 for(; i < n && j < p_siz; ++j) {
530 if (inset.paragraphs.begin()->isInset(j))
532 la += inset.paragraphs.begin()->getChar(j);
535 if (boost::next(inset.paragraphs.begin()) != inset.paragraphs.end() ||
536 (i > 0 && j < p_siz)) {
546 void InsetERT::setButtonLabel() const
548 if (status_ == Collapsed) {
549 setLabel(get_new_label());
556 bool InsetERT::checkInsertChar(LyXFont & /* font */)
559 LyXFont f(LyXFont::ALL_INHERIT, latex_language);
561 font.setFamily(LyXFont::TYPEWRITER_FAMILY);
562 font.setColor(LColor::latex);
568 void InsetERT::dimension(BufferView * bv, LyXFont const & font,
569 Dimension & dim) const
572 inset.dimension(bv, font, dim);
574 InsetCollapsable::dimension(bv, font, dim);
578 void InsetERT::draw(BufferView * bv, LyXFont const & f,
579 int baseline, float & x) const
581 InsetCollapsable::draw(bv, f, baseline, x, inlined());
585 void InsetERT::set_latex_font(BufferView * /* bv */)
588 LyXFont font(LyXFont::ALL_INHERIT, latex_language);
590 font.setFamily(LyXFont::TYPEWRITER_FAMILY);
591 font.setColor(LColor::latex);
593 inset.getLyXText(bv)->setFont(bv, font, false);
598 // attention this function can be called with bv == 0
599 void InsetERT::status(BufferView * bv, ERTStatus const st) const
606 inset.setUpdateStatus(bv, InsetText::INIT);
616 bv->unlockInset(const_cast<InsetERT *>(this));
620 bv->updateInset(const_cast<InsetERT *>(this));
621 bv->buffer()->markDirty();
627 bool InsetERT::showInsetDialog(BufferView * bv) const
629 InsetERTMailer mailer(const_cast<InsetERT &>(*this));
630 mailer.showDialog(bv);
635 void InsetERT::open(BufferView * bv)
643 void InsetERT::close(BufferView * bv) const
645 if (status_ == Collapsed || status_ == Inlined)
648 status(bv, Collapsed);
653 InsetERT::selectNextWordToSpellcheck(BufferView * bv, float &) const
655 bv->unlockInset(const_cast<InsetERT *>(this));
656 return WordLangTuple();
660 void InsetERT::getDrawFont(LyXFont & font) const
662 LyXFont f(LyXFont::ALL_INHERIT, latex_language);
664 font.setFamily(LyXFont::TYPEWRITER_FAMILY);
665 font.setColor(LColor::latex);
669 int InsetERT::getMaxWidth(BufferView * bv, UpdatableInset const * in) const
671 int w = InsetCollapsable::getMaxWidth(bv, in);
672 if (status_ != Inlined || w < 0)
674 LyXText * text = inset.getLyXText(bv);
675 int rw = text->rows().begin()->width();
679 if (text->rows().size() == 1 && rw < w)
685 void InsetERT::update(BufferView * bv, bool reinit)
687 if (inset.need_update & InsetText::INIT ||
688 inset.need_update & InsetText::FULL) {
692 InsetCollapsable::update(bv, reinit);
696 string const InsetERTMailer::name_("ert");
698 InsetERTMailer::InsetERTMailer(InsetERT & inset)
703 string const InsetERTMailer::inset2string() const
705 return params2string(inset_.status());
709 void InsetERTMailer::string2params(string const & in,
710 InsetERT::ERTStatus & status)
712 status = InsetERT::Collapsed;
715 string body = split(in, name, ' ');
720 status = static_cast<InsetERT::ERTStatus>(strToInt(body));
725 InsetERTMailer::params2string(InsetERT::ERTStatus status)
727 return name_ + ' ' + tostr(status);