added improved channel search/filter

- only show items that contain search text based on combo field
 - equal scorers are then arranged in terms of last time stamp 

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3697 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2010-10-25 20:46:26 +00:00
parent a2905bd7ae
commit 80017cc597
3 changed files with 822 additions and 818 deletions

View File

@ -49,9 +49,13 @@
#define ROLE_ID Qt::UserRole #define ROLE_ID Qt::UserRole
#define ROLE_CHANNEL_TITLE Qt::UserRole + 1 #define ROLE_CHANNEL_TITLE Qt::UserRole + 1
#define ROLE_CHANNEL_DESC Qt::UserRole + 2 #define ROLE_CHANNEL_SEARCH_SCORE Qt::UserRole + 2
#define ROLE_CHANNEL_TS Qt::UserRole + 3 #define ROLE_CHANNEL_TS Qt::UserRole + 3
#define COMBO_TITLE_INDEX 0
#define COMBO_DESC_INDEX 1
/**** /****
* #define CHAN_DEBUG * #define CHAN_DEBUG
***/ ***/
@ -68,9 +72,8 @@ ChannelFeed::ChannelFeed(QWidget *parent)
connect(subscribeButton, SIGNAL( clicked( void ) ), this, SLOT( subscribeChannel ( void ) ) ); connect(subscribeButton, SIGNAL( clicked( void ) ), this, SLOT( subscribeChannel ( void ) ) );
connect(unsubscribeButton, SIGNAL( clicked( void ) ), this, SLOT( unsubscribeChannel ( void ) ) ); connect(unsubscribeButton, SIGNAL( clicked( void ) ), this, SLOT( unsubscribeChannel ( void ) ) );
connect(setAllAsReadButton, SIGNAL(clicked()), this, SLOT(setAllAsReadClicked())); connect(setAllAsReadButton, SIGNAL(clicked()), this, SLOT(setAllAsReadClicked()));
connect(searchLine, SIGNAL(returnPressed()), this, SLOT(searchChannels( void )));
connect(pushButtonSearch, SIGNAL(clicked()), this, SLOT(searchChannels( void )));
connect(resetButton, SIGNAL(clicked()), this, SLOT(finishSearching( void ))); connect(resetButton, SIGNAL(clicked()), this, SLOT(finishSearching( void )));
connect( searchLine, SIGNAL(textChanged(const QString &)), this, SLOT(filterRegExpChanged()));
connect(NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int))); connect(NotifyQt::getInstance(), SIGNAL(channelMsgReadSatusChanged(QString,QString,int)), this, SLOT(channelMsgReadSatusChanged(QString,QString,int)));
@ -295,44 +298,35 @@ void ChannelFeed::updateDisplay()
} }
} }
void ChannelFeed::searchChannels(){ void ChannelFeed::filterRegExpChanged(){
// do not allow update of page (new items to be added)
RsAutoUpdatePage::lockAllEvents();
if(searchLine->text().isEmpty()) if(searchLine->text().isEmpty()){
finishSearching(); finishSearching();
return;
}
resetButton->setEnabled(true);
resetButton->setVisible(true); resetButton->setVisible(true);
QChannelItem::setSearchText(searchLine->text()); // force display to be updated
updateChannelList();
model->item(OWN)->sortChildren(COLUMN_NAME, Qt::DescendingOrder);
model->item(SUBSCRIBED)->sortChildren(COLUMN_NAME, Qt::DescendingOrder);
model->item(POPULAR)->sortChildren(COLUMN_NAME, Qt::DescendingOrder);
model->item(OTHER)->sortChildren(COLUMN_NAME, Qt::DescendingOrder);
return; return;
} }
void ChannelFeed::finishSearching(){ void ChannelFeed::finishSearching(){
// unlock channel page update if user is done searching
RsAutoUpdatePage::unlockAllEvents();
searchLine->clear(); searchLine->clear();
resetButton->setVisible(false); resetButton->setVisible(false);
resetButton->setEnabled(false);
mChanSearchScore.clear();
updateChannelList();
return; return;
} }
void ChannelFeed::searchMessages(){
return;
}
void ChannelFeed::updateChannelList() void ChannelFeed::updateChannelList()
{ {
@ -384,6 +378,15 @@ void ChannelFeed::updateChannelList()
} }
} }
// check if search filter is being used
if(! searchLine->text().isEmpty()){
filterChannelList(adminList);
filterChannelList(subList);
filterChannelList(popList);
filterChannelList(otherList);
}
/* now we have our lists ---> update entries */ /* now we have our lists ---> update entries */
fillChannelList(OWN, adminList); fillChannelList(OWN, adminList);
@ -394,6 +397,37 @@ void ChannelFeed::updateChannelList()
updateMessageSummaryList(""); updateMessageSummaryList("");
} }
void ChannelFeed::filterChannelList(std::list<ChannelInfo> &ci){
uint32_t score = 0;
QString scoreString;
mChanSearchScore.clear();
std::list<ChannelInfo>::iterator it = ci.begin();
// first find out which has given word in it
for(;it != ci.end(); it++){
if(sectionCombo->currentIndex() == COMBO_DESC_INDEX){
scoreString = QString::fromStdWString(it->channelDesc);
score = scoreString.count(searchLine->text(), Qt::CaseInsensitive);
mChanSearchScore.insert(std::pair<std::string, uint32_t>(it->channelId, score));
}
else {
scoreString = QString::fromStdWString(it->channelName);
score = scoreString.count(searchLine->text(), Qt::CaseInsensitive);
mChanSearchScore.insert(std::pair<std::string, uint32_t>(it->channelId, score));
}
if(score == 0){
it = ci.erase(it);
it--;
}
}
}
void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos) void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos)
{ {
std::list<ChannelInfo>::iterator iit; std::list<ChannelInfo>::iterator iit;
@ -423,8 +457,8 @@ void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &chann
} }
} }
QStandardItem *chNameItem = NULL;//new QChannelItem(); // use channel item to enable channel specific sorting QStandardItem *chNameItem = NULL;
QStandardItem *chPopItem = NULL;// new QStandardItem(); QStandardItem *chPopItem = NULL;
if (row < rowCount) { if (row < rowCount) {
chNameItem = groupItem->child(row, COLUMN_NAME); chNameItem = groupItem->child(row, COLUMN_NAME);
chPopItem = groupItem->child(row, COLUMN_POPULARITY); chPopItem = groupItem->child(row, COLUMN_POPULARITY);
@ -445,10 +479,12 @@ void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &chann
chNameItem->setText(QString::fromStdWString(ci.channelName)); chNameItem->setText(QString::fromStdWString(ci.channelName));
groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(QString::fromStdWString(ci.channelName), ROLE_CHANNEL_TITLE); groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(QString::fromStdWString(ci.channelName), ROLE_CHANNEL_TITLE);
// important for searching channels // important for arrangement of channels
groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(QString::fromStdWString(ci.channelDesc), ROLE_CHANNEL_DESC); groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(((mChanSearchScore.find(channelId.toStdString()))->second),
ROLE_CHANNEL_SEARCH_SCORE);
groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(QDateTime::fromTime_t(ci.lastPost), ROLE_CHANNEL_TS); groupItem->child(chNameItem->index().row(), COLUMN_DATA)->setData(QDateTime::fromTime_t(ci.lastPost), ROLE_CHANNEL_TS);
chNameItem->setToolTip(tr("Popularity: %1\nFetches: %2\nAvailable: %3").arg(QString::number(ci.pop)).arg(9999).arg(9999)); chNameItem->setToolTip(tr("Popularity: %1\nFetches: %2\nAvailable: %3").arg(QString::number(ci.pop)).arg(9999).arg(9999));
QPixmap chanImage; QPixmap chanImage;
@ -496,6 +532,8 @@ void ChannelFeed::fillChannelList(int channelItem, std::list<ChannelInfo> &chann
} }
} }
model->item(channelItem)->sortChildren(COLUMN_NAME, Qt::DescendingOrder);
} }
void ChannelFeed::channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status) void ChannelFeed::channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status)
@ -705,8 +743,6 @@ void ChannelFeed::setAllAsReadClicked()
} }
} }
QString QChannelItem::searchText = "";
QChannelItem::QChannelItem() QChannelItem::QChannelItem()
: QStandardItem(){ : QStandardItem(){
} }
@ -718,19 +754,17 @@ QChannelItem::QChannelItem()
bool QChannelItem::operator<(const QStandardItem& other) const { bool QChannelItem::operator<(const QStandardItem& other) const {
// calculate *this/other search scores uint32_t otherCount = 0, thisCount = 0;
int otherCount = other.data(ROLE_CHANNEL_TITLE).toString().count(searchText,Qt::CaseInsensitive);
otherCount += other.data(ROLE_CHANNEL_DESC).toString().count(searchText,Qt::CaseInsensitive);
int thisCount = this->data(ROLE_CHANNEL_TITLE).toString().count(searchText, Qt:: CaseInsensitive);
thisCount += this->data(ROLE_CHANNEL_DESC).toString().count(searchText, Qt:: CaseInsensitive);
uint otherChanTs = other.data(ROLE_CHANNEL_TS).toDateTime().toTime_t(); uint otherChanTs = other.data(ROLE_CHANNEL_TS).toDateTime().toTime_t();
uint thisChanTs = this->data(ROLE_CHANNEL_TS).toDateTime().toTime_t(); uint thisChanTs = this->data(ROLE_CHANNEL_TS).toDateTime().toTime_t();
otherCount = other.data(ROLE_CHANNEL_SEARCH_SCORE).toUInt();
thisCount = this->data(ROLE_CHANNEL_SEARCH_SCORE).toUInt();
// if counts are equal then determine by who has the most recent post // if counts are equal then determine by who has the most recent post
if(otherCount == thisCount){ if(otherCount == thisCount){
if(otherChanTs < thisChanTs) if(thisChanTs < otherChanTs)
return true; return true;
} }
@ -738,13 +772,9 @@ bool QChannelItem::operator<(const QStandardItem& other) const {
if(thisCount < otherCount) if(thisCount < otherCount)
return true; return true;
if(thisChanTs < otherChanTs)
return true;
return false; return false;
} }
void QChannelItem::setSearchText(const QString& sText){
searchText = sText;
return;
}

View File

@ -24,6 +24,7 @@
#include <retroshare/rschannels.h> #include <retroshare/rschannels.h>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <map>
#include "mainpage.h" #include "mainpage.h"
#include "RsAutoUpdatePage.h" #include "RsAutoUpdatePage.h"
@ -81,14 +82,14 @@ private slots:
void shareKey(); void shareKey();
void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status); void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status);
void searchChannels(); void filterRegExpChanged();
void searchMessages();
void finishSearching(); void finishSearching();
private: private:
void updateChannelList(); void updateChannelList();
void fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos); void fillChannelList(int channelItem, std::list<ChannelInfo> &channelInfos);
void filterChannelList(std::list<ChannelInfo>&);
void updateChannelMsgs(); void updateChannelMsgs();
void updateMessageSummaryList(const std::string &channelId); void updateMessageSummaryList(const std::string &channelId);
@ -100,6 +101,7 @@ private:
QBoxLayout *mMsgLayout; QBoxLayout *mMsgLayout;
std::list<ChanMsgItem *> mChanMsgItems; std::list<ChanMsgItem *> mChanMsgItems;
std::map<std::string, uint32_t> mChanSearchScore; //chanId, score
QFont mChannelFont; QFont mChannelFont;
QFont itemFont; QFont itemFont;
@ -113,21 +115,12 @@ public:
QChannelItem(); QChannelItem();
virtual ~QChannelItem(); virtual ~QChannelItem();
/**
* Allows users to set the search text for QChannel items
* @param
*/
static void setSearchText(const QString& sText);
/** /**
* reimplementing comparison operator so QChannelItems can be ordered in terms * reimplementing comparison operator so QChannelItems can be ordered in terms
* of occurences of property searchText in its data columns * of occurences of property searchText in its data columns
*/ */
bool operator<(const QStandardItem& other) const; bool operator<(const QStandardItem& other) const;
private:
static QString searchText;
}; };

