File indexing completed on 2024-05-05 16:13:54
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2004 David Faure <faure@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef TRASHIMPL_H 0009 #define TRASHIMPL_H 0010 0011 #include <kio/job.h> 0012 0013 #include <KConfig> 0014 0015 #include <QDateTime> 0016 #include <QMap> 0017 0018 namespace Solid 0019 { 0020 class Device; 0021 } 0022 0023 /** 0024 * Implementation of all low-level operations done by kio_trash. 0025 * The structure of the trash directory follows the freedesktop.org standard: 0026 * https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html 0027 */ 0028 class TrashImpl : public QObject 0029 { 0030 Q_OBJECT 0031 public: 0032 TrashImpl(); 0033 0034 /// Check the "home" trash directory 0035 /// This MUST be called before doing anything else 0036 bool init(); 0037 0038 /// Create info for a file to be trashed 0039 /// Returns trashId and fileId 0040 /// The caller is then responsible for actually trashing the file 0041 bool createInfo(const QString &origPath, int &trashId, QString &fileId); 0042 0043 /// Delete info file for a file to be trashed 0044 /// Usually used for undoing what createInfo did if trashing failed 0045 bool deleteInfo(int trashId, const QString &fileId); 0046 0047 /// Moving a file or directory into the trash. The ids come from createInfo. 0048 bool moveToTrash(const QString &origPath, int trashId, const QString &fileId); 0049 0050 /// Moving a file or directory out of the trash. The ids come from createInfo. 0051 bool moveFromTrash(const QString &origPath, int trashId, const QString &fileId, const QString &relativePath); 0052 0053 /// Copying a file or directory into the trash. The ids come from createInfo. 0054 bool copyToTrash(const QString &origPath, int trashId, const QString &fileId); 0055 0056 /// Copying a file or directory out of the trash. The ids come from createInfo. 0057 bool copyFromTrash(const QString &origPath, int trashId, const QString &fileId, const QString &relativePath); 0058 0059 /// Renaming a file or directory in the trash. 0060 bool moveInTrash(int trashId, const QString &oldFileId, const QString &newFileId); 0061 0062 /// Get rid of a trashed file 0063 bool del(int trashId, const QString &fileId); 0064 0065 /// Empty trash, i.e. delete all trashed files 0066 bool emptyTrash(); 0067 0068 /// Return true if the trash is empty 0069 bool isEmpty() const; 0070 0071 struct TrashedFileInfo { 0072 int trashId; // for the url 0073 QString fileId; // for the url 0074 QString physicalPath; // for stat'ing etc. 0075 QString origPath; // from info file 0076 QDateTime deletionDate; // from info file 0077 }; 0078 /// List trashed files 0079 using TrashedFileInfoList = QList<TrashedFileInfo>; 0080 0081 /// Returns the TrashedFileInfo of all files in all trashes 0082 /// uses scanTrashDirectories() to refresh m_trashDirectories 0083 TrashedFileInfoList list(); 0084 0085 /// Return the info for a given trashed file 0086 bool infoForFile(int trashId, const QString &fileId, TrashedFileInfo &info); 0087 0088 struct TrashSpaceInfo { 0089 qint64 totalSize; // total trash size in bytes 0090 qint64 availableSize; // available trash space in bytes 0091 }; 0092 /// Get the space info for a given trash path 0093 /// Space information is only valid if trashSpaceInfo returns true 0094 bool trashSpaceInfo(const QString &path, TrashSpaceInfo &info); 0095 0096 /// Returns an UDSEntry corresponding to trash:/ 0097 KIO::UDSEntry trashUDSEntry(KIO::StatDetails details); 0098 0099 /// Return the physicalPath for a given trashed file - helper method which 0100 /// encapsulates the call to infoForFile. Don't use if you need more info from TrashedFileInfo. 0101 QString physicalPath(int trashId, const QString &fileId, const QString &relativePath); 0102 0103 /// Move data from the old trash system to the new one 0104 void migrateOldTrash(); 0105 0106 /// KIO error code 0107 int lastErrorCode() const 0108 { 0109 return m_lastErrorCode; 0110 } 0111 QString lastErrorMessage() const 0112 { 0113 return m_lastErrorMessage; 0114 } 0115 0116 QStringList listDir(const QString &physicalPath); 0117 0118 static QUrl makeURL(int trashId, const QString &fileId, const QString &relativePath); 0119 static bool parseURL(const QUrl &url, int &trashId, QString &fileId, QString &relativePath); 0120 0121 using TrashDirMap = QMap<int, QString>; 0122 /// @internal This method is for TestTrash only. Home trash is included (id 0). 0123 TrashDirMap trashDirectories() const; 0124 /// @internal This method is for TestTrash only. No entry with id 0. 0125 TrashDirMap topDirectories() const; 0126 0127 Q_SIGNALS: 0128 void leaveModality(); 0129 0130 private: 0131 /// Helper method. Moves a file or directory using the appropriate method. 0132 bool move(const QString &src, const QString &dest); 0133 bool copy(const QString &src, const QString &dest); 0134 /// Helper method. Tries to call ::rename(src,dest) and does error handling. 0135 bool directRename(const QString &src, const QString &dest); 0136 0137 void fileAdded(); 0138 void fileRemoved(); 0139 0140 bool adaptTrashSize(const QString &origPath, int trashId); 0141 0142 // Warning, returns error code, not a bool 0143 int testDir(const QString &name) const; 0144 void error(int e, const QString &s); 0145 0146 bool readInfoFile(const QString &infoPath, TrashedFileInfo &info, int trashId); 0147 0148 QString infoPath(int trashId, const QString &fileId) const; 0149 QString filesPath(int trashId, const QString &fileId) const; 0150 0151 #ifdef Q_OS_OSX 0152 int idForMountPoint(const QString &mountPoint) const; 0153 #else 0154 int idForDevice(const Solid::Device &device) const; 0155 #endif 0156 void refreshDevices() const; 0157 0158 /// Find the trash dir to use for a given file to delete, based on original path 0159 int findTrashDirectory(const QString &origPath); 0160 0161 QString trashDirectoryPath(int trashId) const; 0162 QString topDirectoryPath(int trashId) const; 0163 0164 bool synchronousDel(const QString &path, bool setLastErrorCode, bool isDir); 0165 0166 void scanTrashDirectories() const; 0167 0168 int idForTrashDirectory(const QString &trashDir) const; 0169 bool initTrashDirectory(const QByteArray &trashDir_c) const; 0170 bool checkTrashSubdirs(const QByteArray &trashDir_c) const; 0171 QString trashForMountPoint(const QString &topdir, bool createIfNeeded) const; 0172 static QString makeRelativePath(const QString &topdir, const QString &path); 0173 0174 void enterLoop(); 0175 0176 private Q_SLOTS: 0177 void jobFinished(KJob *job); 0178 0179 private: 0180 // delete the files and info subdirectories from all known trash directories 0181 // (supposed to be empty!) to make sure OS X sees the trash as empty too. 0182 // Stub except on OS X. 0183 void deleteEmptyTrashInfrastructure(); 0184 // create the trash infrastructure; also called 0185 // to recreate it on OS X. 0186 bool createTrashInfrastructure(int trashId, const QString &path = QString()); 0187 0188 // Inserts a newly found @p trashDir, under @p topdir with @p id 0189 void insertTrashDir(int id, const QString &trashDir, const QString &topdir) const; 0190 0191 /// Last error code stored in class to simplify API. 0192 /// Note that this means almost no method can be const. 0193 int m_lastErrorCode; 0194 QString m_lastErrorMessage; 0195 0196 enum { InitToBeDone, InitOK, InitError } m_initStatus; 0197 0198 // A "trash directory" is a physical directory on disk, 0199 // e.g. $HOME/.local/share/Trash or /mnt/foo/.Trash-$uid 0200 // It has an id (int) and a path. 0201 // The home trash has id 0. 0202 mutable TrashDirMap m_trashDirectories; // id -> path of trash directory 0203 mutable TrashDirMap m_topDirectories; // id -> $topdir of partition 0204 dev_t m_homeDevice; 0205 mutable bool m_trashDirectoriesScanned; 0206 0207 mutable KConfig m_config; 0208 0209 // We don't cache any data related to the trashed files. 0210 // Another KIO worker could change that behind our feet. 0211 // If we want to start caching data - and avoiding some race conditions -, 0212 // we should turn this class into a kded module and use DCOP to talk to it 0213 // from the KIO worker. 0214 }; 0215 0216 #endif