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())


_______________________________________________
scribus-commit mailing list
[email protected]
http://lists.scribus.net/mailman/listinfo/scribus-commit

Reply via email to