mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-27 06:19:36 +00:00
Introducing Paragraph::changeCase().
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21167 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
ce1ec3edd2
commit
1297114b73
@ -66,10 +66,12 @@ using std::ostream;
|
||||
namespace lyx {
|
||||
|
||||
using support::contains;
|
||||
using support::lowercase;
|
||||
using support::prefixIs;
|
||||
using support::suffixIs;
|
||||
using support::rsplit;
|
||||
using support::rtrim;
|
||||
using support::uppercase;
|
||||
|
||||
namespace {
|
||||
/// Inset identifier (above 0x10ffff, for ucs-4)
|
||||
@ -2600,6 +2602,70 @@ int Paragraph::numberOfOptArgs() const
|
||||
}
|
||||
|
||||
|
||||
void Paragraph::changeCase(BufferParams const & bparams, pos_type pos,
|
||||
pos_type right, TextCase action)
|
||||
{
|
||||
// process sequences of modified characters; in change
|
||||
// tracking mode, this approach results in much better
|
||||
// usability than changing case on a char-by-char basis
|
||||
docstring changes;
|
||||
|
||||
bool const trackChanges = bparams.trackChanges;
|
||||
|
||||
bool capitalize = true;
|
||||
|
||||
for (; pos < right; ++pos) {
|
||||
char_type oldChar = d->text_[pos];
|
||||
char_type newChar = oldChar;
|
||||
|
||||
// ignore insets and don't play with deleted text!
|
||||
if (isInset(pos) && !isDeleted(pos)) {
|
||||
switch (action) {
|
||||
case text_lowercase:
|
||||
newChar = lowercase(oldChar);
|
||||
break;
|
||||
case text_capitalization:
|
||||
if (capitalize) {
|
||||
newChar = uppercase(oldChar);
|
||||
capitalize = false;
|
||||
}
|
||||
break;
|
||||
case text_uppercase:
|
||||
newChar = uppercase(oldChar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLetter(pos) || isDeleted(pos)) {
|
||||
// permit capitalization again
|
||||
capitalize = true;
|
||||
}
|
||||
|
||||
if (oldChar != newChar)
|
||||
changes += newChar;
|
||||
|
||||
if (oldChar == newChar || pos == right - 1) {
|
||||
if (oldChar != newChar) {
|
||||
// step behind the changing area
|
||||
pos++;
|
||||
}
|
||||
int erasePos = pos - changes.size();
|
||||
for (size_t i = 0; i < changes.size(); i++) {
|
||||
insertChar(pos, changes[i],
|
||||
getFontSettings(bparams,
|
||||
erasePos),
|
||||
trackChanges);
|
||||
if (!eraseChar(erasePos, trackChanges)) {
|
||||
++erasePos;
|
||||
++pos; // advance
|
||||
++right; // expand selection
|
||||
}
|
||||
}
|
||||
changes.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char_type Paragraph::getChar(pos_type pos) const
|
||||
{
|
||||
return d->text_[pos];
|
||||
|
@ -59,6 +59,16 @@ public:
|
||||
pos_type first, last;
|
||||
};
|
||||
|
||||
///
|
||||
enum TextCase {
|
||||
///
|
||||
text_lowercase = 0,
|
||||
///
|
||||
text_capitalization = 1,
|
||||
///
|
||||
text_uppercase = 2
|
||||
};
|
||||
|
||||
|
||||
/// A Paragraph holds all text, attributes and insets in a text paragraph
|
||||
/// \todo FIXME: any reference to ParagraphMetrics (including inheritance)
|
||||
@ -347,6 +357,10 @@ public:
|
||||
/// return the number of InsetOptArg in a paragraph
|
||||
int numberOfOptArgs() const;
|
||||
|
||||
///
|
||||
void changeCase(BufferParams const & bparams, pos_type pos,
|
||||
pos_type right, TextCase action);
|
||||
|
||||
private:
|
||||
/// Pimpl away stuff
|
||||
class Private;
|
||||
|
65
src/Text.cpp
65
src/Text.cpp
@ -85,9 +85,7 @@ namespace lyx {
|
||||
|
||||
using support::bformat;
|
||||
using support::contains;
|
||||
using support::lowercase;
|
||||
using support::split;
|
||||
using support::uppercase;
|
||||
|
||||
using cap::cutSelection;
|
||||
using cap::pasteParagraphList;
|
||||
@ -827,7 +825,7 @@ void Text::deleteWordBackward(Cursor & cur)
|
||||
|
||||
|
||||
// Kill to end of line.
|
||||
void Text::changeCase(Cursor & cur, Text::TextCase action)
|
||||
void Text::changeCase(Cursor & cur, TextCase action)
|
||||
{
|
||||
BOOST_ASSERT(this == cur.text());
|
||||
CursorSlice from;
|
||||
@ -850,73 +848,14 @@ void Text::changeCase(Cursor & cur, Text::TextCase action)
|
||||
pos_type begPos = from.pos();
|
||||
pos_type endPos = to.pos();
|
||||
|
||||
bool const trackChanges = cur.buffer().params().trackChanges;
|
||||
|
||||
pos_type right = 0; // needed after the for loop
|
||||
|
||||
for (pit_type pit = begPit; pit <= endPit; ++pit) {
|
||||
Paragraph & par = pars_[pit];
|
||||
pos_type parSize = par.size();
|
||||
|
||||
pos_type pos = (pit == begPit ? begPos : 0);
|
||||
right = (pit == endPit ? endPos : parSize);
|
||||
|
||||
// process sequences of modified characters; in change
|
||||
// tracking mode, this approach results in much better
|
||||
// usability than changing case on a char-by-char basis
|
||||
docstring changes;
|
||||
|
||||
bool capitalize = true;
|
||||
|
||||
for (; pos < right; ++pos) {
|
||||
char_type oldChar = par.getChar(pos);
|
||||
char_type newChar = oldChar;
|
||||
|
||||
// ignore insets and don't play with deleted text!
|
||||
if (par.isInset(pos) && !par.isDeleted(pos)) {
|
||||
switch (action) {
|
||||
case text_lowercase:
|
||||
newChar = lowercase(oldChar);
|
||||
break;
|
||||
case text_capitalization:
|
||||
if (capitalize) {
|
||||
newChar = uppercase(oldChar);
|
||||
capitalize = false;
|
||||
}
|
||||
break;
|
||||
case text_uppercase:
|
||||
newChar = uppercase(oldChar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!par.isLetter(pos) || par.isDeleted(pos)) {
|
||||
capitalize = true; // permit capitalization again
|
||||
}
|
||||
|
||||
if (oldChar != newChar) {
|
||||
changes += newChar;
|
||||
}
|
||||
|
||||
if (oldChar == newChar || pos == right - 1) {
|
||||
if (oldChar != newChar) {
|
||||
pos++; // step behind the changing area
|
||||
}
|
||||
int erasePos = pos - changes.size();
|
||||
for (size_t i = 0; i < changes.size(); i++) {
|
||||
par.insertChar(pos, changes[i],
|
||||
par.getFontSettings(cur.buffer().params(),
|
||||
erasePos),
|
||||
trackChanges);
|
||||
if (!par.eraseChar(erasePos, trackChanges)) {
|
||||
++erasePos;
|
||||
++pos; // advance
|
||||
++right; // expand selection
|
||||
}
|
||||
}
|
||||
changes.clear();
|
||||
}
|
||||
}
|
||||
par.changeCase(cur.buffer().params(), pos, right, action);
|
||||
}
|
||||
|
||||
// the selection may have changed due to logically-only deleted chars
|
||||
|
@ -200,15 +200,6 @@ public:
|
||||
bool dissolveInset(Cursor & cur);
|
||||
///
|
||||
bool selectWordWhenUnderCursor(Cursor & cur, word_location);
|
||||
///
|
||||
enum TextCase {
|
||||
///
|
||||
text_lowercase = 0,
|
||||
///
|
||||
text_capitalization = 1,
|
||||
///
|
||||
text_uppercase = 2
|
||||
};
|
||||
/// Change the case of the word at cursor position.
|
||||
void changeCase(Cursor & cur, TextCase action);
|
||||
/// Transposes the character at the cursor with the one before it
|
||||
|
Loading…
Reference in New Issue
Block a user