2 * Copyright (c) 2007 Jeff Mitchell <kde-dev@emailgoeshere.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "pmpbackend.h"
20 #include "pmpdevice.h"
21 #include "pmpkioslave.h"
23 #include <QCoreApplication>
27 #include <kapplication.h>
28 #include <kcomponentdata.h>
30 #include <kdirnotify.h>
31 #include <kio/ioslave_defaults.h>
33 #include <solid/device.h>
34 #include <solid/deviceinterface.h>
35 #include <solid/genericinterface.h>
36 #include <solid/portablemediaplayer.h>
40 extern "C" int KDE_EXPORT
kdemain( int argc
, char **argv
)
42 QCoreApplication
app( argc
, argv
);
43 KComponentData( "kio_pmp", "kdelibs4" );
44 (void) KGlobal::locale();
46 fprintf(stderr
, "ENTERED kdemain of pmp slave\n" );
50 fprintf(stderr
, "Usage: kio_pmp protocol domain-socket1 domain-socket2\n" );
54 PMPProtocol
slave( argv
[1], argv
[2], argv
[3] );
59 PMPProtocol::PMPProtocol( const QByteArray
&protocol
, const QByteArray
&pool
,
60 const QByteArray
&app
)
61 : SlaveBase( protocol
, pool
, app
)
63 , m_mtpInitialized( false )
67 PMPProtocol::~PMPProtocol()
69 foreach( QString udi
, m_devices
.keys() )
70 delete m_devices
[udi
];
74 PMPProtocol::setHost( const QString
&host
, quint16 port
,
75 const QString
&user
, const QString
&pass
)
82 error( KIO::ERR_CANNOT_OPEN_FOR_READING
,
83 i18n("portable media player : Setting a hostname is not supported. \
84 Use a URL of the form pmp:/<udi> or pmp:///<udi>" ) );
89 PMPProtocol::del( const KUrl
&url
, bool isfile
)
91 kDebug() << endl
<< endl
<< "Entering del with url = " << url
<< endl
<< endl
;
92 if( getBackendForUrl( url
) )
93 getBackendForUrl( url
)->del( url
, isfile
);
96 kDebug() << endl
<< endl
<< "Leaving del with url = " << url
<< endl
<< endl
;
100 PMPProtocol::get( const KUrl
&url
)
102 kDebug() << endl
<< endl
<< "Entering get with url = " << url
<< endl
<< endl
;
103 if( getBackendForUrl( url
) )
104 getBackendForUrl( url
)->get( url
);
107 kDebug() << endl
<< endl
<< "Leaving get with url = " << url
<< endl
<< endl
;
111 PMPProtocol::listDir( const KUrl
&url
)
113 kDebug() << endl
<< endl
<< "Entering listDir with url = " << url
<< endl
;
114 kDebug() << "path = " << url
.path() << ", path.isEmpty = " << (url
.path().isEmpty() ? "true" : "false" ) << endl
;
117 listEntry( UDSEntry(), true );
121 if( url
.path().isEmpty() || url
.path() == "/" )
123 QList
<Solid::Device
> deviceList
= Solid::Device::listFromQuery( "is PortableMediaPlayer" );
124 foreach( Solid::Device device
, deviceList
)
127 if( !m_devices
.contains( transUdi( device
.udi() ) ) )
129 m_devices
[transUdi( device
.udi() )] = new PMPDevice( this, device
);
130 m_devices
[transUdi( device
.udi() )]->initialize();
132 QString name
= m_devices
[transUdi( device
.udi() )]->backend()->getFriendlyName();
133 kDebug() << "Friendly name returned from device is: " << name
<< endl
;
136 name
= m_devices
[transUdi( device
.udi() )]->backend()->getModelName();
137 kDebug() << "Model name returned from device is: " << name
<< endl
;
141 name
= getSolidFriendlyName( device
);
142 kDebug() << "Friendly name returned from Solid is: " << name
<< endl
;
144 entry
.insert( KIO::UDSEntry::UDS_NAME
, name
.isEmpty() ? QString( "Portable Media Player at " + device
.udi() ) : name
);
145 entry
.insert( KIO::UDSEntry::UDS_URL
,"pmp:///" + transUdi( device
.udi() ) );
146 entry
.insert( KIO::UDSEntry::UDS_FILE_TYPE
, S_IFDIR
);
147 entry
.insert( KIO::UDSEntry::UDS_HIDDEN
, 0 );
148 listEntry( entry
, false );
150 listEntry( UDSEntry(), true );
156 if( getBackendForUrl( url
) )
157 getBackendForUrl( url
)->listDir( url
);
161 kDebug() << endl
<< endl
<< "Leaving listDir with url = " << url
<< endl
<< endl
;
165 PMPProtocol::rename( const KUrl
&src
, const KUrl
&dest
, bool overwrite
)
167 kDebug() << "srcUrl = " << src
.url() << ", destUrl = " << dest
.url() << endl
;
168 QString srcPath
= src
.path( KUrl::RemoveTrailingSlash
);
169 QString destPath
= dest
.path( KUrl::RemoveTrailingSlash
);
170 while( srcPath
[0] == '/' )
171 srcPath
.remove( 0, 1 );
172 while( destPath
[0] == '/' )
173 destPath
.remove( 0, 1 );
174 //Check to see if they're trying to set a friendly name
175 //i.e. only top-level paths
176 kDebug() << endl
<< "srcPath = " << srcPath
<< ", destPath = " << destPath
<< endl
;
177 kDebug() << endl
<< "src.directory() = " << src
.directory() << ", dest.directory() = " << dest
.directory() << endl
;
178 if( srcPath
.indexOf( '/' ) == -1 && destPath
.indexOf( '/' ) == -1 )
180 QString srcName
= udiFromUrl( src
);
181 QString dstName
= udiFromUrl( dest
);
182 kDebug() << "srcName = " << srcName
<< ", dstName (friendly name) = " << dstName
<< endl
;
183 kDebug() << "m_devices keys: " << endl
;
184 foreach( QString key
, m_devices
.keys() )
185 kDebug() << "key = " << key
<< endl
;
186 if( m_devices
.contains( dstName
) )
187 warning( i18n( "Destination name cannot be the same as a Solid UDI!" ) );
188 else if ( getBackendForUrl( src
) )
190 getBackendForUrl( src
)->setFriendlyName( dstName
);
193 org::kde::KDirNotify::emitFilesAdded( "pmp:///" );
194 //Why doesn't this work...
195 //QTimer::singleShot( 500, this, SLOT( refreshRootDir() ) );
198 if( udiFromUrl( src
) != udiFromUrl( dest
) )
200 //this shouldn't ever happen...
201 warning( i18n( "Could not rename file, files cannot be renamed across devices!" ) );
205 if( getBackendForUrl( src
) )
206 getBackendForUrl( src
)->rename( src
, dest
, overwrite
);
212 PMPProtocol::stat( const KUrl
&url
)
214 kDebug() << endl
<< endl
<< "Entering stat with url = " << url
<< endl
<< endl
;
215 if( url
.path().isEmpty() || url
.path() == "/" )
218 entry
.insert( KIO::UDSEntry::UDS_NAME
, "Available Devices" );
219 entry
.insert( KIO::UDSEntry::UDS_FILE_TYPE
, S_IFDIR
);
220 entry
.insert( KIO::UDSEntry::UDS_ACCESS
, S_IRUSR
| S_IRGRP
| S_IROTH
);
225 else if( getBackendForUrl( url
) )
226 getBackendForUrl( url
)->stat( url
);
229 kDebug() << endl
<< endl
<< "Leaving stat with url = " << url
<< endl
<< endl
;
233 PMPProtocol::getSolidFriendlyName( const Solid::Device
& device
) const
235 kDebug() << "Looking for a friendly name for " << device
.udi() << "..." << endl
;
236 //NOTE/TODO: The following is hal-dependent.
237 const Solid::GenericInterface
*gi
= device
.as
<Solid::GenericInterface
>();
240 kDebug() << "Couldn't get the device as a generic interface." << endl
;
243 if( !gi
->propertyExists( "portable_audio_player.access_method.drivers" ) )
245 kDebug() << "No access_method.drivers property detected." << endl
;
248 QVariant possibleLibraries
= gi
->property( "portable_audio_player.access_method.drivers" );
249 if( !possibleLibraries
.isValid() || possibleLibraries
.isNull() || !possibleLibraries
.canConvert( QVariant::StringList
) )
251 QStringList libraries
= possibleLibraries
.toStringList();
252 foreach( QString library
, libraries
)
254 QVariant possibleName
= gi
->property( "portable_audio_player." + library
+ ".name" );
255 if( possibleName
.isValid() && !possibleName
.isNull() && possibleName
.canConvert( QVariant::String
) )
257 QString name
= possibleName
.toString();
258 if( !name
.isEmpty() )
266 PMPProtocol::udiFromUrl( const KUrl
&url
)
270 error( KIO::ERR_CANNOT_OPEN_FOR_READING
, i18n( "portable media player : Empty UDI passed in" ) );
271 return QString::null
;
274 QString path
= url
.path( KUrl::RemoveTrailingSlash
);
275 while( path
[0] == '/' )
278 int index
= path
.indexOf( '/' );
279 //if not found, use the path as is; if it is truncate so we only get the udi
280 QString udi
= ( index
== -1 ? path
: path
.left( index
) );
281 //translate the udi to its required format
282 udi
= transUdi( udi
);
288 PMPProtocol::getBackendForUrl( const KUrl
&url
)
290 if( !m_devices
.contains( udiFromUrl( url
) ) )
292 m_devices
[udiFromUrl( url
)] = new PMPDevice( this, Solid::Device( untransUdi( udiFromUrl( url
) ) ) );
293 if( m_devices
[udiFromUrl( url
)]->isValid() )
294 m_devices
[udiFromUrl( url
)]->initialize();
297 delete m_devices
[udiFromUrl( url
)];
298 m_devices
.remove( udiFromUrl( url
) );
302 return m_devices
[udiFromUrl( url
)]->backend();
305 #include "pmpkioslave.moc"