Create a unified base class to access the database.
Moved the default database class to QListDB and disallow leaking CMAObjects outside this class. Rewrote QListDB and CMAEvent to use the new internal API. Moved the file format constants to the base database class. Moved the metadata loading methods to the base database class.
This commit is contained in:
6
qcma.pro
6
qcma.pro
@@ -40,7 +40,8 @@ SOURCES += src/main.cpp \
|
|||||||
src/forms/configwidget.cpp \
|
src/forms/configwidget.cpp \
|
||||||
src/forms/confirmdialog.cpp \
|
src/forms/confirmdialog.cpp \
|
||||||
src/forms/pinform.cpp \
|
src/forms/pinform.cpp \
|
||||||
src/forms/progressform.cpp
|
src/forms/progressform.cpp \
|
||||||
|
src/database.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/capability.h \
|
src/capability.h \
|
||||||
@@ -66,7 +67,8 @@ HEADERS += \
|
|||||||
src/forms/configwidget.h \
|
src/forms/configwidget.h \
|
||||||
src/forms/confirmdialog.h \
|
src/forms/confirmdialog.h \
|
||||||
src/forms/pinform.h \
|
src/forms/pinform.h \
|
||||||
src/forms/progressform.h
|
src/forms/progressform.h \
|
||||||
|
src/database.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
src/forms/configwidget.ui \
|
src/forms/configwidget.ui \
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "avdecoder.h"
|
#include "avdecoder.h"
|
||||||
#include "cmaobject.h"
|
#include "database.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "qlistdb.h"
|
#include "qlistdb.h"
|
||||||
#include "cmaevent.h"
|
#include "cmaevent.h"
|
||||||
#include "cmaobject.h"
|
|
||||||
#include "cmabroadcast.h"
|
#include "cmabroadcast.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
269
src/cmaevent.cpp
269
src/cmaevent.cpp
@@ -25,14 +25,13 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QThread>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
QListDB *CmaEvent::db = NULL;
|
QListDB *CmaEvent::db = NULL;
|
||||||
QFile *CmaEvent::m_file = NULL;
|
QFile *CmaEvent::m_file = NULL;
|
||||||
|
|
||||||
metadata_t CmaEvent::g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{17, 240, 136, 0, 1, 1.0f, 2}}, NULL};
|
static metadata_t g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{17, 240, 136, 0, 1, 1.0f, 2}}, NULL};
|
||||||
|
|
||||||
CmaEvent::CmaEvent(vita_device_t *s_device) :
|
CmaEvent::CmaEvent(vita_device_t *s_device) :
|
||||||
device(s_device), is_active(true)
|
device(s_device), is_active(true)
|
||||||
@@ -149,15 +148,13 @@ void CmaEvent::processEvent()
|
|||||||
qDebug("Ended event, code: 0x%x, id: %d", t_event.Code, t_event.Param1);
|
qDebug("Ended event, code: 0x%x, id: %d", t_event.Code, t_event.Param1);
|
||||||
}
|
}
|
||||||
|
|
||||||
quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle)
|
quint16 CmaEvent::processAllObjects(metadata_t &parent_metadata, quint32 handle)
|
||||||
{
|
{
|
||||||
qDebug("Called %s, handle: %d, parent name: %s", Q_FUNC_INFO, handle, parent->metadata.name);
|
qDebug("Called %s, handle: %d, parent name: %s", Q_FUNC_INFO, handle, parent_metadata.name);
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
int fileType = -1;
|
|
||||||
int dataType;
|
int dataType;
|
||||||
|
quint32 *p_handles;
|
||||||
uint32_t *p_handles;
|
|
||||||
unsigned int p_len;
|
unsigned int p_len;
|
||||||
|
|
||||||
if(VitaMTP_GetObject_Info(device, handle, &name, &dataType) != PTP_RC_OK) {
|
if(VitaMTP_GetObject_Info(device, handle, &name, &dataType) != PTP_RC_OK) {
|
||||||
@@ -174,15 +171,16 @@ quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMAObject *object = db->pathToObject(name, parent->metadata.ohfi);
|
int ohfi = db->getPathId(name, parent_metadata.ohfi);
|
||||||
|
const QString fullpath = db->getAbsolutePath(ohfi);
|
||||||
|
|
||||||
if(object) {
|
if(ohfi > 0) {
|
||||||
qDebug("Deleting %s", object->path.toStdString().c_str());
|
qDebug() << "Deleting" << fullpath;
|
||||||
removeRecursively(object->path);
|
removeRecursively(fullpath);
|
||||||
db->remove(object);
|
db->deleteEntry(ohfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir dir(parent->path);
|
QDir dir(db->getAbsolutePath(parent_metadata.ohfi));
|
||||||
|
|
||||||
if(dataType & Folder) {
|
if(dataType & Folder) {
|
||||||
if(!dir.mkpath(name)) {
|
if(!dir.mkpath(name)) {
|
||||||
@@ -205,33 +203,26 @@ quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle)
|
|||||||
VitaMTP_GetObject_Callback(device, handle, &size, CmaEvent::writeCallback);
|
VitaMTP_GetObject_Callback(device, handle, &size, CmaEvent::writeCallback);
|
||||||
m_file->close();
|
m_file->close();
|
||||||
delete m_file;
|
delete m_file;
|
||||||
|
|
||||||
// get the root ohfi type
|
|
||||||
CMAObject *root_obj = parent;
|
|
||||||
while(root_obj->parent) {
|
|
||||||
root_obj = root_obj->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileType = checkFileType(dir.absoluteFilePath(name), root_obj->metadata.ohfi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QFileInfo info(dir, name);
|
QFileInfo info(dir, name);
|
||||||
object = new CMAObject(parent);
|
int new_ohfi = db->insertObjectEntry(info.absoluteFilePath(), parent_metadata.ohfi);
|
||||||
object->initObject(info, fileType);
|
|
||||||
object->metadata.handle = handle;
|
|
||||||
db->append(parent->metadata.ohfi, object);
|
|
||||||
free(name);
|
free(name);
|
||||||
|
|
||||||
qDebug("Added object %s with OHFI %i to database", object->metadata.path, object->metadata.ohfi);
|
qDebug() << QString("Added object %1 with OHFI %2 to database").arg(info.absoluteFilePath(), QString::number(new_ohfi));
|
||||||
|
|
||||||
if(dataType & Folder) {
|
if(dataType & Folder) {
|
||||||
|
metadata_t folder_metadata;
|
||||||
|
db->getObjectMetadata(new_ohfi, folder_metadata);
|
||||||
|
folder_metadata.handle = handle;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < p_len; i++) {
|
for(unsigned int i = 0; i < p_len; i++) {
|
||||||
quint16 ret = processAllObjects(object, p_handles[i]);
|
quint16 ret = processAllObjects(folder_metadata, p_handles[i]);
|
||||||
|
|
||||||
if(ret != PTP_RC_OK) {
|
if(ret != PTP_RC_OK) {
|
||||||
qDebug("Deleteting object with OHFI %d", object->metadata.ohfi);
|
qDebug("Deleteting object with OHFI %d", new_ohfi);
|
||||||
db->remove(object);
|
db->deleteEntry(new_ohfi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,15 +244,15 @@ void CmaEvent::vitaEventGetTreatObject(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
CMAObject *parent = db->ohfiToObject(treatObject.ohfiParent);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(parent == NULL) {
|
if(!db->getObjectMetadata(treatObject.ohfiParent, metadata)) {
|
||||||
qWarning("Cannot find parent OHFI %d", treatObject.ohfiParent);
|
qWarning("Cannot find parent OHFI %d", treatObject.ohfiParent);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VitaMTP_ReportResult(device, eventId, processAllObjects(parent, treatObject.handle));
|
VitaMTP_ReportResult(device, eventId, processAllObjects(metadata, treatObject.handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmaEvent::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventId)
|
void CmaEvent::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventId)
|
||||||
@@ -276,21 +267,20 @@ void CmaEvent::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventI
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
quint64 size = 0;
|
qint64 size;
|
||||||
|
qint64 total_size = 0;
|
||||||
|
|
||||||
for(quint32 i = 0; i < info->count; i++) {
|
for(quint32 i = 0; i < info->count; i++) {
|
||||||
CMAObject *object;
|
if((size = db->getObjectSize(info->ohfi[i])) < 0) {
|
||||||
|
|
||||||
if((object = db->ohfiToObject(info->ohfi[i])) == NULL) {
|
|
||||||
qWarning("Cannot find OHFI %d", info->ohfi[i]);
|
qWarning("Cannot find OHFI %d", info->ohfi[i]);
|
||||||
free(info);
|
free(info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size += object->metadata.size;
|
total_size += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VitaMTP_SendCopyConfirmationInfo(device, eventId, info, size) != PTP_RC_OK) {
|
if(VitaMTP_SendCopyConfirmationInfo(device, eventId, info, total_size) != PTP_RC_OK) {
|
||||||
qWarning("Error sending copy confirmation");
|
qWarning("Error sending copy confirmation");
|
||||||
} else {
|
} else {
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
@@ -311,19 +301,18 @@ void CmaEvent::vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(object == NULL) {
|
if(!db->getObjectMetadata(ohfi, metadata)) {
|
||||||
qWarning("Cannot find OHFI %d in database", ohfi);
|
qWarning("Cannot find OHFI %d in database", ohfi);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata_t *metadata = &object->metadata;
|
metadata.next_metadata = NULL;
|
||||||
metadata->next_metadata = NULL;
|
qDebug("Sending metadata for OHFI %d (%s)", ohfi, metadata.path);
|
||||||
qDebug("Sending metadata for OHFI %d (%s)", ohfi, metadata->path);
|
|
||||||
|
|
||||||
quint16 ret = VitaMTP_SendObjectMetadata(device, eventId, metadata);
|
quint16 ret = VitaMTP_SendObjectMetadata(device, eventId, &metadata);
|
||||||
if(ret != PTP_RC_OK) {
|
if(ret != PTP_RC_OK) {
|
||||||
qWarning("Error sending metadata. Code: %04X", ret);
|
qWarning("Error sending metadata. Code: %04X", ret);
|
||||||
} else {
|
} else {
|
||||||
@@ -368,8 +357,8 @@ void CmaEvent::vitaEventSendNumOfObject(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
uint ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
int items = db->filterObjects(ohfi, NULL);
|
int items = db->childObjectCount(ohfi);
|
||||||
|
|
||||||
if(VitaMTP_SendNumOfObject(device, eventId, items) != PTP_RC_OK) {
|
if(VitaMTP_SendNumOfObject(device, eventId, items) != PTP_RC_OK) {
|
||||||
qWarning("Error occured receiving object count for OHFI parent %d", ohfi);
|
qWarning("Error occured receiving object count for OHFI parent %d", ohfi);
|
||||||
@@ -391,8 +380,9 @@ void CmaEvent::vitaEventSendObjectMetadata(vita_event_t *event, int eventId)
|
|||||||
}
|
}
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
metadata_t *meta;
|
metadata_t *meta = NULL;
|
||||||
int count = db->filterObjects(browse.ohfiParent, &meta, browse.index, browse.numObjects); // if meta is null, will return empty XML
|
|
||||||
|
int count = db->getObjectMetadatas(browse.ohfiParent, meta, browse.index, browse.numObjects); // if meta is null, will return empty XML
|
||||||
qDebug("Sending %i metadata filtered objects for OHFI %d", count, browse.ohfiParent);
|
qDebug("Sending %i metadata filtered objects for OHFI %d", count, browse.ohfiParent);
|
||||||
|
|
||||||
if(VitaMTP_SendObjectMetadata(device, eventId, meta) != PTP_RC_OK) { // send all objects with OHFI parent
|
if(VitaMTP_SendObjectMetadata(device, eventId, meta) != PTP_RC_OK) { // send all objects with OHFI parent
|
||||||
@@ -412,29 +402,27 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
qDebug("Searching object with OHFI %d", ohfi);
|
qDebug("Searching object with OHFI %d", ohfi);
|
||||||
|
|
||||||
QListDB::find_data iters;
|
metadata_t *metadata = NULL;
|
||||||
if(!db->find(ohfi, iters)) {
|
if(!db->getObjectMetadatas(ohfi, metadata)) {
|
||||||
qWarning("Failed to find OHFI %d", ohfi);
|
qWarning("Failed to find OHFI %d", ohfi);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long len = 0;
|
metadata_t *start = metadata;
|
||||||
CMAObject *object = *iters.it;
|
quint32 parentHandle = event->Param3;
|
||||||
CMAObject *start = object;
|
bool send_folder = metadata->dataType & Folder;
|
||||||
uint parentHandle = event->Param3;
|
quint32 handle;
|
||||||
bool send_folder = object->metadata.dataType & Folder;
|
|
||||||
uint handle;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
len = object->metadata.size;
|
unsigned long len = metadata->size;
|
||||||
m_file = new QFile(object->path);
|
m_file = new QFile(db->getAbsolutePath(metadata->ohfi));
|
||||||
|
|
||||||
// read the file to send if it's not a directory
|
// read the file to send if it's not a directory
|
||||||
// if it is a directory, data and len are not used by VitaMTP
|
// if it is a directory, data and len are not used by VitaMTP
|
||||||
if(object->metadata.dataType & File) {
|
if(metadata->dataType & File) {
|
||||||
if(!m_file->open(QIODevice::ReadOnly)) {
|
if(!m_file->open(QIODevice::ReadOnly)) {
|
||||||
qWarning("Failed to read %s", object->path.toStdString().c_str());
|
qWarning() << "Failed to read" << m_file->fileName();
|
||||||
delete m_file;
|
delete m_file;
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object);
|
||||||
return;
|
return;
|
||||||
@@ -445,18 +433,20 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
|
|||||||
// we know the parent has to be before the current node
|
// we know the parent has to be before the current node
|
||||||
// the first time this is called, parentHandle is left untouched
|
// the first time this is called, parentHandle is left untouched
|
||||||
|
|
||||||
if(start != object) {
|
if(start != metadata) {
|
||||||
parentHandle = object->parent->metadata.handle;
|
metadata_t parent_metadata;
|
||||||
|
db->getObjectMetadata(metadata->ohfiParent, parent_metadata);
|
||||||
|
parentHandle = parent_metadata.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the data over
|
// send the data over
|
||||||
qDebug("Sending %s of %lu bytes to device", object->metadata.name, len);
|
qDebug("Sending %s of %lu bytes to device", metadata->name, len);
|
||||||
qDebug("OHFI %d with handle 0x%08X", ohfi, parentHandle);
|
qDebug("OHFI %d with handle 0x%08X", ohfi, parentHandle);
|
||||||
|
|
||||||
VitaMTP_RegisterCancelEventId(eventId);
|
VitaMTP_RegisterCancelEventId(eventId);
|
||||||
quint16 ret = VitaMTP_SendObject_Callback(device, &parentHandle, &handle, &object->metadata, &CmaEvent::readCallback);
|
quint16 ret = VitaMTP_SendObject_Callback(device, &parentHandle, &handle, metadata, &CmaEvent::readCallback);
|
||||||
if(ret != PTP_RC_OK) {
|
if(ret != PTP_RC_OK) {
|
||||||
qWarning("Sending of %s failed. Code: %04X", object->metadata.name, ret);
|
qWarning("Sending of %s failed. Code: %04X", metadata->name, ret);
|
||||||
if(ret == PTP_ERROR_CANCEL) {
|
if(ret == PTP_ERROR_CANCEL) {
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_GeneralError);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_GeneralError);
|
||||||
}
|
}
|
||||||
@@ -465,9 +455,9 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
object->metadata.handle = handle;
|
metadata->handle = handle;
|
||||||
|
|
||||||
if(object->metadata.dataType & File) {
|
if(metadata->dataType & File) {
|
||||||
m_file->close();
|
m_file->close();
|
||||||
delete m_file;
|
delete m_file;
|
||||||
}
|
}
|
||||||
@@ -477,9 +467,9 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
object = *++iters.it;
|
metadata = metadata->next_metadata;
|
||||||
|
|
||||||
} while(iters.it != iters.end && object->metadata.ohfiParent >= OHFI_OFFSET); // get everything under this "folder"
|
} while(metadata && metadata->ohfiParent >= OHFI_OFFSET); // get everything under this "folder"
|
||||||
|
|
||||||
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, handle);
|
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, handle);
|
||||||
|
|
||||||
@@ -573,18 +563,19 @@ void CmaEvent::vitaEventSendObjectStatus(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->pathToObject(objectstatus.title, objectstatus.ohfiRoot);
|
int ohfi = db->getPathId(objectstatus.title, objectstatus.ohfiRoot);
|
||||||
|
|
||||||
if(object == NULL) { // not in database, don't return metadata
|
if(ohfi == 0) { // not in database, don't return metadata
|
||||||
qDebug("Object %s not in database (OHFI: %i). Sending OK response for non-existence", objectstatus.title, objectstatus.ohfiRoot);
|
qDebug("Object %s not in database (OHFI: %i). Sending OK response for non-existence", objectstatus.title, objectstatus.ohfiRoot);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
} else {
|
} else {
|
||||||
metadata_t *metadata = &object->metadata;
|
metadata_t metadata;
|
||||||
metadata->next_metadata = NULL;
|
db->getObjectMetadata(ohfi, metadata);
|
||||||
qDebug("Sending metadata for OHFI %d", object->metadata.ohfi);
|
metadata.next_metadata = NULL;
|
||||||
|
qDebug("Sending metadata for OHFI %d", ohfi);
|
||||||
|
|
||||||
if(VitaMTP_SendObjectMetadata(device, eventId, metadata) != PTP_RC_OK) {
|
if(VitaMTP_SendObjectMetadata(device, eventId, &metadata) != PTP_RC_OK) {
|
||||||
qWarning("Error sending metadata for %d", object->metadata.ohfi);
|
qWarning("Error sending metadata for %d", ohfi);
|
||||||
} else {
|
} else {
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
}
|
}
|
||||||
@@ -600,22 +591,25 @@ void CmaEvent::vitaEventSendObjectThumb(vita_event_t *event, int eventId)
|
|||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
int ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(object == NULL) {
|
if(!db->getObjectMetadata(ohfi, metadata)) {
|
||||||
qWarning("Cannot find OHFI %d in database.", ohfi);
|
qWarning("Cannot find OHFI %d in database.", ohfi);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray data = getThumbnail(object->path, object->metadata.dataType, &g_thumbmeta);
|
QString fullpath = db->getAbsolutePath(ohfi);
|
||||||
|
QByteArray data = getThumbnail(fullpath, metadata.dataType, &g_thumbmeta);
|
||||||
|
|
||||||
if(data.size() == 0) {
|
if(data.size() == 0) {
|
||||||
qWarning("Cannot find/read thumbnail for %s", object->path.toStdString().c_str());
|
qWarning() << "Cannot find/read thumbnail for" << fullpath;
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Data);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: remove this after fixing vitamtp
|
||||||
|
|
||||||
// workaround for the vitamtp locale bug
|
// workaround for the vitamtp locale bug
|
||||||
char *locale = strdup(setlocale(LC_ALL, NULL));
|
char *locale = strdup(setlocale(LC_ALL, NULL));
|
||||||
setlocale(LC_ALL, "C");
|
setlocale(LC_ALL, "C");
|
||||||
@@ -638,17 +632,18 @@ void CmaEvent::vitaEventDeleteObject(vita_event_t *event, int eventId)
|
|||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
int ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(object == NULL) {
|
if(!db->getObjectMetadata(ohfi, metadata)) {
|
||||||
qWarning("OHFI %d not found", ohfi);
|
qWarning("OHFI %d not found", ohfi);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("Deleting %s, OHFI: %i", object->metadata.path, object->metadata.ohfi);
|
QString fullpath = db->getAbsolutePath(ohfi);
|
||||||
removeRecursively(object->path);
|
qDebug() << QString("Deleting %1, OHFI: %2").arg(fullpath, QString::number(ohfi));
|
||||||
db->remove(object);
|
removeRecursively(fullpath);
|
||||||
|
db->deleteEntry(ohfi);
|
||||||
|
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
}
|
}
|
||||||
@@ -727,24 +722,26 @@ void CmaEvent::vitaEventSendPartOfObject(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->ohfiToObject(part_init.ohfi);
|
QString fullpath = db->getAbsolutePath(part_init.ohfi);
|
||||||
|
|
||||||
if(object == NULL) {
|
if(fullpath.isNull()) {
|
||||||
qWarning("Cannot find object for OHFI %d", part_init.ohfi);
|
qWarning("Cannot find object for OHFI %d", part_init.ohfi);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Context);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile file(object->path);
|
QFile file(fullpath);
|
||||||
|
|
||||||
if(!file.open(QIODevice::ReadOnly)) {
|
if(!file.open(QIODevice::ReadOnly)) {
|
||||||
qWarning("Cannot read %s", object->path.toStdString().c_str());
|
qWarning() << "Cannot read" << fullpath;
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
file.seek(part_init.offset);
|
file.seek(part_init.offset);
|
||||||
QByteArray data = file.read(part_init.size);
|
QByteArray data = file.read(part_init.size);
|
||||||
qDebug("Sending %s at file offset %" PRIu64" for %" PRIu64" bytes", object->metadata.path, part_init.offset, part_init.size);
|
qDebug() << QString("Sending %1 at file offset %2 for %3 bytes").arg(
|
||||||
|
fullpath, QString::number(part_init.offset), QString::number(part_init.size)
|
||||||
|
);
|
||||||
|
|
||||||
if(VitaMTP_SendPartOfObject(device, eventId, (unsigned char *)data.data(), data.size()) != PTP_RC_OK) {
|
if(VitaMTP_SendPartOfObject(device, eventId, (unsigned char *)data.data(), data.size()) != PTP_RC_OK) {
|
||||||
qWarning("Failed to send part of object OHFI %d", part_init.ohfi);
|
qWarning("Failed to send part of object OHFI %d", part_init.ohfi);
|
||||||
@@ -767,10 +764,10 @@ void CmaEvent::vitaEventOperateObject(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
CMAObject *root = db->ohfiToObject(operateobject.ohfi);
|
QString fullpath = db->getAbsolutePath(operateobject.ohfi);
|
||||||
|
|
||||||
// end for renaming only
|
// end for renaming only
|
||||||
if(root == NULL) {
|
if(fullpath.isNull()) {
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Not_Exist_Object);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -779,64 +776,46 @@ void CmaEvent::vitaEventOperateObject(vita_event_t *event, int eventId)
|
|||||||
case VITA_OPERATE_CREATE_FOLDER: {
|
case VITA_OPERATE_CREATE_FOLDER: {
|
||||||
qDebug("Operate command %d: Create folder %s", operateobject.cmd, operateobject.title);
|
qDebug("Operate command %d: Create folder %s", operateobject.cmd, operateobject.title);
|
||||||
|
|
||||||
QDir dir(root->path);
|
QDir dir(fullpath);
|
||||||
if(!dir.mkdir(operateobject.title)) {
|
if(!dir.mkdir(operateobject.title)) {
|
||||||
qWarning("Unable to create temporary folder: %s", operateobject.title);
|
qWarning("Unable to create temporary folder: %s", operateobject.title);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
|
||||||
} else {
|
} else {
|
||||||
CMAObject *newobj = new CMAObject(root);
|
int new_ohfi = db->insertObjectEntry(QDir(dir).absoluteFilePath(operateobject.title), operateobject.ohfi);
|
||||||
newobj->initObject(QFileInfo(dir, operateobject.title));
|
qDebug("Created folder %s with OHFI %d", operateobject.title, new_ohfi);
|
||||||
db->append(operateobject.ohfi, newobj);
|
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, new_ohfi);
|
||||||
qDebug("Created folder %s with OHFI %d under parent %s", newobj->metadata.path, newobj->metadata.ohfi, root->metadata.path);
|
|
||||||
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, newobj->metadata.ohfi);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VITA_OPERATE_CREATE_FILE: {
|
case VITA_OPERATE_CREATE_FILE: {
|
||||||
qDebug("Operate command %d: Create file %s", operateobject.cmd, operateobject.title);
|
qDebug("Operate command %d: Create file %s", operateobject.cmd, operateobject.title);
|
||||||
|
|
||||||
QFile file(root->path + QDir::separator() + operateobject.title);
|
QFile file(fullpath + QDir::separator() + operateobject.title);
|
||||||
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
qWarning("Unable to create temporary file: %s", operateobject.title);
|
qWarning("Unable to create temporary file: %s", operateobject.title);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
|
||||||
} else {
|
} else {
|
||||||
CMAObject *newobj = new CMAObject(root);
|
int new_ohfi = db->insertObjectEntry(file.fileName(), operateobject.ohfi);
|
||||||
newobj->initObject(file);
|
//qDebug("Created file %s with OHFI %d under parent %s", newobj->metadata.path, new_ohfi, root->metadata.path);
|
||||||
db->append(root->metadata.ohfi, newobj);
|
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, new_ohfi);
|
||||||
qDebug("Created file %s with OHFI %d under parent %s", newobj->metadata.path, newobj->metadata.ohfi, root->metadata.path);
|
|
||||||
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, newobj->metadata.ohfi);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VITA_OPERATE_RENAME: {
|
case VITA_OPERATE_RENAME: {
|
||||||
qDebug("Operate command %d: Rename %s to %s", operateobject.cmd, root->metadata.name, operateobject.title);
|
//qDebug("Operate command %d: Rename %s to %s", operateobject.cmd, root->metadata.name, operateobject.title);
|
||||||
|
|
||||||
QString oldpath = root->path;
|
db->renameObject(operateobject.ohfi, operateobject.title);
|
||||||
QString oldname = root->metadata.name;
|
QString newpath = db->getAbsolutePath(operateobject.ohfi);
|
||||||
|
|
||||||
//rename the current object
|
|
||||||
root->rename(operateobject.title);
|
|
||||||
QListDB::find_data iters;
|
|
||||||
db->find(root->metadata.ohfi, iters);
|
|
||||||
|
|
||||||
// rename the rest of the list only if has the renamed parent in some part of the chain
|
|
||||||
while(iters.it != iters.end) {
|
|
||||||
CMAObject *obj = *iters.it++;
|
|
||||||
|
|
||||||
if(obj->hasParent(root)) {
|
|
||||||
obj->refreshPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rename in filesystem
|
// rename in filesystem
|
||||||
if(!QFile(oldpath).rename(root->path)) {
|
if(!QFile(fullpath).rename(newpath)) {
|
||||||
qWarning("Unable to rename %s to %s", oldname.toStdString().c_str(), operateobject.title);
|
qWarning("Unable to rename %s to %s", fullpath.toLocal8Bit().constData(), operateobject.title);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("Renamed OHFI %d from %s to %s", root->metadata.ohfi, oldname.toStdString().c_str(), root->metadata.name);
|
qDebug("Renamed OHFI %d from %s to %s", operateobject.ohfi, fullpath.toLocal8Bit().constData(), newpath.toLocal8Bit().constData());
|
||||||
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, root->metadata.ohfi);
|
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, operateobject.ohfi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -862,26 +841,32 @@ void CmaEvent::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
CMAObject *object = db->ohfiToObject(part_init.ohfi);
|
QString fullpath = db->getAbsolutePath(part_init.ohfi);
|
||||||
|
|
||||||
if(object == NULL) {
|
if(fullpath.isNull()) {
|
||||||
qWarning("Cannot find OHFI %d", part_init.ohfi);
|
qWarning("Cannot find OHFI %d", part_init.ohfi);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
||||||
free(data);
|
free(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("Receiving %s at offset %" PRIu64" for %" PRIu64" bytes", object->metadata.path, part_init.offset, part_init.size);
|
qDebug() << QString("Receiving %1 at offset %2 for %3 bytes").arg(
|
||||||
|
fullpath, QString::number(part_init.offset), QString::number(part_init.size)
|
||||||
|
);
|
||||||
|
|
||||||
QFile file(object->path);
|
QFile file(fullpath);
|
||||||
if(!file.open(QIODevice::ReadWrite)) {
|
if(!file.open(QIODevice::ReadWrite)) {
|
||||||
qWarning("Cannot write to file %s", object->path.toStdString().c_str());
|
qWarning() << "Cannot write to file" << fullpath;
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission);
|
||||||
} else {
|
} else {
|
||||||
file.seek(part_init.offset);
|
file.seek(part_init.offset);
|
||||||
file.write((const char *)data, part_init.size);
|
file.write((const char *)data, part_init.size);
|
||||||
object->updateObjectSize(part_init.size);
|
db->setObjectSize(part_init.ohfi, part_init.size);
|
||||||
qDebug("Written %" PRIu64" bytes to %s at offset %" PRIu64, part_init.size, object->path.toStdString().c_str(), part_init.offset);
|
|
||||||
|
qDebug() << QString("Written %1 bytes to %2 at offset %3").arg(
|
||||||
|
QString::number(part_init.size), fullpath, QString::number(part_init.offset)
|
||||||
|
);
|
||||||
|
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -895,20 +880,20 @@ void CmaEvent::vitaEventSendStorageSize(vita_event_t *event, int eventId)
|
|||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
int ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
QString fullpath = db->getAbsolutePath(ohfi);
|
||||||
|
|
||||||
if(object == NULL) {
|
if(fullpath.isNull()) {
|
||||||
qWarning("Error: Cannot find OHFI %d", ohfi);
|
qWarning("Error: Cannot find OHFI %d", ohfi);
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_OHFI);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
QFile file(object->path);
|
QFile file(fullpath);
|
||||||
|
|
||||||
if(!file.exists()) {
|
if(!file.exists()) {
|
||||||
// create the directory if doesn't exist so the query don't fail
|
// create the directory if doesn't exist so the query don't fail
|
||||||
qDebug("Creating %s", object->path.toStdString().c_str());
|
qDebug() << "Creating" << fullpath;
|
||||||
|
|
||||||
if(!QDir(QDir::root()).mkpath(object->path)) {
|
if(!QDir(QDir::root()).mkpath(QDir(fullpath).absolutePath())) {
|
||||||
qWarning("Create directory failed");
|
qWarning("Create directory failed");
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission);
|
||||||
return;
|
return;
|
||||||
@@ -919,7 +904,7 @@ void CmaEvent::vitaEventSendStorageSize(vita_event_t *event, int eventId)
|
|||||||
quint64 total;
|
quint64 total;
|
||||||
quint64 free;
|
quint64 free;
|
||||||
|
|
||||||
if(!getDiskSpace(object->path, &free, &total)) {
|
if(!getDiskSpace(fullpath, &free, &total)) {
|
||||||
qWarning("Cannot get disk space");
|
qWarning("Cannot get disk space");
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Permission);
|
||||||
return;
|
return;
|
||||||
@@ -948,12 +933,12 @@ void CmaEvent::vitaEventCheckExistance(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->pathToObject(existance.name, 0);
|
int ohfi = db->getPathId(existance.name, 0);
|
||||||
|
|
||||||
if(object == NULL) {
|
if(ohfi == 0) {
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Different_Object);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Different_Object);
|
||||||
} else {
|
} else {
|
||||||
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_VITA_Same_Object, object->metadata.ohfi);
|
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_VITA_Same_Object, ohfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
|
@@ -20,7 +20,6 @@
|
|||||||
#ifndef CMAEVENT_H
|
#ifndef CMAEVENT_H
|
||||||
#define CMAEVENT_H
|
#define CMAEVENT_H
|
||||||
|
|
||||||
#include "cmaobject.h"
|
|
||||||
#include "qlistdb.h"
|
#include "qlistdb.h"
|
||||||
#include "httpdownloader.h"
|
#include "httpdownloader.h"
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ public:
|
|||||||
static QListDB *db;
|
static QListDB *db;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t processAllObjects(CMAObject *parent, uint32_t handle);
|
uint16_t processAllObjects(metadata_t &metadata, uint32_t handle);
|
||||||
void vitaEventSendObject(vita_event_t *event, int eventId);
|
void vitaEventSendObject(vita_event_t *event, int eventId);
|
||||||
void vitaEventSendObjectMetadata(vita_event_t *event, int eventId);
|
void vitaEventSendObjectMetadata(vita_event_t *event, int eventId);
|
||||||
void vitaEventSendNumOfObject(vita_event_t *event, int eventId);
|
void vitaEventSendNumOfObject(vita_event_t *event, int eventId);
|
||||||
@@ -79,7 +78,6 @@ private:
|
|||||||
QMutex active;
|
QMutex active;
|
||||||
QSemaphore sema;
|
QSemaphore sema;
|
||||||
|
|
||||||
static metadata_t g_thumbmeta;
|
|
||||||
static QFile *m_file;
|
static QFile *m_file;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "cmaobject.h"
|
#include "cmaobject.h"
|
||||||
#include "sforeader.h"
|
#include "sforeader.h"
|
||||||
#include "avdecoder.h"
|
#include "avdecoder.h"
|
||||||
|
#include "database.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -108,48 +109,6 @@ void CMAObject::loadSfoMetadata(const QString &path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMAObject::loadMusicMetadata(const QString &path)
|
|
||||||
{
|
|
||||||
AVDecoder decoder;
|
|
||||||
bool skipMetadata = QSettings().value("skipMetadata", false).toBool();
|
|
||||||
|
|
||||||
if(!skipMetadata && decoder.open(path)) {
|
|
||||||
decoder.getAudioMetadata(metadata);
|
|
||||||
} else {
|
|
||||||
metadata.data.music.album = strdup(parent->metadata.name ? parent->metadata.name : "");
|
|
||||||
metadata.data.music.artist = strdup("");
|
|
||||||
metadata.data.music.title = strdup(metadata.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMAObject::loadVideoMetadata(const QString &path)
|
|
||||||
{
|
|
||||||
AVDecoder decoder;
|
|
||||||
bool skipMetadata = QSettings().value("skipMetadata", false).toBool();
|
|
||||||
|
|
||||||
if(!skipMetadata && decoder.open(path)) {
|
|
||||||
decoder.getVideoMetadata(metadata);
|
|
||||||
} else {
|
|
||||||
metadata.data.video.title = strdup(metadata.name);
|
|
||||||
metadata.data.video.explanation = strdup("");
|
|
||||||
metadata.data.video.copyright = strdup("");
|
|
||||||
// default to H264 video codec
|
|
||||||
metadata.data.video.tracks->data.track_video.codecType = CODEC_TYPE_AVC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMAObject::loadPhotoMetadata(const QString &path)
|
|
||||||
{
|
|
||||||
QImage img;
|
|
||||||
bool skipMetadata = QSettings().value("skipMetadata", false).toBool();
|
|
||||||
|
|
||||||
if(!skipMetadata && img.load(path)) {
|
|
||||||
metadata.data.photo.tracks->data.track_photo.width = img.width();
|
|
||||||
metadata.data.photo.tracks->data.track_photo.height = img.height();
|
|
||||||
}
|
|
||||||
metadata.data.photo.title = strdup(metadata.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMAObject::initObject(const QFileInfo &file, int file_type)
|
void CMAObject::initObject(const QFileInfo &file, int file_type)
|
||||||
{
|
{
|
||||||
metadata.name = strdup(file.fileName().toUtf8().data());
|
metadata.name = strdup(file.fileName().toUtf8().data());
|
||||||
@@ -181,7 +140,7 @@ void CMAObject::initObject(const QFileInfo &file, int file_type)
|
|||||||
metadata.data.music.tracks = new media_track();
|
metadata.data.music.tracks = new media_track();
|
||||||
metadata.data.music.tracks->type = VITA_TRACK_TYPE_AUDIO;
|
metadata.data.music.tracks->type = VITA_TRACK_TYPE_AUDIO;
|
||||||
metadata.data.music.tracks->data.track_photo.codecType = audio_list[file_type].file_codec;
|
metadata.data.music.tracks->data.track_photo.codecType = audio_list[file_type].file_codec;
|
||||||
loadMusicMetadata(file.absoluteFilePath());
|
Database::loadMusicMetadata(file.absoluteFilePath(), metadata);
|
||||||
} else if(MASK_SET(metadata.dataType, Video | File)) {
|
} else if(MASK_SET(metadata.dataType, Video | File)) {
|
||||||
metadata.data.video.fileName = strdup(metadata.name);
|
metadata.data.video.fileName = strdup(metadata.name);
|
||||||
metadata.data.video.dateTimeUpdated = file.created().toTime_t();
|
metadata.data.video.dateTimeUpdated = file.created().toTime_t();
|
||||||
@@ -191,7 +150,7 @@ void CMAObject::initObject(const QFileInfo &file, int file_type)
|
|||||||
metadata.data.video.numTracks = 1;
|
metadata.data.video.numTracks = 1;
|
||||||
metadata.data.video.tracks = new media_track();
|
metadata.data.video.tracks = new media_track();
|
||||||
metadata.data.video.tracks->type = VITA_TRACK_TYPE_VIDEO;
|
metadata.data.video.tracks->type = VITA_TRACK_TYPE_VIDEO;
|
||||||
loadVideoMetadata(file.absoluteFilePath());
|
Database::loadVideoMetadata(file.absoluteFilePath(), metadata);
|
||||||
} else if(MASK_SET(metadata.dataType, Photo | File)) {
|
} else if(MASK_SET(metadata.dataType, Photo | File)) {
|
||||||
|
|
||||||
if(file_type < 0) {
|
if(file_type < 0) {
|
||||||
@@ -207,7 +166,7 @@ void CMAObject::initObject(const QFileInfo &file, int file_type)
|
|||||||
metadata.data.photo.tracks = new media_track();
|
metadata.data.photo.tracks = new media_track();
|
||||||
metadata.data.photo.tracks->type = VITA_TRACK_TYPE_PHOTO;
|
metadata.data.photo.tracks->type = VITA_TRACK_TYPE_PHOTO;
|
||||||
metadata.data.photo.tracks->data.track_photo.codecType = photo_list[file_type].file_codec;
|
metadata.data.photo.tracks->data.track_photo.codecType = photo_list[file_type].file_codec;
|
||||||
loadPhotoMetadata(file.absoluteFilePath());
|
Database::loadPhotoMetadata(file.absoluteFilePath(), metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = file.absoluteFilePath();
|
path = file.absoluteFilePath();
|
||||||
|
101
src/database.cpp
Normal file
101
src/database.cpp
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#include "database.h"
|
||||||
|
#include "avdecoder.h"
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
const file_type audio_list[] = {
|
||||||
|
{"mp3", FILE_FORMAT_MP3, CODEC_TYPE_MP3},
|
||||||
|
{"mp4", FILE_FORMAT_MP4, CODEC_TYPE_AAC},
|
||||||
|
{"wav", FILE_FORMAT_WAV, CODEC_TYPE_PCM}
|
||||||
|
};
|
||||||
|
|
||||||
|
const file_type photo_list[] = {
|
||||||
|
{"jpg", FILE_FORMAT_JPG, CODEC_TYPE_JPG},
|
||||||
|
{"jpeg", FILE_FORMAT_JPG, CODEC_TYPE_JPG},
|
||||||
|
{"png", FILE_FORMAT_PNG, CODEC_TYPE_PNG},
|
||||||
|
{"tif", FILE_FORMAT_TIF, CODEC_TYPE_TIF},
|
||||||
|
{"tiff", FILE_FORMAT_TIF, CODEC_TYPE_TIF},
|
||||||
|
{"bmp", FILE_FORMAT_BMP, CODEC_TYPE_BMP},
|
||||||
|
{"gif", FILE_FORMAT_GIF, CODEC_TYPE_GIF},
|
||||||
|
};
|
||||||
|
|
||||||
|
const file_type video_list[] = {
|
||||||
|
{"mp4", FILE_FORMAT_MP4, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
Database::Database(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int Database::checkFileType(const QString path, int ohfi_root)
|
||||||
|
{
|
||||||
|
switch(ohfi_root) {
|
||||||
|
case VITA_OHFI_MUSIC:
|
||||||
|
for(int i = 0, max = sizeof(audio_list) / sizeof(file_type); i < max; i++) {
|
||||||
|
if(path.endsWith(audio_list[i].file_ext, Qt::CaseInsensitive)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VITA_OHFI_PHOTO:
|
||||||
|
for(int i = 0, max = sizeof(photo_list) / sizeof(file_type); i< max; i++) {
|
||||||
|
if(path.endsWith(photo_list[i].file_ext, Qt::CaseInsensitive)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VITA_OHFI_VIDEO:
|
||||||
|
for(int i = 0, max = sizeof(video_list) / sizeof(file_type); i< max; i++) {
|
||||||
|
if(path.endsWith(video_list[i].file_ext, Qt::CaseInsensitive)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::loadMusicMetadata(const QString &path, metadata_t &metadata)
|
||||||
|
{
|
||||||
|
AVDecoder decoder;
|
||||||
|
bool skipMetadata = QSettings().value("skipMetadata", false).toBool();
|
||||||
|
|
||||||
|
if(!skipMetadata && decoder.open(path)) {
|
||||||
|
decoder.getAudioMetadata(metadata);
|
||||||
|
} else {
|
||||||
|
metadata.data.music.album = strdup("");
|
||||||
|
metadata.data.music.artist = strdup("");
|
||||||
|
metadata.data.music.title = strdup(metadata.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::loadVideoMetadata(const QString &path, metadata_t &metadata)
|
||||||
|
{
|
||||||
|
AVDecoder decoder;
|
||||||
|
bool skipMetadata = QSettings().value("skipMetadata", false).toBool();
|
||||||
|
|
||||||
|
if(!skipMetadata && decoder.open(path)) {
|
||||||
|
decoder.getVideoMetadata(metadata);
|
||||||
|
} else {
|
||||||
|
metadata.data.video.title = strdup(metadata.name);
|
||||||
|
metadata.data.video.explanation = strdup("");
|
||||||
|
metadata.data.video.copyright = strdup("");
|
||||||
|
// default to H264 video codec
|
||||||
|
metadata.data.video.tracks->data.track_video.codecType = CODEC_TYPE_AVC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::loadPhotoMetadata(const QString &path, metadata_t &metadata)
|
||||||
|
{
|
||||||
|
QImage img;
|
||||||
|
bool skipMetadata = QSettings().value("skipMetadata", false).toBool();
|
||||||
|
|
||||||
|
if(!skipMetadata && img.load(path)) {
|
||||||
|
metadata.data.photo.tracks->data.track_photo.width = img.width();
|
||||||
|
metadata.data.photo.tracks->data.track_photo.height = img.height();
|
||||||
|
}
|
||||||
|
metadata.data.photo.title = strdup(metadata.name);
|
||||||
|
}
|
63
src/database.h
Normal file
63
src/database.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#ifndef DATABASE_H
|
||||||
|
#define DATABASE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <vitamtp.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *file_ext;
|
||||||
|
int file_format;
|
||||||
|
int file_codec;
|
||||||
|
} file_type;
|
||||||
|
|
||||||
|
#define FILE_FORMAT_MP4 1
|
||||||
|
#define FILE_FORMAT_WAV 2
|
||||||
|
#define FILE_FORMAT_MP3 3
|
||||||
|
#define FILE_FORMAT_JPG 4
|
||||||
|
#define FILE_FORMAT_PNG 5
|
||||||
|
#define FILE_FORMAT_GIF 6
|
||||||
|
#define FILE_FORMAT_BMP 7
|
||||||
|
#define FILE_FORMAT_TIF 8
|
||||||
|
|
||||||
|
#define CODEC_TYPE_MPEG4 2
|
||||||
|
#define CODEC_TYPE_AVC 3
|
||||||
|
#define CODEC_TYPE_MP3 12
|
||||||
|
#define CODEC_TYPE_AAC 13
|
||||||
|
#define CODEC_TYPE_PCM 15
|
||||||
|
#define CODEC_TYPE_JPG 17
|
||||||
|
#define CODEC_TYPE_PNG 18
|
||||||
|
#define CODEC_TYPE_TIF 19
|
||||||
|
#define CODEC_TYPE_BMP 20
|
||||||
|
#define CODEC_TYPE_GIF 21
|
||||||
|
|
||||||
|
extern const file_type audio_list[3];
|
||||||
|
extern const file_type photo_list[7];
|
||||||
|
extern const file_type video_list[1];
|
||||||
|
|
||||||
|
class Database : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Database(QObject *parent = 0);
|
||||||
|
|
||||||
|
virtual int childObjectCount(int parent_ohfi) = 0;
|
||||||
|
virtual bool deleteEntry(int ohfi, int root_ohfi = 0) = 0;
|
||||||
|
virtual QString getAbsolutePath(int ohfi) = 0;
|
||||||
|
virtual QString getRelativePath(int ohfi) = 0;
|
||||||
|
virtual bool getObjectMetadata(int ohfi, metadata_t &metadata) = 0;
|
||||||
|
virtual int getObjectMetadatas(int parent_ohfi, metadata_t *&metadata, int index = 0, int max_number = 0) = 0;
|
||||||
|
virtual qint64 getObjectSize(int ohfi) = 0;
|
||||||
|
virtual int getPathId(const char *name, int ohfi) = 0;
|
||||||
|
virtual int insertObjectEntry(const QString &path, int parent_ohfi) = 0;
|
||||||
|
virtual bool renameObject(int ohfi, const QString &name) = 0;
|
||||||
|
virtual void setObjectSize(int ohfi, qint64 size) = 0;
|
||||||
|
virtual int getRootId(int ohfi) = 0;
|
||||||
|
|
||||||
|
static int checkFileType(const QString path, int ohfi_root);
|
||||||
|
static void loadMusicMetadata(const QString &path, metadata_t &metadata);
|
||||||
|
static void loadPhotoMetadata(const QString &path, metadata_t &metadata);
|
||||||
|
static void loadVideoMetadata(const QString &path, metadata_t &metadata);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DATABASE_H
|
@@ -66,12 +66,13 @@ void BackupManagerForm::removeEntry(BackupItem *item)
|
|||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&db->mutex);
|
||||||
|
|
||||||
CMAObject *obj = db->ohfiToObject(item->ohfi);
|
metadata meta;
|
||||||
if(obj) {
|
if(db->getObjectMetadata(item->ohfi, meta)) {
|
||||||
obj->removeReferencedObject();
|
setBackupUsage(db->getObjectSize(meta.ohfiParent));
|
||||||
db->remove(obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db->deleteEntry(item->ohfi);
|
||||||
|
|
||||||
for(int i = 0; i < ui->tableWidget->rowCount(); ++i) {
|
for(int i = 0; i < ui->tableWidget->rowCount(); ++i) {
|
||||||
BackupItem *iter_item = static_cast<BackupItem *>(ui->tableWidget->cellWidget(i, 0));
|
BackupItem *iter_item = static_cast<BackupItem *>(ui->tableWidget->cellWidget(i, 0));
|
||||||
if(iter_item == item) {
|
if(iter_item == item) {
|
||||||
@@ -79,11 +80,6 @@ void BackupManagerForm::removeEntry(BackupItem *item)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = db->ohfiToObject(obj->metadata.ohfiParent);
|
|
||||||
if(obj) {
|
|
||||||
setBackupUsage(obj->metadata.size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackupManagerForm::setBackupUsage(quint64 size)
|
void BackupManagerForm::setBackupUsage(quint64 size)
|
||||||
@@ -146,10 +142,9 @@ void BackupManagerForm::loadBackupListing(int index)
|
|||||||
|
|
||||||
db->mutex.lock();
|
db->mutex.lock();
|
||||||
|
|
||||||
// get the item list
|
// get the item list
|
||||||
metadata_t *meta;
|
metadata_t *meta;
|
||||||
int row_count = db->filterObjects(ohfi, &meta);
|
int row_count = db->getObjectMetadatas(ohfi, meta);
|
||||||
|
|
||||||
ui->tableWidget->setRowCount(row_count);
|
ui->tableWidget->setRowCount(row_count);
|
||||||
|
|
||||||
// exit if there aren't any items
|
// exit if there aren't any items
|
||||||
@@ -167,13 +162,12 @@ void BackupManagerForm::loadBackupListing(int index)
|
|||||||
#else
|
#else
|
||||||
horiz_header->setResizeMode(QHeaderView::Stretch);
|
horiz_header->setResizeMode(QHeaderView::Stretch);
|
||||||
#endif
|
#endif
|
||||||
CMAObject *obj = db->ohfiToObject(ohfi);
|
setBackupUsage(db->getObjectSize(ohfi));
|
||||||
setBackupUsage(obj->metadata.size);
|
QString path = db->getAbsolutePath(ohfi);
|
||||||
|
|
||||||
QList<BackupItem *> item_list;
|
QList<BackupItem *> item_list;
|
||||||
|
|
||||||
while(meta) {
|
while(meta) {
|
||||||
QString base_path = obj->path + QDir::separator() + meta->name;
|
QString base_path = path + QDir::separator() + meta->name;
|
||||||
QString parent_path = sys_dir ? base_path + QDir::separator() + "sce_sys" : base_path;
|
QString parent_path = sys_dir ? base_path + QDir::separator() + "sce_sys" : base_path;
|
||||||
SfoReader reader;
|
SfoReader reader;
|
||||||
QString game_name;
|
QString game_name;
|
||||||
@@ -213,7 +207,7 @@ void BackupManagerForm::loadBackupListing(int index)
|
|||||||
|
|
||||||
item->setItemInfo(game_name, size, info);
|
item->setItemInfo(game_name, size, info);
|
||||||
item->setItemIcon(QDir(parent_path).absoluteFilePath(sys_dir ? "icon0.png" : "ICON0.PNG"), img_width, ohfi == VITA_OHFI_PSMAPP);
|
item->setItemIcon(QDir(parent_path).absoluteFilePath(sys_dir ? "icon0.png" : "ICON0.PNG"), img_width, ohfi == VITA_OHFI_PSMAPP);
|
||||||
item->setDirectory(obj->path + QDir::separator() + meta->name);
|
item->setDirectory(path + QDir::separator() + meta->name);
|
||||||
item->resize(646, 68);
|
item->resize(646, 68);
|
||||||
|
|
||||||
item_list << item;
|
item_list << item;
|
||||||
|
223
src/qlistdb.cpp
223
src/qlistdb.cpp
@@ -28,7 +28,8 @@
|
|||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
QListDB::QListDB() :
|
QListDB::QListDB(QObject *parent) :
|
||||||
|
Database(parent),
|
||||||
mutex(QMutex::Recursive)
|
mutex(QMutex::Recursive)
|
||||||
{
|
{
|
||||||
QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
|
QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
|
||||||
@@ -249,18 +250,18 @@ void QListDB::destroy()
|
|||||||
object_list.clear();
|
object_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QListDB::removeInternal(root_list &list, const CMAObject *obj)
|
bool QListDB::removeInternal(root_list &list, int ohfi)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
QList<CMAObject *>::iterator it = list.begin();
|
QList<CMAObject *>::iterator it = list.begin();
|
||||||
|
|
||||||
while(it != list.end()) {
|
while(it != list.end()) {
|
||||||
if(!found && (*it) == obj) {
|
if(!found && (*it)->metadata.ohfi == ohfi) {
|
||||||
// update the size of the parent objects
|
// update the size of the parent objects
|
||||||
(*it)->updateObjectSize(-(*it)->metadata.size);
|
(*it)->updateObjectSize(-(*it)->metadata.size);
|
||||||
it = list.erase(it);
|
it = list.erase(it);
|
||||||
found = true;
|
found = true;
|
||||||
} else if(found && (*it)->metadata.ohfiParent == obj->metadata.ohfi) {
|
} else if(found && (*it)->metadata.ohfiParent == ohfi) {
|
||||||
it = list.erase(it);
|
it = list.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
@@ -270,22 +271,6 @@ bool QListDB::removeInternal(root_list &list, const CMAObject *obj)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QListDB::remove(const CMAObject *obj, int ohfi_root)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
|
|
||||||
if(ohfi_root) {
|
|
||||||
return removeInternal(object_list[ohfi_root], obj);
|
|
||||||
} else {
|
|
||||||
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
|
||||||
if(removeInternal(*root, obj)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QListDB::lessThanComparator(const CMAObject *a, const CMAObject *b)
|
bool QListDB::lessThanComparator(const CMAObject *a, const CMAObject *b)
|
||||||
{
|
{
|
||||||
return a->metadata.ohfi < b->metadata.ohfi;
|
return a->metadata.ohfi < b->metadata.ohfi;
|
||||||
@@ -326,23 +311,6 @@ bool QListDB::find(int ohfi, QListDB::find_data &data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QListDB::append(int parent_ohfi, CMAObject *object)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
CMAObject parent;
|
|
||||||
parent.setOhfi(parent_ohfi);
|
|
||||||
|
|
||||||
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
|
||||||
root_list *cat_list = &(*root);
|
|
||||||
root_list::const_iterator it = qBinaryFind(cat_list->begin(), cat_list->end(), &parent, QListDB::lessThanComparator);
|
|
||||||
|
|
||||||
if(it != cat_list->end()) {
|
|
||||||
cat_list->append(object);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CMAObject *QListDB::ohfiToObject(int ohfi)
|
CMAObject *QListDB::ohfiToObject(int ohfi)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
@@ -363,24 +331,6 @@ CMAObject *QListDB::pathToObjectInternal(const root_list &list, const char *path
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMAObject *QListDB::pathToObject(const char *path, int ohfiRoot)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
|
|
||||||
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
|
||||||
|
|
||||||
if(ohfiRoot && (*root).first()->metadata.ohfi != ohfiRoot) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CMAObject *obj = pathToObjectInternal(*root, path);
|
|
||||||
|
|
||||||
if(obj) {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QListDB::acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type)
|
int QListDB::acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
@@ -421,10 +371,45 @@ void QListDB::dumpMetadataList(const metadata_t *p_head)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int QListDB::filterObjects(int ohfiParent, metadata_t **p_head, int index, int max_number)
|
bool QListDB::getObjectMetadata(int ohfi, metadata_t &metadata)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
CMARootObject *parent = static_cast<CMARootObject *>(ohfiToObject(ohfiParent));
|
|
||||||
|
CMAObject *obj = ohfiToObject(ohfi);
|
||||||
|
if(obj) {
|
||||||
|
//TODO: return the pointer instead of copying the struct
|
||||||
|
metadata = obj->metadata;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::childObjectCount(int parent_ohfi)
|
||||||
|
{
|
||||||
|
metadata_t *metadata = NULL;
|
||||||
|
return getObjectMetadatas(parent_ohfi, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::deleteEntry(int ohfi, int root_ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
if(root_ohfi) {
|
||||||
|
return removeInternal(object_list[root_ohfi], ohfi);
|
||||||
|
} else {
|
||||||
|
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
||||||
|
if(removeInternal(*root, ohfi)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::getObjectMetadatas(int parent_ohfi, metadata_t *&metadata, int index, int max_number)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
CMARootObject *parent = static_cast<CMARootObject *>(ohfiToObject(parent_ohfi));
|
||||||
|
|
||||||
if(parent == NULL) {
|
if(parent == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -433,11 +418,11 @@ int QListDB::filterObjects(int ohfiParent, metadata_t **p_head, int index, int m
|
|||||||
int type = parent->metadata.type;
|
int type = parent->metadata.type;
|
||||||
|
|
||||||
if(parent->metadata.ohfi < OHFI_OFFSET && parent->filters) { // if we have filters
|
if(parent->metadata.ohfi < OHFI_OFFSET && parent->filters) { // if we have filters
|
||||||
if(ohfiParent == parent->metadata.ohfi) { // if we are looking at root
|
if(parent_ohfi == parent->metadata.ohfi) { // if we are looking at root
|
||||||
return parent->getFilters(p_head);
|
return parent->getFilters(&metadata);
|
||||||
} else { // we are looking at a filter
|
} else { // we are looking at a filter
|
||||||
for(int j = 0; j < parent->num_filters; j++) {
|
for(int j = 0; j < parent->num_filters; j++) {
|
||||||
if(parent->filters[j].ohfi == ohfiParent) {
|
if(parent->filters[j].ohfi == parent_ohfi) {
|
||||||
type = parent->filters[j].type;
|
type = parent->filters[j].type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -472,9 +457,123 @@ int QListDB::filterObjects(int ohfiParent, metadata_t **p_head, int index, int m
|
|||||||
|
|
||||||
tail->next_metadata = NULL;
|
tail->next_metadata = NULL;
|
||||||
|
|
||||||
if(p_head != NULL) {
|
if(metadata != NULL) {
|
||||||
*p_head = temp.next_metadata;
|
metadata = temp.next_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
return numObjects;
|
return numObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint64 QListDB::getObjectSize(int ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
CMAObject *obj = ohfiToObject(ohfi);
|
||||||
|
return obj ? obj->metadata.size : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::getPathId(const char *name, int ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
||||||
|
|
||||||
|
if(ohfi && (*root).first()->metadata.ohfi != ohfi) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CMAObject *obj = pathToObjectInternal(*root, name);
|
||||||
|
|
||||||
|
if(obj) {
|
||||||
|
return obj->metadata.ohfi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::insertObjectEntry(const QString &path, int parent_ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
CMAObject *parent = ohfiToObject(parent_ohfi);
|
||||||
|
|
||||||
|
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
||||||
|
root_list *cat_list = &(*root);
|
||||||
|
root_list::const_iterator it = qBinaryFind(cat_list->begin(), cat_list->end(), parent, QListDB::lessThanComparator);
|
||||||
|
|
||||||
|
if(it != cat_list->end()) {
|
||||||
|
CMAObject *newobj = new CMAObject(parent);
|
||||||
|
newobj->initObject(path);
|
||||||
|
cat_list->append(newobj);
|
||||||
|
return newobj->metadata.ohfi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QListDB::getAbsolutePath(int ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
CMAObject *obj = ohfiToObject(ohfi);
|
||||||
|
return obj ? obj->path : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QListDB::getRelativePath(int ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
CMAObject *obj = ohfiToObject(ohfi);
|
||||||
|
return obj ? obj->metadata.path : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::renameObject(int ohfi, const QString &name)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
CMAObject *root = ohfiToObject(ohfi);
|
||||||
|
|
||||||
|
if(!root) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//rename the current object
|
||||||
|
root->rename(name);
|
||||||
|
QListDB::find_data iters;
|
||||||
|
find(root->metadata.ohfi, iters);
|
||||||
|
|
||||||
|
// rename the rest of the list only if has the renamed parent in some part of the chain
|
||||||
|
while(iters.it != iters.end) {
|
||||||
|
CMAObject *obj = *iters.it++;
|
||||||
|
|
||||||
|
if(obj->hasParent(root)) {
|
||||||
|
obj->refreshPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QListDB::setObjectSize(int ohfi, qint64 size)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
CMAObject *obj = ohfiToObject(ohfi);
|
||||||
|
|
||||||
|
if(obj) {
|
||||||
|
obj->updateObjectSize(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::getRootId(int ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
CMAObject *obj = ohfiToObject(ohfi);
|
||||||
|
|
||||||
|
if(!obj) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(obj->parent) {
|
||||||
|
obj = obj->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj->metadata.ohfi;
|
||||||
|
}
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#ifndef QLISTDB_H
|
#ifndef QLISTDB_H
|
||||||
#define QLISTDB_H
|
#define QLISTDB_H
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
#include "cmarootobject.h"
|
#include "cmarootobject.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@@ -30,51 +31,54 @@
|
|||||||
|
|
||||||
#include <vitamtp.h>
|
#include <vitamtp.h>
|
||||||
|
|
||||||
class QListDB : public QObject
|
class QListDB : public Database
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
explicit QListDB(QObject *parent = 0);
|
||||||
|
~QListDB();
|
||||||
|
|
||||||
|
bool reload(bool &prepared);
|
||||||
|
void setUUID(const QString uuid);
|
||||||
|
|
||||||
|
int childObjectCount(int parent_ohfi);
|
||||||
|
bool deleteEntry(int ohfi, int root_ohfi = 0);
|
||||||
|
QString getAbsolutePath(int ohfi);
|
||||||
|
bool getObjectMetadata(int ohfi, metadata_t &metadata);
|
||||||
|
int getObjectMetadatas(int parent_ohfi, metadata_t *&metadata, int index = 0, int max_number = 0);
|
||||||
|
qint64 getObjectSize(int ohfi);
|
||||||
|
int getPathId(const char *name, int ohfi);
|
||||||
|
QString getRelativePath(int ohfi);
|
||||||
|
int getRootId(int ohfi);
|
||||||
|
int insertObjectEntry(const QString &path, int parent_ohfi);
|
||||||
|
bool renameObject(int ohfi, const QString &name);
|
||||||
|
void setObjectSize(int ohfi, qint64 size);
|
||||||
|
|
||||||
|
QMutex mutex;
|
||||||
|
|
||||||
|
private:
|
||||||
typedef struct {
|
typedef struct {
|
||||||
QList<CMAObject *>::const_iterator it;
|
QList<CMAObject *>::const_iterator it;
|
||||||
QList<CMAObject *>::const_iterator end;
|
QList<CMAObject *>::const_iterator end;
|
||||||
} find_data;
|
} find_data;
|
||||||
|
|
||||||
explicit QListDB();
|
|
||||||
~QListDB();
|
|
||||||
|
|
||||||
bool reload(bool &prepared);
|
|
||||||
void setUUID(const QString uuid);
|
|
||||||
void addEntries(CMAObject *root);
|
|
||||||
CMAObject *ohfiToObject(int ohfi);
|
|
||||||
bool find(int ohfi, find_data &data);
|
|
||||||
void append(int parent_ohfi, CMAObject *object);
|
|
||||||
bool remove(const CMAObject *obj, int ohfi_root = 0);
|
|
||||||
int filterObjects(int ohfiParent, metadata_t **p_head, int index = 0, int max_number = 0);
|
|
||||||
CMAObject *pathToObject(const char *path, int ohfiRoot);
|
|
||||||
int acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type);
|
|
||||||
|
|
||||||
QMutex mutex;
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef QList<CMAObject *> root_list;
|
typedef QList<CMAObject *> root_list;
|
||||||
typedef QMap<int, root_list> map_list;
|
typedef QMap<int, root_list> map_list;
|
||||||
|
|
||||||
static const QStringList audio_types;
|
|
||||||
static const QStringList image_types;
|
|
||||||
static const QStringList video_types;
|
|
||||||
|
|
||||||
|
|
||||||
int create();
|
int create();
|
||||||
void destroy();
|
void destroy();
|
||||||
int scanRootDirectory(root_list &list,int ohfi_type);
|
int scanRootDirectory(root_list &list,int ohfi_type);
|
||||||
int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type);
|
int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type);
|
||||||
bool hasFilter(const CMARootObject *object,int ohfi);
|
bool hasFilter(const CMARootObject *object,int ohfi);
|
||||||
bool removeInternal(root_list &list, const CMAObject *obj);
|
bool removeInternal(root_list &list, int ohfi);
|
||||||
bool findInternal(const root_list &list, int ohfi, find_data &data);
|
bool findInternal(const root_list &list, int ohfi, find_data &data);
|
||||||
CMAObject *getParent(CMAObject *last_dir, const QString ¤t_path);
|
CMAObject *getParent(CMAObject *last_dir, const QString ¤t_path);
|
||||||
CMAObject *pathToObjectInternal(const root_list &list, const char *path);
|
CMAObject *pathToObjectInternal(const root_list &list, const char *path);
|
||||||
static bool lessThanComparator(const CMAObject *a, const CMAObject *b);
|
static bool lessThanComparator(const CMAObject *a, const CMAObject *b);
|
||||||
void dumpMetadataList(const metadata_t *p_head);
|
void dumpMetadataList(const metadata_t *p_head);
|
||||||
|
bool find(int ohfi, find_data &data);
|
||||||
|
int acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type);
|
||||||
|
CMAObject *ohfiToObject(int ohfi);
|
||||||
bool continueOperation();
|
bool continueOperation();
|
||||||
|
|
||||||
// control variables
|
// control variables
|
||||||
|
@@ -115,7 +115,7 @@ static const char *trigger_list[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SQLiteDB::SQLiteDB(QObject *parent) :
|
SQLiteDB::SQLiteDB(QObject *parent) :
|
||||||
QObject(parent)
|
Database(parent)
|
||||||
{
|
{
|
||||||
uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
|
uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
|
||||||
}
|
}
|
||||||
@@ -275,6 +275,13 @@ int SQLiteDB::recursiveScanRootDirectory(const QString &base_path, int parent, i
|
|||||||
return total_objects;
|
return total_objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SQLiteDB::getObjectMetadata(int ohfi, metadata_t &metadata)
|
||||||
|
{
|
||||||
|
Q_UNUSED(ohfi);
|
||||||
|
Q_UNUSED(metadata);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int SQLiteDB::getPathId(const QString &path)
|
int SQLiteDB::getPathId(const QString &path)
|
||||||
{
|
{
|
||||||
QSqlQuery query(QString("SELECT object_id from sources WHERE path = %1").arg(path));
|
QSqlQuery query(QString("SELECT object_id from sources WHERE path = %1").arg(path));
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef SQLITEDB_H
|
#ifndef SQLITEDB_H
|
||||||
#define SQLITEDB_H
|
#define SQLITEDB_H
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
|
|
||||||
#include <vitamtp.h>
|
#include <vitamtp.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -25,7 +27,7 @@
|
|||||||
|
|
||||||
#define OBJECT_APPLICATION 0x00080000
|
#define OBJECT_APPLICATION 0x00080000
|
||||||
|
|
||||||
class SQLiteDB : public QObject
|
class SQLiteDB : public Database
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@@ -51,6 +53,8 @@ public:
|
|||||||
uint insertSavedataEntry(const QString &path, int type, int parent);
|
uint insertSavedataEntry(const QString &path, int type, int parent);
|
||||||
uint insertApplicationEntry(const QString &path, int type, int parent, int app_type);
|
uint insertApplicationEntry(const QString &path, int type, int parent, int app_type);
|
||||||
|
|
||||||
|
bool getObjectMetadata(int ohfi, metadata_t &metadata);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int recursiveScanRootDirectory(const QString &base_path, int parent, int type);
|
int recursiveScanRootDirectory(const QString &base_path, int parent, int type);
|
||||||
uint insertDirectoryEntry(const QString &path, int type, int parent);
|
uint insertDirectoryEntry(const QString &path, int type, int parent);
|
||||||
|
@@ -31,26 +31,6 @@
|
|||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const file_type audio_list[] = {
|
|
||||||
{"mp3", FILE_FORMAT_MP3, CODEC_TYPE_MP3},
|
|
||||||
{"mp4", FILE_FORMAT_MP4, CODEC_TYPE_AAC},
|
|
||||||
{"wav", FILE_FORMAT_WAV, CODEC_TYPE_PCM}
|
|
||||||
};
|
|
||||||
|
|
||||||
const file_type photo_list[] = {
|
|
||||||
{"jpg", FILE_FORMAT_JPG, CODEC_TYPE_JPG},
|
|
||||||
{"jpeg", FILE_FORMAT_JPG, CODEC_TYPE_JPG},
|
|
||||||
{"png", FILE_FORMAT_PNG, CODEC_TYPE_PNG},
|
|
||||||
{"tif", FILE_FORMAT_TIF, CODEC_TYPE_TIF},
|
|
||||||
{"tiff", FILE_FORMAT_TIF, CODEC_TYPE_TIF},
|
|
||||||
{"bmp", FILE_FORMAT_BMP, CODEC_TYPE_BMP},
|
|
||||||
{"gif", FILE_FORMAT_GIF, CODEC_TYPE_GIF},
|
|
||||||
};
|
|
||||||
|
|
||||||
const file_type video_list[] = {
|
|
||||||
{"mp4", FILE_FORMAT_MP4, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total)
|
bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
@@ -195,33 +175,3 @@ QString readable_size(quint64 size, bool use_gib)
|
|||||||
}
|
}
|
||||||
return QString().setNum(size_f,'f',2) + " " + unit;
|
return QString().setNum(size_f,'f',2) + " " + unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int checkFileType(const QString path, int ohfi_root)
|
|
||||||
{
|
|
||||||
switch(ohfi_root) {
|
|
||||||
case VITA_OHFI_MUSIC:
|
|
||||||
for(int i = 0, max = sizeof(audio_list) / sizeof(file_type); i < max; i++) {
|
|
||||||
if(path.endsWith(audio_list[i].file_ext, Qt::CaseInsensitive)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VITA_OHFI_PHOTO:
|
|
||||||
for(int i = 0, max = sizeof(photo_list) / sizeof(file_type); i< max; i++) {
|
|
||||||
if(path.endsWith(photo_list[i].file_ext, Qt::CaseInsensitive)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VITA_OHFI_VIDEO:
|
|
||||||
for(int i = 0, max = sizeof(video_list) / sizeof(file_type); i< max; i++) {
|
|
||||||
if(path.endsWith(video_list[i].file_ext, Qt::CaseInsensitive)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
31
src/utils.h
31
src/utils.h
@@ -26,36 +26,6 @@
|
|||||||
|
|
||||||
#include <vitamtp.h>
|
#include <vitamtp.h>
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *file_ext;
|
|
||||||
int file_format;
|
|
||||||
int file_codec;
|
|
||||||
} file_type;
|
|
||||||
|
|
||||||
#define FILE_FORMAT_MP4 1
|
|
||||||
#define FILE_FORMAT_WAV 2
|
|
||||||
#define FILE_FORMAT_MP3 3
|
|
||||||
#define FILE_FORMAT_JPG 4
|
|
||||||
#define FILE_FORMAT_PNG 5
|
|
||||||
#define FILE_FORMAT_GIF 6
|
|
||||||
#define FILE_FORMAT_BMP 7
|
|
||||||
#define FILE_FORMAT_TIF 8
|
|
||||||
|
|
||||||
#define CODEC_TYPE_MPEG4 2
|
|
||||||
#define CODEC_TYPE_AVC 3
|
|
||||||
#define CODEC_TYPE_MP3 12
|
|
||||||
#define CODEC_TYPE_AAC 13
|
|
||||||
#define CODEC_TYPE_PCM 15
|
|
||||||
#define CODEC_TYPE_JPG 17
|
|
||||||
#define CODEC_TYPE_PNG 18
|
|
||||||
#define CODEC_TYPE_TIF 19
|
|
||||||
#define CODEC_TYPE_BMP 20
|
|
||||||
#define CODEC_TYPE_GIF 21
|
|
||||||
|
|
||||||
extern const file_type audio_list[3];
|
|
||||||
extern const file_type photo_list[7];
|
|
||||||
extern const file_type video_list[1];
|
|
||||||
|
|
||||||
// Qt4 doesn't have public methods for Thread::*sleep
|
// Qt4 doesn't have public methods for Thread::*sleep
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||||
typedef QThread Sleeper;
|
typedef QThread Sleeper;
|
||||||
@@ -79,6 +49,5 @@ bool removeRecursively(const QString &dirName);
|
|||||||
QString readable_size(quint64 size, bool use_gib = false);
|
QString readable_size(quint64 size, bool use_gib = false);
|
||||||
bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total);
|
bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total);
|
||||||
QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata);
|
QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata);
|
||||||
int checkFileType(const QString path, int ohfi_root);
|
|
||||||
|
|
||||||
#endif // UTILS_H
|
#endif // UTILS_H
|
||||||
|
Reference in New Issue
Block a user