summaryrefslogtreecommitdiffstats
path: root/kioslave/trash/trashimpl.h
blob: 1a00e14bd2c64c4f92b9d2cb2108796e4e7b7d44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* This file is part of the KDE project
   Copyright (C) 2004 David Faure <faure@kde.org>

   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 <kio/jobclasses.h>
#include <ksimpleconfig.h>

#include <tqstring.h>
#include <tqdatetime.h>
#include <tqmap.h>
#include <tqvaluelist.h>
#include <tqstrlist.h>
#include <assert.h>

/**
 * Implementation of all low-level operations done by kio_trash
 * The structure of the trash directory follows the freedesktop.org standard <TODO URL>
 */
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<TrashedFileInfo> 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<int, TQString> 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