Merge branch 'feature-database' into testing
This commit is contained in:
23
qcma.pro
23
qcma.pro
@@ -7,7 +7,8 @@
|
|||||||
QT += core \
|
QT += core \
|
||||||
gui \
|
gui \
|
||||||
widgets \
|
widgets \
|
||||||
network
|
network \
|
||||||
|
sql
|
||||||
|
|
||||||
TARGET = qcma
|
TARGET = qcma
|
||||||
|
|
||||||
@@ -17,10 +18,9 @@ TEMPLATE = app
|
|||||||
|
|
||||||
SOURCES += src/main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
src/capability.cpp \
|
src/capability.cpp \
|
||||||
src/database.cpp \
|
|
||||||
src/cmaobject.cpp \
|
src/cmaobject.cpp \
|
||||||
src/cmarootobject.cpp \
|
src/cmarootobject.cpp \
|
||||||
src/utils.cpp \
|
src/cmautils.cpp \
|
||||||
src/mainwidget.cpp \
|
src/mainwidget.cpp \
|
||||||
src/singleapplication.cpp \
|
src/singleapplication.cpp \
|
||||||
src/sforeader.cpp \
|
src/sforeader.cpp \
|
||||||
@@ -31,21 +31,23 @@ SOURCES += src/main.cpp \
|
|||||||
src/clientmanager.cpp \
|
src/clientmanager.cpp \
|
||||||
src/filterlineedit.cpp \
|
src/filterlineedit.cpp \
|
||||||
src/dds.cpp \
|
src/dds.cpp \
|
||||||
|
src/sqlitedb.cpp \
|
||||||
|
src/httpdownloader.cpp \
|
||||||
|
src/qlistdb.cpp \
|
||||||
|
src/database.cpp \
|
||||||
# forms
|
# forms
|
||||||
src/forms/backupitem.cpp \
|
src/forms/backupitem.cpp \
|
||||||
src/forms/backupmanagerform.cpp \
|
src/forms/backupmanagerform.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/httpdownloader.cpp
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/capability.h \
|
src/capability.h \
|
||||||
src/database.h \
|
|
||||||
src/cmaobject.h \
|
src/cmaobject.h \
|
||||||
src/cmarootobject.h \
|
src/cmarootobject.h \
|
||||||
src/utils.h \
|
src/cmautils.h \
|
||||||
src/mainwidget.h \
|
src/mainwidget.h \
|
||||||
src/singleapplication.h \
|
src/singleapplication.h \
|
||||||
src/sforeader.h \
|
src/sforeader.h \
|
||||||
@@ -56,14 +58,17 @@ HEADERS += \
|
|||||||
src/clientmanager.h \
|
src/clientmanager.h \
|
||||||
src/filterlineedit.h \
|
src/filterlineedit.h \
|
||||||
src/dds.h \
|
src/dds.h \
|
||||||
|
src/sqlitedb.h \
|
||||||
|
src/httpdownloader.h \
|
||||||
|
src/qlistdb.h \
|
||||||
|
src/database.h \
|
||||||
# forms
|
# forms
|
||||||
src/forms/backupitem.h \
|
src/forms/backupitem.h \
|
||||||
src/forms/backupmanagerform.h \
|
src/forms/backupmanagerform.h \
|
||||||
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/httpdownloader.h
|
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
src/forms/configwidget.ui \
|
src/forms/configwidget.ui \
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils.h"
|
#include "cmautils.h"
|
||||||
#include "avdecoder.h"
|
#include "avdecoder.h"
|
||||||
#include "cmaobject.h"
|
#include "database.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
|
|||||||
@@ -19,15 +19,15 @@
|
|||||||
|
|
||||||
#include "clientmanager.h"
|
#include "clientmanager.h"
|
||||||
#include "cmaclient.h"
|
#include "cmaclient.h"
|
||||||
#include "utils.h"
|
#include "cmautils.h"
|
||||||
#include "forms/progressform.h"
|
#include "forms/progressform.h"
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
#include <vitamtp.h>
|
#include <vitamtp.h>
|
||||||
|
|
||||||
ClientManager::ClientManager(QObject *parent) :
|
ClientManager::ClientManager(Database *db, QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent), m_db(db)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,11 +63,10 @@ void ClientManager::start()
|
|||||||
// initializing database for the first use
|
// initializing database for the first use
|
||||||
refreshDatabase();
|
refreshDatabase();
|
||||||
|
|
||||||
CmaEvent::db = &db;
|
connect(m_db, SIGNAL(fileAdded(QString)), &progress, SLOT(setFileName(QString)));
|
||||||
connect(&db, SIGNAL(fileAdded(QString)), &progress, SLOT(setFileName(QString)));
|
connect(m_db, SIGNAL(directoryAdded(QString)), &progress, SLOT(setDirectoryName(QString)));
|
||||||
connect(&db, SIGNAL(directoryAdded(QString)), &progress, SLOT(setDirectoryName(QString)));
|
connect(m_db, SIGNAL(updated(int)), this, SLOT(databaseUpdated(int)));
|
||||||
connect(&db, SIGNAL(updated(int)), this, SLOT(databaseUpdated(int)));
|
connect(&progress, SIGNAL(canceled()), m_db, SLOT(cancelOperation()), Qt::DirectConnection);
|
||||||
connect(&progress, SIGNAL(canceled()), &db, SLOT(cancelOperation()), Qt::DirectConnection);
|
|
||||||
|
|
||||||
thread_count = 0;
|
thread_count = 0;
|
||||||
qDebug("Starting cma threads");
|
qDebug("Starting cma threads");
|
||||||
@@ -76,7 +75,7 @@ void ClientManager::start()
|
|||||||
|
|
||||||
if(!settings.value("disableUSB", false).toBool()) {
|
if(!settings.value("disableUSB", false).toBool()) {
|
||||||
usb_thread = new QThread();
|
usb_thread = new QThread();
|
||||||
client = new CmaClient();
|
client = new CmaClient(m_db);
|
||||||
usb_thread->setObjectName("usb_thread");
|
usb_thread->setObjectName("usb_thread");
|
||||||
connect(usb_thread, SIGNAL(started()), client, SLOT(connectUsb()));
|
connect(usb_thread, SIGNAL(started()), client, SLOT(connectUsb()));
|
||||||
connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)));
|
connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)));
|
||||||
@@ -96,7 +95,7 @@ void ClientManager::start()
|
|||||||
|
|
||||||
if(!settings.value("disableWireless", false).toBool()) {
|
if(!settings.value("disableWireless", false).toBool()) {
|
||||||
wireless_thread = new QThread();
|
wireless_thread = new QThread();
|
||||||
client = new CmaClient();
|
client = new CmaClient(m_db);
|
||||||
wireless_thread->setObjectName("wireless_thread");
|
wireless_thread->setObjectName("wireless_thread");
|
||||||
connect(wireless_thread, SIGNAL(started()), client, SLOT(connectWireless()));
|
connect(wireless_thread, SIGNAL(started()), client, SLOT(connectWireless()));
|
||||||
connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)));
|
connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)));
|
||||||
@@ -123,13 +122,12 @@ void ClientManager::start()
|
|||||||
|
|
||||||
void ClientManager::refreshDatabase()
|
void ClientManager::refreshDatabase()
|
||||||
{
|
{
|
||||||
bool prepared;
|
if(m_db->load()) {
|
||||||
if(!db.reload(prepared)) {
|
return;
|
||||||
if(prepared) {
|
}
|
||||||
emit messageSent(tr("Cannot refresh the database while is in use"));
|
|
||||||
} else {
|
if(!m_db->rescan()) {
|
||||||
emit messageSent(tr("No PS Vita system has been registered"));
|
emit messageSent(tr("No PS Vita system has been registered"));
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
progress.showDelayed(1000);
|
progress.showDelayed(1000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#ifndef CLIENTMANAGER_H
|
#ifndef CLIENTMANAGER_H
|
||||||
#define CLIENTMANAGER_H
|
#define CLIENTMANAGER_H
|
||||||
|
|
||||||
#include "database.h"
|
#include "qlistdb.h"
|
||||||
#include "forms/pinform.h"
|
#include "forms/pinform.h"
|
||||||
#include "forms/progressform.h"
|
#include "forms/progressform.h"
|
||||||
|
|
||||||
@@ -31,18 +31,18 @@ class ClientManager : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ClientManager(QObject *parent = 0);
|
explicit ClientManager(Database *db, QObject *parent = 0);
|
||||||
~ClientManager();
|
~ClientManager();
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
Database db;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int thread_count;
|
int thread_count;
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
|
|
||||||
|
Database *m_db;
|
||||||
|
|
||||||
PinForm pinForm;
|
PinForm pinForm;
|
||||||
ProgressForm progress;
|
ProgressForm progress;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include "capability.h"
|
#include "capability.h"
|
||||||
#include "avdecoder.h"
|
#include "avdecoder.h"
|
||||||
#include "cmaevent.h"
|
#include "cmaevent.h"
|
||||||
#include "utils.h"
|
#include "cmautils.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
@@ -45,8 +45,8 @@ bool CmaClient::in_progress = false;
|
|||||||
|
|
||||||
CmaClient *CmaClient::this_object = NULL;
|
CmaClient *CmaClient::this_object = NULL;
|
||||||
|
|
||||||
CmaClient::CmaClient(QObject *parent) :
|
CmaClient::CmaClient(Database *db, QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent), m_db(db)
|
||||||
{
|
{
|
||||||
this_object = this;
|
this_object = this;
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ void CmaClient::enterEventLoop(vita_device_t *device)
|
|||||||
|
|
||||||
qDebug("Starting event loop");
|
qDebug("Starting event loop");
|
||||||
|
|
||||||
CmaEvent eventLoop (device);
|
CmaEvent eventLoop(m_db, device);
|
||||||
QThread thread;
|
QThread thread;
|
||||||
thread.setObjectName("event_thread");
|
thread.setObjectName("event_thread");
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,8 @@
|
|||||||
#ifndef CMACLIENT_H
|
#ifndef CMACLIENT_H
|
||||||
#define CMACLIENT_H
|
#define CMACLIENT_H
|
||||||
|
|
||||||
#include "database.h"
|
#include "qlistdb.h"
|
||||||
#include "cmaevent.h"
|
#include "cmaevent.h"
|
||||||
#include "cmaobject.h"
|
|
||||||
#include "cmabroadcast.h"
|
#include "cmabroadcast.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -36,7 +35,7 @@ class CmaClient : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CmaClient(QObject *parent = 0);
|
explicit CmaClient(Database *db, QObject *parent = 0);
|
||||||
|
|
||||||
static bool isRunning();
|
static bool isRunning();
|
||||||
void launch();
|
void launch();
|
||||||
@@ -56,6 +55,7 @@ private:
|
|||||||
static void registrationComplete();
|
static void registrationComplete();
|
||||||
|
|
||||||
CmaBroadcast broadcast;
|
CmaBroadcast broadcast;
|
||||||
|
Database *m_db;
|
||||||
static QString tempOnlineId;
|
static QString tempOnlineId;
|
||||||
|
|
||||||
//TODO: move all the control variables to the client manager class
|
//TODO: move all the control variables to the client manager class
|
||||||
|
|||||||
313
src/cmaevent.cpp
313
src/cmaevent.cpp
@@ -18,24 +18,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cmaevent.h"
|
#include "cmaevent.h"
|
||||||
#include "utils.h"
|
#include "cmautils.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QThread>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
Database *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(Database *db, vita_device_t *s_device) :
|
||||||
device(s_device), is_active(true)
|
device(s_device), m_db(db), is_active(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,15 +147,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 +170,17 @@ quint16 CmaEvent::processAllObjects(CMAObject *parent, quint32 handle)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CMAObject *object = db->pathToObject(name, parent->metadata.ohfi);
|
int ohfi = m_db->getPathId(name, parent_metadata.ohfi);
|
||||||
|
|
||||||
if(object) {
|
if(ohfi > 0) {
|
||||||
qDebug("Deleting %s", object->path.toStdString().c_str());
|
const QString fullpath = m_db->getAbsolutePath(ohfi);
|
||||||
removeRecursively(object->path);
|
qDebug() << "Deleting" << fullpath;
|
||||||
db->remove(object);
|
removeRecursively(fullpath);
|
||||||
|
m_db->deleteEntry(ohfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir dir(parent->path);
|
QString fullpath = m_db->getAbsolutePath(parent_metadata.ohfi);
|
||||||
|
QDir dir(fullpath);
|
||||||
|
|
||||||
if(dataType & Folder) {
|
if(dataType & Folder) {
|
||||||
if(!dir.mkpath(name)) {
|
if(!dir.mkpath(name)) {
|
||||||
@@ -205,33 +203,24 @@ 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 = Database::checkFileType(dir.absoluteFilePath(name), root_obj->metadata.ohfi);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QFileInfo info(dir, name);
|
int new_ohfi = m_db->insertObjectEntry(fullpath, name, parent_metadata.ohfi);
|
||||||
object = new CMAObject(parent);
|
qDebug("Added object %s with OHFI %i to database", name, new_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);
|
|
||||||
|
|
||||||
if(dataType & Folder) {
|
if(dataType & Folder) {
|
||||||
|
metadata_t folder_metadata;
|
||||||
|
m_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);
|
m_db->deleteEntry(new_ohfi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,17 +240,17 @@ void CmaEvent::vitaEventGetTreatObject(vita_event_t *event, int eventId)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
CMAObject *parent = db->ohfiToObject(treatObject.ohfiParent);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(parent == NULL) {
|
if(!m_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)
|
||||||
@@ -274,23 +263,22 @@ void CmaEvent::vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_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 = m_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);
|
||||||
@@ -309,21 +297,20 @@ void CmaEvent::vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(object == NULL) {
|
if(!m_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 {
|
||||||
@@ -366,10 +353,10 @@ void CmaEvent::vitaEventSendNumOfObject(vita_event_t *event, int eventId)
|
|||||||
{
|
{
|
||||||
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
uint ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
int items = db->filterObjects(ohfi, NULL);
|
int items = m_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);
|
||||||
@@ -389,10 +376,11 @@ void CmaEvent::vitaEventSendObjectMetadata(vita_event_t *event, int eventId)
|
|||||||
qWarning("GetBrowseInfo failed");
|
qWarning("GetBrowseInfo failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_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 = m_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
|
||||||
@@ -400,6 +388,7 @@ void CmaEvent::vitaEventSendObjectMetadata(vita_event_t *event, int eventId)
|
|||||||
} else {
|
} else {
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
}
|
}
|
||||||
|
m_db->freeMetadata(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
|
void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
|
||||||
@@ -408,33 +397,31 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
|
|||||||
|
|
||||||
int ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
qDebug("Searching object with OHFI %d", ohfi);
|
qDebug("Searching object with OHFI %d", ohfi);
|
||||||
|
|
||||||
Database::find_data iters;
|
metadata_t *metadata = NULL;
|
||||||
if(!db->find(ohfi, iters)) {
|
if(!m_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(m_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 +432,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;
|
||||||
|
m_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 +454,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 +466,11 @@ 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_BASE_VALUE); // get everything under this "folder"
|
||||||
|
|
||||||
|
m_db->freeMetadata(start);
|
||||||
|
|
||||||
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, handle);
|
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, handle);
|
||||||
|
|
||||||
@@ -571,20 +562,22 @@ void CmaEvent::vitaEventSendObjectStatus(vita_event_t *event, int eventId)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->pathToObject(objectstatus.title, objectstatus.ohfiRoot);
|
qDebug("Checking for path %s under ohfi %i", objectstatus.title, objectstatus.ohfiRoot);
|
||||||
|
int ohfi = m_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_t();
|
||||||
metadata->next_metadata = NULL;
|
m_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);
|
||||||
}
|
}
|
||||||
@@ -597,25 +590,28 @@ void CmaEvent::vitaEventSendObjectThumb(vita_event_t *event, int eventId)
|
|||||||
{
|
{
|
||||||
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
int ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(object == NULL) {
|
if(!m_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 = m_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");
|
||||||
@@ -635,20 +631,21 @@ void CmaEvent::vitaEventDeleteObject(vita_event_t *event, int eventId)
|
|||||||
{
|
{
|
||||||
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
int ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
metadata_t metadata;
|
||||||
|
|
||||||
if(object == NULL) {
|
if(!m_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 = m_db->getAbsolutePath(ohfi);
|
||||||
removeRecursively(object->path);
|
qDebug() << QString("Deleting %1, OHFI: %2").arg(fullpath, QString::number(ohfi));
|
||||||
db->remove(object);
|
removeRecursively(fullpath);
|
||||||
|
m_db->deleteEntry(ohfi);
|
||||||
|
|
||||||
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
|
||||||
}
|
}
|
||||||
@@ -668,7 +665,7 @@ void CmaEvent::vitaEventGetSettingInfo(vita_event_t *event, int eventId)
|
|||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
if(settings.value("lastAccountId").toString() != settingsinfo->current_account.accountId) {
|
if(settings.value("lastAccountId").toString() != settingsinfo->current_account.accountId) {
|
||||||
db->setUUID(settingsinfo->current_account.accountId);
|
m_db->setUUID(settingsinfo->current_account.accountId);
|
||||||
// set the database to be updated ASAP
|
// set the database to be updated ASAP
|
||||||
emit refreshDatabase();
|
emit refreshDatabase();
|
||||||
}
|
}
|
||||||
@@ -725,26 +722,28 @@ void CmaEvent::vitaEventSendPartOfObject(vita_event_t *event, int eventId)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->ohfiToObject(part_init.ohfi);
|
QString fullpath = m_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);
|
||||||
@@ -765,12 +764,12 @@ void CmaEvent::vitaEventOperateObject(vita_event_t *event, int eventId)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
CMAObject *root = db->ohfiToObject(operateobject.ohfi);
|
QString fullpath = m_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 +778,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 = m_db->insertObjectEntry(fullpath, 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 = m_db->insertObjectEntry(fullpath, operateobject.title, 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;
|
m_db->renameObject(operateobject.ohfi, operateobject.title);
|
||||||
QString oldname = root->metadata.name;
|
QString newpath = m_db->getAbsolutePath(operateobject.ohfi);
|
||||||
|
|
||||||
//rename the current object
|
|
||||||
root->rename(operateobject.title);
|
|
||||||
Database::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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,27 +842,33 @@ void CmaEvent::vitaEventGetPartOfObject(vita_event_t *event, int eventId)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
CMAObject *object = db->ohfiToObject(part_init.ohfi);
|
QString fullpath = m_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);
|
m_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -892,23 +879,23 @@ void CmaEvent::vitaEventSendStorageSize(vita_event_t *event, int eventId)
|
|||||||
{
|
{
|
||||||
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
qDebug("Event recieved in %s, code: 0x%x, id: %d", Q_FUNC_INFO, event->Code, eventId);
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
int ohfi = event->Param2;
|
int ohfi = event->Param2;
|
||||||
CMAObject *object = db->ohfiToObject(ohfi);
|
QString fullpath = m_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 +906,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;
|
||||||
@@ -946,14 +933,14 @@ void CmaEvent::vitaEventCheckExistance(vita_event_t *event, int eventId)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
CMAObject *object = db->pathToObject(existance.name, 0);
|
int ohfi = m_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,10 +20,10 @@
|
|||||||
#ifndef CMAEVENT_H
|
#ifndef CMAEVENT_H
|
||||||
#define CMAEVENT_H
|
#define CMAEVENT_H
|
||||||
|
|
||||||
#include "cmaobject.h"
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "httpdownloader.h"
|
#include "httpdownloader.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
@@ -34,15 +34,11 @@ class CmaEvent : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CmaEvent(vita_device_t *s_device);
|
explicit CmaEvent(Database *db, vita_device_t *s_device);
|
||||||
|
|
||||||
void vitaEventCancelTask(vita_event_t *event, int eventId);
|
void vitaEventCancelTask(vita_event_t *event, int eventId);
|
||||||
|
|
||||||
// don't make the db reference static
|
|
||||||
static Database *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);
|
||||||
@@ -73,13 +69,14 @@ private:
|
|||||||
vita_device_t *device;
|
vita_device_t *device;
|
||||||
vita_event_t t_event;
|
vita_event_t t_event;
|
||||||
|
|
||||||
|
Database *m_db;
|
||||||
|
|
||||||
// control variables
|
// control variables
|
||||||
bool is_active;
|
bool is_active;
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
QMutex active;
|
QMutex active;
|
||||||
QSemaphore sema;
|
QSemaphore sema;
|
||||||
|
|
||||||
static metadata_t g_thumbmeta;
|
|
||||||
static QFile *m_file;
|
static QFile *m_file;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
#include "cmaobject.h"
|
#include "cmaobject.h"
|
||||||
#include "sforeader.h"
|
#include "sforeader.h"
|
||||||
#include "avdecoder.h"
|
#include "avdecoder.h"
|
||||||
#include "utils.h"
|
#include "database.h"
|
||||||
|
#include "cmautils.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
@@ -29,24 +30,6 @@
|
|||||||
|
|
||||||
int CMAObject::ohfi_count = OHFI_OFFSET;
|
int CMAObject::ohfi_count = OHFI_OFFSET;
|
||||||
|
|
||||||
const CMAObject::file_type CMAObject::audio_list[] = {
|
|
||||||
{"mp3", FILE_FORMAT_MP3, CODEC_TYPE_MP3},
|
|
||||||
{"mp4", FILE_FORMAT_MP4, CODEC_TYPE_AAC},
|
|
||||||
{"wav", FILE_FORMAT_WAV, CODEC_TYPE_PCM}
|
|
||||||
};
|
|
||||||
|
|
||||||
const CMAObject::file_type CMAObject::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 char *CMAObject::video_list[] = {"mp4"};
|
|
||||||
|
|
||||||
CMAObject::CMAObject(CMAObject *obj_parent) :
|
CMAObject::CMAObject(CMAObject *obj_parent) :
|
||||||
parent(obj_parent), metadata()
|
parent(obj_parent), metadata()
|
||||||
{
|
{
|
||||||
@@ -126,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());
|
||||||
@@ -199,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();
|
||||||
@@ -209,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) {
|
||||||
@@ -225,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();
|
||||||
@@ -240,15 +181,6 @@ void CMAObject::initObject(const QFileInfo &file, int file_type)
|
|||||||
updateObjectSize(file.size());
|
updateObjectSize(file.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMAObject::removeReferencedObject()
|
|
||||||
{
|
|
||||||
if(metadata.dataType & Folder) {
|
|
||||||
return removeRecursively(path);
|
|
||||||
} else {
|
|
||||||
return QFile::remove(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMAObject::updateObjectSize(qint64 size)
|
void CMAObject::updateObjectSize(qint64 size)
|
||||||
{
|
{
|
||||||
if(parent) {
|
if(parent) {
|
||||||
|
|||||||
@@ -27,26 +27,6 @@
|
|||||||
|
|
||||||
#define OHFI_OFFSET 256
|
#define OHFI_OFFSET 256
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
class CMAObject
|
class CMAObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -54,7 +34,6 @@ public:
|
|||||||
~CMAObject();
|
~CMAObject();
|
||||||
|
|
||||||
void refreshPath();
|
void refreshPath();
|
||||||
bool removeReferencedObject();
|
|
||||||
void rename(const QString &name);
|
void rename(const QString &name);
|
||||||
void updateObjectSize(qint64 size);
|
void updateObjectSize(qint64 size);
|
||||||
bool hasParent(const CMAObject *obj);
|
bool hasParent(const CMAObject *obj);
|
||||||
@@ -72,16 +51,6 @@ public:
|
|||||||
ohfi_count = OHFI_OFFSET;
|
ohfi_count = OHFI_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *file_ext;
|
|
||||||
int file_format;
|
|
||||||
int file_codec;
|
|
||||||
} file_type;
|
|
||||||
|
|
||||||
static const file_type audio_list[3];
|
|
||||||
static const file_type photo_list[7];
|
|
||||||
static const char *video_list[1];
|
|
||||||
|
|
||||||
QString path;
|
QString path;
|
||||||
CMAObject *parent;
|
CMAObject *parent;
|
||||||
metadata_t metadata;
|
metadata_t metadata;
|
||||||
@@ -91,9 +60,6 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void loadSfoMetadata(const QString &path);
|
void loadSfoMetadata(const QString &path);
|
||||||
void loadMusicMetadata(const QString &path);
|
|
||||||
void loadVideoMetadata(const QString &path);
|
|
||||||
void loadPhotoMetadata(const QString &path);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CMAOBJECT_H
|
#endif // CMAOBJECT_H
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "utils.h"
|
#include "cmautils.h"
|
||||||
#include "avdecoder.h"
|
#include "avdecoder.h"
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
@@ -52,31 +52,37 @@ bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool removeRecursively(const QString &dirName)
|
bool removeRecursively(const QString &path)
|
||||||
{
|
{
|
||||||
|
QFileInfo info(path);
|
||||||
|
|
||||||
|
if(info.isDir()) {
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||||
return QDir(dirName).removeRecursively();
|
return QDir(path).removeRecursively();
|
||||||
#else
|
#else
|
||||||
bool result = false;
|
bool result = false;
|
||||||
QDir dir(dirName);
|
QDir dir(path);
|
||||||
|
|
||||||
if(dir.exists(dirName)) {
|
if(dir.exists(path)) {
|
||||||
Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
|
Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
|
||||||
if(info.isDir()) {
|
if(info.isDir()) {
|
||||||
result = removeRecursively(info.absoluteFilePath());
|
result = removeRecursively(info.absoluteFilePath());
|
||||||
} else {
|
} else {
|
||||||
result = QFile::remove(info.absoluteFilePath());
|
result = QFile::remove(info.absoluteFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
result = dir.rmdir(path);
|
||||||
}
|
}
|
||||||
result = dir.rmdir(dirName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
return QFile::remove(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray findFolderAlbumArt(const QString path, metadata_t *metadata)
|
QByteArray findFolderAlbumArt(const QString path, metadata_t *metadata)
|
||||||
@@ -156,7 +162,7 @@ QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString readable_size(quint64 size, bool use_gib)
|
QString readable_size(qint64 size, bool use_gib)
|
||||||
{
|
{
|
||||||
QStringList list;
|
QStringList list;
|
||||||
list << "KiB" << "MiB";
|
list << "KiB" << "MiB";
|
||||||
@@ -45,8 +45,8 @@ public:
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool removeRecursively(const QString &dirName);
|
bool removeRecursively(const QString &path);
|
||||||
QString readable_size(quint64 size, bool use_gib = false);
|
QString readable_size(qint64 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);
|
||||||
|
|
||||||
531
src/database.cpp
531
src/database.cpp
@@ -1,89 +1,45 @@
|
|||||||
/*
|
|
||||||
* QCMA: Cross-platform content manager assistant for the PS Vita
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Codestation
|
|
||||||
*
|
|
||||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "cmaobject.h"
|
#include "avdecoder.h"
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QDirIterator>
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QTextStream>
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
Database::Database() :
|
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),
|
||||||
mutex(QMutex::Recursive)
|
mutex(QMutex::Recursive)
|
||||||
{
|
{
|
||||||
QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
|
|
||||||
CMARootObject::uuid = uuid;
|
|
||||||
thread = new QThread();
|
|
||||||
timer = new QTimer();
|
|
||||||
moveToThread(thread);
|
|
||||||
thread->start();
|
|
||||||
|
|
||||||
timer->setInterval(0);
|
|
||||||
timer->setSingleShot(true);
|
|
||||||
connect(timer, SIGNAL(timeout()), this, SLOT(process()));
|
|
||||||
}
|
}
|
||||||
|
#include <QDebug>
|
||||||
Database::~Database()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
timer->stop();
|
|
||||||
delete timer;
|
|
||||||
thread->quit();
|
|
||||||
thread->wait();
|
|
||||||
delete thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::setUUID(const QString uuid)
|
|
||||||
{
|
|
||||||
CMARootObject::uuid = uuid;
|
|
||||||
QSettings().setValue("lastAccountId", uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::reload(bool &prepared)
|
|
||||||
{
|
|
||||||
if(mutex.tryLock()) {
|
|
||||||
if(CMARootObject::uuid != "ffffffffffffffff") {
|
|
||||||
timer->start();
|
|
||||||
prepared = true;
|
|
||||||
} else {
|
|
||||||
mutex.unlock();
|
|
||||||
prepared = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::process()
|
void Database::process()
|
||||||
{
|
{
|
||||||
destroy();
|
qDebug("Starting database_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId());
|
||||||
|
clear();
|
||||||
cancel_operation = false;
|
cancel_operation = false;
|
||||||
int count = create();
|
int count = create();
|
||||||
cancel_operation = false;
|
cancel_operation = false;
|
||||||
qDebug("Added %i entries to the database", count);
|
qDebug("Total entries added to the database: %i", count);
|
||||||
if(count < 0) {
|
if(count < 0) {
|
||||||
destroy();
|
clear();
|
||||||
}
|
}
|
||||||
emit updated(count);
|
emit updated(count);
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
@@ -101,403 +57,26 @@ bool Database::continueOperation()
|
|||||||
return !cancel_operation;
|
return !cancel_operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::create()
|
|
||||||
{
|
|
||||||
int total_objects = 0;
|
|
||||||
//QMutexLocker locker(&mutex);
|
|
||||||
const int ohfi_array[] = { VITA_OHFI_MUSIC, VITA_OHFI_PHOTO, VITA_OHFI_VIDEO,
|
|
||||||
VITA_OHFI_BACKUP, VITA_OHFI_VITAAPP, VITA_OHFI_PSPAPP,
|
|
||||||
VITA_OHFI_PSPSAVE, VITA_OHFI_PSXAPP, VITA_OHFI_PSMAPP
|
|
||||||
};
|
|
||||||
CMAObject::resetOhfiCounter();
|
|
||||||
QSettings settings;
|
|
||||||
|
|
||||||
for(int i = 0, max = sizeof(ohfi_array) / sizeof(int); i < max; i++) {
|
|
||||||
CMARootObject *obj = new CMARootObject(ohfi_array[i]);
|
|
||||||
|
|
||||||
switch(ohfi_array[i]) {
|
|
||||||
case VITA_OHFI_MUSIC:
|
|
||||||
obj->initObject(settings.value("musicPath").toString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VITA_OHFI_PHOTO:
|
|
||||||
obj->initObject(settings.value("photoPath").toString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VITA_OHFI_VIDEO:
|
|
||||||
obj->initObject(settings.value("videoPath").toString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VITA_OHFI_BACKUP:
|
|
||||||
case VITA_OHFI_VITAAPP:
|
|
||||||
case VITA_OHFI_PSPAPP:
|
|
||||||
case VITA_OHFI_PSPSAVE:
|
|
||||||
case VITA_OHFI_PSXAPP:
|
|
||||||
case VITA_OHFI_PSMAPP:
|
|
||||||
obj->initObject(settings.value("appsPath").toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
root_list list;
|
|
||||||
list << obj;
|
|
||||||
emit directoryAdded(obj->path);
|
|
||||||
int dir_count = recursiveScanRootDirectory(list, obj, ohfi_array[i]);
|
|
||||||
|
|
||||||
if(dir_count < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_objects += dir_count;
|
|
||||||
object_list[ohfi_array[i]] = list;
|
|
||||||
}
|
|
||||||
return total_objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMAObject *Database::getParent(CMAObject *last_dir, const QString ¤t_path)
|
|
||||||
{
|
|
||||||
while(last_dir && current_path != last_dir->path) {
|
|
||||||
last_dir = last_dir->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return last_dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Database::scanRootDirectory(root_list &list, int ohfi_type)
|
|
||||||
{
|
|
||||||
int file_type = -1;
|
|
||||||
int total_objects = 0;
|
|
||||||
CMAObject *last_dir = list.first();
|
|
||||||
QDir dir(last_dir->path);
|
|
||||||
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
|
|
||||||
QDirIterator it(dir, QDirIterator::Subdirectories);
|
|
||||||
|
|
||||||
while(it.hasNext()) {
|
|
||||||
|
|
||||||
if(!continueOperation()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
it.next();
|
|
||||||
QFileInfo info = it.fileInfo();
|
|
||||||
|
|
||||||
if(info.isFile()) {
|
|
||||||
if((file_type = checkFileType(info.absoluteFilePath(), ohfi_type)) < 0) {
|
|
||||||
//qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CMAObject *obj = new CMAObject(getParent(last_dir, info.path()));
|
|
||||||
obj->initObject(info, file_type);
|
|
||||||
//qDebug("Added %s to database with OHFI %d", obj->metadata.name, obj->metadata.ohfi);
|
|
||||||
list << obj;
|
|
||||||
|
|
||||||
if(obj->metadata.dataType & Folder) {
|
|
||||||
last_dir = obj;
|
|
||||||
} else {
|
|
||||||
total_objects++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return total_objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Database::recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type)
|
|
||||||
{
|
|
||||||
int file_type = -1;
|
|
||||||
int total_objects = 0;
|
|
||||||
|
|
||||||
QDir dir(parent->path);
|
|
||||||
dir.setSorting(QDir::Name | QDir::DirsFirst);
|
|
||||||
QFileInfoList qsl = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
|
|
||||||
|
|
||||||
foreach(const QFileInfo &info, qsl) {
|
|
||||||
|
|
||||||
if(!continueOperation()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(info.isFile() && (file_type = checkFileType(info.absoluteFilePath(), ohfi_type)) < 0) {
|
|
||||||
//qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());>
|
|
||||||
} else {
|
|
||||||
CMAObject *obj = new CMAObject(parent);
|
|
||||||
obj->initObject(info, file_type);
|
|
||||||
emit fileAdded(obj->metadata.name);
|
|
||||||
//qDebug("Added %s to database with OHFI %d", obj->metadata.name, obj->metadata.ohfi);
|
|
||||||
list << obj;
|
|
||||||
if(info.isDir()) {
|
|
||||||
emit directoryAdded(obj->path);
|
|
||||||
total_objects += recursiveScanRootDirectory(list, obj, ohfi_type);
|
|
||||||
} else {
|
|
||||||
total_objects++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return total_objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::destroy()
|
|
||||||
{
|
|
||||||
//QMutexLocker locker(&mutex);
|
|
||||||
|
|
||||||
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
|
||||||
CMARootObject *first = static_cast<CMARootObject *>((*root).takeFirst());
|
|
||||||
delete first;
|
|
||||||
qDeleteAll(*root);
|
|
||||||
}
|
|
||||||
|
|
||||||
object_list.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::removeInternal(root_list &list, const CMAObject *obj)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
QList<CMAObject *>::iterator it = list.begin();
|
|
||||||
|
|
||||||
while(it != list.end()) {
|
|
||||||
if(!found && (*it) == obj) {
|
|
||||||
// update the size of the parent objects
|
|
||||||
(*it)->updateObjectSize(-(*it)->metadata.size);
|
|
||||||
it = list.erase(it);
|
|
||||||
found = true;
|
|
||||||
} else if(found && (*it)->metadata.ohfiParent == obj->metadata.ohfi) {
|
|
||||||
it = list.erase(it);
|
|
||||||
} else {
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::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 Database::lessThanComparator(const CMAObject *a, const CMAObject *b)
|
|
||||||
{
|
|
||||||
return a->metadata.ohfi < b->metadata.ohfi;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::hasFilter(const CMARootObject *object,int ohfi)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < object->num_filters; i++) {
|
|
||||||
if(object->filters[i].ohfi == ohfi) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::findInternal(const root_list &list, int ohfi, find_data &data)
|
|
||||||
{
|
|
||||||
if(hasFilter(static_cast<CMARootObject *>(list.first()), ohfi)) {
|
|
||||||
data.it = list.begin();
|
|
||||||
} else {
|
|
||||||
CMAObject obj;
|
|
||||||
obj.setOhfi(ohfi);
|
|
||||||
data.it = qBinaryFind(list.begin(), list.end(), &obj, Database::lessThanComparator);
|
|
||||||
}
|
|
||||||
data.end = list.end();
|
|
||||||
return data.it != data.end;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::find(int ohfi, Database::find_data &data)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
|
|
||||||
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
|
||||||
if(findInternal(*root, ohfi, data)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::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, Database::lessThanComparator);
|
|
||||||
|
|
||||||
if(it != cat_list->end()) {
|
|
||||||
cat_list->append(object);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CMAObject *Database::ohfiToObject(int ohfi)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
find_data data;
|
|
||||||
return find(ohfi, data) ? *data.it : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMAObject *Database::pathToObjectInternal(const root_list &list, const char *path)
|
|
||||||
{
|
|
||||||
// skip the first element since is the root element
|
|
||||||
root_list::const_iterator skipped_first = ++list.begin();
|
|
||||||
|
|
||||||
for(root_list::const_iterator obj = skipped_first; obj != list.end(); ++obj) {
|
|
||||||
if(strcasecmp(path, (*obj)->metadata.path) == 0) {
|
|
||||||
return (*obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMAObject *Database::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 Database::acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
if(MASK_SET(type, VITA_DIR_TYPE_MASK_PHOTO)) {
|
|
||||||
result = (current->metadata.dataType & Photo);
|
|
||||||
} else if(MASK_SET(type, VITA_DIR_TYPE_MASK_VIDEO)) {
|
|
||||||
result = (current->metadata.dataType & Video);
|
|
||||||
} else if(MASK_SET(type, VITA_DIR_TYPE_MASK_MUSIC)) {
|
|
||||||
result = (current->metadata.dataType & Music);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(type == (VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_ARTISTS)) {
|
|
||||||
// unimplemented
|
|
||||||
return 0;
|
|
||||||
} else if(type == (VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_GENRES)) {
|
|
||||||
// unimplemented
|
|
||||||
return 0;
|
|
||||||
} else if(type == (VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_PLAYLISTS)) {
|
|
||||||
// unimplemented
|
|
||||||
return 0;
|
|
||||||
} else if(type & (VITA_DIR_TYPE_MASK_ALL | VITA_DIR_TYPE_MASK_SONGS)) {
|
|
||||||
result = result && (current->metadata.dataType & File);
|
|
||||||
} else if(type & (VITA_DIR_TYPE_MASK_REGULAR)) {
|
|
||||||
result = (parent->metadata.ohfi == current->metadata.ohfiParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Support other filter types
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Database::dumpMetadataList(const metadata_t *p_head)
|
|
||||||
{
|
|
||||||
while(p_head) {
|
|
||||||
qDebug("Metadata: %s with OHFI %d", p_head->name, p_head->ohfi);
|
|
||||||
p_head = p_head->next_metadata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Database::filterObjects(int ohfiParent, metadata_t **p_head, int index, int max_number)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mutex);
|
|
||||||
CMARootObject *parent = static_cast<CMARootObject *>(ohfiToObject(ohfiParent));
|
|
||||||
|
|
||||||
if(parent == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int type = parent->metadata.type;
|
|
||||||
|
|
||||||
if(parent->metadata.ohfi < OHFI_OFFSET && parent->filters) { // if we have filters
|
|
||||||
if(ohfiParent == parent->metadata.ohfi) { // if we are looking at root
|
|
||||||
return parent->getFilters(p_head);
|
|
||||||
} else { // we are looking at a filter
|
|
||||||
for(int j = 0; j < parent->num_filters; j++) {
|
|
||||||
if(parent->filters[j].ohfi == ohfiParent) {
|
|
||||||
type = parent->filters[j].type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
int numObjects = 0;
|
|
||||||
metadata_t temp = metadata_t();
|
|
||||||
metadata_t *tail = &temp;
|
|
||||||
|
|
||||||
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
|
||||||
for(root_list::iterator object = (*root).begin(); object != (*root).end(); ++object) {
|
|
||||||
if(acceptFilteredObject(parent, *object, type)) {
|
|
||||||
if(offset++ >= index) {
|
|
||||||
tail->next_metadata = &(*object)->metadata;
|
|
||||||
tail = tail->next_metadata;
|
|
||||||
numObjects++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(max_number > 0 && numObjects >= max_number) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numObjects > 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tail->next_metadata = NULL;
|
|
||||||
|
|
||||||
if(p_head != NULL) {
|
|
||||||
*p_head = temp.next_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
return numObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Database::checkFileType(const QString path, int ohfi_root)
|
int Database::checkFileType(const QString path, int ohfi_root)
|
||||||
{
|
{
|
||||||
switch(ohfi_root) {
|
switch(ohfi_root) {
|
||||||
case VITA_OHFI_MUSIC:
|
case VITA_OHFI_MUSIC:
|
||||||
for(int i = 0, max = sizeof(CMAObject::audio_list) / sizeof(CMAObject::file_type); i < max; i++) {
|
for(int i = 0, max = sizeof(audio_list) / sizeof(file_type); i < max; i++) {
|
||||||
if(path.endsWith(CMAObject::audio_list[i].file_ext, Qt::CaseInsensitive)) {
|
if(path.endsWith(audio_list[i].file_ext, Qt::CaseInsensitive)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VITA_OHFI_PHOTO:
|
case VITA_OHFI_PHOTO:
|
||||||
for(int i = 0, max = sizeof(CMAObject::photo_list) / sizeof(CMAObject::file_type); i < max; i++) {
|
for(int i = 0, max = sizeof(photo_list) / sizeof(file_type); i< max; i++) {
|
||||||
if(path.endsWith(CMAObject::photo_list[i].file_ext, Qt::CaseInsensitive)) {
|
if(path.endsWith(photo_list[i].file_ext, Qt::CaseInsensitive)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VITA_OHFI_VIDEO:
|
case VITA_OHFI_VIDEO:
|
||||||
for(int i = 0, max = sizeof(CMAObject::video_list) / sizeof(const char *); i < max; i++) {
|
for(int i = 0, max = sizeof(video_list) / sizeof(file_type); i< max; i++) {
|
||||||
if(path.endsWith(CMAObject::video_list[i], Qt::CaseInsensitive)) {
|
if(path.endsWith(video_list[i].file_ext, Qt::CaseInsensitive)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,3 +86,45 @@ int Database::checkFileType(const QString path, int ohfi_root)
|
|||||||
}
|
}
|
||||||
return -1;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
123
src/database.h
123
src/database.h
@@ -1,92 +1,87 @@
|
|||||||
/*
|
|
||||||
* QCMA: Cross-platform content manager assistant for the PS Vita
|
|
||||||
*
|
|
||||||
* Copyright (C) 2013 Codestation
|
|
||||||
*
|
|
||||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DATABASE_H
|
#ifndef DATABASE_H
|
||||||
#define DATABASE_H
|
#define DATABASE_H
|
||||||
|
|
||||||
#include "cmarootobject.h"
|
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <vitamtp.h>
|
#include <vitamtp.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *file_ext;
|
||||||
|
int file_format;
|
||||||
|
int file_codec;
|
||||||
|
} file_type;
|
||||||
|
|
||||||
|
#define OHFI_BASE_VALUE 256
|
||||||
|
|
||||||
|
#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
|
class Database : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
typedef struct {
|
explicit Database(QObject *parent = 0);
|
||||||
QList<CMAObject *>::const_iterator it;
|
|
||||||
QList<CMAObject *>::const_iterator end;
|
|
||||||
} find_data;
|
|
||||||
|
|
||||||
explicit Database();
|
virtual bool load() = 0;
|
||||||
~Database();
|
virtual bool rescan() = 0;
|
||||||
|
virtual void setUUID(const QString &uuid) = 0;
|
||||||
|
|
||||||
bool reload(bool &prepared);
|
virtual int childObjectCount(int parent_ohfi) = 0;
|
||||||
void setUUID(const QString uuid);
|
virtual bool deleteEntry(int ohfi, int root_ohfi = 0) = 0;
|
||||||
void addEntries(CMAObject *root);
|
virtual QString getAbsolutePath(int ohfi) = 0;
|
||||||
CMAObject *ohfiToObject(int ohfi);
|
virtual QString getRelativePath(int ohfi) = 0;
|
||||||
bool find(int ohfi, find_data &data);
|
virtual bool getObjectMetadata(int ohfi, metadata_t &metadata) = 0;
|
||||||
void append(int parent_ohfi, CMAObject *object);
|
virtual int getObjectMetadatas(int parent_ohfi, metadata_t **metadata, int index = 0, int max_number = 0) = 0;
|
||||||
bool remove(const CMAObject *obj, int ohfi_root = 0);
|
virtual qint64 getObjectSize(int ohfi) = 0;
|
||||||
int filterObjects(int ohfiParent, metadata_t **p_head, int index = 0, int max_number = 0);
|
virtual int getPathId(const char *name, int ohfi) = 0;
|
||||||
CMAObject *pathToObject(const char *path, int ohfiRoot);
|
virtual int insertObjectEntry(const QString &path, const QString &name, int parent_ohfi) = 0;
|
||||||
int acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type);
|
virtual bool renameObject(int ohfi, const QString &name) = 0;
|
||||||
|
virtual void setObjectSize(int ohfi, qint64 size) = 0;
|
||||||
|
virtual int getParentId(int ohfi) = 0;
|
||||||
|
virtual int getRootId(int ohfi) = 0;
|
||||||
|
virtual void freeMetadata(metadata_t *metadata) = 0;
|
||||||
|
|
||||||
static int checkFileType(const QString path, int ohfi_root);
|
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);
|
||||||
|
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
typedef QList<CMAObject *> root_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();
|
|
||||||
void destroy();
|
|
||||||
int scanRootDirectory(root_list &list,int ohfi_type);
|
|
||||||
int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type);
|
|
||||||
bool hasFilter(const CMARootObject *object,int ohfi);
|
|
||||||
bool removeInternal(root_list &list, const CMAObject *obj);
|
|
||||||
bool findInternal(const root_list &list, int ohfi, find_data &data);
|
|
||||||
CMAObject *getParent(CMAObject *last_dir, const QString ¤t_path);
|
|
||||||
CMAObject *pathToObjectInternal(const root_list &list, const char *path);
|
|
||||||
static bool lessThanComparator(const CMAObject *a, const CMAObject *b);
|
|
||||||
void dumpMetadataList(const metadata_t *p_head);
|
|
||||||
bool continueOperation();
|
bool continueOperation();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual void clear() = 0;
|
||||||
|
virtual int create() = 0;
|
||||||
|
|
||||||
// control variables
|
// control variables
|
||||||
QMutex cancel;
|
QMutex cancel;
|
||||||
bool cancel_operation;
|
bool cancel_operation;
|
||||||
|
|
||||||
QTimer *timer;
|
|
||||||
QThread *thread;
|
|
||||||
map_list object_list;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void fileAdded(QString);
|
void fileAdded(QString);
|
||||||
void directoryAdded(QString);
|
void directoryAdded(QString);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "backupitem.h"
|
#include "backupitem.h"
|
||||||
#include "ui_backupitem.h"
|
#include "ui_backupitem.h"
|
||||||
#include "utils.h"
|
#include "cmautils.h"
|
||||||
#include "dds.h"
|
#include "dds.h"
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include "cmaobject.h"
|
#include "cmaobject.h"
|
||||||
#include "sforeader.h"
|
#include "sforeader.h"
|
||||||
#include "confirmdialog.h"
|
#include "confirmdialog.h"
|
||||||
#include "utils.h"
|
#include "cmautils.h"
|
||||||
#include "filterlineedit.h"
|
#include "filterlineedit.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
#include <vitamtp.h>
|
#include <vitamtp.h>
|
||||||
|
|
||||||
BackupManagerForm::BackupManagerForm(QWidget *parent) :
|
BackupManagerForm::BackupManagerForm(Database *db, QWidget *parent) :
|
||||||
QWidget(parent),
|
QDialog(parent), m_db(db),
|
||||||
ui(new Ui::BackupManagerForm)
|
ui(new Ui::BackupManagerForm)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@@ -64,13 +64,11 @@ void BackupManagerForm::removeEntry(BackupItem *item)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&db->mutex);
|
QMutexLocker locker(&m_db->mutex);
|
||||||
|
|
||||||
CMAObject *obj = db->ohfiToObject(item->ohfi);
|
int parent_ohfi = m_db->getParentId(item->ohfi);
|
||||||
if(obj) {
|
removeRecursively(m_db->getAbsolutePath(item->ohfi));
|
||||||
obj->removeReferencedObject();
|
m_db->deleteEntry(item->ohfi);
|
||||||
db->remove(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
||||||
@@ -80,13 +78,12 @@ void BackupManagerForm::removeEntry(BackupItem *item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = db->ohfiToObject(obj->metadata.ohfiParent);
|
if(parent_ohfi > 0) {
|
||||||
if(obj) {
|
setBackupUsage(m_db->getObjectSize(parent_ohfi));
|
||||||
setBackupUsage(obj->metadata.size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackupManagerForm::setBackupUsage(quint64 size)
|
void BackupManagerForm::setBackupUsage(qint64 size)
|
||||||
{
|
{
|
||||||
ui->usageLabel->setText(tr("Backup disk usage: %1").arg(readable_size(size, true)));
|
ui->usageLabel->setText(tr("Backup disk usage: %1").arg(readable_size(size, true)));
|
||||||
}
|
}
|
||||||
@@ -144,18 +141,17 @@ void BackupManagerForm::loadBackupListing(int index)
|
|||||||
sys_dir = true;
|
sys_dir = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
db->mutex.lock();
|
m_db->mutex.lock();
|
||||||
|
|
||||||
// get the item list
|
|
||||||
metadata_t *meta;
|
|
||||||
int row_count = db->filterObjects(ohfi, &meta);
|
|
||||||
|
|
||||||
|
// get the item list
|
||||||
|
metadata_t *meta = NULL;
|
||||||
|
int row_count = m_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
|
||||||
if(row_count == 0) {
|
if(row_count == 0) {
|
||||||
setBackupUsage(0);
|
setBackupUsage(0);
|
||||||
db->mutex.unlock();
|
m_db->mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,13 +163,14 @@ void BackupManagerForm::loadBackupListing(int index)
|
|||||||
#else
|
#else
|
||||||
horiz_header->setResizeMode(QHeaderView::Stretch);
|
horiz_header->setResizeMode(QHeaderView::Stretch);
|
||||||
#endif
|
#endif
|
||||||
CMAObject *obj = db->ohfiToObject(ohfi);
|
qint64 backup_size = m_db->getObjectSize(ohfi);
|
||||||
setBackupUsage(obj->metadata.size);
|
setBackupUsage(backup_size);
|
||||||
|
QString path = m_db->getAbsolutePath(ohfi);
|
||||||
QList<BackupItem *> item_list;
|
QList<BackupItem *> item_list;
|
||||||
|
|
||||||
|
metadata_t *first = meta;
|
||||||
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,13 +210,15 @@ 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;
|
||||||
meta = meta->next_metadata;
|
meta = meta->next_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_db->freeMetadata(first);
|
||||||
|
|
||||||
qSort(item_list.begin(), item_list.end(), BackupItem::lessThan);
|
qSort(item_list.begin(), item_list.end(), BackupItem::lessThan);
|
||||||
|
|
||||||
int row;
|
int row;
|
||||||
@@ -233,7 +232,7 @@ void BackupManagerForm::loadBackupListing(int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vert_header->setUpdatesEnabled(true);
|
vert_header->setUpdatesEnabled(true);
|
||||||
db->mutex.unlock();
|
m_db->mutex.unlock();
|
||||||
|
|
||||||
// apply filter
|
// apply filter
|
||||||
this->on_filterLineEdit_textChanged(ui->filterLineEdit->text());
|
this->on_filterLineEdit_textChanged(ui->filterLineEdit->text());
|
||||||
|
|||||||
@@ -23,25 +23,25 @@
|
|||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "backupitem.h"
|
#include "backupitem.h"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QDialog>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class BackupManagerForm;
|
class BackupManagerForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BackupManagerForm : public QWidget
|
class BackupManagerForm : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BackupManagerForm(QWidget *parent = 0);
|
explicit BackupManagerForm(Database *db, QWidget *parent = 0);
|
||||||
~BackupManagerForm();
|
~BackupManagerForm();
|
||||||
|
|
||||||
Database *db;
|
Database *m_db;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupForm();
|
void setupForm();
|
||||||
void setBackupUsage(quint64 size);
|
void setBackupUsage(qint64 size);
|
||||||
|
|
||||||
Ui::BackupManagerForm *ui;
|
Ui::BackupManagerForm *ui;
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ void ConfigWidget::setDefaultData()
|
|||||||
ui->metadataCheck->setChecked(settings.value("skipMetadata", false).toBool());
|
ui->metadataCheck->setChecked(settings.value("skipMetadata", false).toBool());
|
||||||
ui->usbCheck->setChecked(settings.value("disableUSB", false).toBool());
|
ui->usbCheck->setChecked(settings.value("disableUSB", false).toBool());
|
||||||
ui->wifiCheck->setChecked(settings.value("disableWireless", false).toBool());
|
ui->wifiCheck->setChecked(settings.value("disableWireless", false).toBool());
|
||||||
|
ui->databaseSelect->setCurrentIndex(settings.value("useMemoryStorage", true).toBool() ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigWidget::~ConfigWidget()
|
ConfigWidget::~ConfigWidget()
|
||||||
@@ -154,6 +155,7 @@ void ConfigWidget::accept()
|
|||||||
settings.setValue("skipMetadata", ui->metadataCheck->isChecked());
|
settings.setValue("skipMetadata", ui->metadataCheck->isChecked());
|
||||||
settings.setValue("disableUSB", ui->usbCheck->isChecked());
|
settings.setValue("disableUSB", ui->usbCheck->isChecked());
|
||||||
settings.setValue("disableWireless", ui->wifiCheck->isChecked());
|
settings.setValue("disableWireless", ui->wifiCheck->isChecked());
|
||||||
|
settings.setValue("useMemoryStorage", ui->databaseSelect->currentIndex() == 0);
|
||||||
settings.sync();
|
settings.sync();
|
||||||
|
|
||||||
done(Accepted);
|
done(Accepted);
|
||||||
|
|||||||
@@ -282,7 +282,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QComboBox" name="comboBox">
|
<widget class="QComboBox" name="databaseSelect">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -291,6 +291,11 @@
|
|||||||
<string>In Memory</string>
|
<string>In Memory</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>SQLite</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "cmaclient.h"
|
#include "cmaclient.h"
|
||||||
#include "cmaevent.h"
|
#include "cmautils.h"
|
||||||
#include "utils.h"
|
|
||||||
|
#include "qlistdb.h"
|
||||||
|
#include "sqlitedb.h"
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@@ -43,7 +45,7 @@ const QStringList MainWidget::path_list = QStringList() << "photoPath" << "music
|
|||||||
bool sleptOnce = false;
|
bool sleptOnce = false;
|
||||||
|
|
||||||
MainWidget::MainWidget(QWidget *parent) :
|
MainWidget::MainWidget(QWidget *parent) :
|
||||||
QWidget(parent)
|
QWidget(parent), db(NULL), configForm(NULL), managerForm(NULL), backupForm(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,12 +56,12 @@ void MainWidget::checkSettings()
|
|||||||
foreach(const QString &path, path_list) {
|
foreach(const QString &path, path_list) {
|
||||||
if(!settings.contains(path)) {
|
if(!settings.contains(path)) {
|
||||||
first_run = true;
|
first_run = true;
|
||||||
dialog.show();
|
configForm->show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
first_run = false;
|
first_run = false;
|
||||||
manager.start();
|
managerForm->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::dialogResult(int result)
|
void MainWidget::dialogResult(int result)
|
||||||
@@ -67,7 +69,7 @@ void MainWidget::dialogResult(int result)
|
|||||||
if(result == QDialog::Accepted) {
|
if(result == QDialog::Accepted) {
|
||||||
if(first_run) {
|
if(first_run) {
|
||||||
first_run = false;
|
first_run = false;
|
||||||
manager.start();
|
managerForm->start();
|
||||||
}
|
}
|
||||||
} else if(first_run) {
|
} else if(first_run) {
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
@@ -80,7 +82,7 @@ void MainWidget::stopServer()
|
|||||||
if(CmaClient::isRunning()) {
|
if(CmaClient::isRunning()) {
|
||||||
receiveMessage(tr("Stopping QCMA (disconnect your PS Vita)"));
|
receiveMessage(tr("Stopping QCMA (disconnect your PS Vita)"));
|
||||||
}
|
}
|
||||||
manager.stop();
|
managerForm->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::deviceDisconnect()
|
void MainWidget::deviceDisconnect()
|
||||||
@@ -117,6 +119,16 @@ void MainWidget::deviceConnected(QString message)
|
|||||||
|
|
||||||
void MainWidget::prepareApplication()
|
void MainWidget::prepareApplication()
|
||||||
{
|
{
|
||||||
|
//TODO: delete database before exit
|
||||||
|
if(QSettings().value("useMemoryStorage", true).toBool()) {
|
||||||
|
db = new QListDB();
|
||||||
|
} else {
|
||||||
|
db = new SQLiteDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
configForm = new ConfigWidget(this);
|
||||||
|
backupForm = new BackupManagerForm(db, this);
|
||||||
|
managerForm = new ClientManager(db, this);
|
||||||
connectSignals();
|
connectSignals();
|
||||||
createTrayIcon();
|
createTrayIcon();
|
||||||
checkSettings();
|
checkSettings();
|
||||||
@@ -124,13 +136,13 @@ void MainWidget::prepareApplication()
|
|||||||
|
|
||||||
void MainWidget::connectSignals()
|
void MainWidget::connectSignals()
|
||||||
{
|
{
|
||||||
connect(&dialog, SIGNAL(finished(int)), this, SLOT(dialogResult(int)));
|
connect(configForm, SIGNAL(finished(int)), this, SLOT(dialogResult(int)));
|
||||||
connect(&manager, SIGNAL(stopped()), qApp, SLOT(quit()));
|
connect(managerForm, SIGNAL(stopped()), qApp, SLOT(quit()));
|
||||||
connect(&manager, SIGNAL(deviceConnected(QString)), this, SLOT(deviceConnected(QString)));
|
connect(managerForm, SIGNAL(deviceConnected(QString)), this, SLOT(deviceConnected(QString)));
|
||||||
connect(&manager, SIGNAL(deviceDisconnected()), this, SLOT(deviceDisconnect()));
|
connect(managerForm, SIGNAL(deviceDisconnected()), this, SLOT(deviceDisconnect()));
|
||||||
connect(&manager, SIGNAL(messageSent(QString)), this, SLOT(receiveMessage(QString)));
|
connect(managerForm, SIGNAL(messageSent(QString)), this, SLOT(receiveMessage(QString)));
|
||||||
|
|
||||||
form.db = &manager.db;
|
//backupForm.db = managerForm.db;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::setTrayTooltip(QString message)
|
void MainWidget::setTrayTooltip(QString message)
|
||||||
@@ -144,8 +156,8 @@ void MainWidget::setTrayTooltip(QString message)
|
|||||||
|
|
||||||
void MainWidget::openManager()
|
void MainWidget::openManager()
|
||||||
{
|
{
|
||||||
form.loadBackupListing(-1);
|
backupForm->loadBackupListing(-1);
|
||||||
form.show();
|
backupForm->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::showAboutDialog()
|
void MainWidget::showAboutDialog()
|
||||||
@@ -186,9 +198,9 @@ void MainWidget::createTrayIcon()
|
|||||||
about_qt = new QAction(tr("Abou&t Qt"), this);
|
about_qt = new QAction(tr("Abou&t Qt"), this);
|
||||||
quit = new QAction(tr("&Quit"), this);
|
quit = new QAction(tr("&Quit"), this);
|
||||||
|
|
||||||
connect(options, SIGNAL(triggered()), &dialog, SLOT(open()));
|
connect(options, SIGNAL(triggered()), configForm, SLOT(open()));
|
||||||
connect(backup, SIGNAL(triggered()), this, SLOT(openManager()));
|
connect(backup, SIGNAL(triggered()), this, SLOT(openManager()));
|
||||||
connect(reload, SIGNAL(triggered()), &manager, SLOT(refreshDatabase()));
|
connect(reload, SIGNAL(triggered()), managerForm, SLOT(refreshDatabase()));
|
||||||
connect(about, SIGNAL(triggered()), this, SLOT(showAboutDialog()));
|
connect(about, SIGNAL(triggered()), this, SLOT(showAboutDialog()));
|
||||||
connect(about_qt, SIGNAL(triggered()), this, SLOT(showAboutQt()));
|
connect(about_qt, SIGNAL(triggered()), this, SLOT(showAboutQt()));
|
||||||
connect(quit, SIGNAL(triggered()), this, SLOT(stopServer()));
|
connect(quit, SIGNAL(triggered()), this, SLOT(stopServer()));
|
||||||
@@ -255,4 +267,5 @@ MainWidget::~MainWidget()
|
|||||||
#ifndef ENABLE_KDE_NOTIFIER
|
#ifndef ENABLE_KDE_NOTIFIER
|
||||||
trayIcon->hide();
|
trayIcon->hide();
|
||||||
#endif
|
#endif
|
||||||
|
delete db;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,10 +52,13 @@ private:
|
|||||||
|
|
||||||
bool first_run;
|
bool first_run;
|
||||||
|
|
||||||
|
// database
|
||||||
|
Database *db;
|
||||||
|
|
||||||
// forms
|
// forms
|
||||||
ConfigWidget dialog;
|
ConfigWidget *configForm;
|
||||||
ClientManager manager;
|
ClientManager *managerForm;
|
||||||
BackupManagerForm form;
|
BackupManagerForm *backupForm;
|
||||||
|
|
||||||
//system tray
|
//system tray
|
||||||
QAction *quit;
|
QAction *quit;
|
||||||
|
|||||||
568
src/qlistdb.cpp
Normal file
568
src/qlistdb.cpp
Normal file
@@ -0,0 +1,568 @@
|
|||||||
|
/*
|
||||||
|
* QCMA: Cross-platform content manager assistant for the PS Vita
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Codestation
|
||||||
|
*
|
||||||
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cmautils.h"
|
||||||
|
#include "qlistdb.h"
|
||||||
|
#include "cmaobject.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
QListDB::QListDB(QObject *parent) :
|
||||||
|
Database(parent)
|
||||||
|
{
|
||||||
|
QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
|
||||||
|
CMARootObject::uuid = uuid;
|
||||||
|
thread = new QThread();
|
||||||
|
moveToThread(thread);
|
||||||
|
timer = new QTimer();
|
||||||
|
thread->start();
|
||||||
|
|
||||||
|
timer->setInterval(0);
|
||||||
|
timer->setSingleShot(true);
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(process()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QListDB::~QListDB()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
timer->stop();
|
||||||
|
delete timer;
|
||||||
|
thread->quit();
|
||||||
|
thread->wait();
|
||||||
|
delete thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QListDB::setUUID(const QString &uuid)
|
||||||
|
{
|
||||||
|
CMARootObject::uuid = uuid;
|
||||||
|
QSettings().setValue("lastAccountId", uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::load()
|
||||||
|
{
|
||||||
|
// not implemented
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::rescan()
|
||||||
|
{
|
||||||
|
if(mutex.tryLock(1000)) {
|
||||||
|
if(CMARootObject::uuid != "ffffffffffffffff") {
|
||||||
|
timer->start();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
mutex.unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QListDB::clear()
|
||||||
|
{
|
||||||
|
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
||||||
|
CMARootObject *first = static_cast<CMARootObject *>((*root).takeFirst());
|
||||||
|
delete first;
|
||||||
|
qDeleteAll(*root);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::create()
|
||||||
|
{
|
||||||
|
int total_objects = 0;
|
||||||
|
//QMutexLocker locker(&mutex);
|
||||||
|
const int ohfi_array[] = { VITA_OHFI_MUSIC, VITA_OHFI_PHOTO, VITA_OHFI_VIDEO,
|
||||||
|
VITA_OHFI_BACKUP, VITA_OHFI_VITAAPP, VITA_OHFI_PSPAPP,
|
||||||
|
VITA_OHFI_PSPSAVE, VITA_OHFI_PSXAPP, VITA_OHFI_PSMAPP
|
||||||
|
};
|
||||||
|
CMAObject::resetOhfiCounter();
|
||||||
|
QSettings settings;
|
||||||
|
|
||||||
|
for(int i = 0, max = sizeof(ohfi_array) / sizeof(int); i < max; i++) {
|
||||||
|
CMARootObject *obj = new CMARootObject(ohfi_array[i]);
|
||||||
|
|
||||||
|
switch(ohfi_array[i]) {
|
||||||
|
case VITA_OHFI_MUSIC:
|
||||||
|
obj->initObject(settings.value("musicPath").toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VITA_OHFI_PHOTO:
|
||||||
|
obj->initObject(settings.value("photoPath").toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VITA_OHFI_VIDEO:
|
||||||
|
obj->initObject(settings.value("videoPath").toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VITA_OHFI_BACKUP:
|
||||||
|
case VITA_OHFI_VITAAPP:
|
||||||
|
case VITA_OHFI_PSPAPP:
|
||||||
|
case VITA_OHFI_PSPSAVE:
|
||||||
|
case VITA_OHFI_PSXAPP:
|
||||||
|
case VITA_OHFI_PSMAPP:
|
||||||
|
obj->initObject(settings.value("appsPath").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
root_list list;
|
||||||
|
list << obj;
|
||||||
|
emit directoryAdded(obj->path);
|
||||||
|
int dir_count = recursiveScanRootDirectory(list, obj, ohfi_array[i]);
|
||||||
|
|
||||||
|
if(dir_count < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("Added objects for OHFI 0x%02X: %i", ohfi_array[i], dir_count);
|
||||||
|
|
||||||
|
total_objects += dir_count;
|
||||||
|
object_list[ohfi_array[i]] = list;
|
||||||
|
}
|
||||||
|
return total_objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMAObject *QListDB::getParent(CMAObject *last_dir, const QString ¤t_path)
|
||||||
|
{
|
||||||
|
while(last_dir && current_path != last_dir->path) {
|
||||||
|
last_dir = last_dir->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return last_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::scanRootDirectory(root_list &list, int ohfi_type)
|
||||||
|
{
|
||||||
|
int file_type = -1;
|
||||||
|
int total_objects = 0;
|
||||||
|
CMAObject *last_dir = list.first();
|
||||||
|
QDir dir(last_dir->path);
|
||||||
|
dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
|
||||||
|
QDirIterator it(dir, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
while(it.hasNext()) {
|
||||||
|
|
||||||
|
if(!continueOperation()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.next();
|
||||||
|
QFileInfo info = it.fileInfo();
|
||||||
|
|
||||||
|
if(info.isFile()) {
|
||||||
|
if((file_type = checkFileType(info.absoluteFilePath(), ohfi_type)) < 0) {
|
||||||
|
//qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMAObject *obj = new CMAObject(getParent(last_dir, info.path()));
|
||||||
|
obj->initObject(info, file_type);
|
||||||
|
//qDebug("Added %s to database with OHFI %d", obj->metadata.name, obj->metadata.ohfi);
|
||||||
|
list << obj;
|
||||||
|
|
||||||
|
if(obj->metadata.dataType & Folder) {
|
||||||
|
last_dir = obj;
|
||||||
|
} else {
|
||||||
|
total_objects++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total_objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type)
|
||||||
|
{
|
||||||
|
int file_type = -1;
|
||||||
|
int total_objects = 0;
|
||||||
|
|
||||||
|
QDir dir(parent->path);
|
||||||
|
dir.setSorting(QDir::Name | QDir::DirsFirst);
|
||||||
|
QFileInfoList qsl = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
|
||||||
|
|
||||||
|
foreach(const QFileInfo &info, qsl) {
|
||||||
|
|
||||||
|
if(!continueOperation()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(info.isFile() && (file_type = checkFileType(info.absoluteFilePath(), ohfi_type)) < 0) {
|
||||||
|
//qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());>
|
||||||
|
} else {
|
||||||
|
CMAObject *obj = new CMAObject(parent);
|
||||||
|
obj->initObject(info, file_type);
|
||||||
|
emit fileAdded(obj->metadata.name);
|
||||||
|
//qDebug("Added %s to database with OHFI %d", obj->metadata.name, obj->metadata.ohfi);
|
||||||
|
list << obj;
|
||||||
|
if(info.isDir()) {
|
||||||
|
emit directoryAdded(obj->path);
|
||||||
|
total_objects += recursiveScanRootDirectory(list, obj, ohfi_type);
|
||||||
|
} else {
|
||||||
|
total_objects++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::removeInternal(root_list &list, int ohfi)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
QList<CMAObject *>::iterator it = list.begin();
|
||||||
|
|
||||||
|
while(it != list.end()) {
|
||||||
|
if(!found && (*it)->metadata.ohfi == ohfi) {
|
||||||
|
// update the size of the parent objects
|
||||||
|
(*it)->updateObjectSize(-(*it)->metadata.size);
|
||||||
|
it = list.erase(it);
|
||||||
|
found = true;
|
||||||
|
} else if(found && (*it)->metadata.ohfiParent == ohfi) {
|
||||||
|
it = list.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::lessThanComparator(const CMAObject *a, const CMAObject *b)
|
||||||
|
{
|
||||||
|
return a->metadata.ohfi < b->metadata.ohfi;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::hasFilter(const CMARootObject *object,int ohfi)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < object->num_filters; i++) {
|
||||||
|
if(object->filters[i].ohfi == ohfi) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::findInternal(const root_list &list, int ohfi, find_data &data)
|
||||||
|
{
|
||||||
|
if(hasFilter(static_cast<CMARootObject *>(list.first()), ohfi)) {
|
||||||
|
data.it = list.begin();
|
||||||
|
} else {
|
||||||
|
CMAObject obj;
|
||||||
|
obj.setOhfi(ohfi);
|
||||||
|
data.it = qBinaryFind(list.begin(), list.end(), &obj, QListDB::lessThanComparator);
|
||||||
|
}
|
||||||
|
data.end = list.end();
|
||||||
|
return data.it != data.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::find(int ohfi, QListDB::find_data &data)
|
||||||
|
{
|
||||||
|
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
||||||
|
if(findInternal(*root, ohfi, data)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMAObject *QListDB::ohfiToObject(int ohfi)
|
||||||
|
{
|
||||||
|
find_data data;
|
||||||
|
return find(ohfi, data) ? *data.it : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMAObject *QListDB::pathToObjectInternal(const root_list &list, const char *path)
|
||||||
|
{
|
||||||
|
// skip the first element since is the root element
|
||||||
|
root_list::const_iterator skipped_first = ++list.begin();
|
||||||
|
|
||||||
|
for(root_list::const_iterator obj = skipped_first; obj != list.end(); ++obj) {
|
||||||
|
if(strcasecmp(path, (*obj)->metadata.path) == 0) {
|
||||||
|
return (*obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if(MASK_SET(type, VITA_DIR_TYPE_MASK_PHOTO)) {
|
||||||
|
result = (current->metadata.dataType & Photo);
|
||||||
|
} else if(MASK_SET(type, VITA_DIR_TYPE_MASK_VIDEO)) {
|
||||||
|
result = (current->metadata.dataType & Video);
|
||||||
|
} else if(MASK_SET(type, VITA_DIR_TYPE_MASK_MUSIC)) {
|
||||||
|
result = (current->metadata.dataType & Music);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type == (VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_ARTISTS)) {
|
||||||
|
// unimplemented
|
||||||
|
return 0;
|
||||||
|
} else if(type == (VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_GENRES)) {
|
||||||
|
// unimplemented
|
||||||
|
return 0;
|
||||||
|
} else if(type == (VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_PLAYLISTS)) {
|
||||||
|
// unimplemented
|
||||||
|
return 0;
|
||||||
|
} else if(type & (VITA_DIR_TYPE_MASK_ALL | VITA_DIR_TYPE_MASK_SONGS)) {
|
||||||
|
result = result && (current->metadata.dataType & File);
|
||||||
|
} else if(type & (VITA_DIR_TYPE_MASK_REGULAR)) {
|
||||||
|
result = (parent->metadata.ohfi == current->metadata.ohfiParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support other filter types
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QListDB::dumpMetadataList(const metadata_t *p_head)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
while(p_head) {
|
||||||
|
qDebug("Metadata: %s with OHFI %d", p_head->name, p_head->ohfi);
|
||||||
|
p_head = p_head->next_metadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QListDB::getObjectMetadata(int ohfi, metadata_t &metadata)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return getObjectMetadatas(parent_ohfi, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int type = parent->metadata.type;
|
||||||
|
|
||||||
|
if(parent->metadata.ohfi < OHFI_OFFSET && parent->filters) { // if we have filters
|
||||||
|
if(parent_ohfi == parent->metadata.ohfi) { // if we are looking at root
|
||||||
|
return parent->getFilters(metadata);
|
||||||
|
} else { // we are looking at a filter
|
||||||
|
for(int j = 0; j < parent->num_filters; j++) {
|
||||||
|
if(parent->filters[j].ohfi == parent_ohfi) {
|
||||||
|
type = parent->filters[j].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
int numObjects = 0;
|
||||||
|
metadata_t temp = metadata_t();
|
||||||
|
metadata_t *tail = &temp;
|
||||||
|
|
||||||
|
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
|
||||||
|
for(root_list::iterator object = (*root).begin(); object != (*root).end(); ++object) {
|
||||||
|
if(acceptFilteredObject(parent, *object, type)) {
|
||||||
|
if(offset++ >= index) {
|
||||||
|
tail->next_metadata = &(*object)->metadata;
|
||||||
|
tail = tail->next_metadata;
|
||||||
|
numObjects++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(max_number > 0 && numObjects >= max_number) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(numObjects > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tail->next_metadata = NULL;
|
||||||
|
|
||||||
|
if(metadata != NULL) {
|
||||||
|
*metadata = temp.next_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, const QString &name, int parent_ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
|
||||||
|
CMAObject *parent_obj = 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_obj, QListDB::lessThanComparator);
|
||||||
|
|
||||||
|
if(it != cat_list->end()) {
|
||||||
|
CMAObject *newobj = new CMAObject(parent_obj);
|
||||||
|
|
||||||
|
// get the root object
|
||||||
|
while(parent_obj->parent) {
|
||||||
|
parent_obj = parent_obj->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo info(path, name);
|
||||||
|
newobj->initObject(info, parent_obj->metadata.dataType);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QListDB::getParentId(int ohfi)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mutex);
|
||||||
|
CMAObject *obj = ohfiToObject(ohfi);
|
||||||
|
|
||||||
|
return obj ? obj->metadata.ohfiParent : 0;
|
||||||
|
}
|
||||||
94
src/qlistdb.h
Normal file
94
src/qlistdb.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* QCMA: Cross-platform content manager assistant for the PS Vita
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Codestation
|
||||||
|
*
|
||||||
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QLISTDB_H
|
||||||
|
#define QLISTDB_H
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
|
#include "cmarootobject.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <vitamtp.h>
|
||||||
|
|
||||||
|
class QListDB : public Database
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit QListDB(QObject *parent = 0);
|
||||||
|
~QListDB();
|
||||||
|
|
||||||
|
bool load();
|
||||||
|
bool rescan();
|
||||||
|
void close();
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
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 getParentId(int ohfi);
|
||||||
|
int getPathId(const char *name, int ohfi);
|
||||||
|
QString getRelativePath(int ohfi);
|
||||||
|
int getRootId(int ohfi);
|
||||||
|
int insertObjectEntry(const QString &path, const QString &name, int parent_ohfi);
|
||||||
|
bool renameObject(int ohfi, const QString &name);
|
||||||
|
void setObjectSize(int ohfi, qint64 size);
|
||||||
|
void freeMetadata(metadata_t *metadata) {
|
||||||
|
Q_UNUSED(metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef struct {
|
||||||
|
QList<CMAObject *>::const_iterator it;
|
||||||
|
QList<CMAObject *>::const_iterator end;
|
||||||
|
} find_data;
|
||||||
|
|
||||||
|
typedef QList<CMAObject *> root_list;
|
||||||
|
typedef QMap<int, root_list> map_list;
|
||||||
|
|
||||||
|
int create();
|
||||||
|
int scanRootDirectory(root_list &list,int ohfi_type);
|
||||||
|
int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type);
|
||||||
|
bool hasFilter(const CMARootObject *object,int ohfi);
|
||||||
|
bool removeInternal(root_list &list, int ohfi);
|
||||||
|
bool findInternal(const root_list &list, int ohfi, find_data &data);
|
||||||
|
CMAObject *getParent(CMAObject *last_dir, const QString ¤t_path);
|
||||||
|
CMAObject *pathToObjectInternal(const root_list &list, const char *path);
|
||||||
|
static bool lessThanComparator(const CMAObject *a, const CMAObject *b);
|
||||||
|
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);
|
||||||
|
|
||||||
|
QTimer *timer;
|
||||||
|
QThread *thread;
|
||||||
|
map_list object_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QLISTDB_H
|
||||||
1300
src/sqlitedb.cpp
Normal file
1300
src/sqlitedb.cpp
Normal file
File diff suppressed because it is too large
Load Diff
101
src/sqlitedb.h
Normal file
101
src/sqlitedb.h
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* QCMA: Cross-platform content manager assistant for the PS Vita
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Codestation
|
||||||
|
*
|
||||||
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SQLITEDB_H
|
||||||
|
#define SQLITEDB_H
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
|
|
||||||
|
#include <vitamtp.h>
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSqlDatabase>
|
||||||
|
#include <QSqlError>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
class SQLiteDB : public Database
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SQLiteDB(QObject *parent = 0);
|
||||||
|
~SQLiteDB();
|
||||||
|
|
||||||
|
bool load();
|
||||||
|
bool rescan();
|
||||||
|
void close();
|
||||||
|
|
||||||
|
bool reload(bool &prepared);
|
||||||
|
void setUUID(const QString &uuid);
|
||||||
|
|
||||||
|
bool open();
|
||||||
|
int create();
|
||||||
|
void clear();
|
||||||
|
bool initialize();
|
||||||
|
QSqlError getLastError();
|
||||||
|
|
||||||
|
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 getParentId(int ohfi);
|
||||||
|
int getPathId(const char *name, int ohfi);
|
||||||
|
QString getRelativePath(int ohfi);
|
||||||
|
int getRootId(int ohfi);
|
||||||
|
int insertObjectEntry(const QString &path, const QString &name, int parent_ohfi);
|
||||||
|
bool renameObject(int ohfi, const QString &name);
|
||||||
|
void setObjectSize(int ohfi, qint64 size);
|
||||||
|
void freeMetadata(metadata_t *metadata);
|
||||||
|
|
||||||
|
int getPathId(const QString &path);
|
||||||
|
QString getPathFromId(int ohfi);
|
||||||
|
bool updateSize(int ohfi, quint64 size);
|
||||||
|
bool deleteEntry(int ohfi);
|
||||||
|
bool insertSourceEntry(uint object_id, const QString &path, const QString &name);
|
||||||
|
uint insertMusicEntry(const QString &path, const QString &name, int parent, int type);
|
||||||
|
uint insertVideoEntry(const QString &path, const QString &name, int parent, int type);
|
||||||
|
uint insertPhotoEntry(const QString &path, const QString &name, int parent, int type);
|
||||||
|
uint insertSavedataEntry(const QString &path, const QString &name, int parent, int type);
|
||||||
|
bool insertApplicationEntry(const QString &name, int ohfi, int app_type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int recursiveScanRootDirectory(const QString &base_path, const QString &rel_path, int parent_ohfi, int root_ohfi);
|
||||||
|
int insertObjectEntryInternal(const QString &path, const QString &name, int parent_ohfi, int type);
|
||||||
|
int insertDefaultEntry(const QString &path, const QString &name, const QString &title, int parent, int type);
|
||||||
|
int insertNodeEntry(const QString &title, int type, int data_type);
|
||||||
|
bool updateAdjacencyList(int ohfi, int parent);
|
||||||
|
QString getBasePath(int root_ohfi);
|
||||||
|
int getObjectType(int ohfi);
|
||||||
|
void fillMetadata(const QSqlQuery &query, metadata_t &metadata);
|
||||||
|
qint64 getChildenTotalSize(int ohfi);
|
||||||
|
bool updateObjectPath(int ohfi, const QString &name);
|
||||||
|
int getRootItems(int root_ohfi, metadata_t **metadata);
|
||||||
|
bool insertVirtualEntries();
|
||||||
|
bool insertVirtualEntry(int ohfi);
|
||||||
|
|
||||||
|
QTimer *timer;
|
||||||
|
QThread *thread;
|
||||||
|
|
||||||
|
QString uuid;
|
||||||
|
QSqlDatabase db;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SQLITEDB_H
|
||||||
Reference in New Issue
Block a user