1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Merge pull request #5793

TriKriSta (5):
      fix: data validation during the search (fix: #5791, #5723)
      feat: check chat status before start a search
      feat: save selected search text after scrolling up
      refactor: optimize load messages during the search
      fix: update workerStb
This commit is contained in:
sudden6 2019-08-28 21:13:38 +02:00
commit 834baff556
No known key found for this signature in database
GPG Key ID: 279509B499E032B9
5 changed files with 105 additions and 36 deletions

View File

@ -683,7 +683,7 @@ void ChatLog::scrollToLine(ChatLine::Ptr line)
workerStb = false; workerStb = false;
} else { } else {
updateSceneRect(); updateSceneRect();
verticalScrollBar()->setValue(line->sceneBoundingRect().top()); // NOTE: start here verticalScrollBar()->setValue(line->sceneBoundingRect().top());
} }
} }
@ -936,10 +936,12 @@ void ChatLog::onWorkerTimeout()
updateMultiSelectionRect(); updateMultiSelectionRect();
// scroll // scroll
if (workerStb) if (workerStb) {
scrollToBottom(); scrollToBottom();
else workerStb = false;
} else {
scrollToLine(workerAnchorLine); scrollToLine(workerAnchorLine);
}
// don't keep a Ptr to the anchor line // don't keep a Ptr to the anchor line
workerAnchorLine = ChatLine::Ptr(); workerAnchorLine = ChatLine::Ptr();

View File

@ -174,6 +174,7 @@ SearchResult ChatHistory::searchBackward(SearchPos startIdx, const QString& phra
history->getDateWhereFindPhrase(f.getPublicKey().toString(), earliestMessageDate, phrase, history->getDateWhereFindPhrase(f.getPublicKey().toString(), earliestMessageDate, phrase,
parameter); parameter);
if (dateWherePhraseFound.isValid()) {
auto loadIdx = history->getNumMessagesForFriendBeforeDate(f.getPublicKey(), dateWherePhraseFound); auto loadIdx = history->getNumMessagesForFriendBeforeDate(f.getPublicKey(), dateWherePhraseFound);
loadHistoryIntoSessionChatLog(ChatLogIdx(loadIdx)); loadHistoryIntoSessionChatLog(ChatLogIdx(loadIdx));
@ -181,6 +182,11 @@ SearchResult ChatHistory::searchBackward(SearchPos startIdx, const QString& phra
startIdx.logIdx = ChatLogIdx(loadIdx); startIdx.logIdx = ChatLogIdx(loadIdx);
startIdx.numMatches = 0; startIdx.numMatches = 0;
return sessionChatLog.searchBackward(startIdx, phrase, parameter); return sessionChatLog.searchBackward(startIdx, phrase, parameter);
}
SearchResult ret;
ret.found = false;
return ret;
} }
ChatLogIdx ChatHistory::getFirstIdx() const ChatLogIdx ChatHistory::getFirstIdx() const

View File

