From ec282df200afbb06b778bb1e53772cfac80617c6 Mon Sep 17 00:00:00 2001 From: Saki Date: Tue, 24 Dec 2013 15:52:16 +0800 Subject: [PATCH] Major: 0.2.15.18 Bug Fixed: 1. Fixed #6 Infinite replace all bug. 2. Fixed #5 search function creashed bug. --- src/app/kccodeeditor.cpp | 59 ++++++---- src/app/kcsearchwidget.cpp | 10 ++ src/app/kcsearchwidget.h | 4 + src/app/kctextblockdata.cpp | 59 ++++++---- src/app/kctextblockdata.h | 17 +-- src/app/kctexteditor.cpp | 224 ++++++++++++++++++++++++------------ src/app/kctexteditor.h | 10 +- src/app/main.cpp | 2 +- 8 files changed, 250 insertions(+), 135 deletions(-) diff --git a/src/app/kccodeeditor.cpp b/src/app/kccodeeditor.cpp index d0cefcb..9353688 100755 --- a/src/app/kccodeeditor.cpp +++ b/src/app/kccodeeditor.cpp @@ -220,11 +220,17 @@ void KCCodeEditor::showCompileBar() } } +void KCCodeEditor::setUseLastCuror() +{ + searchUseLastCursor=true; +} + void KCCodeEditor::showSearchBar() { if(replaceBar->isVisible()) { searcherConnections.disConnectAll(); + replaceBar->setConnected(false); replaceBar->hideAnime(); } @@ -235,11 +241,15 @@ void KCCodeEditor::showSearchBar() editor->backupSearchTextCursor(); } searchBar->animeShow(); - searcherConnections+=connect(searchBar, SIGNAL(requireLostFocus()), - editor, SLOT(setFocus())); - searcherConnections+=connect(searchBar, SIGNAL(requireLostFocus()), - this, SLOT(setUseLastCuror())); - connectSearchWidgetWithEditor(searchBar); + if(!searchBar->getConnected()) + { + searchBar->setConnected(true); + connectSearchWidgetWithEditor(searchBar); + searcherConnections+=connect(searchBar, SIGNAL(requireLostFocus()), + editor, SLOT(setFocus())); + searcherConnections+=connect(searchBar, SIGNAL(requireLostFocus()), + this, SLOT(setUseLastCuror())); + } } QTextCursor _textCursor=editor->textCursor(); @@ -250,34 +260,37 @@ void KCCodeEditor::showSearchBar() searchBar->setTextFocus(); } -void KCCodeEditor::setUseLastCuror() -{ - searchUseLastCursor=true; -} - void KCCodeEditor::showReplaceBar() { if(searchBar->isVisible()) { - searchBar->animeHide(); searcherConnections.disConnectAll(); + searchBar->setConnected(false); + searchBar->animeHide(); } if(!replaceBar->isVisible()) { + if(!searchUseLastCursor) + { + editor->backupSearchTextCursor(); + } replaceBar->showAnime(); - - connectSearchWidgetWithEditor(replaceBar); - searcherConnections+=connect(replaceBar, SIGNAL(requireLostFocus()), - editor, SLOT(setFocus())); - searcherConnections+=connect(replaceBar, SIGNAL(requireLostFocus()), - this, SLOT(setUseLastCuror())); - searcherConnections+=connect(replaceBar,&KCReplaceWindow::requireReplace, - editor,&KCTextEditor::replace); - searcherConnections+=connect(replaceBar,&KCReplaceWindow::requireReplaceAndFind, - editor,&KCTextEditor::replaceAndFind); - searcherConnections+=connect(replaceBar,&KCReplaceWindow::requireReplaceAll, - editor,&KCTextEditor::replaceAll); + if(!replaceBar->getConnected()) + { + replaceBar->setConnected(true); + connectSearchWidgetWithEditor(replaceBar); + searcherConnections+=connect(replaceBar, SIGNAL(requireLostFocus()), + editor, SLOT(setFocus())); + searcherConnections+=connect(replaceBar, SIGNAL(requireLostFocus()), + this, SLOT(setUseLastCuror())); + searcherConnections+=connect(replaceBar,&KCReplaceWindow::requireReplace, + editor,&KCTextEditor::replace); + searcherConnections+=connect(replaceBar,&KCReplaceWindow::requireReplaceAndFind, + editor,&KCTextEditor::replaceAndFind); + searcherConnections+=connect(replaceBar,&KCReplaceWindow::requireReplaceAll, + editor,&KCTextEditor::replaceAll); + } } QTextCursor _textCursor=editor->textCursor(); diff --git a/src/app/kcsearchwidget.cpp b/src/app/kcsearchwidget.cpp index ce45264..2b2c4c0 100755 --- a/src/app/kcsearchwidget.cpp +++ b/src/app/kcsearchwidget.cpp @@ -178,3 +178,13 @@ void KCSearchWidget::resizeEvent(QResizeEvent *event) { searchText->setFixedWidth(event->size().width()); } +bool KCSearchWidget::getConnected() const +{ + return connected; +} + +void KCSearchWidget::setConnected(bool value) +{ + connected = value; +} + diff --git a/src/app/kcsearchwidget.h b/src/app/kcsearchwidget.h index 3223fea..1efe370 100755 --- a/src/app/kcsearchwidget.h +++ b/src/app/kcsearchwidget.h @@ -55,6 +55,9 @@ class KCSearchWidget : public QWidget static const int searchTextPartWidth; void restoreLastSearchText(); + bool getConnected() const; + void setConnected(bool value); + signals: void requireShowPreviousResult(); void requireShowNextResult(); @@ -83,6 +86,7 @@ public slots: }; int currResultNum; + bool connected; QGridLayout *searchLayout; QToolButton *prevResult, *nextResult; diff --git a/src/app/kctextblockdata.cpp b/src/app/kctextblockdata.cpp index 87feb9b..2f3317f 100755 --- a/src/app/kctextblockdata.cpp +++ b/src/app/kctextblockdata.cpp @@ -33,46 +33,57 @@ void KCTextBlockData::resetForSearch() { needSearchAgain=false; matchedTextPositions.clear(); - matchedInfo gmin,gmax; - gmin.pos=INT_MIN; - gmax.pos=INT_MAX; - matchedTextPositions<::iterator KCTextBlockData::getFirstMatchedTextPosition() +void KCTextBlockData::setSearchCode(const unsigned long long &searchCode) { - return matchedTextPositions.begin()+1; //skip the guard elements + this->searchCode=searchCode; } -QList::iterator KCTextBlockData::getEndMatchedTextPosition() +KCTextBlockData::matchedInfo KCTextBlockData::getMatchedInfo(int index) { - return matchedTextPositions.end()-1; //skip the guard elements + return matchedTextPositions.at(index); } -void KCTextBlockData::setSearchCode(const unsigned long long &searchCode) +int KCTextBlockData::matchedCount() { - this->searchCode=searchCode; + return matchedTextPositions.count(); } void KCTextBlockData::insertMatchedTextPositions(const int &pos, - const int &matchedLen) + const int &matchedLen) { - auto i=matchedTextPositions.begin(), - l=matchedTextPositions.end(); - while(ipos<=pos && pos <= (i+1)->pos) + case 0: + matchedTextPositions.append(newElement); + break; + case 1: + matchedTextPositions.insert(pos>matchedTextPositions.at(0).pos?1:0, + newElement); + break; + default: + int finalPosition=matchedTextPositions.count()-1; + bool insertFlag=false; + for(int i=0;i=pos) + { + insertFlag=true; + matchedTextPositions.insert(i+1,newElement); + break; + } } - - i++; + if(!insertFlag) + { + matchedTextPositions.append(newElement); + } + break; } - - matchedInfo newElement; - newElement.pos=pos; - newElement.matchedLength=matchedLen; - matchedTextPositions.insert(i+1,newElement); } void KCTextBlockData::insertQuotationInfo(const int &beginPos, const int &endPos) @@ -105,7 +116,7 @@ void KCTextBlockData::endUsingSearchDatas() bool KCTextBlockData::hasMatched() { - return matchedTextPositions.size()>2; + return !matchedTextPositions.isEmpty(); } void KCTextBlockData::resetParentheseInfos() diff --git a/src/app/kctextblockdata.h b/src/app/kctextblockdata.h index 4abd3a1..55d8ba9 100755 --- a/src/app/kctextblockdata.h +++ b/src/app/kctextblockdata.h @@ -25,12 +25,6 @@ #include #include -struct matchedInfo -{ - int pos; - int matchedLength; -}; - struct quotationInfo { int beginPos; @@ -56,14 +50,21 @@ struct markUnit class KCTextBlockData : public QTextBlockUserData { public: + struct matchedInfo + { + int pos; + int matchedLength; + }; + KCTextBlockData(); void beginUsingSearchDatas(); void endUsingSearchDatas(); void resetForSearch(); void setSearchCode(const unsigned long long int &searchCode); - QList::iterator getFirstMatchedTextPosition(); - QList::iterator getEndMatchedTextPosition(); + matchedInfo getMatchedInfo(int index); + int matchedCount(); + void insertMatchedTextPositions(const int &pos, const int &matchedLen); bool isSearched(const unsigned long long int &searchCodeNow); bool hasMatched(); diff --git a/src/app/kctexteditor.cpp b/src/app/kctexteditor.cpp index 1c6f875..5ecce3d 100755 --- a/src/app/kctexteditor.cpp +++ b/src/app/kctexteditor.cpp @@ -124,7 +124,7 @@ bool KCTextEditor::showPreviousSearchResult() bool KCTextEditor::showNextSearchResult() { - return findString(false); + return findBackward(); } void KCTextEditor::setTabWidth(int width) @@ -134,18 +134,21 @@ void KCTextEditor::setTabWidth(int width) bool KCTextEditor::findString(bool forward) { - QTextCursor _textCursor; + QTextCursor searchCursor; //Simbol to match a string - bool hasMatch=false; + bool hasMatch=false, + isCursorLine; //Backup current cursor - _textCursor=textCursor(); + searchCursor=textCursor(); //Check search position - int currentCursorPostion=forward?_textCursor.selectionStart(): - _textCursor.selectionEnd(); - _textCursor.setPosition(currentCursorPostion); + int currentCursorPostion=forward?searchCursor.selectionStart(): + searchCursor.selectionEnd(), + matchedCount; + searchCursor.setPosition(currentCursorPostion); + KCTextBlockData::matchedInfo currentMatch; //Search from current place to next place - for(QTextBlock i=_textCursor.block(); //From current block + for(QTextBlock i=searchCursor.block(); //From current block i.isValid() && !hasMatch; //to the destination block i=(forward)?i.previous():i.next()) //If search forward, to previous { //otherwise to the next. @@ -156,48 +159,39 @@ bool KCTextEditor::findString(bool forward) blockData->beginUsingSearchDatas(); if(blockData->hasMatched()) //If current have search result { + isCursorLine=i.blockNumber() == searchCursor.blockNumber(); //If position is forward if(forward) { - auto begin=blockData->getEndMatchedTextPosition(); - auto end=blockData->getFirstMatchedTextPosition(); - for(auto j=begin; - j>=end; - j--) + matchedCount=blockData->matchedCount(); + for(int j=matchedCount-1; j>=0; j--) { - /* - * If it is before the cursor in the current line. - * Or it is before the current block, then we find it. - */ - if((i.blockNumber() == _textCursor.blockNumber() && - j->pos < currentCursorPostion) || - i.blockNumber() != _textCursor.blockNumber()) + currentMatch=blockData->getMatchedInfo(j); + if((isCursorLine && currentMatch.pospos); - _textCursor.movePosition(QTextCursor::NextCharacter, + searchCursor.setPosition(i.position()+currentMatch.pos); + searchCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, - j->matchedLength); + currentMatch.matchedLength); break; } } } else { - auto begin=blockData->getFirstMatchedTextPosition(); - auto end=blockData->getEndMatchedTextPosition(); - for(auto j=begin; - jmatchedCount(); + for(int j=0; jpos >= ((i.blockNumber()==_textCursor.blockNumber())? - _textCursor.positionInBlock():0)) + currentMatch=blockData->getMatchedInfo(j); + if(currentMatch.pos>=(isCursorLine?searchCursor.positionInBlock():0)) { hasMatch=true; - _textCursor.setPosition(i.position()+j->pos); - _textCursor.movePosition(QTextCursor::NextCharacter, + searchCursor.setPosition(i.position()+currentMatch.pos); + searchCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, - j->matchedLength); + currentMatch.matchedLength); break; } } @@ -209,7 +203,7 @@ bool KCTextEditor::findString(bool forward) if(!hasMatch) { //Set the end block number, it will be the current block - int endBlockNumber=_textCursor.blockNumber(); + int endBlockNumber=searchCursor.blockNumber(); //If search forward, to the last block, else to the first for(QTextBlock i=(forward)? document()->lastBlock(): @@ -230,44 +224,40 @@ bool KCTextEditor::findString(bool forward) blockData->beginUsingSearchDatas(); if(blockData->hasMatched()) { + isCursorLine=i.blockNumber() == searchCursor.blockNumber(); //If we search to the forward, do the same things. if(forward) { - auto end=blockData->getFirstMatchedTextPosition(); - for(auto j=blockData->getEndMatchedTextPosition()-1; - j>=end; - j--) + matchedCount=blockData->matchedCount(); + for(int j=matchedCount-1; j>=0; j--) { - if((i.blockNumber() == _textCursor.blockNumber() && - j->pos > _textCursor.positionInBlock()) || - i.blockNumber() != _textCursor.blockNumber()) + currentMatch=blockData->getMatchedInfo(j); + if((isCursorLine && currentMatch.pospos); - _textCursor.movePosition(QTextCursor::NextCharacter, + searchCursor.setPosition(i.position()+currentMatch.pos); + searchCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, - j->matchedLength); + currentMatch.matchedLength); break; } } } else { - //search from end to the first - auto end=blockData->getEndMatchedTextPosition(); - for(auto j=blockData->getFirstMatchedTextPosition(); - jmatchedCount(); + for(int j=0; jpos < _textCursor.positionInBlock()) || - i.blockNumber() != _textCursor.blockNumber()) + currentMatch=blockData->getMatchedInfo(j); + if(currentMatch.pos>=(isCursorLine?searchCursor.positionInBlock():0)) { hasMatch=true; - _textCursor.setPosition(i.position()+j->pos); - _textCursor.movePosition(QTextCursor::NextCharacter, + searchCursor.setPosition(i.position()+currentMatch.pos); + searchCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, - j->matchedLength); + currentMatch.matchedLength); break; } } @@ -279,27 +269,104 @@ bool KCTextEditor::findString(bool forward) if(hasMatch) { - setTextCursor(_textCursor); + setTextCursor(searchCursor); return true; } return false; } -bool KCTextEditor::findPreviousString(KCTextBlockData *blockData, - QTextCursor currentCursor, - bool forward) +bool KCTextEditor::findForward() { - + ; } -bool KCTextEditor::findNextString(KCTextBlockData *blockData, - QTextCursor currentCursor, - bool forward) +bool KCTextEditor::findBackward() { + QTextCursor searchCursor=textCursor(); + //Simbol to match a string + bool hasMatch=false, + isCursorLine; + //Backup current cursor + //Check search position + int currentCursorPostion=searchCursor.position(), + matchedCount, comparePosition; + searchCursor.setPosition(currentCursorPostion); + KCTextBlockData::matchedInfo currentMatch; + //Search from current place to next place + for(QTextBlock i=searchCursor.block(); + i.isValid() && !hasMatch; + i=i.next()) + { + KCTextBlockData *blockData=(KCTextBlockData *) i.userData(); + checkWhetherBlockSearchedAndDealWith(i); + blockData->beginUsingSearchDatas(); + if(blockData->hasMatched()) //If current have search result + { + isCursorLine=i.blockNumber() == searchCursor.blockNumber(); + matchedCount=blockData->matchedCount(); + comparePosition=isCursorLine?searchCursor.position()-i.position():0; + for(int j=0; jgetMatchedInfo(j); + if(currentMatch.pos>=comparePosition) + { + hasMatch=true; + searchCursor.setPosition(i.position()+currentMatch.pos); + searchCursor.movePosition(QTextCursor::NextCharacter, + QTextCursor::KeepAnchor, + currentMatch.matchedLength); + break; + } + } + } + blockData->endUsingSearchDatas(); + } + if(hasMatch) + { + setTextCursor(searchCursor); + return true; + } + return findFirstSeachResult(); } +bool KCTextEditor::findFirstSeachResult() +{ + //Backup current cursor + QTextCursor searchCursor=textCursor(); + //Simbol to match a string + bool hasMatch=false; + KCTextBlockData::matchedInfo currentMatch; + //Search from current place to next place + for(QTextBlock i=document()->begin(); + i.isValid() && !hasMatch; + i=i.next()) + { + KCTextBlockData *blockData=(KCTextBlockData *) i.userData(); + checkWhetherBlockSearchedAndDealWith(i); + blockData->beginUsingSearchDatas(); + if(blockData->hasMatched()) //If current have search result + { + hasMatch=true; + currentMatch=blockData->getMatchedInfo(0); + searchCursor.setPosition(i.position()+currentMatch.pos); + searchCursor.movePosition(QTextCursor::NextCharacter, + QTextCursor::KeepAnchor, + currentMatch.matchedLength); + } + blockData->endUsingSearchDatas(); + } + if(hasMatch) + { + setTextCursor(searchCursor); + } + return hasMatch; +} +bool KCTextEditor::findLastSearchResult() +{ + ; +} void KCTextEditor::searchString(QString searchTextSets, bool regularExpressionSets, @@ -333,7 +400,7 @@ void KCTextEditor::searchString(QString searchTextSets, updateSearchResults(); searchOnOtherThread(searcherForNext,threadNext,firstVisibleBlock(),true); searchOnOtherThread(searcherForPrev,threadPrev,firstVisibleBlock(),false); - findString(false); + findBackward(); } } @@ -419,12 +486,23 @@ bool KCTextEditor::replaceAndFind(const QString &oldText, bool KCTextEditor::replaceAll(const QString &oldText, const QString &newText) { - bool ret=replaceAndFind(oldText,newText); - while(replaceAndFind(oldText,newText)) + int matchedCount=0; + //Search from the very beginning to the last + for(QTextBlock i=document()->begin(); + i.isValid(); + i=i.next()) + { + KCTextBlockData *blockData=(KCTextBlockData *) i.userData(); + checkWhetherBlockSearchedAndDealWith(i); + blockData->beginUsingSearchDatas(); + matchedCount+=blockData->matchedCount(); + blockData->endUsingSearchDatas(); + } + while(replaceAndFind(oldText,newText) && --matchedCount) { ; } - return ret; + return true; } void KCTextEditor::autoIndent() @@ -817,18 +895,18 @@ void KCTextEditor::highlightSearchResult(QList &selec currBlockData->beginUsingSearchDatas(); if(currBlockData->hasMatched()) { - for(auto i=currBlockData->getFirstMatchedTextPosition(), - end=currBlockData->getEndMatchedTextPosition(); - imatchedCount(); i++) { + currentMatched=currBlockData->getMatchedInfo(i); QTextEdit::ExtraSelection selection; _cursor.clearSelection(); - _cursor.setPosition(block.position()+i->pos); + _cursor.setPosition(block.position()+currentMatched.pos); _cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, - i->matchedLength); + currentMatched.matchedLength); selection.cursor=_cursor; selection.format.setBackground(searchResultColor); diff --git a/src/app/kctexteditor.h b/src/app/kctexteditor.h index d441d2e..7538e19 100755 --- a/src/app/kctexteditor.h +++ b/src/app/kctexteditor.h @@ -91,12 +91,10 @@ private slots: QTextCursor cursor); QString parenthesesPair(const QString &parenthesesChar); bool findString(bool forward); - bool findPreviousString(KCTextBlockData *blockData, - QTextCursor currentCursor, - bool forward); - bool findNextString(KCTextBlockData *blockData, - QTextCursor currentCursor, - bool forward); + bool findForward(); + bool findBackward(); + bool findFirstSeachResult(); + bool findLastSearchResult(); void generalSearch(const QTextBlock &block, const int &lines, const bool forward); diff --git a/src/app/main.cpp b/src/app/main.cpp index 2be3c6c..ac9a42b 100755 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -44,7 +44,7 @@ static inline void setApplicationInfo() { QApplication::setApplicationName(QString("Cuties")); - QApplication::setApplicationVersion(QString("0.2.5.17")); + QApplication::setApplicationVersion(QString("0.2.5.18")); QApplication::setOrganizationName("Kreogist Dev Team"); QApplication::setOrganizationDomain("https://kreogist.github.io/Cuties");