#include "author.h"
#include "buffer.h"
+#include "buffer_funcs.h"
#include "bufferparams.h"
#include "BufferView.h"
#include "cursor.h"
#include "support/lstrings.h"
#include "support/textutils.h"
-#include "support/tostr.h"
+#include "support/convert.h"
#include <sstream>
} // namespace anon
-BufferView * LyXText::bv()
-{
- BOOST_ASSERT(bv_owner != 0);
- return bv_owner;
-}
-
BufferView * LyXText::bv() const
{
&& align == LYX_ALIGN_BLOCK
&& !par.params().noindent()
// in charstyles, tabulars and ert paragraphs are never indented!
- && (par.ownerCode() != InsetBase::TEXT_CODE
+ && ((par.ownerCode() != InsetBase::TEXT_CODE || isMainText())
&& par.ownerCode() != InsetBase::ERT_CODE
&& par.ownerCode() != InsetBase::CHARSTYLE_CODE)
&& (par.layout() != tclass.defaultLayout()
maxasc += bufparams.getDefSkip().inPixels(*bv());
}
- if (pars_[pit].params().startOfAppendix())
+ if (par.params().startOfAppendix())
maxasc += int(3 * dh);
// This is special code for the chapter, since the label of this
// layout is printed in an extra row
- if (layout->counter == "chapter" && bufparams.secnumdepth >= 0) {
+ if (layout->counter == "chapter"
+ && !par.params().labelString().empty()) {
labeladdon = int(font_metrics::maxHeight(labelfont)
* layout->spacing.getValue()
* spacing(par));
// incalculate the layout spaces
maxasc += int(layoutasc * 2 / (2 + pars_[pit].getDepth()));
maxdesc += int(layoutdesc * 2 / (2 + pars_[pit].getDepth()));
-
+
+ // Top and bottom margin of the document (only at top-level)
+ if (bv_owner->text() == this) {
+ if (pit == 0 && row.pos() == 0)
+ maxasc += 20;
+ if (pit == pars_.size() - 1 && row.endpos() == par.size())
+ maxdesc += 20;
+ }
+
row.ascent(maxasc + labeladdon);
row.descent(maxdesc);
}
}
-void LyXText::breakParagraph(LCursor & cur, char keep_layout)
+void LyXText::breakParagraph(LCursor & cur, bool keep_layout)
{
BOOST_ASSERT(this == cur.text());
// allow only if at start or end, or all previous is new text
if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos()))
cpar.erase(cur.pos());
- // break the paragraph
+ // How should the layout for the new paragraph be?
+ int preserve_layout = 0;
if (keep_layout)
- keep_layout = 2;
+ preserve_layout = 2;
else
- keep_layout = layout->isEnvironment();
+ preserve_layout = layout->isEnvironment();
+
+ // We need to remember this before we break the paragraph, because
+ // that invalidates the layout variable
+ bool sensitive = layout->labeltype == LABEL_SENSITIVE;
- // we need to set this before we insert the paragraph. IMO the
- // breakParagraph call should return a bool if it inserts the
- // paragraph before or behind and we should react on that one
- // but we can fix this in 1.3.0 (Jug 20020509)
+ // we need to set this before we insert the paragraph.
bool const isempty = cpar.allowEmpty() && cpar.empty();
+
::breakParagraph(cur.buffer().params(), paragraphs(), cpit,
- cur.pos(), keep_layout);
+ cur.pos(), preserve_layout);
+
+ // After this, neither paragraph contains any rows!
cpit = cur.pit();
pit_type next_par = cpit + 1;
// well this is the caption hack since one caption is really enough
- if (layout->labeltype == LABEL_SENSITIVE) {
+ if (sensitive) {
if (cur.pos() == 0)
// set to standard-layout
pars_[cpit].applyLayout(tclass.defaultLayout());
pars_[next_par].applyLayout(tclass.defaultLayout());
}
- // if the cursor is at the beginning of a row without prior newline,
- // move one row up!
- // This touches only the screen-update. Otherwise we would may have
- // an empty row on the screen
- if (cur.pos() != 0 && cur.textRow().pos() == cur.pos()
- && !pars_[cpit].isNewline(cur.pos() - 1))
- {
- cursorLeft(cur);
- }
-
while (!pars_[next_par].empty() && pars_[next_par].isNewline(0))
pars_[next_par].erase(0);
- updateCounters();
+ updateCounters(cur.buffer());
// This check is necessary. Otherwise the new empty paragraph will
// be deleted automatically. And it is more friendly for the user!
cur.message(_("You cannot insert a space at the "
"beginning of a paragraph. Please read the Tutorial."));
sent_space_message = true;
- return;
}
+ return;
}
BOOST_ASSERT(cur.pos() > 0);
if (par.isLineSeparator(cur.pos() - 1)
// the cursor set functions have a special mechanism. When they
// realize, that you left an empty paragraph, they will delete it.
-void LyXText::cursorRightOneWord(LCursor & cur)
+bool LyXText::cursorRightOneWord(LCursor & cur)
{
BOOST_ASSERT(this == cur.text());
- if (cur.pos() == cur.lastpos() && cur.pit() != cur.lastpit()) {
- ++cur.pit();
- cur.pos() = 0;
+
+ LCursor old = cur;
+
+ if (old.pos() == old.lastpos() && old.pit() != old.lastpit()) {
+ ++old.pit();
+ old.pos() = 0;
} else {
// Skip through initial nonword stuff.
// Treat floats and insets as words.
- while (cur.pos() != cur.lastpos() && !cur.paragraph().isLetter(cur.pos()))
- ++cur.pos();
+ while (old.pos() != old.lastpos() && !old.paragraph().isLetter(old.pos()))
+ ++old.pos();
// Advance through word.
- while (cur.pos() != cur.lastpos() && cur.paragraph().isLetter(cur.pos()))
- ++cur.pos();
+ while (old.pos() != old.lastpos() && old.paragraph().isLetter(old.pos()))
+ ++old.pos();
}
- setCursor(cur, cur.pit(), cur.pos());
+ return setCursor(cur, old.pit(), old.pos());
}
-void LyXText::cursorLeftOneWord(LCursor & cur)
+bool LyXText::cursorLeftOneWord(LCursor & cur)
{
BOOST_ASSERT(this == cur.text());
- if (cur.pos() == 0 && cur.pit() != 0) {
- --cur.pit();
- cur.pos() = cur.lastpos();
+
+ LCursor old = cur;
+
+ if (old.pos() == 0 && old.pit() != 0) {
+ --old.pit();
+ old.pos() = old.lastpos();
} else {
// Skip through initial nonword stuff.
// Treat floats and insets as words.
- while (cur.pos() != 0 && !cur.paragraph().isLetter(cur.pos() - 1))
- --cur.pos();
+ while (old.pos() != 0 && !old.paragraph().isLetter(old.pos() - 1))
+ --old.pos();
// Advance through word.
- while (cur.pos() != 0 && cur.paragraph().isLetter(cur.pos() - 1))
- --cur.pos();
+ while (old.pos() != 0 && old.paragraph().isLetter(old.pos() - 1))
+ --old.pos();
}
- setCursor(cur, cur.pit(), cur.pos());
+ return setCursor(cur, old.pit(), old.pos());
}
--cur.pos();
// the counters may have changed
- updateCounters();
+ updateCounters(cur.buffer());
setCursor(cur, cur.pit(), cur.pos(), false);
}
} else {
}
-void LyXText::redoParagraph(pit_type const pit)
+bool LyXText::redoParagraph(pit_type const pit)
{
// remove rows of paragraph, keep track of height changes
Paragraph & par = pars_[pit];
+ // Add bibitem insets if necessary
+ if (par.layout()->labeltype == LABEL_BIBLIO) {
+ bool hasbibitem(false);
+ if (!par.insetlist.empty()
+ // Insist on it being in pos 0
+ && par.getChar(0) == Paragraph::META_INSET) {
+ InsetBase * inset = par.insetlist.begin()->inset;
+ if (inset->lyxCode() == InsetBase::BIBITEM_CODE)
+ hasbibitem = true;
+ }
+ if (!hasbibitem) {
+ InsetBibitem * inset(new
+ InsetBibitem(InsetCommandParams("bibitem")));
+ par.insertInset(0, static_cast<InsetBase *>(inset));
+ bv()->cursor().posRight();
+ }
+ }
+
// redo insets
InsetList::iterator ii = par.insetlist.begin();
InsetList::iterator iend = par.insetlist.end();
z = row.endpos();
} while (z < par.size());
- dim.asc += par.rows()[0].ascent();
- dim.des -= par.rows()[0].ascent();
- par.dim_ = dim;
+ dim.asc += par.rows()[0].ascent();
+ dim.des -= par.rows()[0].ascent();
+
+ bool const same = dim == par.dim();
+
+ par.dim() = dim;
//lyxerr << "redoParagraph: " << par.rows().size() << " rows\n";
+
+ return !same;
}
maxwidth_ = mi.base.textwidth;
//lyxerr << "LyXText::metrics: width: " << mi.base.textwidth
// << " maxWidth: " << maxwidth_ << "\nfont: " << mi.base.font << endl;
+ // save the caller's font locally:
+ font_ = mi.base.font;
unsigned int h = 0;
unsigned int w = 0;
beg.top() = cur.selBegin();
end.top() = cur.selEnd();
-
+
// the selection doesn't touch the visible screen
if (bv_funcs::status(pi.base.bv, beg) == bv_funcs::CUR_BELOW
|| bv_funcs::status(pi.base.bv, end) == bv_funcs::CUR_ABOVE)
Paragraph const & par1 = pars_[beg.pit()];
Paragraph const & par2 = pars_[end.pit()];
-
+
Row const & row1 = par1.getRow(beg.pos());
Row const & row2 = par2.getRow(end.pos());
-
+
int y1,x1,x2;
if (bv_funcs::status(pi.base.bv, beg) == bv_funcs::CUR_ABOVE) {
y1 = 0;
X1 = isRTL(par2) ? 0 : endx;
X2 = isRTL(par2) ? endx : 0 + dim_.wid;
}
-
+
lyxerr << " y1: " << y1 << " y2: " << y2
- << " xo: " << xo_ << " wid: " << dim_.wid
+ << " xo: " << xo_ << " wid: " << dim_.wid
<< endl;
// paint big rectangle in one go
beg.top() = cur.selBegin();
end.top() = cur.selEnd();
-
+
// the selection doesn't touch the visible screen
if (bv_funcs::status(pi.base.bv, beg) == bv_funcs::CUR_BELOW
|| bv_funcs::status(pi.base.bv, end) == bv_funcs::CUR_ABOVE)
Paragraph const & par1 = pars_[beg.pit()];
Paragraph const & par2 = pars_[end.pit()];
-
+
bool const above = (bv_funcs::status(pi.base.bv, beg)
== bv_funcs::CUR_ABOVE);
bool const below = (bv_funcs::status(pi.base.bv, end)
// The paragraph depth
int depth = cur.paragraph().getDepth();
if (depth > 0)
- os << bformat(_(", Depth: %1$s"), tostr(depth));
+ os << bformat(_(", Depth: %1$d"), depth);
// The paragraph spacing, but only if different from
// buffer spacing.
os << _("Double");
break;
case Spacing::Other:
- os << _("Other (") << spacing.getValue() << ')';
+ os << _("Other (") << spacing.getValueAsString() << ')';
break;
case Spacing::Default:
// should never happen, do nothing
pos_type LyXText::x2pos(pit_type pit, int row, int x) const
{
+ BOOST_ASSERT(row < pars_[pit].rows().size());
bool bound = false;
Row const & r = pars_[pit].rows()[row];
return r.pos() + getColumnNearX(pit, r, x, bound);
// Paragraph const & par = pars_[pit];
// Row const & r = par.rows()[row];
// int x = 0;
-// pos -= r.pos();
+// pos -= r.pos();
//}
{
pit_type pit = getPitNearY(y);
int yy = theCoords.get(this, pit).y_ - pars_[pit].ascent();
- lyxerr << "setCursorFromCoordinates: x: " << x << " y: " << y
+ lyxerr << "setCursorFromCoordinates: x: " << x << " y: " << y
<< " pit: " << pit << " yy: " << yy << endl;
Paragraph const & par = pars_[pit];
}
Row const & row = par.rows()[r];
-
+
lyxerr << "setCursorFromCoordinates: row " << r
<< " from pos: " << row.pos() << endl;
-
+
bool bound = false;
int xx = x;
pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound);