#include <config.h>
-#ifdef __GNUG__
-#pragma implementation "lyxtext.h"
-#endif
-
#include "lyxtext.h"
#include "LString.h"
#include "paragraph.h"
#include "counters.h"
#include "insets/inseterror.h"
-#include "insets/insetbib.h"
+#include "insets/insetbibitem.h"
#include "insets/insetspecialchar.h"
#include "insets/insettext.h"
#include "insets/insetfloat.h"
+#include "insets/insetwrap.h"
#include "support/LAssert.h"
#include "support/textutils.h"
#include "support/lstrings.h"
+#include "BoostFormat.h"
+
using std::vector;
using std::copy;
using std::endl;
LyXText::LyXText(BufferView * bv)
: height(0), width(0), first_y(0),
- bv_owner(bv), inset_owner(0), the_locking_inset(0),
- need_break_row(0), refresh_y(0), refresh_row(0),
+ inset_owner(0), the_locking_inset(0), need_break_row(0),
+ refresh_y(0), refresh_row(0), bv_owner(bv),
status_(LyXText::UNCHANGED), firstrow(0), lastrow(0)
{}
LyXText::LyXText(InsetText * inset)
- : height(0), width(0), first_y(0),
- bv_owner(0), inset_owner(inset), the_locking_inset(0),
- need_break_row(0), refresh_y(0), refresh_row(0),
- status_(LyXText::UNCHANGED), firstrow(0), lastrow(0)
+ : height(0), width(0), first_y(0),
+ inset_owner(inset), the_locking_inset(0), need_break_row(0),
+ refresh_y(0), refresh_row(0), bv_owner(0),
+ status_(LyXText::UNCHANGED), firstrow(0), lastrow(0)
{}
// We specialize the 95% common case:
if (!par->getDepth()) {
if (layout->labeltype == LABEL_MANUAL
- && pos < beginningOfMainBody(buf, par)) {
+ && pos < par->beginningOfMainBody()) {
// 1% goes here
LyXFont f = par->getFontSettings(buf->params, pos);
if (par->inInset())
LyXFont layoutfont;
- if (pos < beginningOfMainBody(buf, par)) {
+ if (pos < par->beginningOfMainBody()) {
// 1% goes here
layoutfont = layout->labelfont;
} else {
// Get concrete layout font to reduce against
LyXFont layoutfont;
- if (pos < beginningOfMainBody(buf, par))
+ if (pos < par->beginningOfMainBody())
layoutfont = layout->labelfont;
else
layoutfont = layout->font;
Inset * LyXText::getInset() const
{
- Inset * inset = 0;
- if (cursor.pos() == 0 && cursor.par()->bibkey) {
- inset = cursor.par()->bibkey;
- } else if (cursor.pos() < cursor.par()->size()
+ if (cursor.pos() < cursor.par()->size()
&& cursor.par()->isInset(cursor.pos())) {
- inset = cursor.par()->getInset(cursor.pos());
+ return cursor.par()->getInset(cursor.pos());
}
- return inset;
+ return 0;
}
/* used in setlayout */
// Asger is not sure we want to do this...
-void LyXText::makeFontEntriesLayoutSpecific(Buffer const * buf,
- Paragraph * par)
+void LyXText::makeFontEntriesLayoutSpecific(Buffer const & buf,
+ Paragraph & par)
{
- LyXLayout_ptr const & layout = par->layout();
+ LyXLayout_ptr const & layout = par.layout();
LyXFont layoutfont;
- for (pos_type pos = 0; pos < par->size(); ++pos) {
- if (pos < beginningOfMainBody(buf, par))
+ for (pos_type pos = 0; pos < par.size(); ++pos) {
+ if (pos < par.beginningOfMainBody())
layoutfont = layout->labelfont;
else
layoutfont = layout->font;
- LyXFont tmpfont = par->getFontSettings(buf->params, pos);
+ LyXFont tmpfont = par.getFontSettings(buf.params, pos);
tmpfont.reduce(layoutfont);
- par->setFont(pos, tmpfont);
+ par.setFont(pos, tmpfont);
}
}
do {
par->applyLayout(lyxlayout);
- makeFontEntriesLayoutSpecific(bview->buffer(), par);
+ makeFontEntriesLayoutSpecific(*bview->buffer(), *par);
Paragraph * fppar = par;
fppar->params().spaceTop(lyxlayout->fill_top ?
VSpace(VSpace::VFILL)
: VSpace(VSpace::NONE));
if (lyxlayout->margintype == MARGIN_MANUAL)
par->setLabelWidthString(lyxlayout->labelstring());
- if (lyxlayout->labeltype != LABEL_BIBLIO
- && fppar->bibkey) {
- delete fppar->bibkey;
- fppar->bibkey = 0;
- }
cur.par(par);
par = par->next();
} while (par != epar);
// and sel_end cursor
cursor = selection.start;
- bool anything_changed = false;
-
while (true) {
// NOTE: you can't change the depth of a bibliography entry
if (cursor.par()->layout()->labeltype != LABEL_BIBLIO) {
if (cursor.par()->getDepth()
< prev->getMaxDepthAfter()) {
cursor.par()->params().depth(cursor.par()->getDepth() + 1);
- anything_changed = true;
}
}
}
cursor.par(cursor.par()->next());
}
- // if nothing changed set all depth to 0
- if (!anything_changed) {
- cursor = selection.start;
- while (cursor.par() != selection.end.par()) {
- cursor.par()->params().depth(0);
- cursor.par(cursor.par()->next());
- }
- cursor.par()->params().depth(0);
- }
-
redoParagraphs(bview, selection.start, endpar);
// we have to reset the selection, because the
if (!selection.set()) {
// Determine basis font
LyXFont layoutfont;
- if (cursor.pos() < beginningOfMainBody(bview->buffer(),
- cursor.par())) {
+ if (cursor.pos() < cursor.par()->beginningOfMainBody()) {
layoutfont = getLabelFont(bview->buffer(),
cursor.par());
} else {
{
if (!cursor.row()->next()
|| cursor.row()->next()->par() != cursor.row()->par()) {
- setCursor(bview, cursor.par(), rowLast(cursor.row()) + 1);
+ setCursor(bview, cursor.par(), cursor.row()->lastPos() + 1);
} else {
if (!cursor.par()->empty() &&
- (cursor.par()->getChar(rowLast(cursor.row())) == ' '
- || cursor.par()->isNewline(rowLast(cursor.row())))) {
- setCursor(bview, cursor.par(), rowLast(cursor.row()));
+ (cursor.par()->getChar(cursor.row()->lastPos()) == ' '
+ || cursor.par()->isNewline(cursor.row()->lastPos()))) {
+ setCursor(bview, cursor.par(), cursor.row()->lastPos());
} else {
setCursor(bview,cursor.par(),
- rowLast(cursor.row()) + 1);
+ cursor.row()->lastPos() + 1);
}
}
}
string LyXText::getStringToIndex(BufferView * bview)
{
- string idxstring;
-
// Try implicit word selection
// If there is a change in the language the implicit word selection
// is disabled.
LyXCursor const reset_cursor = cursor;
bool const implicitSelection = selectWordWhenUnderCursor(bview, PREVIOUS_WORD);
- if (!selection.set()) {
+ string idxstring;
+ if (!selection.set())
bview->owner()->message(_("Nothing to index!"));
- return string();
- }
- if (selection.start.par() != selection.end.par()) {
+ else if (selection.start.par() != selection.end.par())
bview->owner()->message(_("Cannot index more than one paragraph!"));
- return string();
- }
+ else
+ idxstring = selectionAsString(bview->buffer(), false);
- idxstring = selectionAsString(bview->buffer(), false);
+ // Reset cursors to their original position.
+ cursor = reset_cursor;
+ setCursor(bview, cursor.par(), cursor.pos());
+ selection.cursor = cursor;
- // Implicit selections are cleared afterwards
- //and cursor is set to the original position.
- if (implicitSelection) {
+ // Clear the implicit selection.
+ if (implicitSelection)
clearSelection();
- cursor = reset_cursor;
- setCursor(bview, cursor.par(), cursor.pos());
- selection.cursor = cursor;
- }
- return idxstring;
-}
-
-pos_type LyXText::beginningOfMainBody(Buffer const * /*buf*/,
- Paragraph const * par) const
-{
- if (par->layout()->labeltype != LABEL_MANUAL)
- return 0;
- else
- return par->beginningOfMainBody();
+ return idxstring;
}
// is it a layout that has an automatic label?
if (layout->labeltype >= LABEL_COUNTER_CHAPTER) {
+ int const i = layout->labeltype - LABEL_COUNTER_CHAPTER;
- int i = layout->labeltype - LABEL_COUNTER_CHAPTER;
- string numbertype;
- string langtype;
ostringstream s;
if (i >= 0 && i <= buf->params.secnumdepth) {
+ string numbertype;
+ string langtype;
textclass.counters().step(layout->latexname());
// Is there a label? Useful for Chapter layout
if (!par->params().appendix()) {
- if (!layout->labelstring().empty())
- par->params().labelString(layout->labelstring());
- else
- par->params().labelString(string());
+ s << layout->labelstring();
} else {
- if (!layout->labelstring_appendix().empty())
- par->params().labelString(layout->labelstring_appendix());
- else
- par->params().labelString(string());
+ s << layout->labelstring_appendix();
}
- // Use if an integer is here less than elegant. For now.
+ // Use of an integer is here less than elegant. For now.
int head = textclass.maxcounter() - LABEL_COUNTER_CHAPTER;
if (!par->params().appendix()) {
numbertype = "sectioning";
.numberLabel(layout->latexname(),
numbertype, langtype, head);
- par->params().labelString(par->params().labelString() + s.str().c_str());
- // We really want to remove the c_str as soon as
- // possible...
+ par->params().labelString(STRCONV(s.str()));
// reset enum counters
textclass.counters().reset("enum");
textclass.counters().step(enumcounter);
s << textclass.counters()
- .numberLabel(enumcounter,
- "enumeration", langtype);
- par->params().labelString(s.str().c_str());
+ .numberLabel(enumcounter, "enumeration");
+ par->params().labelString(STRCONV(s.str()));
}
} else if (layout->labeltype == LABEL_BIBLIO) {// ale970302
textclass.counters().step("bibitem");
int number = textclass.counters().value("bibitem");
- if (!par->bibkey) {
- InsetCommandParams p("bibitem");
- par->bibkey = new InsetBibKey(p);
+ if (par->bibitem()) {
+ par->bibitem()->setCounter(number);
+ par->params().labelString(layout->labelstring());
}
- par->bibkey->setCounter(number);
- par->params().labelString(layout->labelstring());
-
// In biblio should't be following counters but...
} else {
string s = layout->labelstring();
while (tmppar && tmppar->inInset()
// the single '=' is intended below
&& (in = tmppar->inInset()->owner())) {
- if (in->lyxCode() == Inset::FLOAT_CODE) {
+ if (in->lyxCode() == Inset::FLOAT_CODE ||
+ in->lyxCode() == Inset::WRAP_CODE) {
isOK = true;
break;
} else {
textclass.counters().step(fl.type());
// Doesn't work... yet.
+#warning use boost.format
+#if USE_BOOST_FORMAT
+ s = boost::io::str(boost::format(_("%1$s #:")) % fl.name());
+ // s << boost::format(_("%1$s %1$d:")
+ // % fl.name()
+ // % buf->counters().value(fl.name());
+#else
ostringstream o;
- //o << fl.name() << " " << buf->counters().value(fl.name()) << ":";
+ //o << fl.name() << ' ' << buf->counters().value(fl.name()) << ":";
o << fl.name() << " #:";
- s = o.str();
+ s = STRCONV(o.str());
+#endif
} else {
// par->SetLayout(0);
// s = layout->labelstring;
- s = (par->getParLanguage(buf->params)->lang() == "hebrew")
- ? " :úåòîùî øñç" : "Senseless: ";
+ s = _("Senseless: ");
}
}
par->params().labelString(s);
}
-// Updates all counters BEHIND the row. Changed paragraphs
-// with a dynamic left margin will be rebroken.
+// Updates all counters. Paragraphs with changed label string will be rebroken
void LyXText::updateCounters(BufferView * bview) const
{
- Paragraph * par;
-
Row * row = firstrow;
- par = row->par();
+ Paragraph * par = row->par();
// CHECK if this is really needed. (Lgb)
bview->buffer()->params.getLyXTextClass().counters().reset();
while (row->par() != par)
row = row->next();
+ string const oldLabel = par->params().labelString();
+
+ // setCounter can potentially change the labelString.
setCounter(bview->buffer(), par);
- // now check for the headline layouts. remember that they
- // have a dynamic left margin
- LyXLayout_ptr const & layout = par->layout();
+ string const & newLabel = par->params().labelString();
- if (layout->margintype == MARGIN_DYNAMIC
- || layout->labeltype == LABEL_SENSITIVE) {
- // Rebreak the paragraph
+ if (oldLabel.empty() && !newLabel.empty()) {
removeParagraph(row);
appendParagraph(bview, row);
}
+
par = par->next();
}
}
void LyXText::pasteEnvironmentType(BufferView * bview)
{
- setLayout(bview, copylayouttype);
+ // do nothing if there has been no previous copyEnvironmentType()
+ if (!copylayouttype.empty())
+ setLayout(bview, copylayouttype);
}
// cutSelection can invalidate the cursor so we need to set
// it anew. (Lgb)
- cursor = selection.start;
+ // we prefer the end for when tracking changes
+ cursor = selection.end;
// need a valid cursor. (Lgb)
clearSelection();
}
-// sets the selection over the number of characters of string, no check!!
-void LyXText::setSelectionOverString(BufferView * bview, string const & str)
+void LyXText::setSelectionRange(BufferView * bview, lyx::pos_type length)
{
- if (str.empty())
+ if (!length)
return;
selection.cursor = cursor;
- for (string::size_type i = 0; i < str.length(); ++i)
+ while (length--)
cursorRight(bview);
setSelection(bview);
}
// is there a break one row above
if (row->previous() && row->previous()->par() == row->par()) {
- z = nextBreakPoint(bview, row->previous(), workWidth(bview));
+ z = nextBreakPoint(bview, row->previous(), workWidth(*bview));
if (z >= row->pos()) {
// set the dimensions of the row above
y -= row->previous()->height();
}
int const tmpheight = row->height();
- pos_type const tmplast = rowLast(row);
+ pos_type const tmplast = row->lastPos();
refresh_y = y;
refresh_row = row;
breakAgain(bview, row);
- if (row->height() == tmpheight && rowLast(row) == tmplast)
+ if (row->height() == tmpheight && row->lastPos() == tmplast)
status(bview, LyXText::NEED_VERY_LITTLE_REFRESH);
else
status(bview, LyXText::NEED_MORE_REFRESH);
// y is now the cursor baseline
cur.y(y);
- pos_type last = rowLastPrintable(old_row);
+ pos_type last = old_row->lastPrintablePos();
- if (pos > last + 1) {
+ // None of these should happen, but we're scaredy-cats
+ if (pos > par->size()) {
+ pos = 0;
+ cur.pos(0);
+ } else if (pos > last + 1) {
// This shouldn't happen.
pos = last + 1;
cur.pos(pos);
cursor_vpos = (bidi_level(pos) % 2 == 0)
? log2vis(pos) : log2vis(pos) + 1;
- pos_type main_body =
- beginningOfMainBody(bview->buffer(), row->par());
+ pos_type main_body = row->par()->beginningOfMainBody();
if ((main_body > 0) &&
((main_body-1 > last) ||
!row->par()->isLineSeparator(main_body-1)))
x -= singleWidth(bview,
row->par(), main_body - 1);
}
- if (hfillExpansion(bview->buffer(), row, pos)) {
+ if (row->hfillExpansion(pos)) {
x += singleWidth(bview, row->par(), pos);
if (pos >= main_body)
x += fill_hfill;
cur.row(row);
if (beforeFullRowInset(*row, cur)) {
- pos_type last = rowLastPrintable(row);
+ pos_type last = row->lastPrintablePos();
float x = getCursorX(bview, row->next(), cur.pos(), last, bound);
cur.ix(int(x));
cur.iy(y + row->height() + row->next()->baseline());
}
}
}
+
+
+bool LyXText::isTopLevel() const
+{
+ /// only the top-level lyxtext has a non-null bv owner
+ return bv_owner;
+}
+
+
+bool LyXText::isInInset() const
+{
+ return inset_owner;
+}
+
+
+int defaultRowHeight()
+{
+ LyXFont const font(LyXFont::ALL_SANE);
+ return int(font_metrics::maxAscent(font)
+ + font_metrics::maxDescent(font) * 1.5);
+}