* Paragraph.cpp (isChar): new method; returns true when pointer is on

a character that is not a letter. Note that a footnote inset, for 
	example is neither a letter nor a character.
	(isSpace): new method too.

	* LyXRC.cpp:
	* development/MacOSX/lyxrc.dist.in: new variable mac_like_word_movement,
	set to true on Mac OS X. There is no GUI for it now.

	* src/Text.cpp (cursorForwardOneWord, cursorBackWardOneWord): implement
	mac-like and windows like cursor movement. Fix bugs 2815 and 3580.



git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_5_X@25417 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jean-Marc Lasgouttes 2008-07-02 09:48:52 +00:00
parent 3cb8ba94eb
commit 384807184a
6 changed files with 120 additions and 23 deletions

View File

@ -27,6 +27,7 @@
\screen_font_roman "Times"
\screen_font_sans "Helvetica"
\screen_font_typewriter "Courier"
\mac_like_word_movement true
#
# COLOR SECTION ###################################

View File

@ -108,6 +108,7 @@ keyword_item lyxrcTags[] = {
{ "\\language_package", LyXRC::RC_LANGUAGE_PACKAGE },
{ "\\language_use_babel", LyXRC::RC_LANGUAGE_USE_BABEL },
{ "\\load_session", LyXRC::RC_LOADSESSION },
{ "\\mac_like_word_movement", LyXRC::RC_MAC_LIKE_WORD_MOVEMENT },
{ "\\make_backup", LyXRC::RC_MAKE_BACKUP },
{ "\\mark_foreign_language", LyXRC::RC_MARK_FOREIGN_LANGUAGE },
{ "\\num_lastfiles", LyXRC::RC_NUMLASTFILES },
@ -274,6 +275,7 @@ void LyXRC::setDefaults() {
tex_allows_spaces = false;
date_insert_format = "%x";
cursor_follows_scrollbar = false;
mac_like_word_movement = false;
dialogs_iconify_with_main = false;
label_init_length = 3;
preview = PREVIEW_OFF;
@ -849,6 +851,12 @@ int LyXRC::read(Lexer & lexrc)
}
break;
case RC_MAC_LIKE_WORD_MOVEMENT:
if (lexrc.next()) {
mac_like_word_movement = lexrc.getBool();
}
break;
case RC_DIALOGS_ICONIFY_WITH_MAIN:
if (lexrc.next()) {
dialogs_iconify_with_main = lexrc.getBool();
@ -1502,6 +1510,15 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc) const
os << "\\cursor_follows_scrollbar "
<< convert<string>(cursor_follows_scrollbar) << '\n';
}
case RC_MAC_LIKE_WORD_MOVEMENT:
if (ignore_system_lyxrc ||
mac_like_word_movement
!= system_lyxrc.mac_like_word_movement) {
os << "\\mac_like_word_movement "
<< convert<string>(mac_like_word_movement) << '\n';
}
if (tag != RC_LAST)
break;
case RC_DIALOGS_ICONIFY_WITH_MAIN:
if (ignore_system_lyxrc ||
dialogs_iconify_with_main
@ -2159,6 +2176,10 @@ string const LyXRC::getDescription(LyXRCTags tag)
str = _("LyX normally doesn't update the cursor position if you move the scrollbar. Set to true if you'd prefer to always have the cursor on screen.");
break;
case RC_MAC_LIKE_WORD_MOVEMENT:
str = _("Use the Mac OS X conventions for the word-level cursor movement");
break;
case RC_CUSTOM_EXPORT_COMMAND:
break;

View File

@ -55,6 +55,7 @@ public:
RC_CONVERTER_CACHE_MAXAGE,
RC_COPIER,
RC_CURSOR_FOLLOWS_SCROLLBAR,
RC_MAC_LIKE_WORD_MOVEMENT,
RC_CUSTOM_EXPORT_COMMAND,
RC_CUSTOM_EXPORT_FORMAT,
RC_DATE_INSERT_FORMAT,
@ -335,6 +336,8 @@ public:
///
std::string default_language;
///
bool mac_like_word_movement;
///
bool cursor_follows_scrollbar;
///
bool dialogs_iconify_with_main;

View File

@ -2502,6 +2502,28 @@ bool Paragraph::isLetter(pos_type pos) const
}
bool Paragraph::isChar(pos_type pos) const
{
if (isInset(pos))
return getInset(pos)->isChar();
else {
value_type const c = getChar(pos);
return !isLetterChar(c) && !isDigit(c) && !lyx::isSpace(c);
}
}
bool Paragraph::isSpace(pos_type pos) const
{
if (isInset(pos))
return getInset(pos)->isSpace();
else {
value_type const c = getChar(pos);
return lyx::isSpace(c);
}
}
Language const *
Paragraph::getParLanguage(BufferParams const & bparams) const
{

View File

@ -339,6 +339,10 @@ public:
/// True if the character/inset at this point can be part of a word.
/// Note that digits in particular are considered as letters
bool isLetter(pos_type pos) const;
/// True if the element at this point is a character that is not a letter.
bool isChar(pos_type pos) const;
/// True if the element at this point is a space
bool isSpace(pos_type pos) const;
/// returns -1 if inset not found
int getPositionOfInset(Inset const * inset) const;

View File

@ -814,20 +814,46 @@ bool Text::cursorRightOneWord(Cursor & cur)
{
BOOST_ASSERT(this == cur.text());
Cursor old = cur;
pos_type const lastpos = cur.lastpos();
pit_type pit = cur.pit();
pos_type pos = cur.pos();
Paragraph const & par = cur.paragraph();
if (old.pos() == old.lastpos() && old.pit() != old.lastpit()) {
++old.pit();
old.pos() = 0;
} else {
// Advance through word.
while (old.pos() != old.lastpos() && old.paragraph().isLetter(old.pos()))
++old.pos();
// Skip through trailing nonword stuff.
while (old.pos() != old.lastpos() && !old.paragraph().isLetter(old.pos()))
++old.pos();
// Paragraph boundary is a word boundary
if (pos == lastpos) {
if (pit != cur.lastpit())
return setCursor(cur, pit + 1, 0);
else
return false;
}
return setCursor(cur, old.pit(), old.pos());
if (lyxrc.mac_like_word_movement) {
// Skip through trailing punctuation and spaces.
while (pos != lastpos && par.isChar(pos))
++pos;
// Skip over either a non-char inset or a full word
if (pos != lastpos && !par.isLetter(pos))
++pos;
else while (pos != lastpos && par.isLetter(pos))
++pos;
} else {
BOOST_ASSERT(pos < lastpos); // see above
if (par.isLetter(pos))
while (pos != lastpos && par.isLetter(pos))
++pos;
else if (par.isChar(pos))
while (pos != lastpos && par.isChar(pos))
++pos;
else if (!par.isSpace(pos)) // non-char inset
++pos;
// Skip over white space
while (pos != lastpos && par.isSpace(pos))
++pos;
}
return setCursor(cur, pit, pos);
}
@ -835,20 +861,40 @@ bool Text::cursorLeftOneWord(Cursor & cur)
{
BOOST_ASSERT(this == cur.text());
Cursor old = cur;
pit_type pit = cur.pit();
pos_type pos = cur.pos();
Paragraph & par = cur.paragraph();
if (old.pos() == 0 && old.pit() != 0) {
--old.pit();
old.pos() = old.lastpos();
// Paragraph boundary is a word boundary
if (pos == 0 && pit != 0)
return setCursor(cur, pit - 1, getPar(pit - 1).size());
if (lyxrc.mac_like_word_movement) {
// Skip through puctuation and spaces.
while (pos != 0 && par.isChar(pos - 1))
--pos;
// Skip over either a non-char inset or a full word
if (pos != 0 && !par.isLetter(pos - 1) && !par.isChar(pos - 1))
--pos;
else while (pos != 0 && par.isLetter(pos - 1))
--pos;
} else {
// Skip through initial nonword stuff.
while (old.pos() != 0 && !old.paragraph().isLetter(old.pos() - 1))
--old.pos();
// Advance through word.
while (old.pos() != 0 && old.paragraph().isLetter(old.pos() - 1))
--old.pos();
// Skip over white space
while (pos != 0 && par.isSpace(pos - 1))
--pos;
if (pos != 0 && par.isLetter(pos - 1))
while (pos != 0 && par.isLetter(pos - 1))
--pos;
else if (pos != 0 && par.isChar(pos - 1))
while (pos != 0 && par.isChar(pos - 1))
--pos;
else if (pos != 0 && !par.isSpace(pos - 1)) // non-char inset
--pos;
}
return setCursor(cur, old.pit(), old.pos());
return setCursor(cur, pit, pos);
}