From 1297114b73505c3d58eeb77254b2c5119887f3a8 Mon Sep 17 00:00:00 2001 From: Abdelrazak Younes Date: Wed, 24 Oct 2007 07:49:24 +0000 Subject: [PATCH] Introducing Paragraph::changeCase(). git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21167 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Paragraph.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++ src/Paragraph.h | 14 ++++++++++ src/Text.cpp | 65 ++-------------------------------------------- src/Text.h | 9 ------- 4 files changed, 82 insertions(+), 72 deletions(-) diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 21b02b8a50..64ef984eb0 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -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]; diff --git a/src/Paragraph.h b/src/Paragraph.h index 7e206deffe..e264bb2737 100644 --- a/src/Paragraph.h +++ b/src/Paragraph.h @@ -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; diff --git a/src/Text.cpp b/src/Text.cpp index 2c72eefdff..902a4df75c 100644 --- a/src/Text.cpp +++ b/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 diff --git a/src/Text.h b/src/Text.h index f6883e8bd5..6c7c6946ad 100644 --- a/src/Text.h +++ b/src/Text.h @@ -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