fixed the sorting of SearchDialog by age and by size, by using proper delegates for displaying the numbers. Removed the SR_REALSIZE_COL column, that is no longer necessary.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5.0@2839 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-05-02 21:33:44 +00:00
parent 0e1bac6406
commit 758de9b22c
4 changed files with 121 additions and 63 deletions

View File

@ -146,6 +146,7 @@ HEADERS += rshare.h \
gui/mainpage.h \
gui/mainpagestack.h \
gui/MainWindow.h \
gui/RSHumanReadableDelegate.h \
gui/TurtleRouterDialog.h \
gui/AboutDialog.h \
gui/AddLinksDialog.h \

View File

@ -0,0 +1,70 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2010 Cyril Soler
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
/** Use this class for displaying dates and sizes in a readable format, while allowing to read the
* real size in the column.
*
* To use:
*
* - in the QABstractItemView constructor, do a
*
* myView->setItemDelegateForColumn(SR_SIZE_COL,new RSHumanReadableSizeDelegate()) ;
*
* - each field must be filled with a string that allows a proper sorting based on lexicographic
* order. For Sizes, use this:
*
* myView->setText(SR_SIZE_COL, QString("%1").arg(dir.count,(int)15,(int)10));
*
* Note: there's no .cpp file, because the code here is really simple.
*/
#include <QItemDelegate>
#include <util/misc.h>
class RSHumanReadableDelegate: public QAbstractItemDelegate
{
public:
virtual QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const
{
return QSize(50,17) ;
}
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const = 0;
};
class RSHumanReadableAgeDelegate: public RSHumanReadableDelegate
{
public:
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
{
painter->drawText(option.rect, Qt::AlignCenter, misc::userFriendlyDuration(index.data().toLongLong())) ;
}
};
class RSHumanReadableSizeDelegate: public RSHumanReadableDelegate
{
public:
virtual void paint(QPainter *painter,const QStyleOptionViewItem & option, const QModelIndex & index) const
{
painter->drawText(option.rect, Qt::AlignRight, misc::friendlyUnit(index.data().toULongLong()));
}
};

View File

