mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +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 {
|
namespace lyx {
|
||||||
|
|
||||||
using support::contains;
|
using support::contains;
|
||||||
|
using support::lowercase;
|
||||||
using support::prefixIs;
|
using support::prefixIs;
|
||||||
using support::suffixIs;
|
using support::suffixIs;
|
||||||
using support::rsplit;
|
using support::rsplit;
|
||||||
using support::rtrim;
|
using support::rtrim;
|
||||||
|
using support::uppercase;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/// Inset identifier (above 0x10ffff, for ucs-4)
|
/// 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
|
char_type Paragraph::getChar(pos_type pos) const
|
||||||
{
|
{
|
||||||
return d->text_[pos];
|
return d->text_[pos];
|
||||||
|
@ -59,6 +59,16 @@ public:
|
|||||||
pos_type first, last;
|
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
|
/// A Paragraph holds all text, attributes and insets in a text paragraph
|
||||||
/// \todo FIXME: any reference to ParagraphMetrics (including inheritance)
|
/// \todo FIXME: any reference to ParagraphMetrics (including inheritance)
|
||||||
@ -347,6 +357,10 @@ public:
|
|||||||
/// return the number of InsetOptArg in a paragraph
|
/// return the number of InsetOptArg in a paragraph
|
||||||
int numberOfOptArgs() const;
|
int numberOfOptArgs() const;
|
||||||
|
|
||||||
|
///
|
||||||
|
void changeCase(BufferParams const & bparams, pos_type pos,
|
||||||
|
pos_type right, TextCase action);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Pimpl away stuff
|
/// Pimpl away stuff
|
||||||
class Private;
|
class Private;
|
||||||
|
65
src/Text.cpp
65
src/Text.cpp
@ -85,9 +85,7 @@ namespace lyx {
|
|||||||
|
|
||||||
using support::bformat;
|
using support::bformat;
|
||||||
using support::contains;
|
using support::contains;
|
||||||
using support::lowercase;
|
|
||||||
using support::split;
|
using support::split;
|
||||||
using support::uppercase;
|
|
||||||
|
|
||||||
using cap::cutSelection;
|
using cap::cutSelection;
|
||||||
using cap::pasteParagraphList;
|
using cap::pasteParagraphList;
|
||||||
@ -827,7 +825,7 @@ void Text::deleteWordBackward(Cursor & cur)
|
|||||||
|
|
||||||
|
|
||||||
// Kill to end of line.
|
// 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());
|
BOOST_ASSERT(this == cur.text());
|
||||||
CursorSlice from;
|
CursorSlice from;
|
||||||
@ -850,73 +848,14 @@ void Text::changeCase(Cursor & cur, Text::TextCase action)
|
|||||||
pos_type begPos = from.pos();
|
pos_type begPos = from.pos();
|
||||||
pos_type endPos = to.pos();
|
pos_type endPos = to.pos();
|
||||||
|
|
||||||
bool const trackChanges = cur.buffer().params().trackChanges;
|
|
||||||
|
|
||||||
pos_type right = 0; // needed after the for loop
|
pos_type right = 0; // needed after the for loop
|
||||||
|
|
||||||
for (pit_type pit = begPit; pit <= endPit; ++pit) {
|
for (pit_type pit = begPit; pit <= endPit; ++pit) {
|
||||||
Paragraph & par = pars_[pit];
|
Paragraph & par = pars_[pit];
|
||||||
pos_type parSize = par.size();
|
pos_type parSize = par.size();
|
||||||
|
|
||||||
pos_type pos = (pit == begPit ? begPos : 0);
|
pos_type pos = (pit == begPit ? begPos : 0);
|
||||||
right = (pit == endPit ? endPos : parSize);
|
right = (pit == endPit ? endPos : parSize);
|
||||||
|
par.changeCase(cur.buffer().params(), pos, right, 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 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the selection may have changed due to logically-only deleted chars
|
// the selection may have changed due to logically-only deleted chars
|
||||||
|
@ -200,15 +200,6 @@ public:
|
|||||||
bool dissolveInset(Cursor & cur);
|
bool dissolveInset(Cursor & cur);
|
||||||
///
|
///
|
||||||
bool selectWordWhenUnderCursor(Cursor & cur, word_location);
|
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.
|
/// Change the case of the word at cursor position.
|
||||||
void changeCase(Cursor & cur, TextCase action);
|
void changeCase(Cursor & cur, TextCase action);
|
||||||
/// Transposes the character at the cursor with the one before it
|
/// Transposes the character at the cursor with the one before it
|
||||||
|
Loading…
Reference in New Issue
Block a user