r22127 by jghali -
scribus-commit
scribus-commit at lists.scribus.net
Sat Aug 5 01:59:04 UTC 2017
Author: jghali
Date: Sat Aug 5 01:59:04 2017
New Revision: 22127
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=22127
Log:
#14566: add Ignore diacritics & kashida option in Search&Replace dialog
Modified:
trunk/Scribus/scribus/text/specialchars.cpp
trunk/Scribus/scribus/text/specialchars.h
trunk/Scribus/scribus/text/storytext.cpp
trunk/Scribus/scribus/text/storytext.h
trunk/Scribus/scribus/ui/search.cpp
Modified: trunk/Scribus/scribus/text/specialchars.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22127&path=/trunk/Scribus/scribus/text/specialchars.cpp
==============================================================================
--- trunk/Scribus/scribus/text/specialchars.cpp (original)
+++ trunk/Scribus/scribus/text/specialchars.cpp Sat Aug 5 01:59:04 2017
@@ -263,17 +263,13 @@
return false;
}
-bool SpecialChars::isArabicDiacritic(uint ch)
-{
- if (ch >= 0x064B && ch <= 0x065F) /*Fathatan, Dammatan, Kasratan, Fatha,Damma,Kasra,Shadda,Sukun,Maddah, Hamza Above, Hamza Below,Subscript Alef,Inverted Damma,Mark Noon Ghunna*/
- return true;
- else if (ch == 0x0640) //Tatweel
- return true;
- else if (ch >= 0x06D2 && ch <= 0x06DC) /*Yeh Barree,Yeh Barree With Hamza Above, Full Stop Ae,Sad With Lam With Alef,Qaf With Lam With Alef,Small High Meem Initial Form, Small High Lam Alef, Small High Jeem , Small High Three Dots, Small High Seen */
- return true;
- else if (ch >= 0x06DF && ch <= 0x06E8) /*Small High Rounded Zero, Upright Rectangular Zero,Dotless Head Of Khah,Meem Isolated Form, Small Low Seen, Small High Madda,Small Waw, Small Yeh, Small High Yeh, Small High Noon */
- return true;
- else if (ch >= 0x0618 && ch <= 0x061A) /*Small Fatha, Small Damma, Small Kasra*/
+bool SpecialChars::isArabicModifierLetter(uint ch)
+{
+ if (ch == 0x0640) //ARABIC TATWEEL
+ return true;
+ else if (ch == 0x06E5) //ARABIC SMALL WAW
+ return true;
+ else if (ch == 0x06E6) //ARABIC SMALL YEH
return true;
return false;
}
Modified: trunk/Scribus/scribus/text/specialchars.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22127&path=/trunk/Scribus/scribus/text/specialchars.h
==============================================================================
--- trunk/Scribus/scribus/text/specialchars.h (original)
+++ trunk/Scribus/scribus/text/specialchars.h Sat Aug 5 01:59:04 2017
@@ -81,7 +81,7 @@
static bool isCJK(uint ch);
static bool isLetterRequiringSpaceAroundCJK(uint ch);
static bool isIgnorableCodePoint(uint ch);
- static bool isArabicDiacritic(uint ch);
+ static bool isArabicModifierLetter(uint ch);
};
#endif
Modified: trunk/Scribus/scribus/text/storytext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22127&path=/trunk/Scribus/scribus/text/storytext.cpp
==============================================================================
--- trunk/Scribus/scribus/text/storytext.cpp (original)
+++ trunk/Scribus/scribus/text/storytext.cpp Sat Aug 5 01:59:04 2017
@@ -311,21 +311,22 @@
invalidateAll();
}
-int StoryText::indexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
+int StoryText::indexOf(const QString &str, int from, Qt::CaseSensitivity cs, int* pLen) const
{
int foundIndex = -1;
+ if (pLen)
+ *pLen = 0;
if (str.isEmpty() || (from < 0))
return -1;
-
- int strLen = str.length();
- int storyLen = length();
QString qStr = str;
if (cs == Qt::CaseInsensitive)
qStr = qStr.toLower();
QChar ch = qStr.at(0);
+ int strLen = qStr.length();
+ int storyLen = length();
if (cs == Qt::CaseSensitive)
{
int i = indexOf(ch, from, cs);
@@ -341,6 +342,8 @@
if (index == strLen)
{
foundIndex = i;
+ if (pLen)
+ *pLen = strLen;
break;
}
i = indexOf(ch, i + 1, cs);
@@ -348,25 +351,43 @@
}
else
{
+ bool qCharIsDiacritic, curCharIsDiacritic;
int i = indexOf(ch, from, cs);
while (i >= 0 && i < (int) d->len)
{
int index = 0;
- while ((index < strLen) && ((index + i) < storyLen))
+ int diacriticsCounter = 0; //counter for diacritics
+ while ((index < strLen) && ((index + i + diacriticsCounter) < storyLen))
{
- if (qStr.at(index) != d->at(index + i)->ch.toLower())
+ const QChar &qChar = qStr.at(index);
+ const QChar &curChar = d->at(index + diacriticsCounter + i)->ch;
+ qCharIsDiacritic = SpecialChars::isArabicModifierLetter(qChar.unicode()) | (qChar.category() == QChar::Mark_NonSpacing);
+ curCharIsDiacritic = SpecialChars::isArabicModifierLetter(curChar.unicode()) | (curChar.category() == QChar::Mark_NonSpacing);
+ if (qCharIsDiacritic || curCharIsDiacritic)
+ {
+ if (qCharIsDiacritic)
+ {
+ ++index;
+ --diacriticsCounter;
+ }
+ if (curCharIsDiacritic)
+ ++diacriticsCounter;
+ continue;
+ }
+ if (qChar != curChar.toLower())
break;
++index;
}
if (index == strLen)
{
foundIndex = i;
+ if (pLen)
+ *pLen = strLen + diacriticsCounter;
break;
}
i = indexOf(ch, i + 1, cs);
}
}
-
return foundIndex;
}
Modified: trunk/Scribus/scribus/text/storytext.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22127&path=/trunk/Scribus/scribus/text/storytext.h
==============================================================================
--- trunk/Scribus/scribus/text/storytext.h (original)
+++ trunk/Scribus/scribus/text/storytext.h Sat Aug 5 01:59:04 2017
@@ -105,7 +105,7 @@
StoryText copy() const;
// Find text in story
- int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive, int* pLen = 0) const;
int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
// Add, change, replace
Modified: trunk/Scribus/scribus/ui/search.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=22127&path=/trunk/Scribus/scribus/ui/search.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/search.cpp (original)
+++ trunk/Scribus/scribus/ui/search.cpp Sat Aug 5 01:59:04 2017
@@ -261,7 +261,7 @@
if (mode)
Word->setEnabled(false);
OptsLayout->addWidget( Word );
- CaseIgnore = new QCheckBox( tr( "&Ignore Case" ), this );
+ CaseIgnore = new QCheckBox( tr( "&Ignore Case, Diacritics and Kashida" ), this );
if (mode)
CaseIgnore->setEnabled(false);
OptsLayout->addWidget( CaseIgnore );
@@ -434,7 +434,7 @@
uint as = m_item->itemText.cursorPosition();
m_replStart = as;
- int a;
+ int a, textLen(0);
if (m_itemMode)
{
Qt::CaseSensitivity cs = Qt::CaseSensitive;
@@ -446,16 +446,16 @@
found = true;
if (SText->isChecked())
{
- a = m_item->itemText.indexOf(sText, a, cs);
+ a = m_item->itemText.indexOf(sText, a, cs, &textLen);
found = (a >= 0);
if (!found) break;
- if (Word->isChecked() && (a > 0) && !m_item->itemText.text(a - 1).isSpace())
+ if (Word->isChecked() && (a > 0) && m_item->itemText.text(a - 1).isLetterOrNumber())
found = false;
if (Word->isChecked())
{
- int lastChar = qMin(a + sText.length(), maxChar);
- found = ((lastChar == maxChar) || m_item->itemText.text(lastChar).isSpace());
+ int lastChar = qMin(a + textLen, maxChar);
+ found = ((lastChar == maxChar) || !m_item->itemText.text(lastChar).isLetterOrNumber());
}
if (!found) continue;
}
@@ -508,14 +508,14 @@
}
if (found && searchForReplace)
{
- m_item->itemText.select(a, sText.length());
+ m_item->itemText.select(a, textLen);
m_item->HasSel = true;
if (rep)
{
DoReplace->setEnabled(true);
AllReplace->setEnabled(true);
}
- m_item->itemText.setCursorPosition(a + sText.length());
+ m_item->itemText.setCursorPosition(a + textLen);
if (!SText->isChecked())
break;
@@ -551,21 +551,34 @@
if (storyTextEdit->StyledText.length() == 0)
return;
+ QTextCursor cursor = storyTextEdit->textCursor();
+ int position = cursor.position();
+ StoryText& styledText = storyTextEdit->StyledText;
+ int firstChar = -1, lastChar = styledText.length();
if (SText->isChecked())
{
- QTextDocument::FindFlags flags;
- if (!CaseIgnore->isChecked())
- flags |= QTextDocument::FindCaseSensitively;
- if (Word->isChecked())
- flags |= QTextDocument::FindWholeWords;
- do
- {
- found = storyTextEdit->find(sText, flags);
+ Qt::CaseSensitivity cs = Qt::CaseSensitive;
+ if (CaseIgnore->isChecked())
+ cs = Qt::CaseInsensitive;
+
+ for (int i = position; i < styledText.length(); ++i)
+ {
+ i = styledText.indexOf(sText, i, cs, &textLen);
+ found = (i >= 0);
if (!found)
break;
- QTextCursor cursor = storyTextEdit->textCursor();
- int selStart = cursor.selectionStart();
- for (int ap = 0; ap < sText.length(); ++ap)
+
+ if (Word->isChecked() && (i > 0) && styledText.text(i - 1).isLetterOrNumber())
+ found = false;
+ if (Word->isChecked())
+ {
+ int lastChar = qMin(i + textLen, maxChar);
+ found = ((lastChar == maxChar) || !styledText.text(lastChar).isLetterOrNumber());
+ }
+ if (!found) continue;
+
+ int selStart = i;
+ for (int ap = 0; ap < textLen; ++ap)
{
const ParagraphStyle& parStyle = storyTextEdit->StyledText.paragraphStyle(selStart + ap);
const CharStyle& charStyle = storyTextEdit->StyledText.charStyle(selStart + ap);
@@ -588,14 +601,17 @@
if (SEffect->isChecked() && ((charStyle.effects() & ScStyle_UserStyles) != sEff))
found = false;
}
- } while(!found);
+
+ if (found)
+ {
+ firstChar = i;
+ lastChar = i + textLen;
+ break;
+ }
+ }
}
else
{
- QTextCursor cursor = storyTextEdit->textCursor();
- int position = cursor.position();
- StoryText& styledText = storyTextEdit->StyledText;
- int firstChar = -1, lastChar = styledText.length();
for (int i = position; i < styledText.length(); ++i)
{
found = true;
@@ -633,14 +649,13 @@
break;
}
}
-
- found = (firstChar >= 0);
- if (found)
- {
- cursor.setPosition(firstChar);
- cursor.setPosition(lastChar, QTextCursor::KeepAnchor);
- storyTextEdit->setTextCursor(cursor);
- }
+ }
+ found = (firstChar >= 0);
+ if (found)
+ {
+ cursor.setPosition(firstChar);
+ cursor.setPosition(lastChar, QTextCursor::KeepAnchor);
+ storyTextEdit->setTextCursor(cursor);
}
if (found && searchForReplace)
{
@@ -685,35 +700,38 @@
{
QString repl, sear;
int cs, cx;
-// ScText *hg;
+ int textLen = 0;
if (RText->isChecked())
{
repl = RTextVal->text();
sear = STextVal->text();
- if (sear.length() == repl.length())
- {
- for (cs = 0; cs < sear.length(); ++cs)
+ textLen = m_item->itemText.lengthOfSelection();
+ if (textLen == repl.length())
+ {
+ for (cs = 0; cs < textLen; ++cs)
m_item->itemText.replaceChar(m_replStart+cs, repl[cs]);
}
else
{
- if (sear.length() < repl.length())
+ if (textLen < repl.length())
{
- for (cs = 0; cs < sear.length(); ++cs)
+ for (cs = 0; cs < textLen; ++cs)
m_item->itemText.replaceChar(m_replStart+cs, repl[cs]);
for (cx = cs; cx < repl.length(); ++cx)
m_item->itemText.insertChars(m_replStart+cx, repl.mid(cx,1), true);
- // FIXME:NLS also replace styles!!
}
else
{
for (cs = 0; cs < repl.length(); ++cs)
m_item->itemText.replaceChar(m_replStart+cs, repl[cs]);
- m_item->itemText.removeChars(m_replStart+cs, sear.length() - cs);
+ m_item->itemText.removeChars(m_replStart+cs, textLen - cs);
}
- m_item->itemText.deselectAll();
- if (repl.length() > 0)
- m_item->itemText.select(m_replStart, repl.length());
+ }
+ m_item->itemText.deselectAll();
+ if (repl.length() > 0)
+ {
+ m_item->itemText.select(m_replStart, repl.length());
+ m_item->itemText.setCursorPosition(m_replStart + repl.length());
}
}
if (RStyle->isChecked())
More information about the scribus-commit
mailing list