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