@ -70,7 +70,7 @@ struct SearchPos
struct SearchResult struct SearchResult
{ {
bool found; bool found{false};
SearchPos pos; SearchPos pos;
size_t start; size_t start;
size_t len; size_t len;

View File

@ -685,7 +685,11 @@ void GenericChatForm::loadHistoryTo(const QDateTime &time)
} }
if (begin != end) { if (begin != end) {
if (searchResult.found == true && searchResult.pos.logIdx == end) {
renderMessages(begin, end, [this]{enableSearchText();});
} else {
renderMessages(begin, end); renderMessages(begin, end);
}
} else { } else {
chatWidget->setScroll(true); chatWidget->setScroll(true);
} }
@ -730,13 +734,23 @@ void GenericChatForm::removeLastsMessages(const int num)
void GenericChatForm::disableSearchText() void GenericChatForm::disableSearchText()
{ {
auto msgIt = messages.find(searchPos.logIdx); auto msgIt = messages.find(searchResult.pos.logIdx);
if (msgIt != messages.end()) { if (msgIt != messages.end()) {
auto text = qobject_cast<Text*>(msgIt->second->getContent(1)); auto text = qobject_cast<Text*>(msgIt->second->getContent(1));
text->deselectText(); text->deselectText();
} }
} }
void GenericChatForm::enableSearchText()
{
auto msg = messages.at(searchResult.pos.logIdx);
chatWidget->scrollToLine(msg);
auto text = qobject_cast<Text*>(msg->getContent(1));
text->visibilityChanged(true);
text->selectText(searchResult.exp, std::make_pair(searchResult.start, searchResult.len));
}
void GenericChatForm::clearChatArea() void GenericChatForm::clearChatArea()
{ {
clearChatArea(/* confirm = */ true, /* inform = */ true); clearChatArea(/* confirm = */ true, /* inform = */ true);
@ -933,6 +947,7 @@ void GenericChatForm::onExportChat()
void GenericChatForm::onSearchTriggered() void GenericChatForm::onSearchTriggered()
{ {
if (searchForm->isHidden()) { if (searchForm->isHidden()) {
searchResult.found = false;
searchForm->removeSearchPhrase(); searchForm->removeSearchPhrase();
} }
disableSearchText(); disableSearchText();
@ -940,39 +955,43 @@ void GenericChatForm::onSearchTriggered()
void GenericChatForm::searchInBegin(const QString& phrase, const ParameterSearch& parameter) void GenericChatForm::searchInBegin(const QString& phrase, const ParameterSearch& parameter)
{ {
if (phrase.isEmpty()) {
disableSearchText(); disableSearchText();
if (!parameter.time.isNull()) { return;
LoadHistoryDialog::LoadType type = (parameter.period == PeriodSearch::BeforeDate) }
? LoadHistoryDialog::to : LoadHistoryDialog::from;
loadHistory(parameter.time, type); if (chatLog.getNextIdx().get() == messages.rbegin()->first.get() + 1) {
disableSearchText();
} else {
goToCurrentDate();
} }
bool bForwardSearch = false; bool bForwardSearch = false;
switch (parameter.period) { switch (parameter.period) {
case PeriodSearch::WithTheFirst: { case PeriodSearch::WithTheFirst: {
bForwardSearch = true; bForwardSearch = true;
searchPos.logIdx = chatLog.getFirstIdx(); searchResult.pos.logIdx = chatLog.getFirstIdx();
searchPos.numMatches = 0; searchResult.pos.numMatches = 0;
break; break;
} }
case PeriodSearch::WithTheEnd: case PeriodSearch::WithTheEnd:
case PeriodSearch::None: { case PeriodSearch::None: {
bForwardSearch = false; bForwardSearch = false;
searchPos.logIdx = chatLog.getNextIdx(); searchResult.pos.logIdx = chatLog.getNextIdx();
searchPos.numMatches = 0; searchResult.pos.numMatches = 0;
break; break;
} }
case PeriodSearch::AfterDate: { case PeriodSearch::AfterDate: {
bForwardSearch = true; bForwardSearch = true;
searchPos.logIdx = firstItemAfterDate(parameter.time.date(), chatLog); searchResult.pos.logIdx = firstItemAfterDate(parameter.time.date(), chatLog);
searchPos.numMatches = 0; searchResult.pos.numMatches = 0;
break; break;
} }
case PeriodSearch::BeforeDate: { case PeriodSearch::BeforeDate: {
bForwardSearch = false; bForwardSearch = false;
searchPos.logIdx = firstItemAfterDate(parameter.time.date(), chatLog); searchResult.pos.logIdx = firstItemAfterDate(parameter.time.date(), chatLog);
searchPos.numMatches = 0; searchResult.pos.numMatches = 0;
break; break;
} }
} }
@ -986,13 +1005,13 @@ void GenericChatForm::searchInBegin(const QString& phrase, const ParameterSearch
void GenericChatForm::onSearchUp(const QString& phrase, const ParameterSearch& parameter) void GenericChatForm::onSearchUp(const QString& phrase, const ParameterSearch& parameter)
{ {
auto result = chatLog.searchBackward(searchPos, phrase, parameter); auto result = chatLog.searchBackward(searchResult.pos, phrase, parameter);
handleSearchResult(result, SearchDirection::Up); handleSearchResult(result, SearchDirection::Up);
} }
void GenericChatForm::onSearchDown(const QString& phrase, const ParameterSearch& parameter) void GenericChatForm::onSearchDown(const QString& phrase, const ParameterSearch& parameter)
{ {
auto result = chatLog.searchForward(searchPos, phrase, parameter); auto result = chatLog.searchForward(searchResult.pos, phrase, parameter);
handleSearchResult(result, SearchDirection::Down); handleSearchResult(result, SearchDirection::Down);
} }
@ -1005,17 +1024,58 @@ void GenericChatForm::handleSearchResult(SearchResult result, SearchDirection di
disableSearchText(); disableSearchText();
searchPos = result.pos; searchResult = result;
auto const firstRenderedIdx = (messages.empty()) ? chatLog.getNextIdx() : messages.begin()->first; auto searchIdx = result.pos.logIdx;
renderMessages(searchPos.logIdx, firstRenderedIdx, [this, result] { auto firstRenderedIdx = messages.begin()->first;
auto msg = messages.at(searchPos.logIdx); auto endRenderedIdx = messages.rbegin()->first;
chatWidget->scrollToLine(msg);
auto text = qobject_cast<Text*>(msg->getContent(1)); if (direction == SearchDirection::Up) {
text->selectText(result.exp, std::make_pair(result.start, result.len)); if (searchIdx.get() < firstRenderedIdx.get()) {
}); if (searchIdx.get() > DEF_NUM_MSG_TO_LOAD / 2) {
firstRenderedIdx = ChatLogIdx(searchIdx.get() - DEF_NUM_MSG_TO_LOAD / 2);
} else {
firstRenderedIdx = ChatLogIdx(0);
}
}
if (endRenderedIdx.get() - firstRenderedIdx.get() > DEF_NUM_MSG_TO_LOAD) {
endRenderedIdx = ChatLogIdx(firstRenderedIdx.get() + DEF_NUM_MSG_TO_LOAD);
}
} else {
if (searchIdx.get() < firstRenderedIdx.get()) {
firstRenderedIdx = searchIdx;
}
if (firstRenderedIdx == searchIdx || searchIdx.get() > endRenderedIdx.get()) {
if (searchIdx.get() + DEF_NUM_MSG_TO_LOAD > chatLog.getNextIdx().get()) {
endRenderedIdx = chatLog.getNextIdx();
} else {
endRenderedIdx = ChatLogIdx(searchIdx.get() + DEF_NUM_MSG_TO_LOAD);
}
}
if (endRenderedIdx.get() - firstRenderedIdx.get() > DEF_NUM_MSG_TO_LOAD) {
if (endRenderedIdx.get() > DEF_NUM_MSG_TO_LOAD) {
firstRenderedIdx = ChatLogIdx(endRenderedIdx.get() - DEF_NUM_MSG_TO_LOAD);
} else {
firstRenderedIdx = ChatLogIdx(0);
}
}
}
if (!messages.empty() && (firstRenderedIdx.get() < messages.begin()->first.get()
|| endRenderedIdx.get() > messages.rbegin()->first.get())) {
chatWidget->clear();
messages.clear();
auto mediator = endRenderedIdx;
endRenderedIdx = firstRenderedIdx;
firstRenderedIdx = mediator;
}
renderMessages(endRenderedIdx, firstRenderedIdx, [this]{enableSearchText();});
} }
void GenericChatForm::renderMessage(ChatLogIdx idx) void GenericChatForm::renderMessage(ChatLogIdx idx)

View File

@ -156,6 +156,7 @@ protected:
virtual void resizeEvent(QResizeEvent* event) final override; virtual void resizeEvent(QResizeEvent* event) final override;
virtual bool eventFilter(QObject* object, QEvent* event) final override; virtual bool eventFilter(QObject* object, QEvent* event) final override;
void disableSearchText(); void disableSearchText();
void enableSearchText();
bool searchInText(const QString& phrase, const ParameterSearch& parameter, SearchDirection direction); bool searchInText(const QString& phrase, const ParameterSearch& parameter, SearchDirection direction);
std::pair<int, int> indexForSearchInLine(const QString& txt, const QString& phrase, const ParameterSearch& parameter, SearchDirection direction); std::pair<int, int> indexForSearchInLine(const QString& txt, const QString& phrase, const ParameterSearch& parameter, SearchDirection direction);
@ -198,7 +199,7 @@ protected:
IChatLog& chatLog; IChatLog& chatLog;
IMessageDispatcher& messageDispatcher; IMessageDispatcher& messageDispatcher;
SearchPos searchPos; SearchResult searchResult;
std::map<ChatLogIdx, ChatMessage::Ptr> messages; std::map<ChatLogIdx, ChatMessage::Ptr> messages;
bool colorizeNames = false; bool colorizeNames = false;
}; };