two patches from Dekel

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@780 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Lars Gullik Bjønnes 2000-05-30 19:31:11 +00:00
parent aa25dde22d
commit 73b9ca2a4b
13 changed files with 340 additions and 182 deletions

View File

@ -1,3 +1,22 @@
2000-05-27 Dekel Tsur <dekel@math.tau.ac.il>
* src/text.C (draw): draw bars under foreign language words.
* src/LColor.[Ch]: add LColor::language
2000-05-27 Dekel Tsur <dekel@math.tau.ac.il>
* src/lyxcursor.h (boundary): New member variable
* src/text.C (IsBoundary): New methods
* src/text.C: Use the above for currect cursor movement when there
is both RTL & LTR text.
* src/text2.C: ditto
* src/bufferview_funcs.C (ToggleAndShow): ditto
2000-05-30 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
* src/text.C (DeleteLineForward): set selection to true to avoid

View File

@ -659,6 +659,11 @@
# the document. Default is true.
#\language_auto_end false
# Set mark_foreign_language to "false" to disable the highlighting of words
# with a foreign language to the language of the documet.
# Default is "true"
#\mark_foreign_language false
#
# HEBREW SUPPORT SECTION ####################################################
#
@ -675,6 +680,9 @@
# For example,
#\bind "F12" "language hebrew"
# You might want ot disable the foreign language marking:
#\mark_foreign_language false
# Finally, you need to select iso8859-8 font encoding, and select screen fonts
# (below are the default fonts. You need to replace them by Hebrew fonts)
#\screen_font_encoding iso8859-8

View File

@ -66,6 +66,7 @@ LColor::LColor()
{ notebg, N_("note background"), "notebg", "yellow", "notebg" },
{ noteframe, N_("note frame"), "noteframe", "black", "noteframe" },
{ depthbar, N_("depth bar"), "depthbar", "IndianRed", "depthbar" },
{ language, N_("language"), "language", "Blue", "language" },
{ command, N_("command-inset"), "command", "black", "command" },
{ commandbg, N_("command-inset background"), "commandbg", "grey80", "commandbg" },
{ commandframe, N_("inset frame"), "commandframe", "black", "commandframe" },

View File

@ -78,6 +78,8 @@ public:
/// Color for the depth bars in the margin
depthbar,
/// Color for marking foreign language words
language,
/// Text color for command insets
command,

View File

@ -293,5 +293,17 @@ void ToggleAndShow(BufferView * bv, LyXFont const & font)
else
bv->text->ToggleFree(font, toggleall);
bv->update(1);
if (font.language() != ignore_language ||
font.latex() != LyXFont::IGNORE) {
LyXText * text = bv->text;
LyXCursor & cursor = text->cursor;
text->ComputeBidiTables(cursor.row);
if (cursor.boundary !=
text->IsBoundary(cursor.par, cursor.pos,
text->real_current_font) )
text->SetCursor(cursor.par, cursor.pos,
false, !cursor.boundary);
}
}
}

View File

@ -2377,10 +2377,12 @@ extern "C" void DocumentApplyCB(FL_OBJECT *, long)
if (current_view->available()) {
if (old_language != new_language &&
old_language->RightToLeft == new_language->RightToLeft &&
! current_view->buffer()->isMultiLingual() ) {
! current_view->buffer()->isMultiLingual() )
current_view->buffer()->ChangeLanguage(old_language,
new_language);
current_view->buffer()->redraw();
if (old_language != new_language) {
//current_view->buffer()->redraw();
redo = true;
}
}
params->language_info = new_language;

View File

