diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index 0cc840f7e..be439f464 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -206,8 +206,6 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d) RS_STACK_MUTEX(mDirStorageMtx) ; d.children.clear() ; - time_t now = time(NULL) ; - uint32_t type = mFileHierarchy->getType(indx) ; d.ref = (void*)(intptr_t)indx ; @@ -241,8 +239,8 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d) d.type = DIR_TYPE_DIR; d.hash.clear() ; d.count = dir_entry->subdirs.size() + dir_entry->subfiles.size(); - d.min_age = now - dir_entry->dir_most_recent_time ; - d.age = now - dir_entry->dir_modtime ; + d.max_mtime = dir_entry->dir_most_recent_time ; + d.mtime = dir_entry->dir_modtime ; d.name = dir_entry->dir_name; d.path = RsDirUtil::makePath(dir_entry->dir_parent_path, dir_entry->dir_name) ; d.parent = (void*)(intptr_t)dir_entry->parent_index ; @@ -259,10 +257,10 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d) d.type = DIR_TYPE_FILE; d.count = file_entry->file_size; - d.min_age = now - file_entry->file_modtime ; + d.max_mtime = file_entry->file_modtime ; d.name = file_entry->file_name; d.hash = file_entry->file_hash; - d.age = now - file_entry->file_modtime; + d.mtime = file_entry->file_modtime; d.parent = (void*)(intptr_t)file_entry->parent_index ; const InternalFileHierarchyStorage::DirEntry *parent_dir_entry = mFileHierarchy->getDirEntry(file_entry->parent_index); diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 5707b21be..2e8921af2 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -733,9 +733,9 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags d.name = "root"; d.hash.clear() ; d.path = ""; - d.age = 0; + d.mtime = 0; d.flags.clear() ; - d.min_age = 0 ; + d.max_mtime = 0 ; if(flags & RS_FILE_HINTS_LOCAL) { @@ -1054,7 +1054,7 @@ int p3FileDatabase::filterResults(const std::list& firesults,std::li P3FILELISTS_ERROR() << "(EE) Cannot get dir details for entry " << (void*)(intptr_t)*rit << std::endl; continue ; } -#ifdef P3FILELISTS_DEBUG +#ifdef DEBUG_P3FILELISTS P3FILELISTS_DEBUG() << "Filtering candidate " << (void*)(intptr_t)(*rit) << ", flags=" << cdetails.flags << ", peer=" << peer_id ; #endif @@ -1066,11 +1066,11 @@ int p3FileDatabase::filterResults(const std::list& firesults,std::li { cdetails.id.clear() ; results.push_back(cdetails); -#ifdef P3FILELISTS_DEBUG +#ifdef DEBUG_P3FILELISTS std::cerr << ": kept" << std::endl ; #endif } -#ifdef P3FILELISTS_DEBUG +#ifdef DEBUG_P3FILELISTS else std::cerr << ": discarded" << std::endl ; #endif diff --git a/libretroshare/src/retroshare/rstypes.h b/libretroshare/src/retroshare/rstypes.h index aef2d118e..9c098db59 100644 --- a/libretroshare/src/retroshare/rstypes.h +++ b/libretroshare/src/retroshare/rstypes.h @@ -239,9 +239,9 @@ public: RsFileHash hash; std::string path; // full path of the parent directory, when it is a file; full path of the dir otherwise. uint64_t count; - uint32_t age; + uint32_t mtime; // file/directory modification time, according to what the system reports FileStorageFlags flags; - uint32_t min_age ; // minimum age of files in this subtree + uint32_t max_mtime ; // maximum modification time of the whole hierarchy below. std::vector children; std::list parent_groups; // parent groups for the shared directory diff --git a/libretroshare/src/rsserver/rstypes.cc b/libretroshare/src/rsserver/rstypes.cc index 4254ee258..a71e492fc 100644 --- a/libretroshare/src/rsserver/rstypes.cc +++ b/libretroshare/src/rsserver/rstypes.cc @@ -56,8 +56,8 @@ std::ostream &operator<<(std::ostream &out, const DirDetails& d) std::cerr << " Hash : " << d.hash << std::endl; std::cerr << " Path : " << d.path << std::endl; std::cerr << " Count : " << d.count << std::endl; - std::cerr << " Age : " << d.age << std::endl; - std::cerr << " Min age : " << d.min_age << std::endl; + std::cerr << " Age : " << time(NULL) - (int)d.mtime << std::endl; + std::cerr << " Min age : " << time(NULL) - (int)d.max_mtime << std::endl; std::cerr << " Flags : " << d.flags << std::endl; std::cerr << " Parent groups : " ; for(std::list::const_iterator it(d.parent_groups.begin());it!=d.parent_groups.end();++it) std::cerr << (*it) << " "; std::cerr << std::endl; std::cerr << " Children : " ; for(uint32_t i=0;isetText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString())); child->setText(SR_SIZE_COL, QString::number(dir.count)); child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.count); - child->setText(SR_AGE_COL, QString::number(dir.age)); - child->setData(SR_AGE_COL, ROLE_SORT, dir.age); + child->setText(SR_AGE_COL, QString::number(dir.mtime)); + child->setData(SR_AGE_COL, ROLE_SORT, dir.mtime); child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); child->setText(SR_SOURCES_COL, QString::number(1)); @@ -994,8 +994,8 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString())); child->setText(SR_SIZE_COL, QString::number(dir.count)); child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.count); - child->setText(SR_AGE_COL, QString::number(dir.age)); - child->setData(SR_AGE_COL, ROLE_SORT, dir.age); + child->setText(SR_AGE_COL, QString::number(dir.mtime)); + child->setData(SR_AGE_COL, ROLE_SORT, dir.mtime); child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); child->setText(SR_SOURCES_COL, QString::number(1)); child->setData(SR_SOURCES_COL, ROLE_SORT, 1); @@ -1063,8 +1063,8 @@ void SearchDialog::insertDirectory(const QString &txt, qulonglong searchId, cons child->setText(SR_HASH_COL, QString::fromStdString(dir.hash.toStdString())); child->setText(SR_SIZE_COL, QString::number(dir.count)); child->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) dir.count); - child->setText(SR_AGE_COL, QString::number(dir.min_age)); - child->setData(SR_AGE_COL, ROLE_SORT, dir.min_age); + child->setText(SR_AGE_COL, QString::number(dir.max_mtime)); + child->setData(SR_AGE_COL, ROLE_SORT, dir.max_mtime); child->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); child->setText(SR_SOURCES_COL, QString::number(1)); child->setData(SR_SOURCES_COL, ROLE_SORT, 1); @@ -1320,7 +1320,7 @@ void SearchDialog::resultsToTree(const QString& txt,qulonglong searchId, const s fd.hash = it->hash; fd.path = it->path; fd.size = it->count; - fd.age = it->age; + fd.age = it->mtime; fd.rank = 0; insertFile(searchId,fd, FRIEND_SEARCH); diff --git a/retroshare-gui/src/gui/RSHumanReadableDelegate.h b/retroshare-gui/src/gui/RSHumanReadableDelegate.h index 52b516328..0ff6867d1 100644 --- a/retroshare-gui/src/gui/RSHumanReadableDelegate.h +++ b/retroshare-gui/src/gui/RSHumanReadableDelegate.h @@ -93,7 +93,7 @@ class RSHumanReadableAgeDelegate: public RSHumanReadableDelegate QStyleOptionViewItem opt(option) ; setPainterOptions(painter,opt,index) ; - painter->drawText(opt.rect, Qt::AlignCenter, misc::userFriendlyDuration(index.data().toLongLong())) ; + painter->drawText(opt.rect, Qt::AlignCenter, misc::timeRelativeToNow(index.data().toLongLong())) ; } }; diff --git a/retroshare-gui/src/gui/RemoteDirModel.cpp b/retroshare-gui/src/gui/RemoteDirModel.cpp index 4c25700d3..2bcc8cd4e 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.cpp +++ b/retroshare-gui/src/gui/RemoteDirModel.cpp @@ -68,9 +68,9 @@ Qt::DropActions RetroshareDirModel::supportedDragActions() const } #endif -static bool isNewerThanEpoque(uint32_t age) +static bool isNewerThanEpoque(uint32_t ts) { - return age < time(NULL) - 1000 ; // this should be conservative enough + return ts > 0 ; // this should be conservative enough } void FlatStyle_RDM::update() @@ -251,12 +251,13 @@ QString RetroshareDirModel::getGroupsString(FileStorageFlags flags,const std::li return groups_str ; } + QString RetroshareDirModel::getAgeIndicatorString(const DirDetails &details) const { QString ret(""); QString nind = tr("NEW"); // QString oind = tr("OLD"); - uint32_t age = details.min_age; + int32_t age = time(NULL) - details.max_mtime; switch (ageIndicator) { case IND_LAST_DAY: @@ -334,7 +335,9 @@ QVariant RetroshareDirModel::decorationRole(const DirDetails& details,int coln) if (details.type == DIR_TYPE_PERSON) { - if(details.min_age > ageIndicator) + time_t now = time(NULL) ; + + if(ageIndicator != IND_ALWAYS && now > details.max_mtime + ageIndicator) return QIcon(":/images/folder_grey.png"); else if (ageIndicator == IND_LAST_DAY ) return QIcon(":/images/folder_green.png"); @@ -347,7 +350,9 @@ QVariant RetroshareDirModel::decorationRole(const DirDetails& details,int coln) } else if (details.type == DIR_TYPE_DIR) { - if(details.min_age > ageIndicator) + time_t now = time(NULL) ; + + if(ageIndicator != IND_ALWAYS && now > details.max_mtime + ageIndicator) return QIcon(":/images/folder_grey.png"); else if (ageIndicator == IND_LAST_DAY ) return QIcon(":/images/folder_green.png"); @@ -408,10 +413,11 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const case 1: return QString() ; - case 2: if(!isNewerThanEpoque(details.min_age)) + case 2: if(!isNewerThanEpoque(details.max_mtime)) return QString(); else - return misc::userFriendlyDuration(details.min_age); + return misc::timeRelativeToNow(details.max_mtime); + default: return QString() ; } @@ -425,7 +431,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const case 1: return misc::friendlyUnit(details.count); case 2: - return misc::userFriendlyDuration(details.min_age); + return misc::timeRelativeToNow(details.max_mtime); case 3: return QVariant(); case 4: @@ -449,7 +455,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const } return QString::number(details.count) + " " + tr("File"); case 2: - return misc::userFriendlyDuration(details.min_age); + return misc::timeRelativeToNow(details.max_mtime); case 3: return QVariant(); case 4: @@ -493,7 +499,7 @@ QVariant FlatStyle_RDM::displayRole(const DirDetails& details,int coln) const { case 0: return QString::fromUtf8(details.name.c_str()); case 1: return misc::friendlyUnit(details.count); - case 2: return misc::userFriendlyDuration(details.min_age); + case 2: return misc::timeRelativeToNow(details.max_mtime); case 3: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); case 4: return computeDirectoryPath(details); default: @@ -519,7 +525,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& case 1: return QString(); case 2: - return details.min_age; + return details.max_mtime; default: return QString(); } @@ -533,7 +539,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& case 1: return (qulonglong) details.count; case 2: - return details.min_age; + return details.max_mtime; case 3: return getFlagsString(details.flags); case 4: @@ -556,7 +562,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& case 1: return (qulonglong) details.count; case 2: - return details.min_age; + return details.max_mtime; case 3: return getFlagsString(details.flags); default: @@ -579,7 +585,7 @@ QVariant FlatStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& { case 0: return QString::fromUtf8(details.name.c_str()); case 1: return (qulonglong) details.count; - case 2: return details.min_age; + case 2: return details.max_mtime; case 3: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); case 4: { @@ -620,7 +626,7 @@ QVariant RetroshareDirModel::data(const QModelIndex &index, int role) const { if(details.type == DIR_TYPE_FILE && details.hash.isNull()) return QVariant(QColor(Qt::green)) ; - else if(details.min_age > ageIndicator) + else if(ageIndicator != IND_ALWAYS && details.max_mtime + ageIndicator < time(NULL)) return QVariant(QColor(Qt::gray)) ; else if(RemoteMode) { @@ -645,7 +651,7 @@ QVariant RetroshareDirModel::data(const QModelIndex &index, int role) const return decorationRole(details,coln) ; if(role == Qt::ToolTipRole) - if(!isNewerThanEpoque(details.min_age)) + if(!isNewerThanEpoque(details.max_mtime)) return tr("This node hasn't sent any directory information yet.") ; /***************** @@ -921,7 +927,7 @@ Qt::ItemFlags RetroshareDirModel::flags( const QModelIndex & index ) const switch(details.type) { // we grey out a person that has never been updated. It's easy to spot these, since the min age of the directory is approx equal to time(NULL), which exceeds 40 years. - case DIR_TYPE_PERSON:return isNewerThanEpoque(details.min_age)? (Qt::ItemIsEnabled):(Qt::NoItemFlags) ; + case DIR_TYPE_PERSON:return isNewerThanEpoque(details.max_mtime)? (Qt::ItemIsEnabled):(Qt::NoItemFlags) ; case DIR_TYPE_DIR: return Qt::ItemIsSelectable | Qt::ItemIsEnabled; case DIR_TYPE_FILE: return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled; } diff --git a/retroshare-gui/src/util/misc.cpp b/retroshare-gui/src/util/misc.cpp index 4623f30a3..92cd43489 100644 --- a/retroshare-gui/src/util/misc.cpp +++ b/retroshare-gui/src/util/misc.cpp @@ -206,6 +206,15 @@ QString misc::userFriendlyDuration(qlonglong seconds) return tr("%1y %2d", "e.g: 2 years 2days ").arg(years).arg(days); } +QString misc::timeRelativeToNow(uint32_t mtime) +{ + time_t now = time(NULL) ; + if(mtime > now) + return misc::userFriendlyDuration(mtime - (int)now) + " (ahead of now)"; + else + return misc::userFriendlyDuration(now - (int)mtime) ; +} + QString misc::userFriendlyUnit(double count, unsigned int decimal, double factor) { if (count <= 0.0) { diff --git a/retroshare-gui/src/util/misc.h b/retroshare-gui/src/util/misc.h index 0545fa187..6b68293db 100644 --- a/retroshare-gui/src/util/misc.h +++ b/retroshare-gui/src/util/misc.h @@ -152,6 +152,9 @@ class misc : public QObject // time duration like "1d 2h 10m". static QString userFriendlyDuration(qlonglong seconds); + // Computes the time shift between now and the given time, and prints it in a friendly way, accounting for possible negative shifts (time from the future!) + static QString timeRelativeToNow(uint32_t mtime); + static QString userFriendlyUnit(double count, unsigned int decimal, double factor = 1000); static QString removeNewLine(const QString &text);