View File

@ -69,12 +69,6 @@
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout_9"> <layout class="QGridLayout" name="gridLayout_9">
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QFrame" name="chheaderframe"> <widget class="QFrame" name="chheaderframe">
<property name="minimumSize"> <property name="minimumSize">
@ -288,6 +282,50 @@ background: white;</string>
<property name="margin"> <property name="margin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0">
<widget class="QLineEdit" name="searchLine">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1677777</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Enter a Keyword here</string>
</property>
<property name="styleSheet">
<string notr="true">QLineEdit#searchLine{background: transparent;
border: none;}
</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="sectionCombo">
<item>
<property name="text">
<string>Title</string>
</property>
</item>
<item>
<property name="text">
<string>Description</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QPushButton" name="resetButton"> <widget class="QPushButton" name="resetButton">
<property name="minimumSize"> <property name="minimumSize">
@ -325,69 +363,9 @@ border-image: url(:/images/closepressed.png)
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QLineEdit" name="searchLine">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1677777</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Enter a Keyword here</string>
</property>
<property name="styleSheet">
<string notr="true">QLineEdit#searchLine{background: transparent;
border: none;}
</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="pushButtonSearch">
<property name="toolTip">
<string>Start Search</string>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {
border-image: url(:/images/btn1.png) 4;
border-width: 4;
padding: 0px 6px;
font-size: 12px;
}
*{
color: black;
}
QPushButton:hover {
border-image: url(:/images/btn2.png) 4;
}
QPushButton:pressed{
border-image: url(:/images/btn3.png) 4;
}</string>
</property>
<property name="text">
<string>Search</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
@ -419,6 +397,9 @@ border-image: url(:/images/btn3.png) 4;
</widget> </widget>
</item> </item>
</layout> </layout>
<zorder>layoutWidget</zorder>
<zorder>chheaderframe</zorder>
<zorder>treeView</zorder>
</widget> </widget>
<widget class="QWidget" name="layoutWidget"> <widget class="QWidget" name="layoutWidget">
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4">
@ -705,7 +686,7 @@ border-image: url(:/images/btn_26_pressed.png) 4;
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>412</width> <width>413</width>
<height>331</height> <height>331</height>
</rect> </rect>
</property> </property>