mirror of https://github.com/procxx/kepka.git
ctrl+pageup/pagedown/tab/shift+tab now work in search results
This commit is contained in:
parent
7bff0bcdb2
commit
ceb899b69b
|
@ -26,7 +26,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
|
|||
#include "boxes/newgroupbox.h"
|
||||
|
||||
DialogsListWidget::DialogsListWidget(QWidget *parent, MainWidget *main) : QWidget(parent),
|
||||
dialogs(false), contactsNoDialogs(true), contacts(true), sel(0), contactSel(false), selByMouse(false), filteredSel(-1), searchedCount(0), searchedSel(-1), _state(DefaultState) {
|
||||
dialogs(false), contactsNoDialogs(true), contacts(true), sel(0), contactSel(false), selByMouse(false), filteredSel(-1), searchedCount(0), searchedSel(-1), _lastSearchId(0), _state(DefaultState) {
|
||||
connect(main, SIGNAL(dialogToTop(const History::DialogLinks &)), this, SLOT(onDialogToTop(const History::DialogLinks &)));
|
||||
connect(main, SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(onPeerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)));
|
||||
connect(main, SIGNAL(peerPhotoChanged(PeerData *)), this, SLOT(onPeerPhotoChanged(PeerData *)));
|
||||
|
@ -355,6 +355,7 @@ void DialogsListWidget::onFilterUpdate(QString newFilter, bool force) {
|
|||
_state = DefaultState;
|
||||
filterResults.clear();
|
||||
searchResults.clear();
|
||||
_lastSearchId = 0;
|
||||
} else {
|
||||
QStringList::const_iterator fb = f.cbegin(), fe = f.cend(), fi;
|
||||
|
||||
|
@ -449,6 +450,7 @@ void DialogsListWidget::clearSearchResults() {
|
|||
}
|
||||
searchResults.clear();
|
||||
}
|
||||
_lastSearchId = 0;
|
||||
}
|
||||
|
||||
void DialogsListWidget::onItemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||
|
@ -494,6 +496,7 @@ void DialogsListWidget::searchReceived(const QVector<MTPMessage> &messages, bool
|
|||
for (QVector<MTPMessage>::const_iterator i = messages.cbegin(), e = messages.cend(); i != e; ++i) {
|
||||
HistoryItem *item = App::histories().addToBack(*i, -1);
|
||||
searchResults.push_back(new FakeDialogRow(item));
|
||||
_lastSearchId = item->id;
|
||||
}
|
||||
searchedCount = fullCount;
|
||||
if (_state == FilteredState) {
|
||||
|
@ -588,6 +591,7 @@ void DialogsListWidget::clearFilter() {
|
|||
_state = DefaultState;
|
||||
filterResults.clear();
|
||||
searchResults.clear();
|
||||
_lastSearchId = 0;
|
||||
filter = QString();
|
||||
refresh(true);
|
||||
}
|
||||
|
@ -682,7 +686,7 @@ void DialogsListWidget::selectSkip(int32 direction) {
|
|||
}
|
||||
}
|
||||
|
||||
void DialogsListWidget::scrollToPeer(const PeerId &peer) {
|
||||
void DialogsListWidget::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
||||
int32 fromY = -1;
|
||||
if (_state == DefaultState) {
|
||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(peer);
|
||||
|
@ -694,11 +698,21 @@ void DialogsListWidget::scrollToPeer(const PeerId &peer) {
|
|||
fromY = (i.value()->pos + dialogs.list.count) * st::dlgHeight;
|
||||
}
|
||||
}
|
||||
} else if (_state == FilteredState) {
|
||||
for (int32 i = 0, c = filterResults.size(); i < c; ++i) {
|
||||
if (filterResults[i]->history->peer->id == peer) {
|
||||
fromY = i * st::dlgHeight;
|
||||
break;
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (msgId) {
|
||||
for (int32 i = 0, c = searchResults.size(); i < c; ++i) {
|
||||
if (searchResults[i]->_item->history()->peer->id == peer && searchResults[i]->_item->id == msgId) {
|
||||
fromY = filterResults.size() * st::dlgHeight + st::searchedBarHeight + i * st::dlgHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fromY < 0) {
|
||||
for (int32 i = 0, c = filterResults.size(); i < c; ++i) {
|
||||
if (filterResults[i]->history->peer->id == peer) {
|
||||
fromY = i * st::dlgHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -832,65 +846,115 @@ void DialogsListWidget::destroyData() {
|
|||
dialogs.clear();
|
||||
}
|
||||
|
||||
PeerData *DialogsListWidget::peerBefore(const PeerData *peer) const {
|
||||
void DialogsListWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
if (_state == DefaultState) {
|
||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(peer->id);
|
||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id);
|
||||
if (i == dialogs.list.rowByPeer.constEnd()) {
|
||||
i = contactsNoDialogs.list.rowByPeer.constFind(peer->id);
|
||||
i = contactsNoDialogs.list.rowByPeer.constFind(inPeer->id);
|
||||
if (i == contactsNoDialogs.list.rowByPeer.cend()) {
|
||||
return 0;
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
if (i.value()->prev) {
|
||||
return i.value()->prev->history->peer;
|
||||
outPeer = i.value()->prev->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
} else if (dialogs.list.count) {
|
||||
return dialogs.list.end->prev->history->peer;
|
||||
outPeer = dialogs.list.end->prev->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
return 0;
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
if (i.value()->prev) {
|
||||
return i.value()->prev->history->peer;
|
||||
outPeer = i.value()->prev->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (filterResults.isEmpty() || filterResults.at(0)->history->peer == peer) return 0;
|
||||
if (inMsg && !searchResults.isEmpty()) {
|
||||
for (SearchResults::const_iterator b = searchResults.cbegin(), i = b + 1, e = searchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->_item->history()->peer == inPeer && (*i)->_item->id == inMsg) {
|
||||
SearchResults::const_iterator j = i - 1;
|
||||
outPeer = (*j)->_item->history()->peer;
|
||||
outMsg = (*j)->_item->id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filterResults.isEmpty() || filterResults.at(0)->history->peer == inPeer) {
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (FilteredDialogs::const_iterator b = filterResults.cbegin(), i = b + 1, e = filterResults.cend(); i != e; ++i) {
|
||||
if ((*i)->history->peer == peer) {
|
||||
if ((*i)->history->peer == inPeer) {
|
||||
FilteredDialogs::const_iterator j = i - 1;
|
||||
return (*j)->history->peer;
|
||||
outPeer = (*j)->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
}
|
||||
|
||||
PeerData *DialogsListWidget::peerAfter(const PeerData *peer) const {
|
||||
void DialogsListWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
if (_state == DefaultState) {
|
||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(peer->id);
|
||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(inPeer->id);
|
||||
if (i == dialogs.list.rowByPeer.constEnd()) {
|
||||
i = contactsNoDialogs.list.rowByPeer.constFind(peer->id);
|
||||
i = contactsNoDialogs.list.rowByPeer.constFind(inPeer->id);
|
||||
if (i == contactsNoDialogs.list.rowByPeer.cend()) {
|
||||
return 0;
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
if (i.value()->next != contactsNoDialogs.list.end) {
|
||||
return i.value()->next->history->peer;
|
||||
outPeer = i.value()->next->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
return 0;
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (i.value()->next != dialogs.list.end) {
|
||||
return i.value()->next->history->peer;
|
||||
outPeer = i.value()->next->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
} else if (contactsNoDialogs.list.count) {
|
||||
return contactsNoDialogs.list.begin->history->peer;
|
||||
outPeer = contactsNoDialogs.list.begin->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
} else if (_state == FilteredState || _state == SearchedState) {
|
||||
if (inMsg) {
|
||||
for (SearchResults::const_iterator i = searchResults.cbegin(), e = searchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->_item->history()->peer == inPeer && (*i)->_item->id == inMsg) {
|
||||
++i;
|
||||
outPeer = (i == e) ? 0 : (*i)->_item->history()->peer;
|
||||
outMsg = (i == e) ? 0 : (*i)->_item->id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (FilteredDialogs::const_iterator i = filterResults.cbegin(), e = filterResults.cend(); i != e; ++i) {
|
||||
if ((*i)->history->peer == peer) {
|
||||
if ((*i)->history->peer == inPeer) {
|
||||
++i;
|
||||
return (i == e) ? 0 : (*i)->history->peer;
|
||||
outPeer = (i == e) ? 0 : (*i)->history->peer;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
}
|
||||
|
||||
DialogsIndexed &DialogsListWidget::contactsList() {
|
||||
|
@ -905,6 +969,10 @@ DialogsListWidget::SearchResults &DialogsListWidget::searchList() {
|
|||
return searchResults;
|
||||
}
|
||||
|
||||
MsgId DialogsListWidget::lastSearchId() const {
|
||||
return _lastSearchId;
|
||||
}
|
||||
|
||||
DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
|
||||
, _drawShadow(true)
|
||||
, dlgOffset(0)
|
||||
|
@ -1188,6 +1256,7 @@ void DialogsWidget::searchReceived(bool fromStart, const MTPmessages_Messages &r
|
|||
}
|
||||
|
||||
_searchRequest = 0;
|
||||
onListScroll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1214,7 +1283,7 @@ void DialogsWidget::onListScroll() {
|
|||
if (list.state() == DialogsListWidget::SearchedState) {
|
||||
DialogsListWidget::SearchResults &res(list.searchList());
|
||||
if (scroll.scrollTop() > res.size() * st::dlgHeight - 2 * scroll.height()) {
|
||||
onSearchMore(res.isEmpty() ? 0 : res.back()->_item->id);
|
||||
onSearchMore(list.lastSearchId());
|
||||
}
|
||||
} else if (scroll.scrollTop() > list.dialogsList().list.count * st::dlgHeight - scroll.height()) {
|
||||
loadDialogs();
|
||||
|
@ -1285,18 +1354,16 @@ void DialogsWidget::destroyData() {
|
|||
list.destroyData();
|
||||
}
|
||||
|
||||
PeerData *DialogsWidget::peerBefore(const PeerData *peer) const {
|
||||
return list.peerBefore(peer);
|
||||
void DialogsWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
return list.peerBefore(inPeer, inMsg, outPeer, outMsg);
|
||||
}
|
||||
|
||||
PeerData *DialogsWidget::peerAfter(const PeerData *peer) const {
|
||||
return list.peerAfter(peer);
|
||||
void DialogsWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const {
|
||||
return list.peerAfter(inPeer, inMsg, outPeer, outMsg);
|
||||
}
|
||||
|
||||
void DialogsWidget::scrollToPeer(const PeerId &peer) {
|
||||
if (list.state() != DialogsListWidget::SearchedState) {
|
||||
list.scrollToPeer(peer);
|
||||
}
|
||||
void DialogsWidget::scrollToPeer(const PeerId &peer, MsgId msgId) {
|
||||
list.scrollToPeer(peer, msgId);
|
||||
}
|
||||
|
||||
void DialogsWidget::removePeer(PeerData *peer) {
|
||||
|
|
|
@ -58,15 +58,16 @@ public:
|
|||
|
||||
void destroyData();
|
||||
|
||||
PeerData *peerBefore(const PeerData *peer) const;
|
||||
PeerData *peerAfter(const PeerData *peer) const;
|
||||
void scrollToPeer(const PeerId &peer);
|
||||
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void scrollToPeer(const PeerId &peer, MsgId msgId);
|
||||
|
||||
typedef QVector<FakeDialogRow*> SearchResults;
|
||||
|
||||
DialogsIndexed &contactsList();
|
||||
DialogsIndexed &dialogsList();
|
||||
SearchResults &searchList();
|
||||
MsgId lastSearchId() const;
|
||||
|
||||
void setMouseSel(bool msel, bool toTop = false);
|
||||
|
||||
|
@ -121,6 +122,8 @@ private:
|
|||
SearchResults searchResults;
|
||||
int32 searchedCount, searchedSel;
|
||||
|
||||
MsgId _lastSearchId;
|
||||
|
||||
State _state;
|
||||
|
||||
QPoint lastMousePos;
|
||||
|
@ -159,9 +162,9 @@ public:
|
|||
|
||||
void destroyData();
|
||||
|
||||
PeerData *peerBefore(const PeerData *peer) const;
|
||||
PeerData *peerAfter(const PeerData *peer) const;
|
||||
void scrollToPeer(const PeerId &peer);
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||
void scrollToPeer(const PeerId &peer, MsgId msgId);
|
||||
|
||||
void removePeer(PeerData *peer);
|
||||
void removeContact(UserData *user);
|
||||
|
|
|
@ -2949,15 +2949,19 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) {
|
|||
e->ignore();
|
||||
} else if (e->key() == Qt::Key_PageDown) {
|
||||
if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::MetaModifier)) {
|
||||
PeerData *after = App::main()->peerAfter(histPeer);
|
||||
if (after) App::main()->showPeer(after->id);
|
||||
PeerData *after = 0;
|
||||
MsgId afterMsgId = 0;
|
||||
App::main()->peerAfter(histPeer, hist ? hist->activeMsgId : 0, after, afterMsgId);
|
||||
if (after) App::main()->showPeer(after->id, afterMsgId);
|
||||
} else {
|
||||
_scroll.scrollToY(_scroll.scrollTop() + _scroll.height());
|
||||
}
|
||||
} else if (e->key() == Qt::Key_PageUp) {
|
||||
if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::MetaModifier)) {
|
||||
PeerData *before = App::main()->peerBefore(histPeer);
|
||||
if (before) App::main()->showPeer(before->id);
|
||||
PeerData *before = 0;
|
||||
MsgId beforeMsgId = 0;
|
||||
App::main()->peerBefore(histPeer, hist ? hist->activeMsgId : 0, before, beforeMsgId);
|
||||
if (before) App::main()->showPeer(before->id, beforeMsgId);
|
||||
} else {
|
||||
_scroll.scrollToY(_scroll.scrollTop() - _scroll.height());
|
||||
}
|
||||
|
@ -2966,8 +2970,14 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) {
|
|||
} else if (e->key() == Qt::Key_Up) {
|
||||
_scroll.scrollToY(_scroll.scrollTop() - _scroll.height() / 10);
|
||||
} else if ((e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab) && ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::MetaModifier))) {
|
||||
PeerData *p = ((e->modifiers() & Qt::ShiftModifier) || e->key() == Qt::Key_Backtab) ? App::main()->peerBefore(histPeer) : App::main()->peerAfter(histPeer);
|
||||
if (p) App::main()->showPeer(p->id);
|
||||
PeerData *p = 0;
|
||||
MsgId m = 0;
|
||||
if ((e->modifiers() & Qt::ShiftModifier) || e->key() == Qt::Key_Backtab) {
|
||||
App::main()->peerBefore(histPeer, hist ? hist->activeMsgId : 0, p, m);
|
||||
} else {
|
||||
App::main()->peerAfter(histPeer, hist ? hist->activeMsgId : 0, p, m);
|
||||
}
|
||||
if (p) App::main()->showPeer(p->id, m);
|
||||
} else {
|
||||
e->ignore();
|
||||
}
|
||||
|
|
|
@ -998,18 +998,26 @@ void MainWidget::showPeer(const PeerId &peerId, MsgId msgId, bool back, bool for
|
|||
}
|
||||
}
|
||||
}
|
||||
dialogs.scrollToPeer(peerId);
|
||||
dialogs.scrollToPeer(peerId, msgId);
|
||||
dialogs.update();
|
||||
}
|
||||
|
||||
PeerData *MainWidget::peerBefore(const PeerData *peer) {
|
||||
if (selectingPeer()) return 0;
|
||||
return dialogs.peerBefore(peer);
|
||||
void MainWidget::peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) {
|
||||
if (selectingPeer()) {
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
dialogs.peerBefore(inPeer, inMsg, outPeer, outMsg);
|
||||
}
|
||||
|
||||
PeerData *MainWidget::peerAfter(const PeerData *peer) {
|
||||
if (selectingPeer()) return 0;
|
||||
return dialogs.peerAfter(peer);
|
||||
void MainWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) {
|
||||
if (selectingPeer()) {
|
||||
outPeer = 0;
|
||||
outMsg = 0;
|
||||
return;
|
||||
}
|
||||
dialogs.peerAfter(inPeer, inMsg, outPeer, outMsg);
|
||||
}
|
||||
|
||||
PeerData *MainWidget::peer() {
|
||||
|
|
|
@ -201,8 +201,8 @@ public:
|
|||
void updUpdated(int32 pts, int32 date, int32 qts, int32 seq);
|
||||
void historyWasRead();
|
||||
|
||||
PeerData *peerBefore(const PeerData *peer);
|
||||
PeerData *peerAfter(const PeerData *peer);
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||
PeerData *peer();
|
||||
PeerData *activePeer();
|
||||
MsgId activeMsgId();
|
||||
|
|
Loading…
Reference in New Issue