added publish time column in general channel posts files

This commit is contained in:
csoler 2020-06-18 18:31:17 +02:00
parent 9c72797dee
commit 3354246805
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
5 changed files with 67 additions and 34 deletions

View File

@ -35,7 +35,7 @@
//#define DEBUG_CHANNEL_MODEL //#define DEBUG_CHANNEL_MODEL
Q_DECLARE_METATYPE(RsGxsFile) Q_DECLARE_METATYPE(ChannelPostFileInfo)
static std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere static std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere
@ -106,7 +106,7 @@ int RsGxsChannelPostFilesModel::columnCount(const QModelIndex &/*parent*/) const
// return std::vector<std::pair<time_t,RsGxsMessageId> >(); // return std::vector<std::pair<time_t,RsGxsMessageId> >();
// } // }
bool RsGxsChannelPostFilesModel::getFileData(const QModelIndex& i,RsGxsFile& fmpe) const bool RsGxsChannelPostFilesModel::getFileData(const QModelIndex& i,ChannelPostFileInfo& fmpe) const
{ {
if(!i.isValid()) if(!i.isValid())
return true; return true;
@ -249,6 +249,7 @@ QVariant RsGxsChannelPostFilesModel::headerData(int section, Qt::Orientation ori
case COLUMN_FILES_FILE: return QString("Status"); case COLUMN_FILES_FILE: return QString("Status");
case COLUMN_FILES_SIZE: return QString("Size"); case COLUMN_FILES_SIZE: return QString("Size");
case COLUMN_FILES_NAME: return QString("File"); case COLUMN_FILES_NAME: return QString("File");
case COLUMN_FILES_DATE: return QString("Publish date");
default: default:
return QString("[No data]"); return QString("[No data]");
} }
@ -293,7 +294,7 @@ QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) co
return QVariant() ; return QVariant() ;
} }
const RsGxsFile& fmpe(mFiles[mFilteredFiles[entry]]); const ChannelPostFileInfo& fmpe(mFiles[mFilteredFiles[entry]]);
#ifdef TODO #ifdef TODO
if(role == Qt::FontRole) if(role == Qt::FontRole)
@ -376,13 +377,14 @@ class compareOperator
public: public:
compareOperator(int column,Qt::SortOrder order): col(column),ord(order) {} compareOperator(int column,Qt::SortOrder order): col(column),ord(order) {}
bool operator()(const RsGxsFile& f1,const RsGxsFile& f2) const bool operator()(const ChannelPostFileInfo& f1,const ChannelPostFileInfo& f2) const
{ {
switch(col) switch(col)
{ {
default: default:
case RsGxsChannelPostFilesModel::COLUMN_FILES_NAME: return (ord==Qt::AscendingOrder)?(f1.mName<f2.mName):(f1.mName>f2.mName); case RsGxsChannelPostFilesModel::COLUMN_FILES_NAME: return (ord==Qt::AscendingOrder)?(f1.mName<f2.mName):(f1.mName>f2.mName);
case RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE: return (ord==Qt::AscendingOrder)?(f1.mSize<f2.mSize):(f1.mSize>f2.mSize); case RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE: return (ord==Qt::AscendingOrder)?(f1.mSize<f2.mSize):(f1.mSize>f2.mSize);
case RsGxsChannelPostFilesModel::COLUMN_FILES_DATE: return (ord==Qt::AscendingOrder)?(f1.mPublishTime<f2.mPublishTime):(f1.mPublishTime>f2.mPublishTime);
case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE: case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE:
{ {
FileInfo fi1,fi2; FileInfo fi1,fi2;
@ -579,12 +581,13 @@ QVariant RsGxsChannelPostFilesModel::sizeHintRole(int col) const
#endif #endif
} }
QVariant RsGxsChannelPostFilesModel::sortRole(const RsGxsFile& fmpe,int column) const QVariant RsGxsChannelPostFilesModel::sortRole(const ChannelPostFileInfo& fmpe,int column) const
{ {
switch(column) switch(column)
{ {
case COLUMN_FILES_NAME: return QVariant(QString::fromUtf8(fmpe.mName.c_str())); case COLUMN_FILES_NAME: return QVariant(QString::fromUtf8(fmpe.mName.c_str()));
case COLUMN_FILES_SIZE: return QVariant(qulonglong(fmpe.mSize)); case COLUMN_FILES_SIZE: return QVariant(qulonglong(fmpe.mSize));
case COLUMN_FILES_DATE: return QVariant(qulonglong(fmpe.mPublishTime));
case COLUMN_FILES_FILE: case COLUMN_FILES_FILE:
{ {
FileInfo finfo; FileInfo finfo;
@ -600,13 +603,14 @@ QVariant RsGxsChannelPostFilesModel::sortRole(const RsGxsFile& fmpe,int column)
} }
} }
QVariant RsGxsChannelPostFilesModel::displayRole(const RsGxsFile& fmpe,int col) const QVariant RsGxsChannelPostFilesModel::displayRole(const ChannelPostFileInfo& fmpe,int col) const
{ {
switch(col) switch(col)
{ {
case 0: return QString::fromUtf8(fmpe.mName.c_str()); case COLUMN_FILES_NAME: return QString::fromUtf8(fmpe.mName.c_str());
case 1: return QString::number(fmpe.mSize); case COLUMN_FILES_SIZE: return QString::number(fmpe.mSize);
case 2: { case COLUMN_FILES_DATE: return QString::number(fmpe.mPublishTime);
case COLUMN_FILES_FILE: {
FileInfo finfo; FileInfo finfo;
if(rsFiles->FileDetails(fmpe.mHash,RS_FILE_HINTS_DOWNLOAD,finfo)) if(rsFiles->FileDetails(fmpe.mHash,RS_FILE_HINTS_DOWNLOAD,finfo))
return qulonglong(finfo.transfered); return qulonglong(finfo.transfered);
@ -659,7 +663,7 @@ QVariant RsGxsChannelPostFilesModel::displayRole(const RsGxsFile& fmpe,int col)
return QVariant("[ERROR]"); return QVariant("[ERROR]");
} }
QVariant RsGxsChannelPostFilesModel::userRole(const RsGxsFile& fmpe,int col) const QVariant RsGxsChannelPostFilesModel::userRole(const ChannelPostFileInfo& fmpe,int col) const
{ {
switch(col) switch(col)
{ {
@ -695,7 +699,7 @@ void RsGxsChannelPostFilesModel::clear()
emit channelLoaded(); emit channelLoaded();
} }
void RsGxsChannelPostFilesModel::setFiles(const std::list<RsGxsFile>& files) void RsGxsChannelPostFilesModel::setFiles(const std::list<ChannelPostFileInfo> &files)
{ {
preMods(); preMods();

View File

@ -36,6 +36,19 @@ typedef uint32_t ChannelPostFilesModelIndex;
class QTimer; class QTimer;
// This class contains the info for a file as well as additional info such as publication date
struct ChannelPostFileInfo: public RsGxsFile
{
ChannelPostFileInfo(const RsGxsFile& gxs_file,rstime_t t)
: RsGxsFile(gxs_file),mPublishTime(t)
{}
ChannelPostFileInfo() : mPublishTime(0) {}
rstime_t mPublishTime;
};
// This class is the item model used by Qt to display the information // This class is the item model used by Qt to display the information
class RsGxsChannelPostFilesModel : public QAbstractItemModel class RsGxsChannelPostFilesModel : public QAbstractItemModel
@ -50,7 +63,8 @@ public:
COLUMN_FILES_NAME = 0x00, COLUMN_FILES_NAME = 0x00,
COLUMN_FILES_SIZE = 0x01, COLUMN_FILES_SIZE = 0x01,
COLUMN_FILES_FILE = 0x02, COLUMN_FILES_FILE = 0x02,
COLUMN_FILES_NB_COLUMNS = 0x03 COLUMN_FILES_DATE = 0x03,
COLUMN_FILES_NB_COLUMNS = 0x04
}; };
enum Roles{ SortRole = Qt::UserRole+1, enum Roles{ SortRole = Qt::UserRole+1,
@ -66,7 +80,7 @@ public:
QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;} QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;}
// This method will asynchroneously update the data // This method will asynchroneously update the data
void setFiles(const std::list<RsGxsFile>& files); void setFiles(const std::list<ChannelPostFileInfo>& files);
void setFilter(const QStringList &strings, uint32_t &count) ; void setFilter(const QStringList &strings, uint32_t &count) ;
#ifdef TODO #ifdef TODO
@ -102,11 +116,11 @@ public:
// Custom item roles // Custom item roles
QVariant sizeHintRole (int col) const; QVariant sizeHintRole (int col) const;
QVariant displayRole (const RsGxsFile& fmpe, int col) const; QVariant displayRole (const ChannelPostFileInfo& fmpe, int col) const;
QVariant toolTipRole (const RsGxsFile& fmpe, int col) const; QVariant toolTipRole (const ChannelPostFileInfo& fmpe, int col) const;
QVariant userRole (const RsGxsFile& fmpe, int col) const; QVariant userRole (const ChannelPostFileInfo& fmpe, int col) const;
QVariant sortRole (const RsGxsFile& fmpe, int col) const; QVariant sortRole (const ChannelPostFileInfo& fmpe, int col) const;
QVariant filterRole (const RsGxsFile& fmpe, int col) const; QVariant filterRole (const ChannelPostFileInfo& fmpe, int col) const;
#ifdef TODO #ifdef TODO
QVariant decorationRole(const ForumModelPostEntry& fmpe, int col) const; QVariant decorationRole(const ForumModelPostEntry& fmpe, int col) const;
QVariant pinnedRole (const ForumModelPostEntry& fmpe, int col) const; QVariant pinnedRole (const ForumModelPostEntry& fmpe, int col) const;
@ -142,7 +156,7 @@ private:
quintptr getParentRow(quintptr ref,int& row) const; quintptr getParentRow(quintptr ref,int& row) const;
quintptr getChildRef(quintptr ref, int index) const; quintptr getChildRef(quintptr ref, int index) const;
int getChildrenCount(quintptr ref) const; int getChildrenCount(quintptr ref) const;
bool getFileData(const QModelIndex& i,RsGxsFile& fmpe) const; bool getFileData(const QModelIndex& i, ChannelPostFileInfo &fmpe) const;
static bool convertTabEntryToRefPointer(uint32_t entry, quintptr& ref); static bool convertTabEntryToRefPointer(uint32_t entry, quintptr& ref);
static bool convertRefPointerToTabEntry(quintptr ref,uint32_t& entry); static bool convertRefPointerToTabEntry(quintptr ref,uint32_t& entry);
@ -153,7 +167,7 @@ private:
void initEmptyHierarchy(); void initEmptyHierarchy();
std::vector<int> mFilteredFiles ; // store the list of files for the post std::vector<int> mFilteredFiles ; // store the list of files for the post
std::vector<RsGxsFile> mFiles ; // store the list of files for the post std::vector<ChannelPostFileInfo> mFiles ; // store the list of files for the post
QTimer *mTimer; QTimer *mTimer;
}; };

View File

@ -23,14 +23,17 @@
#include <QModelIndex> #include <QModelIndex>
#include <QIcon> #include <QIcon>
#include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxschannels.h"
#include "retroshare/rsexpr.h"
#include "gui/common/FilesDefs.h" #include "gui/common/FilesDefs.h"
#include "util/qtthreadsutils.h" #include "util/qtthreadsutils.h"
#include "util/HandleRichText.h" #include "util/HandleRichText.h"
#include "util/DateTime.h" #include "util/DateTime.h"
#include "GxsChannelPostsModel.h" #include "GxsChannelPostsModel.h"
#include "retroshare/rsgxsflags.h" #include "GxsChannelPostFilesModel.h"
#include "retroshare/rsgxschannels.h"
#include "retroshare/rsexpr.h"
//#define DEBUG_CHANNEL_MODEL //#define DEBUG_CHANNEL_MODEL
@ -142,15 +145,15 @@ void RsGxsChannelPostsModel::postMods()
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredPosts.size(),mColumns-1,(void*)NULL)); emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mFilteredPosts.size(),mColumns-1,(void*)NULL));
} }
void RsGxsChannelPostsModel::getFilesList(std::list<RsGxsFile>& files) void RsGxsChannelPostsModel::getFilesList(std::list<ChannelPostFileInfo>& files)
{ {
// We use an intermediate map so as to remove duplicates // We use an intermediate map so as to remove duplicates
std::map<RsFileHash,RsGxsFile> files_map; std::map<RsFileHash,ChannelPostFileInfo> files_map;
for(uint32_t i=1;i<mPosts.size();++i) for(uint32_t i=0;i<mPosts.size();++i)
for(auto& file:mPosts[i].mFiles) for(auto& file:mPosts[i].mFiles)
files_map[file.mHash] = file; files_map.insert(std::make_pair(file.mHash,ChannelPostFileInfo(file,mPosts[i].mMeta.mPublishTs)));
files.clear(); files.clear();

View File

@ -21,9 +21,12 @@
#include "retroshare/rsgxschannels.h" #include "retroshare/rsgxschannels.h"
#include "retroshare/rsgxsifacetypes.h" #include "retroshare/rsgxsifacetypes.h"
#include "retroshare/rsevents.h" #include "retroshare/rsevents.h"
#include <QModelIndex> #include <QModelIndex>
#include <QColor> #include <QColor>
struct ChannelPostFileInfo;
// This class holds the actual hierarchy of posts, represented by identifiers // This class holds the actual hierarchy of posts, represented by identifiers
// It is responsible for auto-updating when necessary and holds a mutex to allow the Model to // It is responsible for auto-updating when necessary and holds a mutex to allow the Model to
// safely access the data. // safely access the data.
@ -112,7 +115,7 @@ public:
// Retrieve the full list of files for all posts. // Retrieve the full list of files for all posts.
void getFilesList(std::list<RsGxsFile>& files); void getFilesList(std::list<ChannelPostFileInfo> &files);
#ifdef TODO #ifdef TODO
void setSortMode(SortMode mode) ; void setSortMode(SortMode mode) ;

View File

@ -72,7 +72,7 @@ static const int CHANNEL_TABS_POSTS = 1;
#define STAR_OVERLAY_IMAGE ":icons/star_overlay_128.png" #define STAR_OVERLAY_IMAGE ":icons/star_overlay_128.png"
Q_DECLARE_METATYPE(RsGxsFile) Q_DECLARE_METATYPE(ChannelPostFileInfo)
// Delegate used to paint into the table of thumbnails // Delegate used to paint into the table of thumbnails
@ -131,7 +131,7 @@ QSize ChannelPostDelegate::sizeHint(const QStyleOptionViewItem& option, const QM
QWidget *ChannelPostFilesDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const QWidget *ChannelPostFilesDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const
{ {
RsGxsFile file = index.data(Qt::UserRole).value<RsGxsFile>() ; ChannelPostFileInfo file = index.data(Qt::UserRole).value<ChannelPostFileInfo>() ;
if(index.column() == RsGxsChannelPostFilesModel::COLUMN_FILES_FILE) if(index.column() == RsGxsChannelPostFilesModel::COLUMN_FILES_FILE)
return new GxsChannelFilesStatusWidget(file,parent); return new GxsChannelFilesStatusWidget(file,parent);
@ -145,7 +145,7 @@ void ChannelPostFilesDelegate::updateEditorGeometry(QWidget *editor, const QStyl
void ChannelPostFilesDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const void ChannelPostFilesDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{ {
RsGxsFile file = index.data(Qt::UserRole).value<RsGxsFile>() ; ChannelPostFileInfo file = index.data(Qt::UserRole).value<ChannelPostFileInfo>() ;
// prepare // prepare
painter->save(); painter->save();
@ -163,6 +163,8 @@ void ChannelPostFilesDelegate::paint(QPainter * painter, const QStyleOptionViewI
break; break;
case RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE: painter->drawText(option.rect,Qt::AlignRight | Qt::AlignVCenter,misc::friendlyUnit(qulonglong(file.mSize))); case RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE: painter->drawText(option.rect,Qt::AlignRight | Qt::AlignVCenter,misc::friendlyUnit(qulonglong(file.mSize)));
break; break;
case RsGxsChannelPostFilesModel::COLUMN_FILES_DATE: painter->drawText(option.rect,Qt::AlignLeft | Qt::AlignVCenter,QDateTime::fromMSecsSinceEpoch(file.mPublishTime*1000).toString("MM/dd/yyyy, hh:mm"));
break;
case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE: { case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE: {
GxsChannelFilesStatusWidget w(file); GxsChannelFilesStatusWidget w(file);
@ -186,7 +188,7 @@ void ChannelPostFilesDelegate::paint(QPainter * painter, const QStyleOptionViewI
QSize ChannelPostFilesDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const QSize ChannelPostFilesDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{ {
RsGxsFile file = index.data(Qt::UserRole).value<RsGxsFile>() ; ChannelPostFileInfo file = index.data(Qt::UserRole).value<ChannelPostFileInfo>() ;
QFontMetricsF fm(option.font); QFontMetricsF fm(option.font);
@ -194,6 +196,7 @@ QSize ChannelPostFilesDelegate::sizeHint(const QStyleOptionViewItem& option, con
{ {
case RsGxsChannelPostFilesModel::COLUMN_FILES_NAME: return QSize(1.1*fm.width(QString::fromUtf8(file.mName.c_str())),fm.height()); case RsGxsChannelPostFilesModel::COLUMN_FILES_NAME: return QSize(1.1*fm.width(QString::fromUtf8(file.mName.c_str())),fm.height());
case RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE: return QSize(1.1*fm.width(misc::friendlyUnit(qulonglong(file.mSize))),fm.height()); case RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE: return QSize(1.1*fm.width(misc::friendlyUnit(qulonglong(file.mSize))),fm.height());
case RsGxsChannelPostFilesModel::COLUMN_FILES_DATE: return QSize(1.1*fm.width(QDateTime::fromMSecsSinceEpoch(file.mPublishTime*1000).toString("MM/dd/yyyy, hh:mm")),fm.height());
default: default:
case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE: return QSize(option.rect.width(),GxsChannelFilesStatusWidget(file).height()); case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE: return QSize(option.rect.width(),GxsChannelFilesStatusWidget(file).height());
} }
@ -280,6 +283,8 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
/* load settings */ /* load settings */
processSettings(true); processSettings(true);
ui->channelPostFiles_TV->setColumnHidden(RsGxsChannelPostFilesModel::COLUMN_FILES_DATE, true); // no need to show this here.
/* Initialize subscribe button */ /* Initialize subscribe button */
QIcon icon; QIcon icon;
icon.addPixmap(QPixmap(":/images/redled.png"), QIcon::Normal, QIcon::On); icon.addPixmap(QPixmap(":/images/redled.png"), QIcon::Normal, QIcon::On);
@ -396,7 +401,11 @@ void GxsChannelPostsWidgetWithModel::showPostDetails()
mSelectedGroup = mGroup.mMeta.mGroupId; mSelectedGroup = mGroup.mMeta.mGroupId;
mSelectedPost = post.mMeta.mMsgId; mSelectedPost = post.mMeta.mMsgId;
mChannelPostFilesModel->setFiles(post.mFiles); std::list<ChannelPostFileInfo> files;
for(auto& file:post.mFiles)
files.push_back(ChannelPostFileInfo(file,post.mMeta.mPublishTs));
mChannelPostFilesModel->setFiles(files);
auto all_msgs_versions(post.mOlderVersions); auto all_msgs_versions(post.mOlderVersions);
all_msgs_versions.insert(post.mMeta.mMsgId); all_msgs_versions.insert(post.mMeta.mMsgId);
@ -484,7 +493,7 @@ void GxsChannelPostsWidgetWithModel::postChannelPostLoad()
whileBlocking(ui->postsTree)->setCurrentIndex(index); whileBlocking(ui->postsTree)->setCurrentIndex(index);
} }
std::list<RsGxsFile> files; std::list<ChannelPostFileInfo> files;
mChannelPostsModel->getFilesList(files); mChannelPostsModel->getFilesList(files);
mChannelFilesModel->setFiles(files); mChannelFilesModel->setFiles(files);