summaryrefslogtreecommitdiffstats
path: root/amarok/src/mountpointmanager.h
blob: c4d90ccdfa12d489457f292076c67eca6e066a35 (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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*
 *  Copyright (c) 2006-2007 Maximilian Kossick <maximilian.kossick@googlemail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
#ifndef AMAROK_MOUNTPOINTMANAGER_H
#define AMAROK_MOUNTPOINTMANAGER_H

#include "amarok.h"
#include "amarok_export.h"
#include "collectiondb.h"
#include "medium.h"
#include "plugin/plugin.h"
#include "pluginmanager.h"
#include "threadmanager.h"

#include <tdeconfig.h>
#include <kurl.h>

#include <tqmap.h>
#include <tqmutex.h>
#include <tqptrlist.h>
#include <tqstringlist.h>
#include <tqvaluelist.h>

class DeviceHandler;
class DeviceHandlerFactory;

typedef TQValueList<int> IdList;
typedef TQPtrList<DeviceHandlerFactory> FactoryList;
typedef TQMap<int, DeviceHandler*> HandlerMap;


class LIBAMAROK_EXPORT DeviceHandlerFactory : public Amarok::Plugin
{
public:
    DeviceHandlerFactory() {};
    virtual ~DeviceHandlerFactory() {};

    /**
     * checks whether a DeviceHandler subclass can handle a given Medium.
     * @param m the connected medium
     * @return true if the DeviceHandler implementation can handle the medium,
     * false otherwise
     */
    virtual bool canHandle( const Medium* m ) const = 0;

    /**
     * tells the MountPointManager whether it makes sense to ask the factory to
     * create a Devicehandler when a new Medium was connected
     * @return true if the factory can create DeviceHandlers from Medium instances
     */
    virtual bool canCreateFromMedium() const = 0;

    /**
     * creates a DeviceHandler which represents the Medium.
     * @param c the Medium for which a DeviceHandler is required
     * @return a DeviceHandler or 0 if the factory cannot handle the Medium
     */
    virtual DeviceHandler* createHandler( const Medium* m ) const = 0;

    virtual bool canCreateFromConfig() const = 0;

    virtual DeviceHandler* createHandler( const TDEConfig* c ) const = 0;

    /**
     * returns the type of the DeviceHandler. Should be the same as the value used in
     * ~/.trinity/share/config/amarokrc
     * @return a TQString describing the type of the DeviceHandler
     */
    virtual TQString type() const = 0;

};

/**
 *
 *
 */
class DeviceHandler
{
public:
    DeviceHandler() {};
    virtual ~DeviceHandler() {};


    virtual bool isAvailable() const = 0;

    /**
     * returns the type of the DeviceHandler. Should be the same as the value used in
     * ~/.trinity/share/config/amarokrc
     * @return a TQString describing the type of the DeviceHandler
     */
    virtual TQString type() const = 0;

    /**
     * returns an absolute path which is guaranteed to be playable by amarok's current engine. (based on an
     * idea by andrewt512: this method would only be called when we actually want to play the file, not when we
     * simply want to show it to the user. It could for example download a file using TDEIO and return a path to a
     * temporary file. Needs some more thought and is not actually used at the moment.
     * @param absolutePath
     * @param relativePath
     */
    virtual void getPlayableURL( KURL &absolutePath, const KURL &relativePath ) = 0;

    /**
     * builds an absolute path from a relative path and DeviceHandler specific information. The absolute path
     * is not necessarily playable! (based on an idea by andrewt512: allows better handling of files stored in remote  * collections. this method would return a "pretty" URL which might not be playable by amarok's engines.
     * @param absolutePath the not necessarily playbale absolute path
     * @param relativePath the device specific relative path
     */
    virtual void getURL( KURL &absolutePath, const KURL &relativePath ) = 0;

    /**
     * retrieves the unique database id of a given Medium. Implementations are responsible
     * for generating a (sufficiently) unique value which identifies the Medium.
     * Additionally, implementations must recognize unknown mediums and store the necessary
     * information to recognize them the next time they are connected in the database.
     * @return unique identifier which can be used as a foreign key to the media table.
     */
    virtual int getDeviceID() = 0;

    virtual const TQString &getDevicePath() const = 0;

    /**
     * allows MountPointManager to check if a device handler handles a specific medium.
     * @param m
     * @return true if the device handler handles the Medium m
     */
    virtual bool deviceIsMedium( const Medium *m ) const = 0;
};

/**
 *	@author Maximilian Kossick <maximilian.kossick@googlemail.com>
 */
class MountPointManager : public TQObject {
Q_OBJECT
  

signals:
    void mediumConnected( int deviceid );
    void mediumRemoved( int deviceid );

public:
    //the methods of this class a called *very* often. make sure they are as fast as possible
    // (inline them?)

    /**
     * factory method.
     * @return a MountPointManager instance
     */
    static MountPointManager *instance();

    /**
     *
     * @param url
     * @return
     */
    int getIdForUrl( KURL url );
    int getIdForUrl( const TQString &url );
    /**
     *
     * @param id
     * @return
     */
    TQString getMountPointForId( const int id ) const;
    /**
     * builds the absolute path from the mount point of the medium and the given relative
     * path.
     * @param deviceId the medium(device)'s unique id
     * @param relativePath relative path on the medium
     * @return the absolute path
     */
    void getAbsolutePath( const int deviceId, const KURL& relativePath, KURL& absolutePath ) const;
    TQString getAbsolutePath ( const int deviceId, const TQString& relativePath ) const;
    /**
     * calculates a file's/directory's relative path on a given device.
     * @param deviceId the unique id which identifies the device the file/directory is supposed to be on
     * @param absolutePath the file's/directory's absolute path
     * @param relativePath the calculated relative path
     */
    void getRelativePath( const int deviceId, const KURL& absolutePath, KURL& relativePath ) const;
    TQString getRelativePath( const int deviceId, const TQString& absolutePath ) const;
    /**
     * allows calling code to access the ids of all active devices
     * @return the ids of all devices which are currently mounted or otherwise accessible
     */
    IdList getMountedDeviceIds() const;

    TQStringList collectionFolders();
    void setCollectionFolders( const TQStringList &folders );

public slots:
    void mediumAdded( const Medium *m );
    /**
     * initiates the update of the class' internal list of mounted mediums.
     * @param m the medium whose status changed
     */
    void mediumChanged( const Medium* m );
    void mediumRemoved( const Medium* m );

    void updateStatisticsURLs( bool changed = true );

private slots:
    void migrateStatistics();
    void checkDeviceAvailability();
    void startStatisticsUpdateJob();

private:
    MountPointManager();

    ~MountPointManager();

    /**
     * checks whether a medium identified by its unique database id is currently mounted.
     * Note: does not handle deviceId = -1! It only checks real devices
     * @param deviceId the mediums unique id
     * @return true if the medium is mounted, false otherwise
     */
    bool isMounted ( const int deviceId ) const;
    void init();
    void handleMissingMediaManager();
    /**
     * maps a device id to a mount point. does only work for mountable filesystems and needs to be
     * changed for the real Dynamic Collection implementation.
     */
    HandlerMap m_handlerMap;
    mutable TQMutex m_handlerMapMutex;
    FactoryList m_mediumFactories;
    FactoryList m_remoteFactories;
    bool m_noDeviceManager;

};

class UrlUpdateJob : public ThreadManager::DependentJob
{
public:
    UrlUpdateJob( TQObject *dependent ) : DependentJob( dependent, "UrlUpdateJob" ) {}

    virtual bool doJob();

    virtual void completeJob() {}

private:
    void updateStatistics();
    void updateLabels();
};

#endif