* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
- * \author Jürgen Vigna
+ * \author Jürgen Vigna
*
* Full author contact details are available in file CREDITS.
*/
#include "InsetText.h"
+#include "insets/InsetOptArg.h"
+
#include "buffer_funcs.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "DispatchResult.h"
#include "ErrorList.h"
#include "FuncRequest.h"
+#include "FuncStatus.h"
+#include "InsetCaption.h"
#include "InsetList.h"
#include "Intl.h"
#include "Lexer.h"
#include "MetricsInfo.h"
#include "output_docbook.h"
#include "output_latex.h"
+#include "output_xhtml.h"
#include "OutputParams.h"
#include "output_plaintext.h"
#include "paragraph_funcs.h"
#include "TextClass.h"
#include "Text.h"
#include "TextMetrics.h"
+#include "TocBackend.h"
#include "frontends/alert.h"
#include "frontends/Painter.h"
#include "support/lstrings.h"
#include <boost/bind.hpp>
-#include <boost/assert.hpp>
+#include "support/lassert.h"
using namespace std;
using namespace lyx::support;
/////////////////////////////////////////////////////////////////////
-InsetText::InsetText(Buffer const & buf)
+InsetText::InsetText(Buffer const & buf, UsePlain type)
: drawFrame_(false), frame_color_(Color_insetframe)
{
- initParagraphs(buf);
+ setBuffer(const_cast<Buffer &>(buf));
+ initParagraphs(type);
}
}
-InsetText::InsetText()
-{}
+void InsetText::setBuffer(Buffer & buf)
+{
+ ParagraphList::iterator end = paragraphs().end();
+ for (ParagraphList::iterator it = paragraphs().begin(); it != end; ++it)
+ it->setBuffer(buf);
+ Inset::setBuffer(buf);
+}
-void InsetText::initParagraphs(Buffer const & buf)
+void InsetText::initParagraphs(UsePlain type)
{
- BOOST_ASSERT(paragraphs().empty());
- buffer_ = const_cast<Buffer *>(&buf);
+ LASSERT(paragraphs().empty(), /**/);
paragraphs().push_back(Paragraph());
Paragraph & ourpar = paragraphs().back();
- ourpar.setEmptyOrDefaultLayout(buf.params().documentClass());
ourpar.setInsetOwner(this);
+ DocumentClass const & dc = buffer_->params().documentClass();
+ if (type == DefaultLayout)
+ ourpar.setDefaultLayout(dc);
+ else
+ ourpar.setPlainLayout(dc);
}
+
void InsetText::setParagraphOwner()
{
for_each(paragraphs().begin(), paragraphs().end(),
void InsetText::clear()
{
ParagraphList & pars = paragraphs();
- BOOST_ASSERT(!pars.empty());
+ LASSERT(!pars.empty(), /**/);
// This is a gross hack...
Layout const & old_layout = pars.begin()->layout();
Paragraph oldpar = *paragraphs().begin();
paragraphs().clear();
ErrorList errorList;
+ lex.setContext("InsetText::read");
bool res = text_.read(buffer(), lex, errorList, this);
- if (!res) {
- lex.printError("Missing \\end_inset at this point. "
- "Read: `$$Token'");
- }
+ if (!res)
+ lex.printError("Missing \\end_inset at this point. ");
// sanity check
// ensure we have at least one paragraph.
// Hand font through to contained lyxtext:
tm.font_.fontInfo() = mi.base.font;
mi.base.textwidth -= 2 * TEXT_TO_INSET_OFFSET;
+
+ // This can happen when a layout has a left and right margin,
+ // and the view is made very narrow. We can't do better than
+ // to draw it partly out of view (bug 5890).
+ if (mi.base.textwidth < 1)
+ mi.base.textwidth = 1;
+
if (hasFixedWidth())
tm.metrics(mi, dim, mi.base.textwidth);
else
int const h = tm.height() + 2 * TEXT_TO_INSET_OFFSET;
int const xframe = x + TEXT_TO_INSET_OFFSET / 2;
if (pi.full_repaint)
- pi.pain.fillRectangle(xframe, yframe, w, h, backgroundColor());
+ pi.pain.fillRectangle(xframe, yframe, w, h,
+ pi.backgroundColor(this));
+
if (drawFrame_)
pi.pain.rectangle(xframe, yframe, w, h, frameColor());
}
+ ColorCode const old_color = pi.background_color;
+ pi.background_color = pi.backgroundColor(this, false);
+
tm.draw(pi, x + TEXT_TO_INSET_OFFSET, y);
+
+ pi.background_color = old_color;
}
{
LYXERR(Debug::ACTION, "InsetText::doDispatch()"
<< " [ cmd.action = " << cmd.action << ']');
- text_.dispatch(cur, cmd);
+
+ // Dispatch only to text_ if the cursor is inside
+ // the text_. It is not for context menus (bug 5797).
+ if (cur.text() == &text_)
+ text_.dispatch(cur, cmd);
+ else
+ cur.undispatched();
+
+ if (!cur.result().dispatched())
+ Inset::doDispatch(cur, cmd);
}
bool InsetText::getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & status) const
{
- return text_.getStatus(cur, cmd, status);
+ switch (cmd.action) {
+ case LFUN_LAYOUT:
+ status.setEnabled(!forcePlainLayout());
+ return true;
+
+ case LFUN_LAYOUT_PARAGRAPH:
+ case LFUN_PARAGRAPH_PARAMS:
+ case LFUN_PARAGRAPH_PARAMS_APPLY:
+ case LFUN_PARAGRAPH_SPACING:
+ case LFUN_PARAGRAPH_UPDATE:
+ status.setEnabled(allowParagraphCustomization());
+ return true;
+ default:
+ // Dispatch only to text_ if the cursor is inside
+ // the text_. It is not for context menus (bug 5797).
+ bool ret = false;
+ if (cur.text() == &text_)
+ ret = text_.getStatus(cur, cmd, status);
+
+ if (!ret)
+ ret = Inset::getStatus(cur, cmd, status);
+ return ret;
+ }
}
}
-void InsetText::acceptChanges(BufferParams const & bparams)
+void InsetText::acceptChanges()
{
- text_.acceptChanges(bparams);
+ text_.acceptChanges(buffer().params());
}
-void InsetText::rejectChanges(BufferParams const & bparams)
+void InsetText::rejectChanges()
{
- text_.rejectChanges(bparams);
+ text_.rejectChanges(buffer().params());
}
}
+docstring InsetText::xhtml(odocstream & os, OutputParams const & runparams) const
+{
+ xhtmlParagraphs(paragraphs(), buffer(), os, runparams);
+ return docstring();
+}
+
+
void InsetText::validate(LaTeXFeatures & features) const
{
for_each(paragraphs().begin(), paragraphs().end(),
}
-// FIXME: instead of this hack, which only works by chance,
-// cells should have their own insetcell type, which returns CELL_CODE!
-bool InsetText::isTableCell() const
-{
- // this is only true for tabular cells
- return !text_.isMainText(buffer()) && lyxCode() == TEXT_CODE;
-}
-
-
-
-bool InsetText::neverIndent() const
-{
- return isTableCell();
-}
-
-
ParagraphList const & InsetText::paragraphs() const
{
return text_.paragraphs();
{
ParIterator it2 = it;
it2.forwardPos();
- BOOST_ASSERT(&it2.inset() == this && it2.pit() == 0);
- lyx::updateLabels(buffer(), it2);
+ LASSERT(&it2.inset() == this && it2.pit() == 0, return);
+ if (producesOutput())
+ buffer().updateLabels(it2);
+ else {
+ DocumentClass const & tclass = buffer().masterBuffer()->params().documentClass();
+ Counters const savecnt = tclass.counters();
+ buffer().updateLabels(it2);
+ tclass.counters() = savecnt;
+ }
+}
+
+
+void InsetText::addToToc(DocIterator const & cdit)
+{
+ DocIterator dit = cdit;
+ dit.push_back(CursorSlice(*this));
+ Toc & toc = buffer().tocBackend().toc("tableofcontents");
+
+ BufferParams const & bufparams = buffer_->params();
+ const int min_toclevel = bufparams.documentClass().min_toclevel();
+
+ // For each paragraph, traverse its insets and let them add
+ // their toc items
+ ParagraphList & pars = paragraphs();
+ pit_type pend = paragraphs().size();
+ for (pit_type pit = 0; pit != pend; ++pit) {
+ Paragraph const & par = pars[pit];
+ dit.pit() = pit;
+ // the string that goes to the toc (could be the optarg)
+ docstring tocstring;
+ InsetList::const_iterator it = par.insetList().begin();
+ InsetList::const_iterator end = par.insetList().end();
+ for (; it != end; ++it) {
+ Inset & inset = *it->inset;
+ dit.pos() = it->pos;
+ //lyxerr << (void*)&inset << " code: " << inset.lyxCode() << std::endl;
+ inset.addToToc(dit);
+ switch (inset.lyxCode()) {
+ case OPTARG_CODE: {
+ if (!tocstring.empty())
+ break;
+ dit.pos() = 0;
+ Paragraph const & insetpar =
+ *static_cast<InsetOptArg&>(inset).paragraphs().begin();
+ if (!par.labelString().empty())
+ tocstring = par.labelString() + ' ';
+ tocstring += insetpar.asString(AS_STR_INSETS);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ // now the toc entry for the paragraph
+ int const toclevel = par.layout().toclevel;
+ if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel) {
+ dit.pos() = 0;
+ // insert this into the table of contents
+ if (tocstring.empty())
+ tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
+ toc.push_back(TocItem(dit, toclevel - min_toclevel, tocstring));
+ }
+
+ // And now the list of changes.
+ par.addChangesToToc(dit, buffer());
+ }
}
bool InsetText::notifyCursorLeaves(Cursor const & old, Cursor & cur)
{
- if (cur.buffer().isClean())
+ if (buffer().isClean())
return Inset::notifyCursorLeaves(old, cur);
// find text inset in old cursor
Cursor insetCur = old;
int scriptSlice = insetCur.find(this);
- BOOST_ASSERT(scriptSlice != -1);
+ LASSERT(scriptSlice != -1, /**/);
insetCur.cutOff(scriptSlice);
- BOOST_ASSERT(&insetCur.inset() == this);
+ LASSERT(&insetCur.inset() == this, /**/);
// update the old paragraph's words
- insetCur.paragraph().updateWords(insetCur.top());
+ insetCur.paragraph().updateWords();
return Inset::notifyCursorLeaves(old, cur);
}
bool InsetText::completionSupported(Cursor const & cur) const
{
- Cursor const & bvCur = cur.bv().cursor();
- if (&bvCur.inset() != this)
- return false;
+ //LASSERT(&cur.bv().cursor().inset() != this, return false);
return text_.completionSupported(cur);
}
}
+InsetCaption const * InsetText::getCaptionInset() const
+{
+ ParagraphList::const_iterator pit = paragraphs().begin();
+ for (; pit != paragraphs().end(); ++pit) {
+ InsetList::const_iterator it = pit->insetList().begin();
+ for (; it != pit->insetList().end(); ++it) {
+ Inset & inset = *it->inset;
+ if (inset.lyxCode() == CAPTION_CODE) {
+ InsetCaption const * ins =
+ static_cast<InsetCaption const *>(it->inset);
+ return ins;
+ }
+ }
+ }
+ return 0;
+}
+
+
+docstring InsetText::getCaptionText(OutputParams const & runparams) const
+{
+ InsetCaption const * ins = getCaptionInset();
+ if (ins == 0)
+ return docstring();
+
+ odocstringstream ods;
+ ins->getCaptionAsPlaintext(ods, runparams);
+ return ods.str();
+}
+
+
+docstring InsetText::getCaptionHTML(OutputParams const & runparams) const
+{
+ InsetCaption const * ins = getCaptionInset();
+ if (ins == 0)
+ return docstring();
+
+ odocstringstream ods;
+ docstring def = ins->getCaptionAsHTML(ods, runparams);
+ if (!def.empty())
+ ods << def << '\n';
+ return ods.str();
+}
+
+
} // namespace lyx