/* This file is part of the KDE project Copyright (C) 2004 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef TRASHIMPL_H #define TRASHIMPL_H #include #include #include #include #include #include #include #include /** * Implementation of all low-level operations done by kio_trash * The structure of the trash directory follows the freedesktop.org standard */ class TrashImpl : public QObject { Q_OBJECT public: TrashImpl(); /// Check the "home" trash directory /// This MUST be called before doing anything else bool init(); /// Create info for a file to be trashed /// Returns trashId and fileId /// The caller is then responsible for actually trashing the file bool createInfo( const TQString& origPath, int& trashId, TQString& fileId ); /// Delete info file for a file to be trashed /// Usually used for undoing what createInfo did if trashing failed bool deleteInfo( int trashId, const TQString& fileId ); /// Moving a file or directory into the trash. The ids come from createInfo. bool moveToTrash( const TQString& origPath, int trashId, const TQString& fileId ); /// Moving a file or directory out of the trash. The ids come from createInfo. bool moveFromTrash( const TQString& origPath, int trashId, const TQString& fileId, const TQString& relativePath ); /// Copying a file or directory into the trash. The ids come from createInfo. bool copyToTrash( const TQString& origPath, int trashId, const TQString& fileId ); /// Copying a file or directory out of the trash. The ids come from createInfo. bool copyFromTrash( const TQString& origPath, int trashId, const TQString& fileId, const TQString& relativePath ); /// Create a top-level trashed directory //bool mkdir( int trashId, const TQString& fileId, int permissions ); /// Get rid of a trashed file bool del( int trashId, const TQString& fileId ); /// Empty trash, i.e. delete all trashed files bool emptyTrash(); /// Return true if the trash is empty bool isEmpty() const; struct TrashedFileInfo { int trashId; // for the url TQString fileId; // for the url TQString physicalPath; // for stat'ing etc. TQString origPath; // from info file TQDateTime deletionDate; // from info file }; /// List trashed files typedef TQValueList TrashedFileInfoList; TrashedFileInfoList list(); /// Return the info for a given trashed file bool infoForFile( int trashId, const TQString& fileId, TrashedFileInfo& info ); /// Return the physicalPath for a given trashed file - helper method which /// encapsulates the call to infoForFile. Don't use if you need more info from TrashedFileInfo. TQString physicalPath( int trashId, const TQString& fileId, const TQString& relativePath ); /// Move data from the old trash system to the new one void migrateOldTrash(); /// KIO error code int lastErrorCode() const { return m_lastErrorCode; } TQString lastErrorMessage() const { return m_lastErrorMessage; } TQStrList listDir( const TQString& physicalPath ); static KURL makeURL( int trashId, const TQString& fileId, const TQString& relativePath ); static bool parseURL( const KURL& url, int& trashId, TQString& fileId, TQString& relativePath ); typedef TQMap TrashDirMap; /// @internal This method is for TestTrash only. Home trash is included (id 0). TrashDirMap trashDirectories() const; /// @internal This method is for TestTrash only. No entry with id 0. TrashDirMap topDirectories() const; private: /// Helper method. Moves a file or directory using the appropriate method. bool move( const TQString& src, const TQString& dest ); bool copy( const TQString& src, const TQString& dest ); /// Helper method. Tries to call ::rename(src,dest) and does error handling. bool directRename( const TQString& src, const TQString& dest ); void fileAdded(); void fileRemoved(); // Warning, returns error code, not a bool int testDir( const TQString& name ) const; void error( int e, const TQString& s ); bool readInfoFile( const TQString& infoPath, TrashedFileInfo& info, int trashId ); TQString infoPath( int trashId, const TQString& fileId ) const; TQString filesPath( int trashId, const TQString& fileId ) const; /// Find the trash dir to use for a given file to delete, based on original path int findTrashDirectory( const TQString& origPath ); TQString trashDirectoryPath( int trashId ) const; TQString topDirectoryPath( int trashId ) const; bool synchronousDel( const TQString& path, bool setLastErrorCode, bool isDir ); void scanTrashDirectories() const; int idForTrashDirectory( const TQString& trashDir ) const; bool initTrashDirectory( const TQCString& trashDir_c ) const; bool checkTrashSubdirs( const TQCString& trashDir_c ) const; TQString trashForMountPoint( const TQString& topdir, bool createIfNeeded ) const; static TQString makeRelativePath( const TQString& topdir, const TQString& path ); private slots: void jobFinished(KIO::Job *job); private: /// Last error code stored in class to simplify API. /// Note that this means almost no method can be const. int m_lastErrorCode; TQString m_lastErrorMessage; enum { InitToBeDone, InitOK, InitError } m_inittqStatus; // A "trash directory" is a physical directory on disk, // e.g. $HOME/.local/share/Trash/$uid or /mnt/foo/.Trash/$uid // It has an id (number) and a path. // The home trash has id 0. mutable TrashDirMap m_trashDirectories; // id -> path of trash directory mutable TrashDirMap m_topDirectories; // id -> $topdir of partition mutable int m_lastId; dev_t m_homeDevice; mutable bool m_trashDirectoriesScanned; int m_mibEnum; KSimpleConfig m_config; // We don't cache any data related to the trashed files. // Another kioslave could change that behind our feet. // If we want to start caching data - and avoiding some race conditions -, // we should turn this class into a kded module and use DCOP to talk to it // from the kioslave. }; #endif