@ -24,6 +24,8 @@ struct LyXCursor {
///
LyXParagraph::size_type pos;
///
bool boundary;
///
int x;
///
int x_fix;
@ -33,9 +35,9 @@ struct LyXCursor {
Row * row;
///
inline bool operator==(const LyXCursor &a) const
{ return (a.par == par) && (a.pos == pos); }
{ return a.par == par && a.pos == pos && a.boundary == boundary ; }
inline bool operator!=(const LyXCursor &a) const
{ return (a.par != par) || (a.pos != pos); }
{ return a.par != par || a.pos != pos || a.boundary != boundary; }
};
#endif

View File

@ -1222,11 +1222,9 @@ string LyXFunc::Dispatch(int ac,
break;
case LFUN_LANGUAGE:
{
Lang(owner->view(), argument);
owner->view()->setState();
owner->getMiniBuffer()->Set(CurrentState(owner->view()));
}
break;
case LFUN_EMPH:
@ -1367,7 +1365,7 @@ string LyXFunc::Dispatch(int ac,
owner->view()->beforeChange();
owner->view()->update(-2);
if (is_rtl)
tmptext->CursorLeft();
tmptext->CursorLeft(false);
if (tmptext->cursor.pos < tmptext->cursor.par->Last()
&& tmptext->cursor.par->GetChar(tmptext->cursor.pos)
== LyXParagraph::META_INSET
@ -1379,7 +1377,7 @@ string LyXFunc::Dispatch(int ac,
break;
}
if (!is_rtl)
tmptext->CursorRight();
tmptext->CursorRight(false);
owner->view()->text->FinishUndo();
moveCursorUpdate(false);
owner->getMiniBuffer()->Set(CurrentState(owner->view()));
@ -1395,7 +1393,7 @@ string LyXFunc::Dispatch(int ac,
if(!txt->mark_set) owner->view()->beforeChange();
owner->view()->update(-2);
if (!is_rtl)
txt->CursorLeft();
txt->CursorLeft(false);
if (txt->cursor.pos < txt->cursor.par->Last()
&& txt->cursor.par->GetChar(txt->cursor.pos)
== LyXParagraph::META_INSET
@ -1412,7 +1410,7 @@ string LyXFunc::Dispatch(int ac,
break;
}
if (is_rtl)
txt->CursorRight();
txt->CursorRight(false);
owner->view()->text->FinishUndo();
moveCursorUpdate(false);

View File

@ -137,6 +137,7 @@ enum LyXRCTags {
RC_BACKUPDIR_PATH,
RC_RTL_SUPPORT,
RC_AUTO_NUMBER,
RC_MARK_FOREIGN_LANGUAGE,
RC_LANGUAGE_PACKAGE,
RC_LANGUAGE_AUTO_BEGIN,
RC_LANGUAGE_AUTO_END,
@ -213,6 +214,7 @@ keyword_item lyxrcTags[] = {
{ "\\literate_error_filter", RC_LITERATE_ERROR_FILTER },
{ "\\literate_extension", RC_LITERATE_EXTENSION },
{ "\\make_backup", RC_MAKE_BACKUP },
{ "\\mark_foreign_language", RC_MARK_FOREIGN_LANGUAGE },
{ "\\num_lastfiles", RC_NUMLASTFILES },
{ "\\override_x_deadkeys", RC_OVERRIDE_X_DEADKEYS },
{ "\\pdf_mode", RC_PDF_MODE },
@ -367,6 +369,7 @@ void LyXRC::setDefaults() {
hasBindFile = false;
rtl_support = false;
auto_number = true;
mark_foreign_language = true;
language_package = "\\usepackage{babel}";
language_auto_begin = true;
language_auto_end = true;
@ -1011,6 +1014,9 @@ int LyXRC::read(string const & filename)
if (lexrc.next())
auto_number = lexrc.GetBool();
break;
case RC_MARK_FOREIGN_LANGUAGE:
if (lexrc.next())
mark_foreign_language = lexrc.GetBool();
case RC_SHOW_BANNER:
if (lexrc.next())
show_banner = lexrc.GetBool();
@ -1337,6 +1343,9 @@ void LyXRC::output(ostream & os) const
os << "\\rtl " << tostr(rtl_support) << "\n";
case RC_AUTO_NUMBER:
os << "\\auto_number" << tostr(auto_number) << "\n";
case RC_MARK_FOREIGN_LANGUAGE:
os << "\\mark_foreign_language " <<
tostr(mark_foreign_language) << "\n";
case RC_LANGUAGE_AUTO_BEGIN:
os << "\\language_auto_begin "
<< tostr(language_auto_begin) << "\n";

View File

@ -221,6 +221,8 @@ public:
///
bool auto_number;
///
bool mark_foreign_language;
///
bool show_banner;
/// Do we have to use a GUI?
bool use_gui;

View File

@ -182,7 +182,7 @@ public:
/** returns the column near the specified x-coordinate of the row
x is set to the real beginning of this column
*/
int GetColumnNearX(Row * row, int & x) const;
int GetColumnNearX(Row * row, int & x, bool & boundary) const;
/** returns a pointer to a specified row. y is set to the beginning
of the row
@ -244,13 +244,28 @@ public:
///
void SetCursor(LyXParagraph * par,
LyXParagraph::size_type pos,
bool setfont = true) const;
bool setfont = true,
bool boundary = false) const;
void SetCursor(LyXCursor &, LyXParagraph * par,
LyXParagraph::size_type pos) const;
LyXParagraph::size_type pos,
bool boundary = false) const;
///
void SetCursorIntern(LyXParagraph * par,
LyXParagraph::size_type pos,
bool setfont = true) const;
bool setfont = true,
bool boundary = false) const;
///
void SetCurrentFont() const;
///
bool IsBoundary(LyXParagraph * par,
LyXParagraph::size_type pos) const;
///
bool IsBoundary(LyXParagraph * par,
LyXParagraph::size_type pos,
LyXFont const & font) const;
///
void SetCursorFromCoordinates(int x, long y) const;
void SetCursorFromCoordinates(LyXCursor &, int x, long y) const;
@ -259,9 +274,13 @@ public:
///
void CursorDown() const;
///
void CursorLeft() const;
void CursorLeft(bool internal = true) const;
///
void CursorRight() const;
void CursorRight(bool internal = true) const;
///
void CursorLeftIntern(bool internal = true) const;
///
void CursorRightIntern(bool internal = true) const;
///
void CursorLeftOneWord() const;
///
@ -469,10 +488,6 @@ public:
/// for external use in lyx_cb.C
void SetCursorParUndo();
///
void CursorLeftIntern() const;
///
void CursorRightIntern() const;
///
void RemoveTableRow(LyXCursor * cursor) const;
///
bool IsEmptyTableCell() const;
@ -480,6 +495,41 @@ public:
void toggleAppendix();
///
unsigned short paperWidth() const { return paperwidth; }
///
void ComputeBidiTables(Row *row) const;
/// Maps positions in the visual string to positions in logical string.
inline
LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return log2vis_list[pos-bidi_start];
}
/// Maps positions in the logical string to positions in visual string.
inline
LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return vis2log_list[pos-bidi_start];
}
inline
int bidi_level(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return 0;
else
return bidi_levels[pos-bidi_start];
}
inline
bool bidi_InRange(LyXParagraph::size_type pos) const {
return bidi_start == -1 ||
(bidi_start <= pos && pos <= bidi_end);
}
private:
///
BufferView * owner_;
@ -612,36 +662,10 @@ private:
mutable LyXParagraph::size_type bidi_start;
///
mutable bool bidi_same_direction;
mutable LyXParagraph::size_type bidi_end;
///
void ComputeBidiTables(Row *row) const;
/// Maps positions in the visual string to positions in logical string.
inline
LyXParagraph::size_type log2vis(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return log2vis_list[pos-bidi_start];
}
/// Maps positions in the logical string to positions in visual string.
inline
LyXParagraph::size_type vis2log(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return pos;
else
return vis2log_list[pos-bidi_start];
}
inline
int bidi_level(LyXParagraph::size_type pos) const {
if (bidi_start == -1)
return 0;
else
return bidi_levels[pos-bidi_start];
}
mutable bool bidi_same_direction;
///
unsigned char TransformChar(unsigned char c, Letter_Form form) const;

View File

@ -280,26 +280,26 @@ void LyXText::ComputeBidiTables(Row * row) const
bidi_start = -1;
return;
}
LyXParagraph::size_type last = RowLastPrintable(row);
bidi_start = row->pos;
bidi_end = RowLastPrintable(row);
if (bidi_start > last) {
if (bidi_start > bidi_end) {
bidi_start = -1;
return;
}
if (last + 2 - bidi_start >
if (bidi_end + 2 - bidi_start >
static_cast<LyXParagraph::size_type>(log2vis_list.size())) {
LyXParagraph::size_type new_size =
(last + 2 - bidi_start < 500) ?
500 : 2 * (last + 2 - bidi_start);
(bidi_end + 2 - bidi_start < 500) ?
500 : 2 * (bidi_end + 2 - bidi_start);
log2vis_list.resize(new_size);
vis2log_list.resize(new_size);
bidi_levels.resize(new_size);
}
vis2log_list[last + 1 - bidi_start] = -1;
log2vis_list[last + 1 - bidi_start] = -1;
vis2log_list[bidi_end + 1 - bidi_start] = -1;
log2vis_list[bidi_end + 1 - bidi_start] = -1;
LyXParagraph::size_type stack[2];
bool rtl_par = row->par->getParLanguage()->RightToLeft;
@ -308,10 +308,11 @@ void LyXText::ComputeBidiTables(Row * row) const
bool rtl0 = false;
LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) {
for (LyXParagraph::size_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
bool is_space = row->par->IsLineSeparator(lpos);
LyXParagraph::size_type pos =
(is_space && lpos+1 <= last &&
(is_space && lpos+1 <= bidi_end &&
!row->par->IsLineSeparator(lpos+1) &&
(!row->par->table || !row->par->IsNewline(lpos+1)) )
? lpos + 1 : lpos;
LyXFont font = row->par->GetFontSettings(pos);
@ -367,14 +368,14 @@ void LyXText::ComputeBidiTables(Row * row) const
while (level > 0) {
LyXParagraph::size_type old_lpos = stack[--level];
int delta = last - old_lpos;
int delta = bidi_end - old_lpos;
if (level % 2)
delta = -delta;
log2vis_list[old_lpos - bidi_start] += delta;
}
LyXParagraph::size_type vpos = bidi_start - 1;
for (LyXParagraph::size_type lpos = bidi_start; lpos <= last; ++lpos) {
for (LyXParagraph::size_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
vpos += log2vis_list[lpos - bidi_start];
vis2log_list[vpos - bidi_start] = lpos;
log2vis_list[lpos - bidi_start] = vpos;
@ -382,6 +383,43 @@ void LyXText::ComputeBidiTables(Row * row) const
}
// This method requires a previous call to ComputeBidiTables()
bool LyXText::IsBoundary(LyXParagraph * par, LyXParagraph::size_type pos) const
{
if (!lyxrc.rtl_support)
return false; // This is just for speedup
if (!bidi_InRange(pos - 1) ||
(par->table && par->IsNewline(pos-1)) )
return false;
bool rtl = bidi_level(pos - 1) % 2;
bool rtl2 = rtl;
if (pos == par->Last() ||
(par->table && par->IsNewline(pos)))
rtl2 = par->isRightToLeftPar();
else if (bidi_InRange(pos))
rtl2 = bidi_level(pos) % 2;
return rtl != rtl2;
}
bool LyXText::IsBoundary(LyXParagraph * par, LyXParagraph::size_type pos,
LyXFont const & font) const
{
if (!lyxrc.rtl_support)
return false; // This is just for speedup
bool rtl = font.isVisibleRightToLeft();
bool rtl2 = rtl;
if (pos == par->Last() ||
(par->table && par->IsNewline(pos)))
rtl2 = par->isRightToLeftPar();
else if (bidi_InRange(pos))
rtl2 = bidi_level(pos) % 2;
return rtl != rtl2;
}
void LyXText::draw(Row const * row,
LyXParagraph::size_type & vpos,
int offset, float & x)
@ -390,6 +428,7 @@ void LyXText::draw(Row const * row,
LyXParagraph::size_type pos = vis2log(vpos);
char c = row->par->GetChar(pos);
float tmpx = x;
if (IsNewlineChar(c)) {
++vpos;
@ -492,8 +531,6 @@ void LyXText::draw(Row const * row,
font.setColor(LColor::footnote);
float tmpx = x;
// draw it and set new x position
pain.text(int(x), offset + y, fs, font);
@ -511,6 +548,14 @@ void LyXText::draw(Row const * row,
offset + row->baseline, x);
}
++vpos;
if (lyxrc.mark_foreign_language &&
font.language() != buffer->params.language_info) {
int y = offset + row->baseline + 2;
pain.line(int(tmpx), y, int(x), y,
LColor::language);
}
return;
}
@ -532,7 +577,6 @@ void LyXText::draw(Row const * row,
++vpos;
LyXParagraph::size_type last = RowLastPrintable(row);
float tmpx = x;
if (font.language()->lang == "hebrew") {
if (is_nikud(c)) {
@ -597,6 +641,11 @@ void LyXText::draw(Row const * row,
pain.line(int(tmpx), offset + row->baseline + 2,
int(x), offset + row->baseline + 2);
} else if (lyxrc.mark_foreign_language &&
font.language() != buffer->params.language_info) {
int y = offset + row->baseline + 2;
pain.line(int(tmpx), y, int(x), y,
LColor::language);
}
// If we want ulem.sty support, drawing
@ -2403,7 +2452,7 @@ void LyXText::InsertCharInTable(char c)
}
}
cursor.pos++;
++cursor.pos;
CheckParagraphInTable(cursor.par, cursor.pos);
@ -2439,7 +2488,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par,
if (par->table->SetWidthOfCell(NumberOfCell(par, pos),
WidthOfCell(par, tmp_pos))) {
LyXCursor tmpcursor = cursor;
SetCursorIntern(par, pos);
SetCursorIntern(par, pos, false);
/* make a complete redraw */
RedoDrawingOfParagraph(cursor);
cursor = tmpcursor;
@ -2460,7 +2509,7 @@ void LyXText::CheckParagraphInTable(LyXParagraph * par,
else
status = LyXText::NEED_MORE_REFRESH;
}
SetCursorIntern(cursor.par, cursor.pos);
SetCursorIntern(cursor.par, cursor.pos, false, cursor.boundary);
}
@ -2525,7 +2574,9 @@ void LyXText::BackspaceInTable()
current_font = rawtmpfont;
real_current_font = realtmpfont;
}
SetCursorIntern(cursor.par, cursor.pos);
SetCursorIntern(cursor.par, cursor.pos, true, cursor.boundary);
if (IsBoundary(cursor.par, cursor.pos) != cursor.boundary)
SetCursor(cursor.par, cursor.pos, false, !cursor.boundary);
}
/* table stuff -- end*/
@ -2666,7 +2717,7 @@ void LyXText::InsertChar(char c)
current_font = rawtmpfont;
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos + 1, false);
SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
/* cursor MUST be in row now */
if (row->next && row->next->par == row->par)
@ -2706,7 +2757,7 @@ void LyXText::InsertChar(char c)
}
current_font = rawtmpfont;
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos + 1, false);
SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
if (row->next && row->next->par == row->par)
need_break_row = row->next;
else
@ -2726,7 +2777,7 @@ void LyXText::InsertChar(char c)
current_font = rawtmpfont;
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos + 1, false);
SetCursor(cursor.par, cursor.pos + 1, false, cursor.boundary);
}
/* check, wether the last characters font has changed. */
@ -3299,11 +3350,13 @@ void LyXText::Backspace()
}
/* table stuff -- end */
LyXFont rawtmpfont = current_font;
LyXFont realtmpfont = real_current_font;
// LyXFont rawtmpfont = current_font;
// LyXFont realtmpfont = real_current_font;
// We don't need the above variables as calling to SetCursor() with third
// argument eqaul to false, will not change current_font & real_current_font
// Get the font that is used to calculate the baselineskip
int const lastpos = cursor.par->Last();
LyXParagraph::size_type lastpos = cursor.par->Last();
LyXFont rawparfont = cursor.par->GetFontSettings(lastpos - 1);
if (cursor.pos == 0) {
@ -3365,7 +3418,7 @@ void LyXText::Backspace()
if (cursor.par->Previous()) {
// steps into the above paragraph.
SetCursorIntern(cursor.par->Previous(),
cursor.par->Previous()->Last());
cursor.par->Previous()->Last(), false);
}
/* Pasting is not allowed, if the paragraphs have different
@ -3416,7 +3469,7 @@ void LyXText::Backspace()
UpdateCounters(cursor.row);
// the row may have changed, block, hfills etc.
SetCursor(cursor.par, cursor.pos);
SetCursor(cursor.par, cursor.pos, false);
}
} else {
/* this is the code for a normal backspace, not pasting
@ -3428,7 +3481,7 @@ void LyXText::Backspace()
// not a good idea since it triggers the auto-delete
// mechanism. So we do a CursorLeftIntern()-lite,
// without the dreaded mechanism. (JMarc)
SetCursorIntern(cursor.par, cursor.pos - 1);
SetCursorIntern(cursor.par, cursor.pos - 1, false, cursor.boundary);
// some insets are undeletable here
if (cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET) {
@ -3529,12 +3582,12 @@ void LyXText::Backspace()
refresh_y = y;
refresh_row = tmprow;
status = LyXText::NEED_MORE_REFRESH;
current_font = rawtmpfont;
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos, false);
SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
//current_font = rawtmpfont;
//real_current_font = realtmpfont;
// check, whether the last character's font has changed.
rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
if (rawparfont != rawtmpfont)
if (rawparfont !=
cursor.par->GetFontSettings(cursor.par->Last() - 1))
RedoHeightOfParagraph(cursor);
return;
}
@ -3560,9 +3613,7 @@ void LyXText::Backspace()
status = LyXText::NEED_MORE_REFRESH;
BreakAgainOneRow(row);
current_font = rawtmpfont;
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos, false);
SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
// cursor MUST be in row now
if (row->next && row->next->par == row->par)
@ -3580,19 +3631,23 @@ void LyXText::Backspace()
status = LyXText::NEED_MORE_REFRESH;
refresh_y = y;
refresh_row = row;
current_font = rawtmpfont;
real_current_font = realtmpfont;
SetCursor(cursor.par, cursor.pos, false);
SetCursor(cursor.par, cursor.pos, false, cursor.boundary);
}
}
// restore the current font
// That is what a user expects!
current_font = rawtmpfont;
real_current_font = realtmpfont;
// current_font = rawtmpfont;
// real_current_font = realtmpfont;
lastpos = cursor.par->Last();
if (cursor.pos == lastpos) {
SetCurrentFont();
if (IsBoundary(cursor.par, cursor.pos) != cursor.boundary)
SetCursor(cursor.par, cursor.pos, false, !cursor.boundary);
}
// check, wether the last characters font has changed.
rawtmpfont = cursor.par->GetFontSettings(cursor.par->Last() - 1);
if (rawparfont != rawtmpfont) {
if (rawparfont !=
cursor.par->GetFontSettings(lastpos - 1)) {
RedoHeightOfParagraph(cursor);
} else {
// now the special right address boxes
@ -4444,7 +4499,7 @@ int LyXText::DefaultHeight() const
/* returns the column near the specified x-coordinate of the row
* x is set to the real beginning of this column */
int LyXText::GetColumnNearX(Row * row, int & x) const
int LyXText::GetColumnNearX(Row * row, int & x, bool & boundary) const
{
float tmpx = 0.0;
float fill_separator, fill_hfill, fill_label_hfill;
@ -4457,6 +4512,8 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
LyXParagraph::size_type c = 0;
LyXLayout const & layout = textclasslist.Style(buffer->params.textclass,
row->par->GetLayout());
bool left_side = false;
/* table stuff -- begin */
if (row->par->table) {
//the last row doesn't need a newline at the end
@ -4464,27 +4521,30 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
&& row->par->IsNewline(last))
last--;
int cell = NumberOfCell(row->par, row->pos);
float x_old = tmpx;
bool ready = false;
float cell_x = tmpx + row->par->table->WidthOfColumn(cell);
tmpx += row->par->table->GetBeginningOfTextInCell(cell);
while (vc <= last
&& (c = vis2log(vc)) >= 0
&& tmpx + (SingleWidth(row->par, c)/2) <= x
&& !ready){
float last_tmpx = tmpx;
while (vc <= last && tmpx <= x) {
c = vis2log(vc);
last_tmpx = tmpx;
if (row->par->IsNewline(c)) {
if (x_old + row->par->table->WidthOfColumn(cell) <= x){
tmpx = x_old + row->par->table->WidthOfColumn(cell);
x_old = tmpx;
if (cell_x <= x){
++cell;
tmpx += row->par->table->GetBeginningOfTextInCell(cell);
tmpx = cell_x + row->par->table->GetBeginningOfTextInCell(cell);
cell_x += row->par->table->WidthOfColumn(cell);
++vc;
} else
ready = true;
break;
} else {
tmpx += SingleWidth(row->par, c);
++vc;
}
}
if (vc > row->pos && !row->par->IsNewline(c) &&
(tmpx+last_tmpx)/2 > x) {
tmpx = last_tmpx;
left_side = true;
}
} else {
/* table stuff -- end*/
LyXParagraph::size_type main_body = BeginningOfMainBody(row->par);
@ -4523,28 +4583,31 @@ int LyXText::GetColumnNearX(Row * row, int & x) const
}
if (vc > row->pos && (tmpx+last_tmpx)/2 > x) {
vc--;
tmpx = last_tmpx;
left_side = true;
}
}
if (vc > last + 1) // This shouldn't happen.
vc = last+1;
boundary = false;
if (row->pos > last) // Row is empty?
c = row->pos;
else if (vc > last ||
(vc - 1 >= row->pos &&
( (row->par->IsSeparator(vis2log(vc)) && vis2log(vc) != last)
|| (row->par->table && row->par->IsNewline(vc) )
))) {
c = vis2log(vc - 1);
if (bidi_level(c) % 2 == 0)
++c;
} else {
else if (vc == row->pos ||
(row->par->table && vc <= last && row->par->IsNewline(vc-1)) ) {
c = vis2log(vc);
if (bidi_level(c) % 2 == 1)
++c;
} else {
c = vis2log(vc - 1);
bool rtl = (bidi_level(c) % 2 == 1);
if (left_side == rtl) {
++c;
boundary = IsBoundary(row->par, c);
}
}
if (!row->par->table && row->pos <= last && c > last

View File

@ -846,7 +846,7 @@ void LyXText::SetFont(LyXFont const & font, bool toggleall)
SetCursor(sel_end_cursor.par, sel_end_cursor.pos);
ClearSelection();
SetSelection();
SetCursor(tmpcursor.par, tmpcursor.pos);
SetCursor(tmpcursor.par, tmpcursor.pos, true, tmpcursor.boundary);
}
@ -875,7 +875,7 @@ void LyXText::RedoHeightOfParagraph(LyXCursor const & cur)
status = LyXText::NEED_MORE_REFRESH;
refresh_y = y;
refresh_row = tmprow;
SetCursor(cur.par, cur.pos);
SetCursor(cur.par, cur.pos, false, cursor.boundary);
}
@ -1054,8 +1054,8 @@ void LyXText::SetSelection()
}
// a selection with no contents is not a selection
if (sel_start_cursor.x == sel_end_cursor.x &&
sel_start_cursor.y == sel_end_cursor.y)
if (sel_start_cursor.par == sel_end_cursor.par &&
sel_start_cursor.pos == sel_end_cursor.pos)
selection = false;
// Stuff what we got on the clipboard. Even if there is no selection.
@ -3115,16 +3115,17 @@ int LyXText::UpdateInset(Inset * inset)
void LyXText::SetCursor(LyXParagraph * par,
LyXParagraph::size_type pos, bool setfont) const
LyXParagraph::size_type pos,
bool setfont, bool boundary) const
{
LyXCursor old_cursor = cursor;
SetCursorIntern(par, pos, setfont);
SetCursorIntern(par, pos, setfont, boundary);
DeleteEmptyParagraphMechanism(old_cursor);
}
void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
LyXParagraph::size_type pos) const
LyXParagraph::size_type pos, bool boundary) const
{
// correct the cursor position if impossible
if (pos > par->Last()){
@ -3154,6 +3155,7 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
cur.par = par;
cur.pos = pos;
cur.boundary = boundary;
/* get the cursor y position in text */
long y = 0;
@ -3175,16 +3177,18 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
if (last < row->pos)
cursor_vpos = 0;
else if ((pos > last) ||
((pos - 1 >= row->pos) &&
(row->par->IsSeparator(pos) ||
(row->par->table && row->par->IsNewline(pos)))))
else if (pos > last && !boundary)
cursor_vpos = (row->par->isRightToLeftPar())
? row->pos : last+1;
else if (pos > row->pos &&
(pos > last || boundary ||
(row->par->table && row->par->IsNewline(pos))))
/// Place cursor after char at (logical) position pos-1
cursor_vpos = !(bidi_level(pos-1) % 2)
cursor_vpos = (bidi_level(pos-1) % 2 == 0)
? log2vis(pos-1) + 1 : log2vis(pos-1);
else
/// Place cursor before char at (logical) position pos
cursor_vpos = !(bidi_level(pos) % 2)
cursor_vpos = (bidi_level(pos) % 2 == 0)
? log2vis(pos) : log2vis(pos) + 1;
/* table stuff -- begin*/
@ -3248,9 +3252,10 @@ void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
void LyXText::SetCursorIntern(LyXParagraph * par,
LyXParagraph::size_type pos, bool setfont) const
LyXParagraph::size_type pos,
bool setfont, bool boundary) const
{
SetCursor(cursor, par, pos);
SetCursor(cursor, par, pos, boundary);
// #warning Remove this when verified working (Jug 20000413)
#if 0
// correct the cursor position if impossible
@ -3369,18 +3374,32 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
cursor.x_fix = cursor.x;
cursor.row = row;
#endif
if (setfont) {
if (cursor.pos &&
(cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos)
|| (cursor.par->table && cursor.par->IsNewline(cursor.pos))
)) {
current_font = cursor.par->GetFontSettings(cursor.pos - 1);
real_current_font = GetFont(cursor.par, cursor.pos - 1);
} else {
current_font = cursor.par->GetFontSettings(cursor.pos);
real_current_font = GetFont(cursor.par, cursor.pos);
if (setfont)
SetCurrentFont();
}
void LyXText::SetCurrentFont() const
{
LyXParagraph::size_type pos = cursor.pos;
if (cursor.boundary && pos > 0)
--pos;
if (pos > 0) {
if (pos == cursor.par->Last() ||
(cursor.par->table && cursor.par->IsNewline(pos)))
--pos;
else if (cursor.par->IsSeparator(pos)) {
if (pos > cursor.row->pos &&
bidi_level(pos) % 2 ==
bidi_level(pos - 1) % 2)
--pos;
else if (pos + 1 < cursor.par->Last())
++pos;
}
}
current_font = cursor.par->GetFontSettings(pos);
real_current_font = GetFont(cursor.par, pos);
}
@ -3391,29 +3410,14 @@ void LyXText::SetCursorFromCoordinates(int x, long y) const
/* get the row first */
Row * row = GetRowNearY(y);
cursor.par = row->par;
int column = GetColumnNearX(row, x);
int column = GetColumnNearX(row, x, cursor.boundary);
cursor.pos = row->pos + column;
cursor.x = x;
cursor.y = y + row->baseline;
cursor.row = row;
if (cursor.pos &&
(cursor.pos == cursor.par->Last()
|| cursor.par->IsSeparator(cursor.pos)
|| (cursor.pos && cursor.pos == BeginningOfMainBody(cursor.par)
&& !cursor.par->IsSeparator(cursor.pos))
|| (cursor.par->table && cursor.par->IsNewline(cursor.pos))
)) {
current_font = cursor.par->GetFontSettings(cursor.pos - 1);
real_current_font = GetFont(cursor.par, cursor.pos - 1);
} else {
current_font = cursor.par->GetFontSettings(cursor.pos);
real_current_font = GetFont(cursor.par, cursor.pos);
}
SetCurrentFont();
DeleteEmptyParagraphMechanism(old_cursor);
}
@ -3422,7 +3426,7 @@ void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
/* get the row first */
Row * row = GetRowNearY(y);
int column = GetColumnNearX(row, x);
int column = GetColumnNearX(row, x, cur.boundary);
cur.par = row->par;
cur.pos = row->pos + column;
@ -3432,9 +3436,9 @@ void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
}
void LyXText::CursorLeft() const
void LyXText::CursorLeft(bool internal) const
{
CursorLeftIntern();
CursorLeftIntern(internal);
if (cursor.par->table) {
int cell = NumberOfCell(cursor.par, cursor.pos);
if (cursor.par->table->IsContRow(cell) &&
@ -3445,20 +3449,27 @@ void LyXText::CursorLeft() const
}
void LyXText::CursorLeftIntern() const
void LyXText::CursorLeftIntern(bool internal) const
{
if (cursor.pos > 0) {
SetCursor(cursor.par, cursor.pos - 1);
}
else if (cursor.par->Previous()) { // steps into the above paragraph.
SetCursor(cursor.par->Previous(), cursor.par->Previous()->Last());
bool boundary = cursor.boundary;
SetCursor(cursor.par, cursor.pos - 1, true, false);
if (!internal && !boundary &&
IsBoundary(cursor.par, cursor.pos + 1))
SetCursor(cursor.par, cursor.pos + 1, true, true);
} else if (cursor.par->Previous()) { // steps into the above paragraph.
LyXParagraph * par = cursor.par->Previous();
LyXParagraph::size_type pos = par->Last();
SetCursor(par, pos);
if (IsBoundary(par, pos))
SetCursor(par, pos, false, true);
}
}
void LyXText::CursorRight() const
void LyXText::CursorRight(bool internal) const
{
CursorRightIntern();
CursorRightIntern(internal);
if (cursor.par->table) {
int cell = NumberOfCell(cursor.par, cursor.pos);
if (cursor.par->table->IsContRow(cell) &&
@ -3469,15 +3480,20 @@ void LyXText::CursorRight() const
}
void LyXText::CursorRightIntern() const
void LyXText::CursorRightIntern(bool internal) const
{
if (cursor.pos < cursor.par->Last()) {
SetCursor(cursor.par, cursor.pos + 1);
if (!internal && cursor.boundary &&
(!cursor.par->table || !cursor.par->IsNewline(cursor.pos)))
SetCursor(cursor.par, cursor.pos, true, false);
else {
SetCursor(cursor.par, cursor.pos + 1, true, false);
if (!internal && IsBoundary(cursor.par, cursor.pos))
SetCursor(cursor.par, cursor.pos, true, true);
}
else if (cursor.par->Next()) {
} else if (cursor.par->Next())
SetCursor(cursor.par->Next(), 0);
}
}
void LyXText::CursorUp() const