better mouse selection within tabulars

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8938 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2004-08-14 22:38:45 +00:00
parent 8b4681181c
commit 1c8329d3a4
4 changed files with 65 additions and 54 deletions

View File

@ -1,3 +1,8 @@
2004-08-14 André Pönitz <poenitz@gmx.net>
* insettabular.C (priv_dispatch): fix MOUSE_MOTION handling
2004-08-14 Jean-Marc Lasgouttes <lasgouttes@lyx.org> 2004-08-14 Jean-Marc Lasgouttes <lasgouttes@lyx.org>
* insettabular.C (metrics): when the width of a cell is zero(), * insettabular.C (metrics): when the width of a cell is zero(),

View File

@ -437,11 +437,12 @@ void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest & cmd)
case LFUN_MOUSE_MOTION: case LFUN_MOUSE_MOTION:
lyxerr << "# InsetTabular::MouseMotion\n" << bvcur << endl; lyxerr << "# InsetTabular::MouseMotion\n" << bvcur << endl;
if (cmd.button() != mouse_button::button1) { if (cmd.button() == mouse_button::button1) {
// only accept motions to places not deeper nested than the real anchor // only accept motions to places not deeper nested than the real anchor
if (bvcur.anchor_.hasPart(cur)) { if (bvcur.anchor_.hasPart(cur)) {
setPos(cur, cmd.x, cmd.y); setPos(cur, cmd.x, cmd.y);
bvcur.setCursor(cur); bvcur.setCursor(cur);
bvcur.selection() = true;
} }
} }
break; break;

View File

