/***************************************************************************
- * Copyright (C) 2005-09 by the Quassel Project *
+ * Copyright (C) 2005-2020 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "chatviewsearchcontroller.h"
+#include <algorithm>
+
#include <QAbstractItemModel>
#include <QPainter>
#include "chatscene.h"
#include "messagemodel.h"
-ChatViewSearchController::ChatViewSearchController(QObject *parent)
- : QObject(parent),
- _scene(0),
- _currentHighlight(0),
- _caseSensitive(false),
- _searchSenders(false),
- _searchMsgs(true),
- _searchOnlyRegularMsgs(true)
+ChatViewSearchController::ChatViewSearchController(QObject* parent)
+ : QObject(parent)
+{}
+
+void ChatViewSearchController::setSearchString(const QString& searchString)
{
+ QString oldSearchString = _searchString;
+ _searchString = searchString;
+ if (_scene) {
+ if (!searchString.startsWith(oldSearchString) || oldSearchString.isEmpty()) {
+ // we can't reuse our all findings... cler the scene and do it all over
+ updateHighlights();
+ }
+ else {
+ // reuse all findings
+ updateHighlights(true);
+ }
+ }
}
-void ChatViewSearchController::setSearchString(const QString &searchString) {
- QString oldSearchString = _searchString;
- _searchString = searchString;
- if(_scene) {
- if(!searchString.startsWith(oldSearchString) || oldSearchString.isEmpty()) {
- // we can't reuse our all findings... cler the scene and do it all over
- updateHighlights();
- } else {
- // reuse all findings
- updateHighlights(true);
+void ChatViewSearchController::setScene(ChatScene* scene)
+{
+ Q_ASSERT(scene);
+ if (scene == _scene)
+ return;
+
+ if (_scene) {
+ disconnect(_scene, nullptr, this, nullptr);
+ disconnect(Client::messageModel(), nullptr, this, nullptr);
+ qDeleteAll(_highlightItems);
+ _highlightItems.clear();
}
- }
-}
- void ChatViewSearchController::setScene(ChatScene *scene) {
- Q_ASSERT(scene);
- if(scene == _scene)
- return;
+ _scene = scene;
+ if (!scene)
+ return;
- if(_scene) {
- disconnect(_scene, 0, this, 0);
- qDeleteAll(_highlightItems);
- _highlightItems.clear();
- }
-
- _scene = scene;
- if(!scene)
- return;
-
- connect(_scene, SIGNAL(destroyed()), this, SLOT(sceneDestroyed()));
- connect(_scene, SIGNAL(layoutChanged()), this, SLOT(repositionHighlights()));
- updateHighlights();
- }
-
-void ChatViewSearchController::highlightNext() {
- if(_highlightItems.isEmpty())
- return;
-
- if(_currentHighlight < _highlightItems.count()) {
- _highlightItems.at(_currentHighlight)->setHighlighted(false);
- }
-
- _currentHighlight++;
- if(_currentHighlight >= _highlightItems.count())
- _currentHighlight = 0;
- _highlightItems.at(_currentHighlight)->setHighlighted(true);
- emit newCurrentHighlight(_highlightItems.at(_currentHighlight));
+ connect(_scene, &QObject::destroyed, this, &ChatViewSearchController::sceneDestroyed);
+ connect(_scene, &ChatScene::layoutChanged, this, [this]() { repositionHighlights(); });
+ connect(Client::messageModel(), &MessageModel::finishedBacklogFetch, this, [this]() { updateHighlights(); });
+ updateHighlights();
}
-void ChatViewSearchController::highlightPrev() {
- if(_highlightItems.isEmpty())
- return;
+void ChatViewSearchController::highlightNext()
+{
+ if (_highlightItems.isEmpty())
+ return;
- if(_currentHighlight < _highlightItems.count()) {
- _highlightItems.at(_currentHighlight)->setHighlighted(false);
- }
+ if (_currentHighlight < _highlightItems.count()) {
+ _highlightItems.at(_currentHighlight)->setHighlighted(false);
+ }
- _currentHighlight--;
- if(_currentHighlight < 0)
- _currentHighlight = _highlightItems.count() - 1;
- _highlightItems.at(_currentHighlight)->setHighlighted(true);
- emit newCurrentHighlight(_highlightItems.at(_currentHighlight));
+ _currentHighlight++;
+ if (_currentHighlight >= _highlightItems.count())
+ _currentHighlight = 0;
+ _highlightItems.at(_currentHighlight)->setHighlighted(true);
+ emit newCurrentHighlight(_highlightItems.at(_currentHighlight));
}
-void ChatViewSearchController::updateHighlights(bool reuse) {
- if(!_scene)
- return;
+void ChatViewSearchController::highlightPrev()
+{
+ if (_highlightItems.isEmpty())
+ return;
- if(reuse) {
- QSet<ChatLine *> chatLines;
- foreach(SearchHighlightItem *highlightItem, _highlightItems) {
- ChatLine *line = qgraphicsitem_cast<ChatLine *>(highlightItem->parentItem());
- if(line)
- chatLines << line;
+ if (_currentHighlight < _highlightItems.count()) {
+ _highlightItems.at(_currentHighlight)->setHighlighted(false);
}
- foreach(ChatLine *line, QList<ChatLine *>(chatLines.toList())) {
- updateHighlights(line);
- }
- } else {
- QPointF oldHighlightPos;
- if(!_highlightItems.isEmpty() && _currentHighlight < _highlightItems.count()) {
- oldHighlightPos = _highlightItems[_currentHighlight]->scenePos();
+
+ _currentHighlight--;
+ if (_currentHighlight < 0)
+ _currentHighlight = _highlightItems.count() - 1;
+ _highlightItems.at(_currentHighlight)->setHighlighted(true);
+ emit newCurrentHighlight(_highlightItems.at(_currentHighlight));
+}
+
+void ChatViewSearchController::updateHighlights(bool reuse)
+{
+ if (!_scene)
+ return;
+
+ if (reuse) {
+ QSet<ChatLine*> chatLines;
+ foreach (SearchHighlightItem* highlightItem, _highlightItems) {
+ auto* line = qgraphicsitem_cast<ChatLine*>(highlightItem->parentItem());
+ if (line)
+ chatLines << line;
+ }
+ foreach (ChatLine* line, chatLines) {
+ updateHighlights(line);
+ }
}
- qDeleteAll(_highlightItems);
- _highlightItems.clear();
- Q_ASSERT(_highlightItems.isEmpty());
-
- if(searchString().isEmpty() || !(_searchSenders || _searchMsgs))
- return;
-
- checkMessagesForHighlight();
-
- if(!_highlightItems.isEmpty()) {
- if(!oldHighlightPos.isNull()) {
- int start = 0; int end = _highlightItems.count() - 1;
- QPointF startPos;
- QPointF endPos;
- while(1) {
- startPos = _highlightItems[start]->scenePos();
- endPos = _highlightItems[end]->scenePos();
- if(startPos == oldHighlightPos) {
- _currentHighlight = start;
- break;
- }
- if(endPos == oldHighlightPos) {
- _currentHighlight = end;
- break;
- }
- if(end - start == 1) {
- _currentHighlight = start;
- break;
- }
- int pivot = (end + start) / 2;
- QPointF pivotPos = _highlightItems[pivot]->scenePos();
- if(startPos.y() == endPos.y()) {
- if(oldHighlightPos.x() <= pivotPos.x())
- end = pivot;
- else
- start = pivot;
- } else {
- if(oldHighlightPos.y() <= pivotPos.y())
- end = pivot;
- else
- start = pivot;
- }
- }
- } else {
- _currentHighlight = _highlightItems.count() - 1;
- }
- _highlightItems[_currentHighlight]->setHighlighted(true);
- emit newCurrentHighlight(_highlightItems[_currentHighlight]);
+ else {
+ QPointF oldHighlightPos;
+ if (!_highlightItems.isEmpty() && _currentHighlight < _highlightItems.count()) {
+ oldHighlightPos = _highlightItems[_currentHighlight]->scenePos();
+ }
+ qDeleteAll(_highlightItems);
+ _highlightItems.clear();
+ Q_ASSERT(_highlightItems.isEmpty());
+
+ if (searchString().isEmpty() || !(_searchSenders || _searchMsgs))
+ return;
+
+ checkMessagesForHighlight();
+
+ if (!_highlightItems.isEmpty()) {
+ if (!oldHighlightPos.isNull()) {
+ int start = 0;
+ int end = _highlightItems.count() - 1;
+ QPointF startPos;
+ QPointF endPos;
+ while (true) {
+ startPos = _highlightItems[start]->scenePos();
+ endPos = _highlightItems[end]->scenePos();
+ if (startPos == oldHighlightPos) {
+ _currentHighlight = start;
+ break;
+ }
+ if (endPos == oldHighlightPos) {
+ _currentHighlight = end;
+ break;
+ }
+ if (end - start == 1) {
+ _currentHighlight = start;
+ break;
+ }
+ if (end == 0 && start == 0) {
+ // Sometimes we can run into an issue where the start and end are both set
+ // to zero. Rather than endlessly spin this loop, bail out. Search seems
+ // to work fine.
+ // [Test case]
+ // Unfortunately, this seems specific to the contents of a buffer. First,
+ // find a buffer that you've encountered freezing, and keep track of what
+ // was loaded, where it was, and the two most recent search terms.
+ // For example...
+ // 1. Load some backlog to a buffer
+ // 2. Search for term with any number of matches
+ // 3. Making sure to -type over existing words without first backspacing-,
+ // search for another term with only one match
+ // Expected: Search results found, no freezing
+ // Actual: Quassel hangs. startPos and endPos = same place, start = 0,
+ // end = 0, _currentHighlight appears to retain values from the
+ // previous search.
+
+ // Reset _currentHighlight to start, otherwise it'll retain the value from
+ // previous search, resulting in an index-out-of-bounds error.
+ _currentHighlight = start;
+ // Escape from the loop!
+ break;
+ }
+ int pivot = (end + start) / 2;
+ QPointF pivotPos = _highlightItems[pivot]->scenePos();
+ if (startPos.y() == endPos.y()) {
+ if (oldHighlightPos.x() <= pivotPos.x())
+ end = pivot;
+ else
+ start = pivot;
+ }
+ else {
+ if (oldHighlightPos.y() <= pivotPos.y())
+ end = pivot;
+ else
+ start = pivot;
+ }
+ }
+ }
+ else {
+ _currentHighlight = _highlightItems.count() - 1;
+ }
+ _highlightItems[_currentHighlight]->setHighlighted(true);
+ emit newCurrentHighlight(_highlightItems[_currentHighlight]);
+ }
}
- }
}
-void ChatViewSearchController::checkMessagesForHighlight(int start, int end) {
- QAbstractItemModel *model = _scene->model();
- Q_ASSERT(model);
-
- if(end == -1) {
- end = model->rowCount() - 1;
- if(end == -1)
- return;
- }
-
- QModelIndex index;
- for(int row = start; row <= end; row++) {
- if(_searchOnlyRegularMsgs) {
- index = model->index(row, 0);
- if(!checkType((Message::Type)index.data(MessageModel::TypeRole).toInt()))
- continue;
+void ChatViewSearchController::checkMessagesForHighlight(int start, int end)
+{
+ QAbstractItemModel* model = _scene->model();
+ Q_ASSERT(model);
+
+ if (end == -1) {
+ end = model->rowCount() - 1;
+ if (end == -1)
+ return;
}
- highlightLine(_scene->chatLine(row));
- }
-}
-void ChatViewSearchController::updateHighlights(ChatLine *line) {
- QList<ChatItem *> checkItems;
- if(_searchSenders)
- checkItems << &(line->item(MessageModel::SenderColumn));
+ QModelIndex index;
+ for (int row = start; row <= end; row++) {
+ if (_searchOnlyRegularMsgs) {
+ index = model->index(row, 0);
+ if (!checkType((Message::Type)index.data(MessageModel::TypeRole).toInt()))
+ continue;
+ }
+ highlightLine(_scene->chatLine(row));
+ }
+}
- if(_searchMsgs)
- checkItems << &(line->item(MessageModel::ContentsColumn));
+void ChatViewSearchController::updateHighlights(ChatLine* line)
+{
+ QList<ChatItem*> checkItems;
+ if (_searchSenders)
+ checkItems << line->item(MessageModel::SenderColumn);
+
+ if (_searchMsgs)
+ checkItems << line->item(MessageModel::ContentsColumn);
+
+ QHash<quint64, QHash<quint64, QRectF>> wordRects;
+ foreach (ChatItem* item, checkItems) {
+ foreach (QRectF wordRect, item->findWords(searchString(), caseSensitive())) {
+ wordRects[(quint64)(wordRect.x() + item->x())][(quint64)(wordRect.y())] = wordRect;
+ }
+ }
- QHash<quint64, QHash<quint64, QRectF> > wordRects;
- foreach(ChatItem *item, checkItems) {
- foreach(QRectF wordRect, item->findWords(searchString(), caseSensitive())) {
- wordRects[(quint64)(wordRect.x() + item->x())][(quint64)(wordRect.y())] = wordRect;
+ bool deleteAll = false;
+ QAbstractItemModel* model = _scene->model();
+ Q_ASSERT(model);
+ if (_searchOnlyRegularMsgs) {
+ QModelIndex index = model->index(line->row(), 0);
+ if (!checkType((Message::Type)index.data(MessageModel::TypeRole).toInt()))
+ deleteAll = true;
}
- }
-
- bool deleteAll = false;
- QAbstractItemModel *model = _scene->model();
- Q_ASSERT(model);
- if(_searchOnlyRegularMsgs) {
- QModelIndex index = model->index(line->row(), 0);
- if(!checkType((Message::Type)index.data(MessageModel::TypeRole).toInt()))
- deleteAll = true;
- }
-
-
- foreach(QGraphicsItem *child, line->childItems()) {
- SearchHighlightItem *highlightItem = qgraphicsitem_cast<SearchHighlightItem *>(child);
- if(!highlightItem)
- continue;
-
- if(!deleteAll && wordRects.contains((quint64)(highlightItem->pos().x())) && wordRects[(quint64)(highlightItem->pos().x())].contains((quint64)(highlightItem->pos().y()))) {
- QRectF &wordRect = wordRects[(quint64)(highlightItem->pos().x())][(quint64)(highlightItem->pos().y())];
- highlightItem->updateGeometry(wordRect.width(), wordRect.height());
- } else {
- int pos = _highlightItems.indexOf(highlightItem);
- if(pos == _currentHighlight) {
- highlightPrev();
- } else if (pos < _currentHighlight) {
- _currentHighlight--;
- }
-
- _highlightItems.removeAt(pos);
- delete highlightItem;
+
+ foreach (QGraphicsItem* child, line->childItems()) {
+ auto* highlightItem = qgraphicsitem_cast<SearchHighlightItem*>(child);
+ if (!highlightItem)
+ continue;
+
+ if (!deleteAll && wordRects.contains((quint64)(highlightItem->pos().x()))
+ && wordRects[(quint64)(highlightItem->pos().x())].contains((quint64)(highlightItem->pos().y()))) {
+ QRectF& wordRect = wordRects[(quint64)(highlightItem->pos().x())][(quint64)(highlightItem->pos().y())];
+ highlightItem->updateGeometry(wordRect.width(), wordRect.height());
+ }
+ else {
+ int pos = _highlightItems.indexOf(highlightItem);
+ if (pos == _currentHighlight) {
+ highlightPrev();
+ }
+ else if (pos < _currentHighlight) {
+ _currentHighlight--;
+ }
+
+ _highlightItems.removeAt(pos);
+ delete highlightItem;
+ }
}
- }
}
-void ChatViewSearchController::highlightLine(ChatLine *line) {
- QList<ChatItem *> checkItems;
- if(_searchSenders)
- checkItems << &(line->item(MessageModel::SenderColumn));
+void ChatViewSearchController::highlightLine(ChatLine* line)
+{
+ QList<ChatItem*> checkItems;
+ if (_searchSenders)
+ checkItems << line->item(MessageModel::SenderColumn);
- if(_searchMsgs)
- checkItems << &(line->item(MessageModel::ContentsColumn));
+ if (_searchMsgs)
+ checkItems << line->item(MessageModel::ContentsColumn);
- foreach(ChatItem *item, checkItems) {
- foreach(QRectF wordRect, item->findWords(searchString(), caseSensitive())) {
- _highlightItems << new SearchHighlightItem(wordRect.adjusted(item->x(), 0, item->x(), 0), line);
+ foreach (ChatItem* item, checkItems) {
+ foreach (QRectF wordRect, item->findWords(searchString(), caseSensitive())) {
+ _highlightItems << new SearchHighlightItem(wordRect.adjusted(item->x(), 0, item->x(), 0), line);
+ }
}
- }
}
-void ChatViewSearchController::repositionHighlights() {
- QSet<ChatLine *> chatLines;
- foreach(SearchHighlightItem *item, _highlightItems) {
- ChatLine *line = qgraphicsitem_cast<ChatLine *>(item->parentItem());
- if(line)
- chatLines << line;
- }
- QList<ChatLine *> chatLineList(chatLines.toList());
- foreach(ChatLine *line, chatLineList) {
- repositionHighlights(line);
- }
+void ChatViewSearchController::repositionHighlights()
+{
+ QSet<ChatLine*> chatLines;
+ foreach (SearchHighlightItem* item, _highlightItems) {
+ auto* line = qgraphicsitem_cast<ChatLine*>(item->parentItem());
+ if (line)
+ chatLines << line;
+ }
+ foreach (ChatLine* line, chatLines) {
+ repositionHighlights(line);
+ }
}
-void ChatViewSearchController::repositionHighlights(ChatLine *line) {
- QList<SearchHighlightItem *> searchHighlights;
- foreach(QGraphicsItem *child, line->childItems()) {
- SearchHighlightItem *highlightItem = qgraphicsitem_cast<SearchHighlightItem *>(child);
- if(highlightItem)
- searchHighlights << highlightItem;
- }
-
- if(searchHighlights.isEmpty())
- return;
-
- QList<QPointF> wordPos;
- if(_searchSenders) {
- foreach(QRectF wordRect, line->senderItem().findWords(searchString(), caseSensitive())) {
- wordPos << QPointF(wordRect.x() + line->senderItem().x(), wordRect.y());
+void ChatViewSearchController::repositionHighlights(ChatLine* line)
+{
+ QList<SearchHighlightItem*> searchHighlights;
+ foreach (QGraphicsItem* child, line->childItems()) {
+ auto* highlightItem = qgraphicsitem_cast<SearchHighlightItem*>(child);
+ if (highlightItem)
+ searchHighlights << highlightItem;
}
- }
- if(_searchMsgs) {
- foreach(QRectF wordRect, line->contentsItem().findWords(searchString(), caseSensitive())) {
- wordPos << QPointF(wordRect.x() + line->contentsItem().x(), wordRect.y());
+
+ if (searchHighlights.isEmpty())
+ return;
+
+ QList<QPointF> wordPos;
+ if (_searchSenders) {
+ foreach (QRectF wordRect, line->senderItem()->findWords(searchString(), caseSensitive())) {
+ wordPos << QPointF(wordRect.x() + line->senderItem()->x(), wordRect.y());
+ }
+ }
+ if (_searchMsgs) {
+ foreach (QRectF wordRect, line->contentsItem()->findWords(searchString(), caseSensitive())) {
+ wordPos << QPointF(wordRect.x() + line->contentsItem()->x(), wordRect.y());
+ }
}
- }
- qSort(searchHighlights.begin(), searchHighlights.end(), SearchHighlightItem::firstInLine);
+ std::sort(searchHighlights.begin(), searchHighlights.end(), SearchHighlightItem::firstInLine);
- Q_ASSERT(wordPos.count() == searchHighlights.count());
- for(int i = 0; i < searchHighlights.count(); i++) {
- searchHighlights.at(i)->setPos(wordPos.at(i));
- }
+ Q_ASSERT(wordPos.count() == searchHighlights.count());
+ for (int i = 0; i < searchHighlights.count(); i++) {
+ searchHighlights.at(i)->setPos(wordPos.at(i));
+ }
}
-void ChatViewSearchController::sceneDestroyed() {
- // WARNING: don't call any methods on scene!
- _scene = 0;
- // the items will be automatically deleted when the scene is destroyed
- // so we just have to clear the list;
- _highlightItems.clear();
+void ChatViewSearchController::sceneDestroyed()
+{
+ // WARNING: don't call any methods on scene!
+ _scene = nullptr;
+ // the items will be automatically deleted when the scene is destroyed
+ // so we just have to clear the list;
+ _highlightItems.clear();
}
-void ChatViewSearchController::setCaseSensitive(bool caseSensitive) {
- if(_caseSensitive == caseSensitive)
- return;
+void ChatViewSearchController::setCaseSensitive(bool caseSensitive)
+{
+ if (_caseSensitive == caseSensitive)
+ return;
- _caseSensitive = caseSensitive;
+ _caseSensitive = caseSensitive;
- // we can reuse the original search results if the new search
- // parameters are a restriction of the original one
- updateHighlights(caseSensitive);
+ // we can reuse the original search results if the new search
+ // parameters are a restriction of the original one
+ updateHighlights(caseSensitive);
}
-void ChatViewSearchController::setSearchSenders(bool searchSenders) {
- if(_searchSenders == searchSenders)
- return;
+void ChatViewSearchController::setSearchSenders(bool searchSenders)
+{
+ if (_searchSenders == searchSenders)
+ return;
- _searchSenders = searchSenders;
- // we can reuse the original search results if the new search
- // parameters are a restriction of the original one
- updateHighlights(!searchSenders);
+ _searchSenders = searchSenders;
+ // we can reuse the original search results if the new search
+ // parameters are a restriction of the original one
+ updateHighlights(!searchSenders);
}
-void ChatViewSearchController::setSearchMsgs(bool searchMsgs) {
- if(_searchMsgs == searchMsgs)
- return;
+void ChatViewSearchController::setSearchMsgs(bool searchMsgs)
+{
+ if (_searchMsgs == searchMsgs)
+ return;
- _searchMsgs = searchMsgs;
+ _searchMsgs = searchMsgs;
- // we can reuse the original search results if the new search
- // parameters are a restriction of the original one
- updateHighlights(!searchMsgs);
+ // we can reuse the original search results if the new search
+ // parameters are a restriction of the original one
+ updateHighlights(!searchMsgs);
}
-void ChatViewSearchController::setSearchOnlyRegularMsgs(bool searchOnlyRegularMsgs) {
- if(_searchOnlyRegularMsgs == searchOnlyRegularMsgs)
- return;
+void ChatViewSearchController::setSearchOnlyRegularMsgs(bool searchOnlyRegularMsgs)
+{
+ if (_searchOnlyRegularMsgs == searchOnlyRegularMsgs)
+ return;
- _searchOnlyRegularMsgs = searchOnlyRegularMsgs;
+ _searchOnlyRegularMsgs = searchOnlyRegularMsgs;
- // we can reuse the original search results if the new search
- // parameters are a restriction of the original one
- updateHighlights(searchOnlyRegularMsgs);
+ // we can reuse the original search results if the new search
+ // parameters are a restriction of the original one
+ updateHighlights(searchOnlyRegularMsgs);
}
-
// ==================================================
// SearchHighlightItem
// ==================================================
-SearchHighlightItem::SearchHighlightItem(QRectF wordRect, QGraphicsItem *parent)
- : QObject(),
- QGraphicsItem(parent),
- _highlighted(false),
- _alpha(100),
- _timeLine(150)
+SearchHighlightItem::SearchHighlightItem(QRectF wordRect, QGraphicsItem* parent)
+ : QObject()
+ , QGraphicsItem(parent)
+ , _highlighted(false)
+ , _alpha(70)
+ , _timeLine(150)
{
- setPos(wordRect.x(), wordRect.y());
- updateGeometry(wordRect.width(), wordRect.height());
+ setPos(wordRect.x(), wordRect.y());
+ updateGeometry(wordRect.width(), wordRect.height());
- connect(&_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(updateHighlight(qreal)));
+ connect(&_timeLine, &QTimeLine::valueChanged, this, &SearchHighlightItem::updateHighlight);
}
-void SearchHighlightItem::setHighlighted(bool highlighted) {
- _highlighted = highlighted;
+void SearchHighlightItem::setHighlighted(bool highlighted)
+{
+ _highlighted = highlighted;
- if(highlighted)
- _timeLine.setDirection(QTimeLine::Forward);
- else
- _timeLine.setDirection(QTimeLine::Backward);
+ if (highlighted)
+ _timeLine.setDirection(QTimeLine::Forward);
+ else
+ _timeLine.setDirection(QTimeLine::Backward);
- if(_timeLine.state() != QTimeLine::Running)
- _timeLine.start();
+ if (_timeLine.state() != QTimeLine::Running)
+ _timeLine.start();
- update();
+ update();
}
-void SearchHighlightItem::updateHighlight(qreal value) {
- _alpha = 100 + (int)(155 * value);
- update();
+void SearchHighlightItem::updateHighlight(qreal value)
+{
+ _alpha = 70 + (int)(80 * value);
+ update();
}
-void SearchHighlightItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
- Q_UNUSED(option);
- Q_UNUSED(widget);
-
- painter->setPen(QPen(QColor(0, 0, 0, _alpha), 1.5));
- painter->setBrush(QColor(254, 237, 45, _alpha));
- painter->setRenderHints(QPainter::Antialiasing);
- qreal radius = boundingRect().height() * 0.30;
- painter->drawRoundedRect(boundingRect(), radius, radius);
+void SearchHighlightItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ painter->setPen(QPen(QColor(0, 0, 0), 1.5));
+ painter->setBrush(QColor(254, 237, 45, _alpha));
+ painter->setRenderHints(QPainter::Antialiasing);
+ qreal radius = boundingRect().height() * 0.30;
+ painter->drawRoundedRect(boundingRect(), radius, radius);
}
-void SearchHighlightItem::updateGeometry(qreal width, qreal height) {
- prepareGeometryChange();
- qreal sizedelta = height * 0.1;
- _boundingRect = QRectF(-sizedelta, -sizedelta, width + 2 * sizedelta, height + 2 * sizedelta);
- update();
+void SearchHighlightItem::updateGeometry(qreal width, qreal height)
+{
+ prepareGeometryChange();
+ qreal sizedelta = height * 0.1;
+ _boundingRect = QRectF(-sizedelta, -sizedelta, width + 2 * sizedelta, height + 2 * sizedelta);
+ update();
}
-bool SearchHighlightItem::firstInLine(QGraphicsItem *item1, QGraphicsItem *item2) {
- if(item1->pos().y() != item2->pos().y())
- return item1->pos().y() < item2->pos().y();
- else
- return item1->pos().x() < item2->pos().x();
+bool SearchHighlightItem::firstInLine(QGraphicsItem* item1, QGraphicsItem* item2)
+{
+ if (item1->pos().y() != item2->pos().y())
+ return item1->pos().y() < item2->pos().y();
+ else
+ return item1->pos().x() < item2->pos().x();
}