diff --git a/krusader/DiskUsage/diskusage.cpp b/krusader/DiskUsage/diskusage.cpp --- a/krusader/DiskUsage/diskusage.cpp +++ b/krusader/DiskUsage/diskusage.cpp @@ -347,14 +347,14 @@ if (currentFileItem->isDir() && !currentFileItem->isSymLink()) { newItem = new Directory(currentParent, currentFileItem->getName(), dirToCheck, currentFileItem->getSize(), currentFileItem->getMode(), currentFileItem->getOwner(), currentFileItem->getGroup(), - currentFileItem->getPerm(), currentFileItem->getTime_t(), currentFileItem->isSymLink(), + currentFileItem->getPerm(), currentFileItem->getModificationTime(), currentFileItem->isSymLink(), mime); directoryStack.push((dirToCheck.isEmpty() ? "" : dirToCheck + '/') + currentFileItem->getName()); parentStack.push(dynamic_cast(newItem)); } else { newItem = new File(currentParent, currentFileItem->getName(), dirToCheck, currentFileItem->getSize(), currentFileItem->getMode(), currentFileItem->getOwner(), currentFileItem->getGroup(), - currentFileItem->getPerm(), currentFileItem->getTime_t(), currentFileItem->isSymLink(), + currentFileItem->getPerm(), currentFileItem->getModificationTime(), currentFileItem->isSymLink(), mime); currentSize += currentFileItem->getSize(); } diff --git a/krusader/FileSystem/fileitem.h b/krusader/FileSystem/fileitem.h --- a/krusader/FileSystem/fileitem.h +++ b/krusader/FileSystem/fileitem.h @@ -56,8 +56,9 @@ * @param size size of file * @param mode mode of file (file type and permissions) * @param mtime file modification time - * @param ctime file changed time + * @param ctime file change time. Use -1 if unknown. * @param atime file access time + * @param btime file creation time. Use -1 if unknown. * @param uid Unix user id of file owner. Use -1 here and provide an owner name for non-local files. * @param gid Unix group id of file group. Use -1 here and provide a group name for non-local files. * @param owner user name of file owner. Can be empty for local files @@ -70,7 +71,7 @@ */ FileItem(const QString &name, const QUrl &url, bool isDir, KIO::filesize_t size, mode_t mode, - time_t mtime, time_t ctime, time_t atime, + time_t mtime, time_t ctime, time_t atime, time_t btime, uid_t uid = -1, gid_t gid = -1, const QString &owner = QString(), const QString &group = QString(), bool isLink = false, const QString &linkDest = QString(), bool isBrokenLink = false, @@ -97,9 +98,14 @@ inline bool isBrokenLink() const { return m_isBrokenLink; } inline const QString &getSymDest() const { return m_linkDest; } inline mode_t getMode() const { return m_mode; } - inline time_t getTime_t() const { return m_mtime; } - inline time_t getChangedTime() const { return m_ctime; } + /** Return the file modification time (mtime) or -1 if unknown. */ + inline time_t getModificationTime() const { return m_mtime; } + /** Return the file change time (ctime) or -1 if unknown. */ + inline time_t getChangeTime() const { return m_ctime; } + /** Return the file access time (atime) or -1 if unknown. */ inline time_t getAccessTime() const { return m_atime; } + /** Return the file creation time (btime) or -1 if unknown. */ + inline time_t getCreationTime() const { return m_btime; } inline const QUrl &getUrl() const { return m_url; } inline const QString &getOwner() const { return m_owner; } inline const QString &getGroup() const { return m_group; } @@ -136,8 +142,9 @@ mode_t m_mode; //< file mode (file type and permissions) time_t m_mtime; //< file modification time - time_t m_ctime; //< file changed time + time_t m_ctime; //< file change time time_t m_atime; //< file access time + time_t m_btime; //< file creation time uid_t m_uid; //< file owner id gid_t m_gid; //< file group id diff --git a/krusader/FileSystem/fileitem.cpp b/krusader/FileSystem/fileitem.cpp --- a/krusader/FileSystem/fileitem.cpp +++ b/krusader/FileSystem/fileitem.cpp @@ -47,13 +47,13 @@ FileItem::FileItem(const QString &name, const QUrl &url, bool isDir, KIO::filesize_t size, mode_t mode, - time_t mtime, time_t ctime, time_t atime, + time_t mtime, time_t ctime, time_t atime, time_t btime, uid_t uid, gid_t gid, const QString &owner, const QString &group, bool isLink, const QString &linkDest, bool isBrokenLink, const QString &acl, const QString &defaultAcl) : m_name(name), m_url(url), m_isDir(isDir), m_size(size), m_mode(mode), - m_mtime(mtime), m_ctime(ctime), m_atime(atime), + m_mtime(mtime), m_ctime(ctime), m_atime(atime), m_btime(btime), m_uid(uid), m_gid(gid), m_owner(owner), m_group(group), m_isLink(isLink), m_linkDest(linkDest), m_isBrokenLink(isBrokenLink), m_acl(acl), m_defaulfAcl(defaultAcl), m_AclLoaded(false), @@ -76,32 +76,33 @@ { FileItem *file = new FileItem("..", QUrl(), true, 0, 0, - 0, 0, 0); + -1, -1, -1, -1); file->setIconName("go-up"); return file; } FileItem *FileItem::createBroken(const QString &name, const QUrl &url) { FileItem *file = new FileItem(name, url, false, - 0, 0, 0, 0, 0); + 0, 0, + -1, -1, -1, -1); file->setIconName("file-broken"); return file; } FileItem *FileItem::createVirtualDir(const QString &name, const QUrl &url) { return new FileItem(name, url, true, 0, 0700, - time(nullptr), time(nullptr), time(nullptr), + -1, -1, -1, -1, getuid(), getgid()); } FileItem *FileItem::createCopy(const FileItem &file, const QString &newName) { return new FileItem(newName, file.getUrl(), file.isDir(), file.getSize(), file.getMode(), - file.getTime_t(), file.getChangedTime(), file.getAccessTime(), + file.getModificationTime(), file.getChangeTime(), file.getAccessTime(), file.getCreationTime(), file.m_uid, file.m_gid, file.getOwner(), file.getGroup(), file.isSymLink(), file.getSymDest(), file.isBrokenLink()); } @@ -203,8 +204,10 @@ entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_NAME, getName()); entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_SIZE, getSize()); - entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_MODIFICATION_TIME, getTime_t()); - entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_CREATION_TIME, getChangedTime()); + entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_MODIFICATION_TIME, getModificationTime()); + if (m_btime != -1) { + entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_CREATION_TIME, getCreationTime()); + } entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_ACCESS_TIME, getAccessTime()); entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_USER, getOwner()); entry.UDS_ENTRY_INSERT(KIO::UDSEntry::UDS_GROUP, getGroup()); diff --git a/krusader/FileSystem/filesystem.cpp b/krusader/FileSystem/filesystem.cpp --- a/krusader/FileSystem/filesystem.cpp +++ b/krusader/FileSystem/filesystem.cpp @@ -232,10 +232,12 @@ } } + // TODO use statx available in glibc >= 2.28 supporting creation time (btime) and more + // create normal file item return new FileItem(fileItemName, fileItemUrl, isDir, size, stat_p.st_mode, - stat_p.st_mtime, stat_p.st_ctime, stat_p.st_atime, + stat_p.st_mtime, stat_p.st_ctime, stat_p.st_atime, -1, stat_p.st_uid, stat_p.st_gid, QString(), QString(), isLink, linkDestination, brokenLink); } @@ -296,17 +298,19 @@ // get file statistics... const time_t mtime = kfi.time(KFileItem::ModificationTime).toTime_t(); - const time_t ctime = kfi.time(KFileItem::CreationTime).toTime_t(); // "Creation"? its "Changed" const time_t atime = kfi.time(KFileItem::AccessTime).toTime_t(); const mode_t mode = kfi.mode() | kfi.permissions(); + const QDateTime creationTime = kfi.time(KFileItem::CreationTime); + const time_t btime = creationTime.isValid() ? creationTime.toTime_t() : (time_t) -1; + // NOTE: we could get the mimetype (and file icon) from the kfileitem here but this is very // slow. Instead, the file item class has it's own (faster) way to determine the file type. // NOTE: "broken link" flag is always false, checking link destination existence is // considered to be too expensive return new FileItem(fname, url, kfi.isDir(), kfi.size(), mode, - mtime, ctime, atime, + mtime, -1, atime, btime, (uid_t) -1, (gid_t) -1, kfi.user(), kfi.group(), kfi.isLink(), kfi.linkDest(), false, kfi.ACL().asString(), kfi.defaultACL().asString()); diff --git a/krusader/FileSystem/krquery.cpp b/krusader/FileSystem/krquery.cpp --- a/krusader/FileSystem/krquery.cpp +++ b/krusader/FileSystem/krquery.cpp @@ -308,7 +308,7 @@ if (maxSize && size > maxSize) return false; // check the time frame - time_t mtime = item->getTime_t(); + time_t mtime = item->getModificationTime(); if (olderThen && mtime > olderThen) return false; if (newerThen && mtime < newerThen) diff --git a/krusader/Panel/PanelView/krsort.cpp b/krusader/Panel/PanelView/krsort.cpp --- a/krusader/Panel/PanelView/krsort.cpp +++ b/krusader/Panel/PanelView/krsort.cpp @@ -263,9 +263,9 @@ return compareTexts(sp->name(), sp2->name(), sp->properties(), sp->isAscending(), true); return file1->getSize() < file2->getSize(); case KrViewProperties::Modified: - return compareTime(file1->getTime_t(), file2->getTime_t(), sp, sp2); + return compareTime(file1->getModificationTime(), file2->getModificationTime(), sp, sp2); case KrViewProperties::Changed: - return compareTime(file1->getChangedTime(), file2->getChangedTime(), sp, sp2); + return compareTime(file1->getChangeTime(), file2->getChangeTime(), sp, sp2); case KrViewProperties::Accessed: return compareTime(file1->getAccessTime(), file2->getAccessTime(), sp, sp2); case KrViewProperties::Type: diff --git a/krusader/Panel/PanelView/listmodel.cpp b/krusader/Panel/PanelView/listmodel.cpp --- a/krusader/Panel/PanelView/listmodel.cpp +++ b/krusader/Panel/PanelView/listmodel.cpp @@ -152,10 +152,10 @@ return mimeType.isEmpty() ? QVariant() : mimeType; } case KrViewProperties::Modified: { - return fileitem == _dummyFileItem ? QVariant() : dateText(fileitem->getTime_t()); + return fileitem == _dummyFileItem ? QVariant() : dateText(fileitem->getModificationTime()); } case KrViewProperties::Changed: { - return fileitem == _dummyFileItem ? QVariant() : dateText(fileitem->getChangedTime()); + return fileitem == _dummyFileItem ? QVariant() : dateText(fileitem->getChangeTime()); } case KrViewProperties::Accessed: { return fileitem == _dummyFileItem ? QVariant() : dateText(fileitem->getAccessTime()); @@ -508,8 +508,8 @@ text += i18n("Size: %1", size) + "
"; } text += i18nc("File property", "Type: %1", KrView::mimeTypeText(fileItem)); - text += "
" + i18nc("File property", "Modified: %1", dateText(fileItem->getTime_t())); - text += "
" + i18nc("File property", "Changed: %1", dateText(fileItem->getChangedTime())); + text += "
" + i18nc("File property", "Modified: %1", dateText(fileItem->getModificationTime())); + text += "
" + i18nc("File property", "Changed: %1", dateText(fileItem->getChangeTime())); text += "
" + i18nc("File property", "Last Access: %1", dateText(fileItem->getAccessTime())); text += "
" + i18nc("File property", "Permissions: %1", KrView::permissionsText(properties(), fileItem)); @@ -528,6 +528,10 @@ QString ListModel::dateText(time_t time) { + if (time == -1) { + // unknown time + return QString(); + } struct tm* t = localtime((time_t *) & time); const QDateTime dateTime(QDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday), diff --git a/krusader/Panel/listpanel.cpp b/krusader/Panel/listpanel.cpp --- a/krusader/Panel/listpanel.cpp +++ b/krusader/Panel/listpanel.cpp @@ -666,7 +666,7 @@ if (otherItem) { if (!func->getFileItem(item)->isDir()) isDifferent = otherPanel()->func->getFileItem(otherItem)->getSize() != func->getFileItem(item)->getSize(); - isNewer = func->getFileItem(item)->getTime_t() > otherPanel()->func->getFileItem(otherItem)->getTime_t(); + isNewer = func->getFileItem(item)->getModificationTime() > otherPanel()->func->getFileItem(otherItem)->getModificationTime(); } switch (compareMode) { diff --git a/krusader/Synchronizer/synchronizer.cpp b/krusader/Synchronizer/synchronizer.cpp --- a/krusader/Synchronizer/synchronizer.cpp +++ b/krusader/Synchronizer/synchronizer.cpp @@ -244,15 +244,15 @@ continue; if ((right_file = right_directory->search(file_name, ignoreCase)) == nullptr) - addLeftOnlyItem(parent, file_name, leftDir, left_file->getSize(), left_file->getTime_t(), + addLeftOnlyItem(parent, file_name, leftDir, left_file->getSize(), left_file->getModificationTime(), readLink(left_file), left_file->getOwner(), left_file->getGroup(), left_file->getMode(), left_file->getACL()); else { if (isDir(right_file)) continue; addDuplicateItem(parent, file_name, right_file->getName(), leftDir, rightDir, left_file->getSize(), right_file->getSize(), - left_file->getTime_t(), right_file->getTime_t(), readLink(left_file), + left_file->getModificationTime(), right_file->getModificationTime(), readLink(left_file), readLink(right_file), left_file->getOwner(), right_file->getOwner(), left_file->getGroup(), right_file->getGroup(), left_file->getMode(), right_file->getMode(), @@ -275,7 +275,7 @@ continue; if (left_directory->search(file_name, ignoreCase) == nullptr) - addRightOnlyItem(parent, file_name, rightDir, right_file->getSize(), right_file->getTime_t(), + addRightOnlyItem(parent, file_name, rightDir, right_file->getSize(), right_file->getModificationTime(), readLink(right_file), right_file->getOwner(), right_file->getGroup(), right_file->getMode(), right_file->getACL()); } @@ -298,7 +298,7 @@ if ((right_file = right_directory->search(left_file_name, ignoreCase)) == nullptr) { SynchronizerFileItem *me = addLeftOnlyItem(parent, left_file_name, leftDir, 0, - left_file->getTime_t(), readLink(left_file), + left_file->getModificationTime(), readLink(left_file), left_file->getOwner(), left_file->getGroup(), left_file->getMode(), left_file->getACL(), true, !query->match(left_file)); @@ -308,7 +308,7 @@ QString right_file_name = right_file->getName(); SynchronizerFileItem *me = addDuplicateItem(parent, left_file_name, right_file_name, leftDir, rightDir, 0, 0, - left_file->getTime_t(), right_file->getTime_t(), + left_file->getModificationTime(), right_file->getModificationTime(), readLink(left_file), readLink(right_file), left_file->getOwner(), right_file->getOwner(), left_file->getGroup(), right_file->getGroup(), @@ -339,7 +339,7 @@ if (left_directory->search(file_name, ignoreCase) == nullptr) { SynchronizerFileItem *me = addRightOnlyItem(parent, file_name, rightDir, 0, - right_file->getTime_t(), readLink(right_file), + right_file->getModificationTime(), readLink(right_file), right_file->getOwner(), right_file->getGroup(), right_file->getMode(), right_file->getACL(), true, !query->match(right_file)); @@ -533,10 +533,10 @@ continue; if (isLeft) - addLeftOnlyItem(parent, file_name, dirName, file->getSize(), file->getTime_t(), readLink(file), + addLeftOnlyItem(parent, file_name, dirName, file->getSize(), file->getModificationTime(), readLink(file), file->getOwner(), file->getGroup(), file->getMode(), file->getACL()); else - addRightOnlyItem(parent, file_name, dirName, file->getSize(), file->getTime_t(), readLink(file), + addRightOnlyItem(parent, file_name, dirName, file->getSize(), file->getModificationTime(), readLink(file), file->getOwner(), file->getGroup(), file->getMode(), file->getACL()); } @@ -554,11 +554,11 @@ SynchronizerFileItem *me; if (isLeft) - me = addLeftOnlyItem(parent, file_name, dirName, 0, file->getTime_t(), readLink(file), + me = addLeftOnlyItem(parent, file_name, dirName, 0, file->getModificationTime(), readLink(file), file->getOwner(), file->getGroup(), file->getMode(), file->getACL(), true, !query->match(file)); else - me = addRightOnlyItem(parent, file_name, dirName, 0, file->getTime_t(), readLink(file), + me = addRightOnlyItem(parent, file_name, dirName, 0, file->getModificationTime(), readLink(file), file->getOwner(), file->getGroup(), file->getMode(), file->getACL(), true, !query->match(file)); stack.append(new CompareTask(me, url + file_name + '/',