kde-workspace/kioslave/mtp/kio_mtp_helpers.cpp
2014-11-19 01:03:24 +00:00

435 lines
14 KiB
C++

/*
* Helper implementations for KIO-MTP
* Copyright (C) 2013 Philipp Schmidt <philschmidt@gmx.net>
*
* 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.
*/
#include "kio_mtp_helpers.h"
int dataProgress ( uint64_t const sent, uint64_t const, void const *const priv )
{
( ( MTPSlave* ) priv )->processedSize ( sent );
return 0;
}
/**
* MTPDataPutFunc callback function, "puts" data from the device somewhere else
*/
uint16_t dataPut ( void*, void *priv, uint32_t sendlen, unsigned char *data, uint32_t *putlen )
{
kDebug(KIO_MTP) << "transferring" << sendlen << "bytes to data()";
( ( MTPSlave* ) priv )->data ( QByteArray ( ( char* ) data, ( int ) sendlen ) );
*putlen = sendlen;
return LIBMTP_HANDLER_RETURN_OK;
}
/**
* MTPDataGetFunc callback function, "gets" data and puts it on the device
*/
uint16_t dataGet ( void*, void *priv, uint32_t, unsigned char *data, uint32_t *gotlen )
{
( ( MTPSlave* ) priv )->dataReq();
QByteArray buffer;
*gotlen = ( ( MTPSlave* ) priv )->readData ( buffer );
kDebug(KIO_MTP) << "transferring" << *gotlen << "bytes to data()";
data = ( unsigned char* ) buffer.data();
return LIBMTP_HANDLER_RETURN_OK;
}
QString convertToPath( const QStringList& pathItems, const int elements )
{
QString path;
for ( int i = 0; i < elements && elements <= pathItems.size(); i++ )
{
path.append( QLatin1Char ('/') );
path.append( pathItems.at(i) );
}
return path;
}
QString getMimetype ( LIBMTP_filetype_t filetype )
{
switch ( filetype )
{
case LIBMTP_FILETYPE_FOLDER:
return QLatin1String ( "inode/directory" );
case LIBMTP_FILETYPE_WAV:
return QLatin1String ( "audio/wav" );
case LIBMTP_FILETYPE_MP3:
return QLatin1String ( "audio/x-mp3" );
case LIBMTP_FILETYPE_WMA:
return QLatin1String ( "audio/x-ms-wma" );
case LIBMTP_FILETYPE_OGG:
return QLatin1String ( "audio/x-vorbis+ogg" );
case LIBMTP_FILETYPE_AUDIBLE:
return QLatin1String ( "" );
case LIBMTP_FILETYPE_MP4:
return QLatin1String ( "audio/mp4" );
case LIBMTP_FILETYPE_UNDEF_AUDIO:
return QLatin1String ( "" );
case LIBMTP_FILETYPE_WMV:
return QLatin1String ( "video/x-ms-wmv" );
case LIBMTP_FILETYPE_AVI:
return QLatin1String ( "video/x-msvideo" );
case LIBMTP_FILETYPE_MPEG:
return QLatin1String ( "video/mpeg" );
case LIBMTP_FILETYPE_ASF:
return QLatin1String ( "video/x-ms-asf" );
case LIBMTP_FILETYPE_QT:
return QLatin1String ( "video/quicktime" );
case LIBMTP_FILETYPE_UNDEF_VIDEO:
return QLatin1String ( "" );
case LIBMTP_FILETYPE_JPEG:
return QLatin1String ( "image/jpeg" );
case LIBMTP_FILETYPE_JFIF:
return QLatin1String ( "" );
case LIBMTP_FILETYPE_TIFF:
return QLatin1String ( "image/tiff" );
case LIBMTP_FILETYPE_BMP:
return QLatin1String ( "image/bmp" );
case LIBMTP_FILETYPE_GIF:
return QLatin1String ( "image/gif" );
case LIBMTP_FILETYPE_PICT:
return QLatin1String ( "image/x-pict" );
case LIBMTP_FILETYPE_PNG:
return QLatin1String ( "image/png" );
case LIBMTP_FILETYPE_VCALENDAR1:
return QLatin1String ( "text/x-vcalendar" );
case LIBMTP_FILETYPE_VCALENDAR2:
return QLatin1String ( "text/x-vcalendar" );
case LIBMTP_FILETYPE_VCARD2:
return QLatin1String ( "text/x-vcard" );
case LIBMTP_FILETYPE_VCARD3:
return QLatin1String ( "text/x-vcard" );
case LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT:
return QLatin1String ( "image/x-wmf" );
case LIBMTP_FILETYPE_WINEXEC:
return QLatin1String ( "application/x-ms-dos-executable" );
case LIBMTP_FILETYPE_TEXT:
return QLatin1String ( "text/plain" );
case LIBMTP_FILETYPE_HTML:
return QLatin1String ( "text/html" );
case LIBMTP_FILETYPE_FIRMWARE:
return QLatin1String ( "" );
case LIBMTP_FILETYPE_AAC:
return QLatin1String ( "audio/aac" );
case LIBMTP_FILETYPE_MEDIACARD:
return QLatin1String ( "" );
case LIBMTP_FILETYPE_FLAC:
return QLatin1String ( "audio/flac" );
case LIBMTP_FILETYPE_MP2:
return QLatin1String ( "video/mpeg" );
case LIBMTP_FILETYPE_M4A:
return QLatin1String ( "audio/mp4" );
case LIBMTP_FILETYPE_DOC:
return QLatin1String ( "application/msword" );
case LIBMTP_FILETYPE_XML:
return QLatin1String ( "text/xml" );
case LIBMTP_FILETYPE_XLS:
return QLatin1String ( "application/vnd.ms-excel" );
case LIBMTP_FILETYPE_PPT:
return QLatin1String ( "application/vnd.ms-powerpoint" );
case LIBMTP_FILETYPE_MHT:
return QLatin1String ( "" );
case LIBMTP_FILETYPE_JP2:
return QLatin1String ( "image/jpeg2000" );
case LIBMTP_FILETYPE_JPX:
return QLatin1String ( "application/x-jbuilder-project" );
case LIBMTP_FILETYPE_UNKNOWN:
return QLatin1String ( "" );
default:
return QLatin1String ( "" );
}
}
LIBMTP_filetype_t getFiletype ( const QString &filename )
{
LIBMTP_filetype_t filetype;
QString ptype = filename.split ( QLatin1Char ( '.' ) ).last();
/* This need to be kept constantly updated as new file types arrive. */
if ( ptype == QLatin1String ( "wav" ) )
{
filetype = LIBMTP_FILETYPE_WAV;
}
else if ( ptype == QLatin1String ( "mp3" ) )
{
filetype = LIBMTP_FILETYPE_MP3;
}
else if ( ptype == QLatin1String ( "wma" ) )
{
filetype = LIBMTP_FILETYPE_WMA;
}
else if ( ptype == QLatin1String ( "ogg" ) )
{
filetype = LIBMTP_FILETYPE_OGG;
}
else if ( ptype == QLatin1String ( "mp4" ) )
{
filetype = LIBMTP_FILETYPE_MP4;
}
else if ( ptype == QLatin1String ( "wmv" ) )
{
filetype = LIBMTP_FILETYPE_WMV;
}
else if ( ptype == QLatin1String ( "avi" ) )
{
filetype = LIBMTP_FILETYPE_AVI;
}
else if ( ptype == QLatin1String ( "mpeg" ) ||
ptype == QLatin1String ( "mpg" ) )
{
filetype = LIBMTP_FILETYPE_MPEG;
}
else if ( ptype == QLatin1String ( "asf" ) )
{
filetype = LIBMTP_FILETYPE_ASF;
}
else if ( ptype == QLatin1String ( "qt" ) ||
ptype == QLatin1String ( "mov" ) )
{
filetype = LIBMTP_FILETYPE_QT;
}
else if ( ptype == QLatin1String ( "wma" ) )
{
filetype = LIBMTP_FILETYPE_WMA;
}
else if ( ptype == QLatin1String ( "jpg" ) ||
ptype == QLatin1String ( "jpeg" ) )
{
filetype = LIBMTP_FILETYPE_JPEG;
}
else if ( ptype == QLatin1String ( "jfif" ) )
{
filetype = LIBMTP_FILETYPE_JFIF;
}
else if ( ptype == QLatin1String ( "tif" ) ||
ptype == QLatin1String ( "tiff" ) )
{
filetype = LIBMTP_FILETYPE_TIFF;
}
else if ( ptype == QLatin1String ( "bmp" ) )
{
filetype = LIBMTP_FILETYPE_BMP;
}
else if ( ptype == QLatin1String ( "gif" ) )
{
filetype = LIBMTP_FILETYPE_GIF;
}
else if ( ptype == QLatin1String ( "pic" ) ||
ptype == QLatin1String ( "pict" ) )
{
filetype = LIBMTP_FILETYPE_PICT;
}
else if ( ptype == QLatin1String ( "png" ) )
{
filetype = LIBMTP_FILETYPE_PNG;
}
else if ( ptype == QLatin1String ( "wmf" ) )
{
filetype = LIBMTP_FILETYPE_WINDOWSIMAGEFORMAT;
}
else if ( ptype == QLatin1String ( "ics" ) )
{
filetype = LIBMTP_FILETYPE_VCALENDAR2;
}
else if ( ptype == QLatin1String ( "exe" ) ||
ptype == QLatin1String ( "com" ) ||
ptype == QLatin1String ( "bat" ) ||
ptype == QLatin1String ( "dll" ) ||
ptype == QLatin1String ( "sys" ) )
{
filetype = LIBMTP_FILETYPE_WINEXEC;
}
else if ( ptype == QLatin1String ( "aac" ) )
{
filetype = LIBMTP_FILETYPE_AAC;
}
else if ( ptype == QLatin1String ( "mp2" ) )
{
filetype = LIBMTP_FILETYPE_MP2;
}
else if ( ptype == QLatin1String ( "flac" ) )
{
filetype = LIBMTP_FILETYPE_FLAC;
}
else if ( ptype == QLatin1String ( "m4a" ) )
{
filetype = LIBMTP_FILETYPE_M4A;
}
else if ( ptype == QLatin1String ( "doc" ) )
{
filetype = LIBMTP_FILETYPE_DOC;
}
else if ( ptype == QLatin1String ( "xml" ) )
{
filetype = LIBMTP_FILETYPE_XML;
}
else if ( ptype == QLatin1String ( "xls" ) )
{
filetype = LIBMTP_FILETYPE_XLS;
}
else if ( ptype == QLatin1String ( "ppt" ) )
{
filetype = LIBMTP_FILETYPE_PPT;
}
else if ( ptype == QLatin1String ( "mht" ) )
{
filetype = LIBMTP_FILETYPE_MHT;
}
else if ( ptype == QLatin1String ( "jp2" ) )
{
filetype = LIBMTP_FILETYPE_JP2;
}
else if ( ptype == QLatin1String ( "jpx" ) )
{
filetype = LIBMTP_FILETYPE_JPX;
}
else if ( ptype == QLatin1String ( "bin" ) )
{
filetype = LIBMTP_FILETYPE_FIRMWARE;
}
else if ( ptype == QLatin1String ( "vcf" ) )
{
filetype = LIBMTP_FILETYPE_VCARD3;
}
else
{
/* Tagging as unknown file type */
filetype = LIBMTP_FILETYPE_UNKNOWN;
}
return filetype;
}
QMap<QString, LIBMTP_devicestorage_t*> getDevicestorages ( LIBMTP_mtpdevice_t *&device )
{
kDebug ( KIO_MTP ) << "[ENTER]" << ( device == 0 );
QMap<QString, LIBMTP_devicestorage_t*> storages;
if ( device )
{
for ( LIBMTP_devicestorage_t* storage = device->storage; storage != NULL; storage = storage->next )
{
// char *storageIdentifier = storage->VolumeIdentifier;
char *storageDescription = storage->StorageDescription;
QString storagename;
// if ( !storageIdentifier )
storagename = QString::fromUtf8 ( storageDescription );
// else
// storagename = QString::fromUtf8 ( storageIdentifier );
kDebug(KIO_MTP) << "found storage" << storagename;
storages.insert ( storagename, storage );
}
}
kDebug ( KIO_MTP ) << "[EXIT]" << storages.size();
return storages;
}
QMap<QString, LIBMTP_file_t*> getFiles ( LIBMTP_mtpdevice_t *&device, uint32_t storage_id, uint32_t parent_id )
{
kDebug ( KIO_MTP ) << "getFiles() for parent" << parent_id;
QMap<QString, LIBMTP_file_t*> fileMap;
LIBMTP_file_t *files = LIBMTP_Get_Files_And_Folders ( device, storage_id, parent_id ), *file;
for ( file = files; file != NULL; file = file->next )
{
fileMap.insert ( QString::fromUtf8 ( file->filename ), file );
// kDebug(KIO_MTP) << "found file" << file->filename;
}
kDebug ( KIO_MTP ) << "[EXIT]";
return fileMap;
}
void getEntry ( UDSEntry &entry, LIBMTP_mtpdevice_t* device )
{
char *charName = LIBMTP_Get_Friendlyname ( device );
char *charModel = LIBMTP_Get_Modelname ( device );
// prefer friendly devicename over model
QString deviceName;
if ( !charName )
deviceName = QString::fromUtf8 ( charModel );
else
deviceName = QString::fromUtf8 ( charName );
entry.insert ( UDSEntry::UDS_NAME, deviceName );
entry.insert ( UDSEntry::UDS_ICON_NAME, QLatin1String ( "multimedia-player" ) );
entry.insert ( UDSEntry::UDS_FILE_TYPE, S_IFDIR );
entry.insert ( UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH );
entry.insert ( UDSEntry::UDS_MIME_TYPE, QLatin1String ( "inode/directory" ) );
}
void getEntry ( UDSEntry &entry, const LIBMTP_devicestorage_t* storage )
{
// char *charIdentifier = storage->VolumeIdentifier;
char *charDescription = storage->StorageDescription;
QString storageName;
// if ( !charIdentifier )
storageName = QString::fromUtf8 ( charDescription );
// else
// storageName = QString::fromUtf8 ( charIdentifier );
entry.insert ( UDSEntry::UDS_NAME, storageName );
entry.insert ( UDSEntry::UDS_ICON_NAME, QLatin1String ( "drive-removable-media" ) );
entry.insert ( UDSEntry::UDS_FILE_TYPE, S_IFDIR );
entry.insert ( UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH );
entry.insert ( UDSEntry::UDS_MIME_TYPE, QLatin1String ( "inode/directory" ) );
}
void getEntry ( UDSEntry &entry, const LIBMTP_file_t* file )
{
entry.insert ( UDSEntry::UDS_NAME, QString::fromUtf8 ( file->filename ) );
if ( file->filetype == LIBMTP_FILETYPE_FOLDER )
{
entry.insert ( UDSEntry::UDS_FILE_TYPE, S_IFDIR );
entry.insert ( UDSEntry::UDS_ACCESS, S_IRWXU | S_IRWXG | S_IRWXO );
entry.insert ( UDSEntry::UDS_MIME_TYPE, QLatin1String ( "inode/directory" ) );
}
else
{
entry.insert ( UDSEntry::UDS_FILE_TYPE, S_IFREG );
entry.insert ( UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH );
entry.insert ( UDSEntry::UDS_SIZE, file->filesize );
entry.insert ( UDSEntry::UDS_MIME_TYPE, getMimetype( file->filetype ) );
}
entry.insert ( UDSEntry::UDS_INODE, file->item_id );
entry.insert ( UDSEntry::UDS_ACCESS_TIME, file->modificationdate );
entry.insert ( UDSEntry::UDS_MODIFICATION_TIME, file->modificationdate );
entry.insert ( UDSEntry::UDS_CREATION_TIME, file->modificationdate );
}