-/* This file is part of
- * ======================================================
+/**
+ * \file insettext.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
*
- * LyX, The Document Processor
+ * \author Jürgen Vigna
*
- * Copyright 1998-2001 The LyX Team.
- *
- * ======================================================
+ * Full author contact details are available in file CREDITS
*/
#include <config.h>
-#ifdef __GNUG__
-#pragma implementation
-#endif
#include "insettext.h"
-#include "paragraph.h"
-#include "lyxlex.h"
-#include "debug.h"
-#include "lyxfont.h"
+
#include "buffer.h"
-#include "frontends/LyXView.h"
#include "BufferView.h"
-#include "LaTeXFeatures.h"
-#include "frontends/Painter.h"
-#include "lyxtext.h"
-#include "lyxcursor.h"
#include "CutAndPaste.h"
-#include "frontends/font_metrics.h"
+#include "debug.h"
+#include "funcrequest.h"
+#include "gettext.h"
+#include "intl.h"
+#include "LaTeXFeatures.h"
#include "LColor.h"
+#include "lyxfont.h"
+#include "lyxcursor.h"
+#include "lyxfind.h"
+#include "lyxlex.h"
#include "lyxrow.h"
#include "lyxrc.h"
-#include "intl.h"
-#include "trans_mgr.h"
-#include "frontends/screen.h"
-#include "gettext.h"
-#include "lyxfunc.h"
+#include "lyxtext.h"
+#include "paragraph.h"
#include "ParagraphParameters.h"
+#include "trans_mgr.h"
#include "undo_funcs.h"
-#include "lyxfind.h"
-#include "funcrequest.h"
+#include "WordLangTuple.h"
+#include "paragraph_funcs.h"
+#include "sgml.h"
+#include "rowpainter.h"
#include "frontends/Alert.h"
#include "frontends/Dialogs.h"
+#include "frontends/font_metrics.h"
+#include "frontends/LyXView.h"
+#include "frontends/Painter.h"
+#include "frontends/screen.h"
#include "support/textutils.h"
#include "support/LAssert.h"
#include "support/lstrings.h"
#include "support/lyxalgo.h" // lyx::count
+#include <boost/bind.hpp>
+
#include <fstream>
#include <algorithm>
#include <cstdlib>
using std::make_pair;
using std::vector;
using std::pair;
+using std::for_each;
using lyx::pos_type;
using lyx::textclass_type;
void InsetText::saveLyXTextState(LyXText * t) const
{
// check if my paragraphs are still valid
- Paragraph * p = par;
- while (p) {
- if (p == t->cursor.par())
+ ParagraphList::iterator it = paragraphs.begin();
+ ParagraphList::iterator end = paragraphs.end();
+ for (; it != end; ++it) {
+ if (&*it == t->cursor.par())
break;
- p = p->next();
}
- if (p && t->cursor.pos() <= p->size()) {
+ if (it != end && t->cursor.pos() <= it->size()) {
sstate.lpar = t->cursor.par();
sstate.pos = t->cursor.pos();
sstate.boundary = t->cursor.boundary();
}
}
+
void InsetText::restoreLyXTextState(BufferView * bv, LyXText * t) const
{
if (sstate.lpar) {
: UpdatableInset(), lt(0), in_update(false), do_resize(0),
do_reinit(false)
{
- par = new Paragraph;
- par->layout(bp.getLyXTextClass().defaultLayout());
+ paragraphs.set(new Paragraph);
+ paragraphs.begin()->layout(bp.getLyXTextClass().defaultLayout());
+ if (bp.tracking_changes)
+ paragraphs.begin()->trackChanges();
init();
}
: UpdatableInset(in, same_id), lt(0), in_update(false), do_resize(0),
do_reinit(false)
{
- par = 0;
init(&in, same_id);
}
void InsetText::init(InsetText const * ins, bool same_id)
{
if (ins) {
- setParagraphData(ins->par, same_id);
+ setParagraphData(&*(ins->paragraphs.begin()), same_id);
autoBreakRows = ins->autoBreakRows;
drawFrame_ = ins->drawFrame_;
frame_color = ins->frame_color;
if (same_id)
id_ = ins->id_;
} else {
- Paragraph * p = par;
- while (p) {
- p->setInsetOwner(this);
- p = p->next();
- }
+ for_each(paragraphs.begin(), paragraphs.end(),
+ boost::bind(&Paragraph::setInsetOwner, _1, this));
+
the_locking_inset = 0;
drawFrame_ = NEVER;
frame_color = LColor::insetframe;
InsetText::~InsetText()
{
- cached_bview = 0;
-
- // NOTE
-
- while (par) {
- Paragraph * tmp = par->next();
- delete par;
- par = tmp;
- }
+ paragraphs.clear();
}
-void InsetText::clear()
+void InsetText::clear(bool just_mark_erased)
{
+ if (just_mark_erased) {
+ ParagraphList::iterator it = paragraphs.begin();
+ ParagraphList::iterator end = paragraphs.end();
+ for (; it != end; ++it) {
+ it->markErased();
+ }
+ need_update = FULL;
+ return;
+ }
+
// This is a gross hack...
- LyXLayout_ptr old_layout = par->layout();
+ LyXLayout_ptr old_layout = paragraphs.begin()->layout();
- while (par) {
- Paragraph * tmp = par->next();
- delete par;
- par = tmp;
- }
- par = new Paragraph;
- par->setInsetOwner(this);
- par->layout(old_layout);
+ paragraphs.clear();
+ paragraphs.set(new Paragraph);
+ paragraphs.begin()->setInsetOwner(this);
+ paragraphs.begin()->layout(old_layout);
reinitLyXText();
need_update = INIT;
void InsetText::writeParagraphData(Buffer const * buf, ostream & os) const
{
- par->writeFile(buf, os, buf->params, 0);
+ ParagraphList::iterator it = paragraphs.begin();
+ ParagraphList::iterator end = paragraphs.end();
+ Paragraph::depth_type dth = 0;
+ for (; it != end; ++it) {
+ it->write(buf, os, buf->params, dth);
+ }
}
Paragraph::depth_type depth = 0;
LyXFont font(LyXFont::ALL_INHERIT);
- clear();
+ clear(false);
+
+ if (buf->params.tracking_changes)
+ paragraphs.begin()->trackChanges();
while (lex.isOK()) {
lex.nextToken();
if (token.empty())
continue;
if (token == "\\end_inset") {
-#ifndef NO_COMPABILITY
- const_cast<Buffer*>(buf)->insertErtContents(par, pos, false);
-#endif
break;
}
+ Paragraph * tmp = &*(paragraphs.begin());
+
if (const_cast<Buffer*>(buf)->
- parseSingleLyXformat2Token(lex, par, return_par,
+ parseSingleLyXformat2Token(lex, tmp, return_par,
token, pos, depth, font)) {
// the_end read this should NEVER happen
lex.printError("\\the_end read in inset! Error in document!");
return;
}
+ paragraphs.set(tmp);
}
if (!return_par)
- return_par = par;
- par = return_par;
+ return_par = &*(paragraphs.begin());
+ paragraphs.set(return_par);
while (return_par) {
return_par->setInsetOwner(this);
return_par = return_par->next();
}
// no draw is necessary !!!
- if ((drawFrame_ == LOCKED) && !locked && !par->size()) {
+ if ((drawFrame_ == LOCKED) && !locked && paragraphs.begin()->empty()) {
top_baseline = baseline;
x += width(bv, f);
if (need_update & CLEAR_FRAME)
int yf = y_offset + first;
y = 0;
while ((row != 0) && (yf < ph)) {
- lt->getVisibleRow(bv, y + y_offset + first, int(x),
- row, y + lt->first_y, cleared);
+ Row * prev = row->previous();
+ RowPainter rp(*bv, *lt, *row);
+ if (rp.paint(y + y_offset + first, int(x), y + lt->first_y, cleared))
+ lt->markChangeInDraw(bv, row, prev);
if (bv->text->status() == LyXText::CHANGED_IN_DRAW) {
lt->need_break_row = row;
lt->fullRebreak(bv);
return;
}
- if (!autoBreakRows && par->next())
+ if (!autoBreakRows && paragraphs.begin()->next())
collapseParagraphs(bv);
if (the_locking_inset) {
void InsetText::updateLocal(BufferView * bv, int what, bool mark_dirty) const
{
- if (!autoBreakRows && par->next())
+ if (!autoBreakRows && paragraphs.begin()->next())
collapseParagraphs(bv);
bool clear = false;
if (!lt) {
finishUndo();
// If the inset is empty set the language of the current font to the
// language to the surronding text (if different).
- if (par->size() == 0 && !par->next() &&
+ if (paragraphs.begin()->empty() && !paragraphs.begin()->next() &&
bv->getParentLanguage(this) != lt->current_font.language())
{
LyXFont font(LyXFont::ALL_IGNORE);
showInsetCursor(bv);
// Tell the paragraph dialog that we've entered an insettext.
- bv->owner()->getDialogs()->updateParagraph();
+ bv->owner()->getDialogs().updateParagraph();
}
clear = true;
}
if (front)
- lt->setCursor(bv, par, 0);
+ lt->setCursor(bv, &*(paragraphs.begin()), 0);
else {
- Paragraph * p = par;
- while (p->next())
- p = p->next();
+ ParagraphList::iterator it = paragraphs.begin();
+ ParagraphList::iterator end = paragraphs.end();
+ while (boost::next(it) != end)
+ ++it;
// int const pos = (p->size() ? p->size()-1 : p->size());
- lt->setCursor(bv, p, p->size());
+ lt->setCursor(bv, &*it, it->size());
}
lt->clearSelection();
finishUndo();
// If the inset is empty set the language of the current font to the
// language to the surronding text (if different).
- if (par->size() == 0 && !par->next() &&
+ if (paragraphs.begin()->empty() && !paragraphs.begin()->next() &&
bv->getParentLanguage(this) != lt->current_font.language()) {
LyXFont font(LyXFont::ALL_IGNORE);
font.setLanguage(bv->getParentLanguage(this));
} else
bv->owner()->setLayout(bv->text->cursor.par()->layout()->name());
// hack for deleteEmptyParMech
- if (par->size()) {
- lt->setCursor(bv, par, 0);
- } else if (par->next()) {
- lt->setCursor(bv, par->next(), 0);
+ if (!paragraphs.begin()->empty()) {
+ lt->setCursor(bv, &*(paragraphs.begin()), 0);
+ } else if (paragraphs.begin()->next()) {
+ lt->setCursor(bv, paragraphs.begin()->next(), 0);
}
if (clear)
lt = 0;
lt = getLyXText(bv);
clear = true;
}
- lt->setCursor(bv, par, 0);
+ lt->setCursor(bv, &*(paragraphs.begin()), 0);
lt->clearSelection();
finishUndo();
// If the inset is empty set the language of the current font to the
// language to the surronding text (if different).
- if (par->size() == 0 && !par->next() &&
+ if (paragraphs.begin()->empty() && !paragraphs.begin()->next() &&
bv->getParentLanguage(this) != lt->current_font.language()) {
LyXFont font(LyXFont::ALL_IGNORE);
font.setLanguage(bv->getParentLanguage(this));
if (!inset)
return false;
if (!the_locking_inset) {
- Paragraph * p = par;
+ Paragraph * p = &*(paragraphs.begin());
int const id = inset->id();
while(p) {
- Paragraph::inset_iterator it =
- p->inset_iterator_begin();
- Paragraph::inset_iterator const end =
- p->inset_iterator_end();
+ InsetList::iterator it =
+ p->insetlist.begin();
+ InsetList::iterator const end =
+ p->insetlist.end();
for (; it != end; ++it) {
- if ((*it) == inset) {
+ if (it.getInset() == inset) {
getLyXText(bv)->setCursorIntern(bv, p, it.getPos());
lockInset(bv, inset);
return true;
}
- if ((*it)->getInsetFromID(id)) {
+ if (it.getInset()->getInsetFromID(id)) {
getLyXText(bv)->setCursorIntern(bv, p, it.getPos());
- (*it)->edit(bv);
+ it.getInset()->edit(bv);
return the_locking_inset->lockInsetInInset(bv, inset);
}
}
bool InsetText::updateInsetInInset(BufferView * bv, Inset * inset)
{
- if (!autoBreakRows && par->next())
+ if (!autoBreakRows && paragraphs.begin()->next())
collapseParagraphs(bv);
if (inset == this)
return true;
}
-void InsetText::insetButtonPress(BufferView * bv,
- int x, int y, mouse_button::state button)
+void InsetText::lfunMousePress(FuncRequest const & cmd)
{
no_selection = true;
// use this to check mouse motion for selection!
- mouse_x = x;
- mouse_y = y;
+ mouse_x = cmd.x;
+ mouse_y = cmd.y;
+ BufferView * bv = cmd.view();
+ FuncRequest cmd1 = cmd;
+ cmd1.x -= inset_x;
+ cmd1.y -= inset_y;
if (!locked)
lockInset(bv);
- int tmp_x = x - drawTextXOffset;
- int tmp_y = y + insetAscent - getLyXText(bv)->first_y;
- Inset * inset = bv->checkInsetHit(getLyXText(bv), tmp_x, tmp_y);
+ int tmp_x = cmd.x - drawTextXOffset;
+ int tmp_y = cmd.y + insetAscent - getLyXText(bv)->first_y;
+ Inset * inset = getLyXText(bv)->checkInsetHit(bv, tmp_x, tmp_y);
hideInsetCursor(bv);
if (the_locking_inset) {
if (the_locking_inset == inset) {
- the_locking_inset->insetButtonPress(bv,
- x - inset_x,
- y - inset_y,
- button);
+ the_locking_inset->localDispatch(cmd1);
return;
}
#if 0
inset_x = cix(bv) - top_x + drawTextXOffset;
inset_y = ciy(bv) + drawTextYOffset;
the_locking_inset = 0;
- inset->insetButtonPress(bv, x - inset_x,
- y - inset_y, button);
+ inset->localDispatch(cmd1);
// inset->edit(bv, x - inset_x, y - inset_y, button);
if (the_locking_inset)
updateLocal(bv, CURSOR, false);
if (bv->theLockingInset()) {
if (isHighlyEditableInset(inset)) {
// We just have to lock the inset before calling a
- // PressFuncRequest on it!
+ // PressEvent on it!
UpdatableInset * uinset = static_cast<UpdatableInset*>(inset);
if (!bv->lockInset(uinset)) {
lyxerr[Debug::INSETS] << "Cannot lock inset" << endl;
}
- inset->insetButtonPress(bv, x - inset_x, y - inset_y, button);
+ inset->localDispatch(cmd1);
if (the_locking_inset)
updateLocal(bv, CURSOR, false);
return;
}
if (!inset) { // && (button == mouse_button::button2)) {
bool paste_internally = false;
- if ((button == mouse_button::button2) && getLyXText(bv)->selection.set()) {
- localDispatch(bv, FuncRequest(LFUN_COPY));
+ if (cmd.button() == mouse_button::button2 && getLyXText(bv)->selection.set()) {
+ localDispatch(FuncRequest(bv, LFUN_COPY));
paste_internally = true;
}
bool clear = false;
}
int old_first_y = lt->first_y;
- lt->setCursorFromCoordinates(bv, x - drawTextXOffset,
- y + insetAscent);
+ lt->setCursorFromCoordinates(bv, cmd.x - drawTextXOffset,
+ cmd.y + insetAscent);
// set the selection cursor!
lt->selection.cursor = lt->cursor;
lt->cursor.x_fix(lt->cursor.x());
// Insert primary selection with middle mouse
// if there is a local selection in the current buffer,
// insert this
- if (button == mouse_button::button2) {
+ if (cmd.button() == mouse_button::button2) {
if (paste_internally)
- localDispatch(bv, FuncRequest(LFUN_PASTE));
+ localDispatch(FuncRequest(bv, LFUN_PASTE));
else
- localDispatch(bv, FuncRequest(LFUN_PASTESELECTION, "paragraph"));
+ localDispatch(FuncRequest(bv, LFUN_PASTESELECTION, "paragraph"));
}
} else {
getLyXText(bv)->clearSelection();
}
-bool InsetText::insetButtonRelease(BufferView * bv,
- int x, int y, mouse_button::state button)
+bool InsetText::lfunMouseRelease(FuncRequest const & cmd)
{
+ BufferView * bv = cmd.view();
+ FuncRequest cmd1 = cmd;
+ cmd1.x -= inset_x;
+ cmd1.y -= inset_y;
+
no_selection = true;
- if (the_locking_inset) {
- return the_locking_inset->insetButtonRelease(bv,
- x - inset_x, y - inset_y,
- button);
- }
- int tmp_x = x - drawTextXOffset;
- int tmp_y = y + insetAscent - getLyXText(bv)->first_y;
- Inset * inset = bv->checkInsetHit(getLyXText(bv), tmp_x, tmp_y);
+ if (the_locking_inset)
+ return the_locking_inset->localDispatch(cmd1);
+
+ int tmp_x = cmd.x - drawTextXOffset;
+ int tmp_y = cmd.y + insetAscent - getLyXText(bv)->first_y;
+ Inset * inset = getLyXText(bv)->checkInsetHit(bv, tmp_x, tmp_y);
bool ret = false;
if (inset) {
- if (isHighlyEditableInset(inset)) {
- ret = inset->insetButtonRelease(bv, x - inset_x,
- y - inset_y, button);
- } else {
+ if (isHighlyEditableInset(inset))
+ ret = inset->localDispatch(cmd1);
+ else {
inset_x = cix(bv) - top_x + drawTextXOffset;
inset_y = ciy(bv) + drawTextYOffset;
- ret = inset->insetButtonRelease(bv, x - inset_x,
- y - inset_y, button);
- inset->edit(bv, x - inset_x,
- y - inset_y, button);
+ cmd1.x = cmd.x - inset_x;
+ cmd1.y = cmd.x - inset_y;
+// note that we should do ret = inset->localDispatch(cmd1)
+// and fix this instead (Alfredo);
+ ret = true;
+ inset->edit(bv, cmd1.x, cmd1.y, cmd.button());
}
updateLocal(bv, CURSOR_PAR, false);
}
}
-void InsetText::insetMotionNotify(BufferView * bv, int x, int y, mouse_button::state state)
+void InsetText::lfunMouseMotion(FuncRequest const & cmd)
{
+ FuncRequest cmd1 = cmd;
+ cmd1.x -= inset_x;
+ cmd1.y -= inset_y;
+
if (the_locking_inset) {
- the_locking_inset->insetMotionNotify(bv, x - inset_x,
- y - inset_y,state);
+ the_locking_inset->localDispatch(cmd1);
return;
}
- if (no_selection || ((mouse_x == x) && (mouse_y == y)))
+ if (no_selection || (mouse_x == cmd.x && mouse_y == cmd.y))
return;
+ BufferView * bv = cmd.view();
bool clear = false;
if (!lt) {
lt = getLyXText(bv);
}
hideInsetCursor(bv);
LyXCursor cur = lt->cursor;
- lt->setCursorFromCoordinates(bv, x - drawTextXOffset, y + insetAscent);
+ lt->setCursorFromCoordinates
+ (bv, cmd.x - drawTextXOffset, cmd.y + insetAscent);
lt->cursor.x_fix(lt->cursor.x());
if (cur == lt->cursor) {
if (clear)
}
-UpdatableInset::RESULT
-InsetText::localDispatch(BufferView * bv, FuncRequest const & ev)
+Inset::RESULT InsetText::localDispatch(FuncRequest const & ev)
{
- bool was_empty = par->size() == 0 && !par->next();
+ BufferView * bv = ev.view();
+ switch (ev.action) {
+ case LFUN_MOUSE_PRESS:
+ lfunMousePress(ev);
+ return DISPATCHED;
+ case LFUN_MOUSE_MOTION:
+ lfunMouseMotion(ev);
+ return DISPATCHED;
+ case LFUN_MOUSE_RELEASE:
+ return lfunMouseRelease(ev) ? DISPATCHED : UNDISPATCHED;
+ default:
+ break;
+ }
+
+ bool was_empty = (paragraphs.begin()->empty() && !paragraphs.begin()->next());
no_selection = false;
- UpdatableInset::RESULT
- result= UpdatableInset::localDispatch(bv, ev);
+ RESULT result = UpdatableInset::localDispatch(ev);
if (result != UNDISPATCHED)
return DISPATCHED;
return FINISHED;
if (the_locking_inset) {
- result = the_locking_inset->localDispatch(bv, ev);
+ result = the_locking_inset->localDispatch(ev);
if (result == DISPATCHED_NOUPDATE)
return result;
else if (result == DISPATCHED) {
}
break;
case FINISHED_DOWN:
- {
- LyXText *lt = getLyXText(bv);
- if (lt->cursor.irow()->next()) {
- lt->setCursorFromCoordinates(
- bv, lt->cursor.ix() + inset_x,
- lt->cursor.iy() -
- lt->cursor.irow()->baseline() +
- lt->cursor.irow()->height() + 1);
- lt->cursor.x_fix(lt->cursor.x());
+ if ((result = moveDown(bv)) >= FINISHED) {
updateLocal(bv, CURSOR, false);
- } else {
bv->unlockInset(this);
}
- }
break;
default:
result = DISPATCHED;
int updwhat = 0;
int updflag = false;
switch (ev.action) {
+
// Normal chars
case LFUN_SELFINSERT:
if (bv->buffer()->isReadonly()) {
* typed in now. Depends on lyxrc settings
* "auto_region_delete", which defaults to
* true (on). */
-
+#if 0
+ // This should not be needed here and is also WRONG!
setUndo(bv, Undo::INSERT,
lt->cursor.par(), lt->cursor.par()->next());
+#endif
bv->switchKeyMap();
if (lyxrc.auto_region_delete) {
if (lt->selection.set()) {
}
lt->clearSelection();
for (string::size_type i = 0; i < ev.argument.length(); ++i) {
- bv->owner()->getIntl()->getTransManager().
+ bv->owner()->getIntl().getTransManager().
TranslateAndInsert(ev.argument[i], lt);
}
}
lt->cursorEnd(bv);
updwhat = CURSOR;
break;
+ case LFUN_PRIOR:
+ if (!crow(bv)->previous())
+ result = FINISHED_UP;
+ else {
+ lt->cursorPrevious(bv);
+ result = DISPATCHED_NOUPDATE;
+ }
+ updwhat = CURSOR;
+ break;
+ case LFUN_NEXT:
+ if (!crow(bv)->next())
+ result = FINISHED_DOWN;
+ else {
+ lt->cursorNext(bv);
+ result = DISPATCHED_NOUPDATE;
+ }
+ updwhat = CURSOR;
+ break;
case LFUN_BACKSPACE: {
- setUndo(bv, Undo::DELETE,
- lt->cursor.par(), lt->cursor.par()->next());
if (lt->selection.set())
lt->cutSelection(bv, true, false);
else
break;
case LFUN_DELETE: {
- setUndo(bv, Undo::DELETE,
- lt->cursor.par(), lt->cursor.par()->next());
if (lt->selection.set()) {
lt->cutSelection(bv, true, false);
} else {
break;
case LFUN_CUT: {
- setUndo(bv, Undo::DELETE,
- lt->cursor.par(), lt->cursor.par()->next());
lt->cutSelection(bv);
updwhat = CURSOR_PAR;
updflag = true;
if (!autoBreakRows) {
if (CutAndPaste::nrOfParagraphs() > 1) {
- Alert::alert(_("Impossible operation"),
+ Alert::alert(_("Impossible operation!"),
_("Cannot include more than one paragraph!"),
_("Sorry."));
break;
}
}
+#if 0
+ // This should not be needed here and is also WRONG!
setUndo(bv, Undo::INSERT,
lt->cursor.par(), lt->cursor.par()->next());
+#endif
lt->pasteSelection(bv);
// bug 393
lt->clearSelection();
result = DISPATCHED;
break;
}
+#if 0
+ // This should not be needed here and is also WRONG!
setUndo(bv, Undo::INSERT,
lt->cursor.par(), lt->cursor.par()->next());
+#endif
lt->insertChar(bv, Paragraph::META_NEWLINE);
updwhat = CURSOR | CURSOR_PAR;
updflag = true;
// see if we found the layout number:
if (!hasLayout) {
FuncRequest lf(LFUN_MESSAGE, N_("Layout ") + ev.argument + N_(" not known"));
- bv->owner()->getLyXFunc()->dispatch(lf);
+ bv->owner()->dispatch(lf);
break;
}
updateLocal(bv, updwhat, updflag);
/// If the action has deleted all text in the inset, we need to change the
// language to the language of the surronding text.
- if (!was_empty && par->size() == 0 && !par->next()) {
+ if (!was_empty && paragraphs.begin()->empty() && !paragraphs.begin()->next()) {
LyXFont font(LyXFont::ALL_IGNORE);
font.setLanguage(bv->getParentLanguage(this));
setFont(bv, font, false);
}
-int InsetText::latex(Buffer const * buf, ostream & os, bool moving_arg, bool) const
+int InsetText::latex(Buffer const * buf, ostream & os,
+ bool moving_arg, bool) const
{
TexRow texrow;
- buf->latexParagraphs(os, par, 0, texrow, moving_arg);
+ buf->latexParagraphs(os, paragraphs.begin(), paragraphs.end(),
+ texrow, moving_arg);
return texrow.rows();
}
int InsetText::ascii(Buffer const * buf, ostream & os, int linelen) const
{
- Paragraph * p = par;
unsigned int lines = 0;
- while (p) {
- string const tmp = buf->asciiParagraph(p, linelen, p->previous()==0);
+ ParagraphList::iterator beg = paragraphs.begin();
+ ParagraphList::iterator end = paragraphs.end();
+ ParagraphList::iterator it = beg;
+ for (; it != end; ++it) {
+ string const tmp = buf->asciiParagraph(*it, linelen, it == beg);
lines += lyx::count(tmp.begin(), tmp.end(), '\n');
os << tmp;
- p = p->next();
}
return lines;
}
int InsetText::docbook(Buffer const * buf, ostream & os, bool mixcont) const
{
- Paragraph * p = par;
+ Paragraph * p = &*(paragraphs.begin());
unsigned int lines = 0;
vector<string> environment_stack(10);
for (; depth > p->params().depth(); --depth) {
if (environment_inner[depth] != "!-- --") {
item_name = "listitem";
- lines += buf->sgmlCloseTag(os, command_depth + depth, mixcont, item_name);
+ lines += sgml::closeTag(os, command_depth + depth, mixcont, item_name);
if (environment_inner[depth] == "varlistentry")
- lines += buf->sgmlCloseTag(os, depth+command_depth, mixcont, environment_inner[depth]);
+ lines += sgml::closeTag(os, depth+command_depth, mixcont, environment_inner[depth]);
}
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, environment_stack[depth]);
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, environment_stack[depth]);
environment_stack[depth].erase();
environment_inner[depth].erase();
}
&& !environment_stack[depth].empty()) {
if (environment_inner[depth] != "!-- --") {
item_name= "listitem";
- lines += buf->sgmlCloseTag(os, command_depth+depth, mixcont, item_name);
+ lines += sgml::closeTag(os, command_depth+depth, mixcont, item_name);
if (environment_inner[depth] == "varlistentry")
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, environment_inner[depth]);
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, environment_inner[depth]);
}
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, environment_stack[depth]);
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, environment_stack[depth]);
environment_stack[depth].erase();
environment_inner[depth].erase();
// Write opening SGML tags.
switch (style->latextype) {
case LATEX_PARAGRAPH:
- lines += buf->sgmlOpenTag(os, depth + command_depth, mixcont, style->latexname());
+ lines += sgml::openTag(os, depth + command_depth, mixcont, style->latexname());
break;
case LATEX_COMMAND:
- buf->sgmlError(p, 0, _("Error : LatexType Command not allowed here.\n"));
+ buf->sgmlError(p, 0, _("Error: LatexType Command not allowed here.\n"));
return -1;
break;
}
environment_stack[depth] = style->latexname();
environment_inner[depth] = "!-- --";
- lines += buf->sgmlOpenTag(os, depth + command_depth, mixcont, environment_stack[depth]);
+ lines += sgml::openTag(os, depth + command_depth, mixcont, environment_stack[depth]);
} else {
if (environment_inner[depth] != "!-- --") {
item_name= "listitem";
- lines += buf->sgmlCloseTag(os, command_depth + depth, mixcont, item_name);
+ lines += sgml::closeTag(os, command_depth + depth, mixcont, item_name);
if (environment_inner[depth] == "varlistentry")
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, environment_inner[depth]);
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, environment_inner[depth]);
}
}
if (style->latexparam() == "CDATA")
os << "<![CDATA[";
else
- lines += buf->sgmlOpenTag(os, depth + command_depth, mixcont, style->latexparam());
+ lines += sgml::openTag(os, depth + command_depth, mixcont, style->latexparam());
}
break;
}
desc_on = (style->labeltype == LABEL_MANUAL);
- environment_inner[depth] = desc_on?"varlistentry":"listitem";
- lines += buf->sgmlOpenTag(os, depth + 1 + command_depth, mixcont, environment_inner[depth]);
+ environment_inner[depth] = desc_on ? "varlistentry" : "listitem";
+ lines += sgml::openTag(os, depth + 1 + command_depth, mixcont, environment_inner[depth]);
- item_name = desc_on?"term":"para";
- lines += buf->sgmlOpenTag(os, depth + 1 + command_depth, mixcont, item_name);
+ item_name = desc_on ? "term" : "para";
+ lines += sgml::openTag(os, depth + 1 + command_depth, mixcont, item_name);
break;
default:
- lines += buf->sgmlOpenTag(os, depth + command_depth, mixcont, style->latexname());
+ lines += sgml::openTag(os, depth + command_depth, mixcont, style->latexname());
break;
}
if (style->latexparam() == "CDATA")
os << "]]>";
else
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, style->latexparam());
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, style->latexparam());
}
break;
case LATEX_ITEM_ENVIRONMENT:
if (desc_on == 1) break;
end_tag= "para";
- lines += buf->sgmlCloseTag(os, depth + 1 + command_depth, mixcont, end_tag);
+ lines += sgml::closeTag(os, depth + 1 + command_depth, mixcont, end_tag);
break;
case LATEX_PARAGRAPH:
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, style->latexname());
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, style->latexname());
break;
default:
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, style->latexname());
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, style->latexname());
break;
}
}
if (!environment_stack[depth].empty()) {
if (environment_inner[depth] != "!-- --") {
item_name = "listitem";
- lines += buf->sgmlCloseTag(os, command_depth + depth, mixcont, item_name);
+ lines += sgml::closeTag(os, command_depth + depth, mixcont, item_name);
if (environment_inner[depth] == "varlistentry")
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, environment_inner[depth]);
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, environment_inner[depth]);
}
- lines += buf->sgmlCloseTag(os, depth + command_depth, mixcont, environment_stack[depth]);
+ lines += sgml::closeTag(os, depth + command_depth, mixcont, environment_stack[depth]);
}
}
void InsetText::validate(LaTeXFeatures & features) const
{
- Paragraph * p = par;
- while (p) {
- p->validate(features);
- p = p->next();
- }
-}
-
-
-int InsetText::beginningOfMainBody(Paragraph * p) const
-{
- if (p->layout()->labeltype != LABEL_MANUAL)
- return 0;
- else
- return p->beginningOfMainBody();
+ for_each(paragraphs.begin(), paragraphs.end(),
+ boost::bind(&Paragraph::validate, _1, boost::ref(features)));
}
}
-UpdatableInset::RESULT
+Inset::RESULT
InsetText::moveRight(BufferView * bv, bool activate_inset, bool selecting)
{
if (getLyXText(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params))
}
-UpdatableInset::RESULT
+Inset::RESULT
InsetText::moveLeft(BufferView * bv, bool activate_inset, bool selecting)
{
if (getLyXText(bv)->cursor.par()->isRightToLeftPar(bv->buffer()->params))
}
-UpdatableInset::RESULT
+Inset::RESULT
InsetText::moveRightIntern(BufferView * bv, bool front,
bool activate_inset, bool selecting)
{
}
-UpdatableInset::RESULT
+Inset::RESULT
InsetText::moveLeftIntern(BufferView * bv, bool front,
bool activate_inset, bool selecting)
{
}
-UpdatableInset::RESULT
-InsetText::moveUp(BufferView * bv)
+Inset::RESULT InsetText::moveUp(BufferView * bv)
{
if (!crow(bv)->previous())
return FINISHED_UP;
}
-UpdatableInset::RESULT
-InsetText::moveDown(BufferView * bv)
+Inset::RESULT InsetText::moveDown(BufferView * bv)
{
if (!crow(bv)->next())
return FINISHED_DOWN;
{
vector<string> label_list;
- Paragraph * tpar = par;
- while (tpar) {
- Paragraph::inset_iterator beg = tpar->inset_iterator_begin();
- Paragraph::inset_iterator end = tpar->inset_iterator_end();
+ ParagraphList::iterator pit = paragraphs.begin();
+ ParagraphList::iterator pend = paragraphs.end();
+ for (; pit != pend; ++pit) {
+ InsetList::iterator beg = pit->insetlist.begin();
+ InsetList::iterator end = pit->insetlist.end();
for (; beg != end; ++beg) {
- vector<string> const l = (*beg)->getLabelList();
+ vector<string> const l = beg.getInset()->getLabelList();
label_list.insert(label_list.end(), l.begin(), l.end());
}
- tpar = tpar->next();
}
return label_list;
}
the_locking_inset->setFont(bv, font, toggleall, selectall);
return;
}
- if ((!par->next() && !par->size()) || !cpar(bv)->size()) {
+ if ((!paragraphs.begin()->next() && paragraphs.begin()->empty()) || cpar(bv)->empty()) {
getLyXText(bv)->setFont(bv, font, toggleall);
return;
}
x -= drawTextXOffset;
int dummyx = x;
int dummyy = y + insetAscent;
- Inset * inset = bv->checkInsetHit(getLyXText(bv), dummyx, dummyy);
+ Inset * inset = getLyXText(bv)->checkInsetHit(bv, dummyx, dummyy);
// we only do the edit() call if the inset was hit by the mouse
// or if it is a highly editable inset. So we should call this
// function from our own edit with button < 0.
{
// we have to unlock any locked inset otherwise we're in troubles
the_locking_inset = 0;
- while (par) {
- Paragraph * tmp = par->next();
- delete par;
- par = tmp;
- }
- par = new Paragraph(*p, same_id);
- par->setInsetOwner(this);
- Paragraph * np = par;
+ paragraphs.clear();
+ paragraphs.set(new Paragraph(*p, same_id));
+ paragraphs.begin()->setInsetOwner(this);
+ Paragraph * np = &*(paragraphs.begin());
while (p->next()) {
p = p->next();
np->next(new Paragraph(*p, same_id));
}
+void InsetText::markNew(bool track_changes)
+{
+ ParagraphList::iterator pit = paragraphs.begin();
+ ParagraphList::iterator pend = paragraphs.end();
+ for (; pit != pend; ++pit) {
+ if (track_changes) {
+ pit->trackChanges();
+ } else {
+ // no-op when not tracking
+ pit->cleanChanges();
+ }
+ }
+}
+
+
void InsetText::setText(string const & data, LyXFont const & font)
{
- clear();
- for (unsigned int i=0; i < data.length(); ++i)
- par->insertChar(i, data[i], font);
+ clear(false);
+ for (unsigned int i = 0; i < data.length(); ++i)
+ paragraphs.begin()->insertChar(i, data[i], font);
reinitLyXText();
}
if (recursive && the_locking_inset)
return the_locking_inset->getLyXText(lbv, true);
LyXText * lt = cached_text.get();
- lyx::Assert(lt && lt->firstRow()->par() == par);
+ lyx::Assert(lt && lt->firstRow()->par() == &*(paragraphs.begin()));
return lt;
}
// Super UGLY! (Lgb)
it->second.remove = true;
if (recursive) {
/// then remove all LyXText in text-insets
- Paragraph * p = par;
- for (; p; p = p->next()) {
- p->deleteInsetsLyXText(bv);
- }
+ for_each(paragraphs.begin(), paragraphs.end(),
+ boost::bind(&Paragraph::deleteInsetsLyXText, _1, bv));
}
}
}
do_resize = 0;
// lyxerr << "InsetText::resizeLyXText\n";
- if (!par->next() && !par->size()) { // no data, resize not neccessary!
+ if (!paragraphs.begin()->next() && paragraphs.begin()->empty()) { // no data, resize not neccessary!
// we have to do this as a fixed width may have changed!
LyXText * t = getLyXText(bv);
saveLyXTextState(t);
LyXText * t = it->second.text.get();
saveLyXTextState(t);
- for (Paragraph * p = par; p; p = p->next()) {
- p->resizeInsetsLyXText(bv);
- }
+
+ for_each(paragraphs.begin(), paragraphs.end(),
+ boost::bind(&Paragraph::resizeInsetsLyXText, _1, bv));
+
t->init(bv, true);
restoreLyXTextState(bv, t);
if (the_locking_inset) {
do_reinit = false;
do_resize = 0;
// lyxerr << "InsetText::reinitLyXText\n";
- for(Cache::iterator it = cache.begin(); it != cache.end(); ++it) {
+ for (Cache::iterator it = cache.begin(); it != cache.end(); ++it) {
lyx::Assert(it->second.text.get());
LyXText * t = it->second.text.get();
BufferView * bv = it->first;
saveLyXTextState(t);
- for (Paragraph * p = par; p; p = p->next()) {
- p->resizeInsetsLyXText(bv);
- }
+
+ for_each(paragraphs.begin(), paragraphs.end(),
+ boost::bind(&Paragraph::resizeInsetsLyXText, _1, bv));
+
t->init(bv, true);
restoreLyXTextState(bv, t);
if (the_locking_inset) {
{
bool changed = false;
- for (Paragraph * p = par; p; p = p->next()) {
- for (int i = 0; i < p->size(); ++i) {
- if (p->getChar(i) == Paragraph::META_NEWLINE) {
+ ParagraphList::iterator it = paragraphs.begin();
+ ParagraphList::iterator end = paragraphs.end();
+ for (; it != end; ++it) {
+ for (int i = 0; i < it->size(); ++i) {
+ if (it->getChar(i) == Paragraph::META_NEWLINE) {
changed = true;
- p->erase(i);
+ it->erase(i);
}
}
}
}
-Paragraph * InsetText::getParFromID(int id) const
-{
-#if 0
- Paragraph * result = par;
- Paragraph * ires = 0;
- while (result && result->id() != id) {
- if ((ires = result->getParFromID(id)))
- return ires;
- result = result->next();
- }
- return result;
-#else
- Paragraph * tmp = par;
- while (tmp) {
- if (tmp->id() == id) {
- return tmp;
- }
- Paragraph * tmp2 = tmp->getParFromID(id);
- if (tmp2 != 0) {
- return tmp2;
- }
- tmp = tmp->next();
- }
- return 0;
-#endif
-}
-
-
Paragraph * InsetText::firstParagraph() const
{
Paragraph * result;
if (the_locking_inset)
if ((result = the_locking_inset->firstParagraph()))
return result;
- return par;
+ return &*(paragraphs.begin());
}
Paragraph * InsetText::getFirstParagraph(int i) const
{
- return (i == 0) ? par : 0;
+ return (i == 0) ? &*(paragraphs.begin()) : 0;
}
LyXCursor const & InsetText::cursor(BufferView * bv) const
{
- if (the_locking_inset)
- return the_locking_inset->cursor(bv);
- return getLyXText(bv)->cursor;
+ if (the_locking_inset)
+ return the_locking_inset->cursor(bv);
+ return getLyXText(bv)->cursor;
}
Paragraph * InsetText::paragraph() const
{
- return par;
+ return &*(paragraphs.begin());
}
// as we could have to insert a paragraph before this one and just
// link the actual to a new ones next and set it with this function
// and are done!
- par = p;
+ paragraphs.set(p);
// set ourself as owner for all the paragraphs inserted!
- Paragraph * np = par;
- while (np) {
- np->setInsetOwner(this);
- np = np->next();
- }
+ for_each(paragraphs.begin(), paragraphs.end(),
+ boost::bind(&Paragraph::setInsetOwner, _1, this));
+
reinitLyXText();
// redraw myself when asked for
need_update = INIT;
if (id_arg == id())
return const_cast<InsetText *>(this);
- Paragraph * lp = par;
-
- while (lp) {
- for (Paragraph::inset_iterator it = lp->inset_iterator_begin(),
- en = lp->inset_iterator_end();
- it != en; ++it)
- {
- if ((*it)->id() == id_arg)
- return *it;
- Inset * in = (*it)->getInsetFromID(id_arg);
+ ParagraphList::iterator pit = paragraphs.begin();
+ ParagraphList::iterator pend = paragraphs.end();
+ for (; pit != pend; ++pit) {
+ InsetList::iterator it = pit->insetlist.begin();
+ InsetList::iterator end = pit->insetlist.end();
+ for (; it != end; ++it) {
+ if (it.getInset()->id() == id_arg)
+ return it.getInset();
+ Inset * in = it.getInset()->getInsetFromID(id_arg);
if (in)
return in;
}
- lp = lp->next();
}
return 0;
}
-WordLangTuple InsetText::selectNextWordToSpellcheck(BufferView * bv, float & value) const
+WordLangTuple const
+InsetText::selectNextWordToSpellcheck(BufferView * bv,
+ float & value) const
{
bool clear = false;
WordLangTuple word;
}
+bool InsetText::nextChange(BufferView * bv, lyx::pos_type & length)
+{
+ bool clear = false;
+ if (!lt) {
+ lt = getLyXText(bv);
+ clear = true;
+ }
+ if (the_locking_inset) {
+ if (the_locking_inset->nextChange(bv, length))
+ return true;
+ lt->cursorRight(bv, true);
+ }
+ lyxfind::SearchResult result =
+ lyxfind::findNextChange(bv, lt, length);
+
+ if (result == lyxfind::SR_FOUND) {
+ LyXCursor cur = lt->cursor;
+ bv->unlockInset(bv->theLockingInset());
+ if (bv->lockInset(this))
+ locked = true;
+ lt->cursor = cur;
+ lt->setSelectionRange(bv, length);
+ updateLocal(bv, SELECTION, false);
+ }
+ if (clear)
+ lt = 0;
+ return result != lyxfind::SR_NOT_FOUND;
+}
+
+
bool InsetText::searchForward(BufferView * bv, string const & str,
bool cs, bool mw)
{
if (bv->lockInset(this))
locked = true;
lt->cursor = cur;
- lt->setSelectionOverString(bv, str);
+ lt->setSelectionRange(bv, str.length());
updateLocal(bv, SELECTION, false);
}
if (clear)
clear = true;
}
if (!locked) {
- Paragraph * p = par;
+ Paragraph * p = &*(paragraphs.begin());
while (p->next())
p = p->next();
lt->setCursor(bv, p, p->size());
if (bv->lockInset(this))
locked = true;
lt->cursor = cur;
- lt->setSelectionOverString(bv, str);
+ lt->setSelectionRange(bv, str.length());
updateLocal(bv, SELECTION, false);
}
if (clear)
void InsetText::collapseParagraphs(BufferView * bv) const
{
- BufferParams const & bparams = bv->buffer()->params;
LyXText * llt = getLyXText(bv);
- while(par->next()) {
- if (par->size() && par->next()->size() &&
- !par->isSeparator(par->size()-1))
+ while (paragraphs.begin()->next()) {
+ if (!paragraphs.begin()->empty() && !paragraphs.begin()->next()->empty() &&
+ !paragraphs.begin()->isSeparator(paragraphs.begin()->size() - 1))
{
- par->insertChar(par->size(), ' ');
+ paragraphs.begin()->insertChar(paragraphs.begin()->size(), ' ');
}
if (llt->selection.set()) {
- if (llt->selection.start.par() == par->next()) {
- llt->selection.start.par(par);
+ if (llt->selection.start.par() == paragraphs.begin()->next()) {
+ llt->selection.start.par(&*(paragraphs.begin()));
llt->selection.start.pos(
- llt->selection.start.pos() + par->size());
+ llt->selection.start.pos() + paragraphs.begin()->size());
}
- if (llt->selection.end.par() == par->next()) {
- llt->selection.end.par(par);
+ if (llt->selection.end.par() == paragraphs.begin()->next()) {
+ llt->selection.end.par(&*(paragraphs.begin()));
llt->selection.end.pos(
- llt->selection.end.pos() + par->size());
+ llt->selection.end.pos() + paragraphs.begin()->size());
}
}
- par->pasteParagraph(bparams);
+ mergeParagraph(bv->buffer(), paragraphs.begin());
}
reinitLyXText();
}
}
-void InsetText::appendParagraphs(BufferParams const & bparams,
+void InsetText::appendParagraphs(Buffer * buffer,
Paragraph * newpar)
{
+ BufferParams const & bparams = buffer->params;
Paragraph * buf;
Paragraph * tmpbuf = newpar;
Paragraph * lastbuffer = buf = new Paragraph(*tmpbuf, false);
+ if (bparams.tracking_changes)
+ buf->cleanChanges();
while (tmpbuf->next()) {
tmpbuf = tmpbuf->next();
lastbuffer->next(new Paragraph(*tmpbuf, false));
lastbuffer->next()->previous(lastbuffer);
lastbuffer = lastbuffer->next();
+ if (bparams.tracking_changes)
+ lastbuffer->cleanChanges();
}
- lastbuffer = par;
+ lastbuffer = &*(paragraphs.begin());
while (lastbuffer->next())
lastbuffer = lastbuffer->next();
- if (newpar->size() && lastbuffer->size() &&
- !lastbuffer->isSeparator(lastbuffer->size()-1))
+ if (!newpar->empty() && !lastbuffer->empty() &&
+ !lastbuffer->isSeparator(lastbuffer->size() - 1))
{
lastbuffer->insertChar(lastbuffer->size(), ' ');
}
// paste it!
lastbuffer->next(buf);
buf->previous(lastbuffer);
- lastbuffer->pasteParagraph(bparams);
+ mergeParagraph(buffer, lastbuffer);
reinitLyXText();
}
{
Paragraph * par = getFirstParagraph(0);
while (par) {
- Paragraph::inset_iterator it = par->inset_iterator_begin();
- Paragraph::inset_iterator end = par->inset_iterator_end();
+ InsetList::iterator it = par->insetlist.begin();
+ InsetList::iterator end = par->insetlist.end();
for (; it != end; ++it) {
- it->addPreview(loader);
+ it.getInset()->addPreview(loader);
}
par = par->next();