@ -449,10 +449,11 @@ int LyXText::singleWidth(par_type par, pos_type pos) const
} }
int LyXText::singleWidth(par_type pit, int LyXText::singleWidth(par_type const pit,
pos_type pos, char c, LyXFont const & font) const pos_type pos, char c, LyXFont const & font) const
{ {
if (pos >= pars_[pit].size()) { Paragraph const & par = pars_[pit];
if (pos >= par.size()) {
lyxerr << "in singleWidth(), pos: " << pos << endl; lyxerr << "in singleWidth(), pos: " << pos << endl;
BOOST_ASSERT(false); BOOST_ASSERT(false);
return 0; return 0;
@ -467,7 +468,7 @@ int LyXText::singleWidth(par_type pit,
if (Encodings::IsComposeChar_arabic(c)) if (Encodings::IsComposeChar_arabic(c))
return 0; return 0;
else else
c = pars_[pit].transformChar(c, pos); c = par.transformChar(c, pos);
} else if (font.language()->lang() == "hebrew" && } else if (font.language()->lang() == "hebrew" &&
Encodings::IsComposeChar_hebrew(c)) Encodings::IsComposeChar_hebrew(c))
return 0; return 0;
@ -476,7 +477,7 @@ int LyXText::singleWidth(par_type pit,
} }
if (c == Paragraph::META_INSET) if (c == Paragraph::META_INSET)
return pars_[pit].getInset(pos)->width(); return par.getInset(pos)->width();
if (IsSeparatorChar(c)) if (IsSeparatorChar(c))
c = ' '; c = ' ';
@ -490,11 +491,12 @@ int LyXText::leftMargin(par_type pit) const
} }
int LyXText::leftMargin(par_type pit, pos_type pos) const int LyXText::leftMargin(par_type const pit, pos_type const pos) const
{ {
Paragraph const & par = pars_[pit];
LyXTextClass const & tclass = LyXTextClass const & tclass =
bv()->buffer()->params().getLyXTextClass(); bv()->buffer()->params().getLyXTextClass();
LyXLayout_ptr const & layout = pars_[pit].layout(); LyXLayout_ptr const & layout = par.layout();
string parindent = layout->parindent; string parindent = layout->parindent;
@ -505,14 +507,14 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
l_margin += font_metrics::signedWidth(tclass.leftmargin(), tclass.defaultfont()); l_margin += font_metrics::signedWidth(tclass.leftmargin(), tclass.defaultfont());
if (pars_[pit].getDepth() != 0) { if (par.getDepth() != 0) {
// find the next level paragraph // find the next level paragraph
par_type newpar = outerHook(pit, pars_); par_type newpar = outerHook(pit, pars_);
if (newpar != par_type(pars_.size())) { if (newpar != par_type(pars_.size())) {
if (pars_[newpar].layout()->isEnvironment()) { if (pars_[newpar].layout()->isEnvironment()) {
l_margin = leftMargin(newpar); l_margin = leftMargin(newpar);
} }
if (pars_[pit].layout() == tclass.defaultLayout()) { if (par.layout() == tclass.defaultLayout()) {
if (pars_[newpar].params().noindent()) if (pars_[newpar].params().noindent())
parindent.erase(); parindent.erase();
else else
@ -527,10 +529,10 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
if (!layout->leftmargin.empty()) if (!layout->leftmargin.empty())
l_margin += font_metrics::signedWidth(layout->leftmargin, l_margin += font_metrics::signedWidth(layout->leftmargin,
tclass.defaultfont()); tclass.defaultfont());
if (!pars_[pit].getLabelstring().empty()) { if (!par.getLabelstring().empty()) {
l_margin += font_metrics::signedWidth(layout->labelindent, l_margin += font_metrics::signedWidth(layout->labelindent,
labelfont); labelfont);
l_margin += font_metrics::width(pars_[pit].getLabelstring(), l_margin += font_metrics::width(par.getLabelstring(),
labelfont); labelfont);
l_margin += font_metrics::width(layout->labelsep, labelfont); l_margin += font_metrics::width(layout->labelsep, labelfont);
} }
@ -539,9 +541,9 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
case MARGIN_MANUAL: case MARGIN_MANUAL:
l_margin += font_metrics::signedWidth(layout->labelindent, labelfont); l_margin += font_metrics::signedWidth(layout->labelindent, labelfont);
// The width of an empty par, even with manual label, should be 0 // The width of an empty par, even with manual label, should be 0
if (!pars_[pit].empty() && pos >= pars_[pit].beginOfBody()) { if (!par.empty() && pos >= par.beginOfBody()) {
if (!pars_[pit].getLabelWidthString().empty()) { if (!par.getLabelWidthString().empty()) {
l_margin += font_metrics::width(pars_[pit].getLabelWidthString(), l_margin += font_metrics::width(par.getLabelWidthString(),
labelfont); labelfont);
l_margin += font_metrics::width(layout->labelsep, labelfont); l_margin += font_metrics::width(layout->labelsep, labelfont);
} }
@ -550,12 +552,12 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
case MARGIN_STATIC: case MARGIN_STATIC:
l_margin += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()) * 4 l_margin += font_metrics::signedWidth(layout->leftmargin, tclass.defaultfont()) * 4
/ (pars_[pit].getDepth() + 4); / (par.getDepth() + 4);
break; break;
case MARGIN_FIRST_DYNAMIC: case MARGIN_FIRST_DYNAMIC:
if (layout->labeltype == LABEL_MANUAL) { if (layout->labeltype == LABEL_MANUAL) {
if (pos >= pars_[pit].beginOfBody()) { if (pos >= par.beginOfBody()) {
l_margin += font_metrics::signedWidth(layout->leftmargin, l_margin += font_metrics::signedWidth(layout->leftmargin,
labelfont); labelfont);
} else { } else {
@ -577,7 +579,7 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
l_margin += font_metrics::signedWidth(layout->labelindent, l_margin += font_metrics::signedWidth(layout->labelindent,
labelfont); labelfont);
l_margin += font_metrics::width(layout->labelsep, labelfont); l_margin += font_metrics::width(layout->labelsep, labelfont);
l_margin += font_metrics::width(pars_[pit].getLabelstring(), l_margin += font_metrics::width(par.getLabelstring(),
labelfont); labelfont);
} }
break; break;
@ -586,8 +588,8 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
#if 0 #if 0
// ok, a terrible hack. The left margin depends on the widest // ok, a terrible hack. The left margin depends on the widest
// row in this paragraph. // row in this paragraph.
RowList::iterator rit = pars_[pit].rows.begin(); RowList::iterator rit = par.rows.begin();
RowList::iterator end = pars_[pit].rows.end(); RowList::iterator end = par.rows.end();
#ifdef WITH_WARNINGS #ifdef WITH_WARNINGS
#warning This is wrong. #warning This is wrong.
#endif #endif
@ -605,15 +607,15 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
} }
} }
if (!pars_[pit].params().leftIndent().zero()) if (!par.params().leftIndent().zero())
l_margin += pars_[pit].params().leftIndent().inPixels(maxwidth_); l_margin += par.params().leftIndent().inPixels(maxwidth_);
LyXAlignment align; LyXAlignment align;
if (pars_[pit].params().align() == LYX_ALIGN_LAYOUT) if (par.params().align() == LYX_ALIGN_LAYOUT)
align = layout->align; align = layout->align;
else else
align = pars_[pit].params().align(); align = par.params().align();
// set the correct parindent // set the correct parindent
if (pos == 0 if (pos == 0
@ -624,11 +626,11 @@ int LyXText::leftMargin(par_type pit, pos_type pos) const
&& layout->latextype == LATEX_ENVIRONMENT && layout->latextype == LATEX_ENVIRONMENT
&& !isFirstInSequence(pit, pars_))) && !isFirstInSequence(pit, pars_)))
&& align == LYX_ALIGN_BLOCK && align == LYX_ALIGN_BLOCK
&& !pars_[pit].params().noindent() && !par.params().noindent()
// in tabulars and ert paragraphs are never indented! // in tabulars and ert paragraphs are never indented!
&& (pars_[pit].ownerCode() != InsetBase::TEXT_CODE && (par.ownerCode() != InsetBase::TEXT_CODE
&& pars_[pit].ownerCode() != InsetBase::ERT_CODE) && par.ownerCode() != InsetBase::ERT_CODE)
&& (pars_[pit].layout() != tclass.defaultLayout() && (par.layout() != tclass.defaultLayout()
|| bv()->buffer()->params().paragraph_separation == || bv()->buffer()->params().paragraph_separation ==
BufferParams::PARSEP_INDENT)) BufferParams::PARSEP_INDENT))
{ {
@ -660,7 +662,7 @@ int LyXText::rightMargin(Paragraph const & par) const
} }
int LyXText::labelEnd(par_type pit) const int LyXText::labelEnd(par_type const pit) const
{ {
// labelEnd is only needed if the layout fills a flushleft label. // labelEnd is only needed if the layout fills a flushleft label.
if (pars_[pit].layout()->margintype != MARGIN_MANUAL) if (pars_[pit].layout()->margintype != MARGIN_MANUAL)
@ -687,9 +689,10 @@ pos_type addressBreakPoint(pos_type i, Paragraph const & par)
}; };
void LyXText::rowBreakPoint(par_type pit, Row & row) const void LyXText::rowBreakPoint(par_type const pit, Row & row) const
{ {
pos_type const end = pars_[pit].size(); Paragraph const & par = pars_[pit];
pos_type const end = par.size();
pos_type const pos = row.pos(); pos_type const pos = row.pos();
if (pos == end) { if (pos == end) {
row.endpos(end); row.endpos(end);
@ -697,20 +700,20 @@ void LyXText::rowBreakPoint(par_type pit, Row & row) const
} }
// maximum pixel width of a row // maximum pixel width of a row
int width = maxwidth_ - rightMargin(pars_[pit]); // - leftMargin(pit, row); int width = maxwidth_ - rightMargin(par); // - leftMargin(pit, row);
if (width < 0) { if (width < 0) {
row.endpos(end); row.endpos(end);
return; return;
} }
LyXLayout_ptr const & layout = pars_[pit].layout(); LyXLayout_ptr const & layout = par.layout();
if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) { if (layout->margintype == MARGIN_RIGHT_ADDRESS_BOX) {
row.endpos(addressBreakPoint(pos, pars_[pit])); row.endpos(addressBreakPoint(pos, par));
return; return;
} }
pos_type const body_pos = pars_[pit].beginOfBody(); pos_type const body_pos = par.beginOfBody();
// Now we iterate through until we reach the right margin // Now we iterate through until we reach the right margin
@ -727,7 +730,7 @@ void LyXText::rowBreakPoint(par_type pit, Row & row) const
pos_type point = end; pos_type point = end;
pos_type i = pos; pos_type i = pos;
for ( ; i < end; ++i, ++fi) { for ( ; i < end; ++i, ++fi) {
char const c = pars_[pit].getChar(i); char const c = par.getChar(i);
{ {
int thiswidth = singleWidth(pit, i, c, *fi); int thiswidth = singleWidth(pit, i, c, *fi);
@ -761,26 +764,26 @@ void LyXText::rowBreakPoint(par_type pit, Row & row) const
break; break;
} }
if (pars_[pit].isNewline(i)) { if (par.isNewline(i)) {
point = i + 1; point = i + 1;
break; break;
} }
// Break before... // Break before...
if (i + 1 < end) { if (i + 1 < end) {
if (pars_[pit].isInset(i + 1) && pars_[pit].getInset(i + 1)->display()) { if (par.isInset(i + 1) && par.getInset(i + 1)->display()) {
point = i + 1; point = i + 1;
break; break;
} }
// ...and after. // ...and after.
if (pars_[pit].isInset(i) && pars_[pit].getInset(i)->display()) { if (par.isInset(i) && par.getInset(i)->display()) {
point = i + 1; point = i + 1;
break; break;
} }
} }
if (!pars_[pit].isInset(i) || pars_[pit].getInset(i)->isChar()) { if (!par.isInset(i) || par.getInset(i)->isChar()) {
// some insets are line separators too // some insets are line separators too
if (pars_[pit].isLineSeparator(i)) { if (par.isLineSeparator(i)) {
// register breakpoint: // register breakpoint:
point = i + 1; point = i + 1;
chunkwidth = 0; chunkwidth = 0;
@ -802,15 +805,16 @@ void LyXText::rowBreakPoint(par_type pit, Row & row) const
} }
void LyXText::setRowWidth(par_type pit, Row & row) const void LyXText::setRowWidth(par_type const pit, Row & row) const
{ {
// get the pure distance // get the pure distance
pos_type const end = row.endpos(); pos_type const end = row.endpos();
string labelsep = pars_[pit].layout()->labelsep; Paragraph const & par = pars_[pit];
string labelsep = par.layout()->labelsep;
int w = leftMargin(pit, row.pos()); int w = leftMargin(pit, row.pos());
pos_type const body_pos = pars_[pit].beginOfBody(); pos_type const body_pos = par.beginOfBody();
pos_type i = row.pos(); pos_type i = row.pos();
if (i < end) { if (i < end) {
@ -818,23 +822,23 @@ void LyXText::setRowWidth(par_type pit, Row & row) const
for ( ; i < end; ++i, ++fi) { for ( ; i < end; ++i, ++fi) {
if (body_pos > 0 && i == body_pos) { if (body_pos > 0 && i == body_pos) {
w += font_metrics::width(labelsep, getLabelFont(pit)); w += font_metrics::width(labelsep, getLabelFont(pit));
if (pars_[pit].isLineSeparator(i - 1)) if (par.isLineSeparator(i - 1))
w -= singleWidth(pit, i - 1); w -= singleWidth(pit, i - 1);
w = max(w, labelEnd(pit)); w = max(w, labelEnd(pit));
} }
char const c = pars_[pit].getChar(i); char const c = par.getChar(i);
w += singleWidth(pit, i, c, *fi); w += singleWidth(pit, i, c, *fi);
} }
} }
if (body_pos > 0 && body_pos >= end) { if (body_pos > 0 && body_pos >= end) {
w += font_metrics::width(labelsep, getLabelFont(pit)); w += font_metrics::width(labelsep, getLabelFont(pit));
if (end > 0 && pars_[pit].isLineSeparator(end - 1)) if (end > 0 && par.isLineSeparator(end - 1))
w -= singleWidth(pit, end - 1); w -= singleWidth(pit, end - 1);
w = max(w, labelEnd(pit)); w = max(w, labelEnd(pit));
} }
row.width(w + rightMargin(pars_[pit])); row.width(w + rightMargin(par));
} }

View File

@ -149,20 +149,21 @@ InsetBase * LyXText::checkInsetHit(int x, int y) const
// The difference is that this one is used for displaying, and thus we // The difference is that this one is used for displaying, and thus we
// are allowed to make cosmetic improvements. For instance make footnotes // are allowed to make cosmetic improvements. For instance make footnotes
// smaller. (Asger) // smaller. (Asger)
LyXFont LyXText::getFont(par_type pit, pos_type pos) const LyXFont LyXText::getFont(par_type const pit, pos_type const pos) const
{ {
BOOST_ASSERT(pos >= 0); BOOST_ASSERT(pos >= 0);
LyXLayout_ptr const & layout = pars_[pit].layout(); Paragraph const & par = pars_[pit];
LyXLayout_ptr const & layout = par.layout();
#ifdef WITH_WARNINGS #ifdef WITH_WARNINGS
#warning broken? #warning broken?
#endif #endif
BufferParams const & params = bv()->buffer()->params(); BufferParams const & params = bv()->buffer()->params();
pos_type const body_pos = pars_[pit].beginOfBody(); pos_type const body_pos = par.beginOfBody();
// We specialize the 95% common case: // We specialize the 95% common case:
if (!pars_[pit].getDepth()) { if (!par.getDepth()) {
LyXFont f = pars_[pit].getFontSettings(params, pos); LyXFont f = par.getFontSettings(params, pos);
if (!isMainText()) if (!isMainText())
f.realize(font_); f.realize(font_);
if (layout->labeltype == LABEL_MANUAL && pos < body_pos) if (layout->labeltype == LABEL_MANUAL && pos < body_pos)
@ -178,7 +179,7 @@ LyXFont LyXText::getFont(par_type pit, pos_type pos) const
else else
layoutfont = layout->font; layoutfont = layout->font;
LyXFont font = pars_[pit].getFontSettings(params, pos); LyXFont font = par.getFontSettings(params, pos);
font.realize(layoutfont); font.realize(layoutfont);
if (!isMainText()) if (!isMainText())
@ -192,7 +193,7 @@ LyXFont LyXText::getFont(par_type pit, pos_type pos) const
} }
LyXFont LyXText::getLayoutFont(par_type pit) const LyXFont LyXText::getLayoutFont(par_type const pit) const
{ {
LyXLayout_ptr const & layout = pars_[pit].layout(); LyXLayout_ptr const & layout = pars_[pit].layout();