@ -25,6 +25,7 @@
#include "SearchDialog.h"
#include "RetroShareLink.h"
#include "msgs/ChanMsgDialog.h"
#include <gui/RSHumanReadableDelegate.h>
#include "rsiface/rsiface.h"
#include "rsiface/rsexpr.h"
@ -61,11 +62,8 @@
#define SR_TYPE_COL 3
#define SR_AGE_COL 4
#define SR_HASH_COL 5
#define SR_SEARCH_ID_COL 6
#define SR_UID_COL 7
#define SR_REALSIZE_COL 8
/* indicies for search summary item columns SS_ = Search Summary */
#define SS_TEXT_COL 0
@ -123,22 +121,25 @@ SearchDialog::SearchDialog(QWidget *parent)
connect( ui.resetButton, SIGNAL(clicked()), this, SLOT(clearKeyword()));
connect( ui.lineEdit, SIGNAL( textChanged(const QString &)), this, SLOT(togglereset()));
//connect( ui.searchSummaryWidget, SIGNAL( itemSelectionChanged ( void ) ), this, SLOT( selectSearchResults( void ) ) );
connect( ui.searchResultWidget, SIGNAL( itemDoubleClicked ( QTreeWidgetItem *, int)), this, SLOT(download()));
connect ( ui.searchSummaryWidget, SIGNAL( currentItemChanged ( QTreeWidgetItem *, QTreeWidgetItem * ) ),
this, SLOT( selectSearchResults( void ) ) );
//connect(ui.FileTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboIndexChanged(int)));
connect(ui.FileTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectSearchResults(int)));
/* hide the Tree +/- */
ui.searchResultWidget -> setRootIsDecorated( true );
ui.searchResultWidget -> setColumnHidden( SR_UID_COL,true );
ui.searchResultWidget -> setColumnHidden( SR_REALSIZE_COL,true );
ui.searchSummaryWidget -> setRootIsDecorated( false );
// We set some delegates to handle the display of size and date.
// To allow a proper sorting, be careful to pad at right with spaces. This
// is achieved by using QString("%1").arg(number,15,10).
//
ui.searchResultWidget->setItemDelegateForColumn(SR_SIZE_COL,new RSHumanReadableSizeDelegate()) ;
ui.searchResultWidget->setItemDelegateForColumn(SR_AGE_COL,new RSHumanReadableAgeDelegate()) ;
/* make it extended selection */
ui.searchResultWidget -> setSelectionMode(QAbstractItemView::ExtendedSelection);
@ -279,22 +280,15 @@ void SearchDialog::download()
std::cerr << "SearchDialog::download() Calling File Request";
std::cerr << std::endl;
std::list<std::string> srcIds;
#ifdef SUSPENDED
// I suspend this. For turtle F2F download, we dont' need sources:
// - if we put sources, they make double with some tunnels.
// - they won't transfer because ASSUME_AVAILABILITY can't be used,
// and no chunk maps are transfered except in tunnels.
srcIds.push_back(item->text(SR_UID_COL).toStdString()) ;
#endif
if(!rsFiles -> FileRequest((item->text(SR_NAME_COL)).toStdString(),
(item->text(SR_HASH_COL)).toStdString(),
(item->text(SR_REALSIZE_COL)).toULongLong(),
(item->text(SR_SIZE_COL)).toULongLong(),
"", RS_FILE_HINTS_NETWORK_WIDE, srcIds))
attemptDownloadLocal = true ;
else
{
std::cout << "isuing file request from search dialog: -" << (item->text(SR_NAME_COL)).toStdString() << "-" << (item->text(SR_HASH_COL)).toStdString() << "-" << (item->text(SR_REALSIZE_COL)).toULongLong() << "-ids=" ;
std::cout << "isuing file request from search dialog: -" << (item->text(SR_NAME_COL)).toStdString() << "-" << (item->text(SR_HASH_COL)).toStdString() << "-" << (item->text(SR_SIZE_COL)).toULongLong() << "-ids=" ;
for(std::list<std::string>::const_iterator it(srcIds.begin());it!=srcIds.end();++it)
std::cout << *it << "-" << std::endl ;
}
@ -308,11 +302,9 @@ void SearchDialog::download()
void SearchDialog::downloadDirectory(const QTreeWidgetItem *item, const QString &base)
{
if (!item->childCount()) {
if (!item->childCount())
{
std::list<std::string> srcIds;
#ifdef SUSPENDED
srcIds.push_back(item->text(SR_UID_COL).toStdString());
#endif
QString path = QString::fromStdString(rsFiles->getDownloadDirectory())
+ tr("/") + base + tr("/");
@ -320,14 +312,14 @@ void SearchDialog::downloadDirectory(const QTreeWidgetItem *item, const QString
rsFiles->FileRequest(item->text(SR_NAME_COL).toStdString(),
item->text(SR_HASH_COL).toStdString(),
item->text(SR_REALSIZE_COL).toULongLong(),
item->text(SR_SIZE_COL).toULongLong(),
cleanPath.toStdString(),RS_FILE_HINTS_NETWORK_WIDE, srcIds);
std::cout << "SearchDialog::downloadDirectory(): "\
"issuing file request from search dialog: -"
<< (item->text(SR_NAME_COL)).toStdString()
<< "-" << (item->text(SR_HASH_COL)).toStdString()
<< "-" << (item->text(SR_REALSIZE_COL)).toULongLong()
<< "-" << (item->text(SR_SIZE_COL)).toULongLong()
<< "-ids=" ;
for(std::list<std::string>::const_iterator it(srcIds.begin());
it!=srcIds.end();++it)
@ -671,9 +663,8 @@ void SearchDialog::insertDirectory(const std::string &txt, qulonglong searchId,
child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str()));
child->setText(SR_HASH_COL, QString::fromStdString(dir.hash));
QString ext = QFileInfo(QString::fromStdString(dir.name)).suffix();
child->setText(SR_SIZE_COL, misc::friendlyUnit(dir.count));
child->setText(SR_AGE_COL, misc::userFriendlyDuration(dir.age));
child->setText(SR_REALSIZE_COL, QString::number(dir.count));
child->setText(SR_SIZE_COL, QString("%1").arg(dir.count,(int)15,(int)10)); // very important for sorting
child->setText(SR_AGE_COL, QString("%1").arg(dir.age,15,10));
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
child->setText(SR_ID_COL, QString::number(1));
@ -700,9 +691,9 @@ void SearchDialog::insertDirectory(const std::string &txt, qulonglong searchId,
child->setIcon(SR_NAME_COL, QIcon(IMAGE_DIRECTORY));
child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str()));
child->setText(SR_HASH_COL, QString::fromStdString(dir.hash));
child->setText(SR_SIZE_COL, misc::toQString(dir.count));
child->setText(SR_AGE_COL, misc::userFriendlyDuration(dir.age));
child->setText(SR_REALSIZE_COL, QString::number(dir.count));
//child->setText(SR_SIZE_COL, misc::toQString(dir.count));
child->setText(SR_SIZE_COL, QString("%1").arg(dir.count,15,10)); // very important for sorting
child->setText(SR_AGE_COL, QString("%1").arg(dir.age,15,10));
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
child->setText(SR_ID_COL, QString::number(1));
child->setTextAlignment( SR_ID_COL, Qt::AlignRight );
@ -763,9 +754,8 @@ void SearchDialog::insertDirectory(const std::string &txt, qulonglong searchId,
child->setIcon(SR_NAME_COL, QIcon(IMAGE_DIRECTORY));
child->setText(SR_NAME_COL, QString::fromUtf8(dir.name.c_str()));
child->setText(SR_HASH_COL, QString::fromStdString(dir.hash));
child->setText(SR_SIZE_COL, misc::toQString(dir.count));
child->setText(SR_AGE_COL, misc::userFriendlyDuration(dir.min_age));
child->setText(SR_REALSIZE_COL, QString::number(dir.count));
child->setText(SR_SIZE_COL, QString("%1").arg(dir.count,(int)15,(int)10)); // very important for sorting
child->setText(SR_AGE_COL, QString("%1").arg(dir.min_age,15,10));
child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
child->setText(SR_ID_COL, QString::number(1));
child->setTextAlignment( SR_ID_COL, Qt::AlignRight );
@ -969,9 +959,8 @@ void SearchDialog::insertFile(const std::string& txt,qulonglong searchId, const
* to facilitate downlaods we need to save the file size too
*/
item->setText(SR_SIZE_COL, misc::friendlyUnit(file.size));
item->setText(SR_REALSIZE_COL, QString::number(file.size));
item->setText(SR_AGE_COL, misc::userFriendlyDuration(file.age));
item->setText(SR_SIZE_COL, QString("%1").arg(file.size,15,10)); // very important for sorting
item->setText(SR_AGE_COL, QString("%1").arg(file.age,15,10));
item->setTextAlignment( SR_SIZE_COL, Qt::AlignRight );
if(searchType == FRIEND_SEARCH)
{
@ -1204,7 +1193,7 @@ void SearchDialog::copysearchLink()
std::cerr << std::endl;
QString fhash = item->text(SR_HASH_COL);
qulonglong fsize = item->text(SR_REALSIZE_COL).toULongLong();
qulonglong fsize = item->text(SR_SIZE_COL).toULongLong();
QString fname = item->text(SR_NAME_COL);
RetroShareLink link(fname, fsize, fhash);

View File

@ -300,34 +300,32 @@ class misc : public QObject{
// Take a number of seconds and return an user-friendly
// time duration like "1d 2h 10m".
static QString userFriendlyDuration(qlonglong seconds) {
if(seconds < 0) {
return tr("Unknown");
}
if(seconds < 60) {
return tr("< 1m", "< 1 minute");
}
int minutes = seconds / 60;
if(minutes < 60) {
return tr("%1 minutes","e.g: 10minutes").arg(QString::QString::fromUtf8(misc::toString(minutes).c_str()));
}
int hours = minutes / 60;
minutes = minutes - hours*60;
if(hours < 24) {
return tr("%1h %2m", "e.g: 3hours 5minutes").arg(QString::fromUtf8(misc::toString(hours).c_str())).arg(QString::fromUtf8(misc::toString(minutes).c_str()));
}
int days = hours / 24;
hours = hours - days * 24;
if(days < 365) {
return tr("%1d %2h %3m", "e.g: 2days 10hours 2minutes").arg(QString::fromUtf8(misc::toString(days).c_str())).arg(QString::fromUtf8(misc::toString(hours).c_str())).arg(QString::fromUtf8(misc::toString(minutes).c_str()));
}
int years = days / 365;
days = days - years * 365;
if(years > 1) {
return tr("%1y %2d %3h %4m", "e.g: 2 years 2days 10hours 2minutes").arg(QString::fromUtf8(misc::toString(years).c_str())).arg(QString::fromUtf8(misc::toString(days).c_str())).arg(QString::fromUtf8(misc::toString(hours).c_str())).arg(QString::fromUtf8(misc::toString(minutes).c_str()));
}
return tr("Unknown");
}
static QString userFriendlyDuration(qlonglong seconds)
{
if(seconds < 0) {
return tr("Unknown");
}
if(seconds < 60) {
return tr("< 1m", "< 1 minute");
}
int minutes = seconds / 60;
if(minutes < 60) {
return tr("%1 minutes","e.g: 10minutes").arg(QString::QString::fromUtf8(misc::toString(minutes).c_str()));
}
int hours = minutes / 60;
minutes = minutes - hours*60;
if(hours < 24) {
return tr("%1h %2m", "e.g: 3hours 5minutes").arg(QString::fromUtf8(misc::toString(hours).c_str())).arg(QString::fromUtf8(misc::toString(minutes).c_str()));
}
int days = hours / 24;
hours = hours - days * 24;
if(days < 365) {
return tr("%1d %2h", "e.g: 2days 10hours").arg(QString::fromUtf8(misc::toString(days).c_str())).arg(QString::fromUtf8(misc::toString(hours).c_str()));
}
int years = days / 365;
days = days - years * 365;
return tr("%1y %2d", "e.g: 2 years 2days ").arg(QString::fromUtf8(misc::toString(years).c_str())).arg(QString::fromUtf8(misc::toString(days).c_str()));
}
};
// Trick to get a portable sleep() function