Update the database in a different thread so it doesn't freeze the main

thread.
Show PIN in a dialog instead of a notification popup.
Translations updated.
This commit is contained in:
codestation
2013-08-30 11:10:43 -04:30
parent b46156b507
commit 04853712d0
27 changed files with 772 additions and 133 deletions

View File

@@ -36,14 +36,17 @@ class AVDecoder
public: public:
AVDecoder(); AVDecoder();
~AVDecoder(); ~AVDecoder();
bool open(const QString filename); bool open(const QString filename);
void close();
QByteArray getAudioThumbnail(int width, int height); QByteArray getAudioThumbnail(int width, int height);
QByteArray getVideoThumbnail(int width, int height); QByteArray getVideoThumbnail(int width, int height);
void getPictureMetadata(metadata_t &metadata); void getPictureMetadata(metadata_t &metadata);
void getAudioMetadata(metadata_t &metadata); void getAudioMetadata(metadata_t &metadata);
void getVideoMetadata(metadata_t &metadata); void getVideoMetadata(metadata_t &metadata);
void close();
// simulate a static constructor to initialize libav only once
class AvInit class AvInit
{ {
public: public:

View File

@@ -42,8 +42,8 @@ public:
static bool lessThan(const BackupItem *s1, const BackupItem *s2); static bool lessThan(const BackupItem *s1, const BackupItem *s2);
int ohfi;
int row; int row;
int ohfi;
QString title; QString title;
private: private:

View File

@@ -1,5 +1,24 @@
#include "clientmanager.h" /*
* 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 "clientmanager.h"
#include "progressform.h"
#include "cmaclient.h" #include "cmaclient.h"
ClientManager::ClientManager(QObject *parent) : ClientManager::ClientManager(QObject *parent) :
@@ -7,11 +26,31 @@ ClientManager::ClientManager(QObject *parent) :
{ {
} }
void ClientManager::databaseUpdated(int count)
{
progress.hide();
if(count >= 0) {
emit messageSent(tr("Added %1 items to the database").arg(count));
} else {
emit messageSent(tr("Database indexing aborted by user"));
}
}
void ClientManager::showPinDialog(QString name, int pin)
{
pinForm.setPin(name, pin);
pinForm.startCountdown();
}
void ClientManager::start() void ClientManager::start()
{ {
// initializing database for the first use // initializing database for the first use
refreshDatabase(); refreshDatabase();
CmaEvent::db = &db; CmaEvent::db = &db;
connect(&db, SIGNAL(fileAdded(QString)), &progress, SLOT(setFileName(QString)));
connect(&db, SIGNAL(directoryAdded(QString)), &progress, SLOT(setDirectoryName(QString)));
connect(&db, SIGNAL(updated(int)), this, SLOT(databaseUpdated(int)));
connect(&progress, SIGNAL(canceled()), &db, SLOT(cancelOperation()), Qt::DirectConnection);
thread_count = 2; thread_count = 2;
qDebug("Starting cma threads"); qDebug("Starting cma threads");
@@ -21,7 +60,6 @@ void ClientManager::start()
client = new CmaClient(); client = new CmaClient();
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(receivedPin(int)), this, SIGNAL(receivedPin(int)));
connect(client, SIGNAL(finished()), usb_thread, SLOT(quit()), Qt::DirectConnection); connect(client, SIGNAL(finished()), usb_thread, SLOT(quit()), Qt::DirectConnection);
connect(usb_thread, SIGNAL(finished()), usb_thread, SLOT(deleteLater())); connect(usb_thread, SIGNAL(finished()), usb_thread, SLOT(deleteLater()));
connect(usb_thread, SIGNAL(finished()), this, SLOT(threadStopped())); connect(usb_thread, SIGNAL(finished()), this, SLOT(threadStopped()));
@@ -38,11 +76,13 @@ void ClientManager::start()
client = new CmaClient(); client = new CmaClient();
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(receivedPin(QString,int)), this, SLOT(showPinDialog(QString,int)));
connect(client, SIGNAL(finished()), wireless_thread, SLOT(quit()), Qt::DirectConnection); connect(client, SIGNAL(finished()), wireless_thread, SLOT(quit()), Qt::DirectConnection);
connect(wireless_thread, SIGNAL(finished()), wireless_thread, SLOT(deleteLater())); connect(wireless_thread, SIGNAL(finished()), wireless_thread, SLOT(deleteLater()));
connect(wireless_thread, SIGNAL(finished()), this, SLOT(threadStopped())); connect(wireless_thread, SIGNAL(finished()), this, SLOT(threadStopped()));
connect(wireless_thread, SIGNAL(finished()), client, SLOT(deleteLater())); connect(wireless_thread, SIGNAL(finished()), client, SLOT(deleteLater()));
connect(client, SIGNAL(deviceConnected(QString)), &pinForm, SLOT(hide()));
connect(client, SIGNAL(deviceConnected(QString)), this, SIGNAL(deviceConnected(QString))); connect(client, SIGNAL(deviceConnected(QString)), this, SIGNAL(deviceConnected(QString)));
connect(client, SIGNAL(deviceDisconnected()), this, SIGNAL(deviceDisconnected())); connect(client, SIGNAL(deviceDisconnected()), this, SIGNAL(deviceDisconnected()));
connect(client, SIGNAL(refreshDatabase()), this, SLOT(refreshDatabase())); connect(client, SIGNAL(refreshDatabase()), this, SLOT(refreshDatabase()));
@@ -53,12 +93,11 @@ void ClientManager::start()
void ClientManager::refreshDatabase() void ClientManager::refreshDatabase()
{ {
QMutexLocker locker(&db.mutex); if(!db.reload()) {
emit messageSent(tr("Cannot refresh the database while is in use"));
db.destroy(); } else {
int count = db.create(); progress.show();
qDebug("Added %i entries to the database", count); }
emit databaseUpdated(tr("Added %1 entries to the database").arg(count));
} }
void ClientManager::stop() void ClientManager::stop()

View File

@@ -1,7 +1,28 @@
/*
* 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 CLIENTMANAGER_H #ifndef CLIENTMANAGER_H
#define CLIENTMANAGER_H #define CLIENTMANAGER_H
#include "pinform.h"
#include "database.h" #include "database.h"
#include "progressform.h"
#include <QObject> #include <QObject>
#include <QThread> #include <QThread>
@@ -21,19 +42,24 @@ private:
int thread_count; int thread_count;
QMutex mutex; QMutex mutex;
PinForm pinForm;
ProgressForm progress;
QThread *usb_thread; QThread *usb_thread;
QThread *wireless_thread; QThread *wireless_thread;
signals: signals:
void deviceConnected(QString);
void deviceDisconnected();
void receivedPin(int);
void databaseUpdated(QString);
void stopped(); void stopped();
void receivedPin(int);
void deviceDisconnected();
void messageSent(QString);
void deviceConnected(QString);
private slots: private slots:
void refreshDatabase();
void threadStopped(); void threadStopped();
void refreshDatabase();
void databaseUpdated(int count);
void showPinDialog(QString name, int pin);
}; };
#endif // CLIENTMANAGER_H #endif // CLIENTMANAGER_H

View File

@@ -40,6 +40,7 @@ private:
QByteArray reply; QByteArray reply;
QString hostname; QString hostname;
QUdpSocket *socket; QUdpSocket *socket;
static const QString broadcast_reply; static const QString broadcast_reply;
static const char *broadcast_query; static const char *broadcast_query;
static const char *broadcast_ok; static const char *broadcast_ok;

View File

@@ -128,6 +128,7 @@ void CmaClient::processNewConnection(vita_device_t *device)
int CmaClient::deviceRegistered(const char *deviceid) int CmaClient::deviceRegistered(const char *deviceid)
{ {
qDebug("Got connection request from %s", deviceid); qDebug("Got connection request from %s", deviceid);
// TODO: check the device to see if is already registered
return 1; return 1;
} }
@@ -137,7 +138,7 @@ int CmaClient::generatePin(wireless_vita_info_t *info, int *p_err)
int pin = qrand() % 100000000; int pin = qrand() % 100000000;
qDebug("Your registration PIN for %s is: %08d", info->name, pin); qDebug("Your registration PIN for %s is: %08d", info->name, pin);
*p_err = 0; *p_err = 0;
emit this_object->receivedPin(pin); emit this_object->receivedPin(info->name, pin);
return pin; return pin;
} }
@@ -154,7 +155,13 @@ void CmaClient::enterEventLoop(vita_device_t *device)
qDebug("Starting event loop"); qDebug("Starting event loop");
CmaEvent eventLoop (device); CmaEvent eventLoop (device);
eventLoop.start("event_thread"); QThread thread;
thread.setObjectName("event_thread");
eventLoop.moveToThread(&thread);
connect(&thread, SIGNAL(started()), &eventLoop, SLOT(process()));
connect(&eventLoop, SIGNAL(finishedEventLoop()), &thread, SLOT(quit()), Qt::DirectConnection);
thread.start();
while(isActive()) { while(isActive()) {
if(VitaMTP_Read_Event(device, &event) < 0) { if(VitaMTP_Read_Event(device, &event) < 0) {
@@ -181,7 +188,7 @@ void CmaClient::enterEventLoop(vita_device_t *device)
} }
eventLoop.stop(); eventLoop.stop();
eventLoop.wait(); thread.wait();
qDebug("Finishing event loop"); qDebug("Finishing event loop");
} }

View File

@@ -20,11 +20,10 @@
#ifndef CMACLIENT_H #ifndef CMACLIENT_H
#define CMACLIENT_H #define CMACLIENT_H
#include "baseworker.h"
#include "cmabroadcast.h"
#include "cmaobject.h"
#include "database.h" #include "database.h"
#include "cmaevent.h" #include "cmaevent.h"
#include "cmaobject.h"
#include "cmabroadcast.h"
#include <QObject> #include <QObject>
#include <QSemaphore> #include <QSemaphore>
@@ -54,6 +53,8 @@ private:
static int cancelCallback(); static int cancelCallback();
CmaBroadcast broadcast; CmaBroadcast broadcast;
//TODO: move all the control variables to the client manager class
static bool is_active; static bool is_active;
static bool in_progress; static bool in_progress;
static int is_cancelled; static int is_cancelled;
@@ -65,7 +66,7 @@ private:
signals: signals:
void newEvent(vita_event_t event); void newEvent(vita_event_t event);
void receivedPin(int); void receivedPin(QString, int);
void deviceDetected(); void deviceDetected();
void deviceConnected(QString); void deviceConnected(QString);
void deviceDisconnected(); void deviceDisconnected();

View File

@@ -1,3 +1,22 @@
/*
* 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 "cmaevent.h" #include "cmaevent.h"
#include "utils.h" #include "utils.h"
@@ -11,8 +30,8 @@ Database *CmaEvent::db = NULL;
metadata_t CmaEvent::g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{18, 144, 80, 0, 1, 1.0f, 2}}, NULL}; metadata_t CmaEvent::g_thumbmeta = {0, 0, 0, NULL, NULL, 0, 0, 0, Thumbnail, {{18, 144, 80, 0, 1, 1.0f, 2}}, NULL};
CmaEvent::CmaEvent(vita_device_t *s_device, QObject *parent) : CmaEvent::CmaEvent(vita_device_t *s_device) :
BaseWorker(parent), device(s_device), is_active(true) device(s_device), is_active(true)
{ {
} }
@@ -29,7 +48,7 @@ void CmaEvent::process()
mutex.unlock(); mutex.unlock();
} }
qDebug("Finishing event_thread"); qDebug("Finishing event_thread");
emit finished(); emit finishedEventLoop();
} }
bool CmaEvent::isActive() bool CmaEvent::isActive()

View File

@@ -1,21 +1,40 @@
/*
* 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 CMAEVENT_H #ifndef CMAEVENT_H
#define CMAEVENT_H #define CMAEVENT_H
#include "cmaobject.h" #include "cmaobject.h"
#include "database.h" #include "database.h"
#include "baseworker.h"
#include <QObject> #include <QObject>
#include <QSemaphore> #include <QSemaphore>
#include <vitamtp.h> #include <vitamtp.h>
class CmaEvent : public BaseWorker class CmaEvent : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit CmaEvent(vita_device_t *s_device, QObject *parent = 0); explicit CmaEvent(vita_device_t *s_device);
// don't make the db reference static
static Database *db; static Database *db;
private: private:
@@ -46,6 +65,8 @@ private:
vita_device_t *device; vita_device_t *device;
vita_event_t t_event; vita_event_t t_event;
// control variables
bool is_active; bool is_active;
QMutex mutex; QMutex mutex;
QMutex active; QMutex active;
@@ -54,7 +75,6 @@ private:
static metadata_t g_thumbmeta; static metadata_t g_thumbmeta;
signals: signals:
void finished();
void finishedEventLoop(); void finishedEventLoop();
void refreshDatabase(); void refreshDatabase();

View File

@@ -34,21 +34,21 @@ public:
~CMAObject(); ~CMAObject();
void refreshPath(); void refreshPath();
void rename(const QString &name);
bool removeReferencedObject(); bool removeReferencedObject();
void initObject(const QFileInfo &file); void rename(const QString &name);
void updateObjectSize(qint64 size); void updateObjectSize(qint64 size);
bool hasParent(const CMAObject *obj); bool hasParent(const CMAObject *obj);
void initObject(const QFileInfo &file);
bool operator==(const CMAObject &obj); bool operator==(const CMAObject &obj);
bool operator!=(const CMAObject &obj); bool operator!=(const CMAObject &obj);
bool operator<(const CMAObject &obj); bool operator<(const CMAObject &obj);
void setOhfi(int ohfi) { inline void setOhfi(int ohfi) {
metadata.ohfi = ohfi; metadata.ohfi = ohfi;
} }
static void resetOhfiCounter() { inline static void resetOhfiCounter() {
ohfi_count = OHFI_OFFSET; ohfi_count = OHFI_OFFSET;
} }

View File

@@ -23,6 +23,7 @@
#include <QDirIterator> #include <QDirIterator>
#include <QSettings> #include <QSettings>
#include <QTextStream> #include <QTextStream>
#include <QThread>
#include <QDebug> #include <QDebug>
#define OHFI_OFFSET 1000 #define OHFI_OFFSET 1000
@@ -31,16 +32,29 @@ const QStringList Database::image_types = QStringList() << "jpg" << "jpeg" << "p
const QStringList Database::audio_types = QStringList() << "mp3" << "mp4" << "wav"; const QStringList Database::audio_types = QStringList() << "mp3" << "mp4" << "wav";
const QStringList Database::video_types = QStringList() << "mp4"; const QStringList Database::video_types = QStringList() << "mp4";
Database::Database(QObject *parent) : Database::Database() :
QObject(parent), mutex(QMutex::Recursive) mutex(QMutex::Recursive)
{ {
QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString(); QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
CMARootObject::uuid = uuid; 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()));
} }
Database::~Database() Database::~Database()
{ {
destroy(); destroy();
timer->stop();
delete timer;
thread->quit();
thread->wait();
delete thread;
} }
void Database::setUUID(const QString uuid) void Database::setUUID(const QString uuid)
@@ -49,10 +63,46 @@ void Database::setUUID(const QString uuid)
QSettings().setValue("lastAccountId", uuid); QSettings().setValue("lastAccountId", uuid);
} }
bool Database::reload()
{
if(mutex.tryLock()) {
timer->start();
return true;
} else {
return false;
}
}
void Database::process()
{
destroy();
cancel_operation = false;
int count = create();
cancel_operation = false;
qDebug("Added %i entries to the database", count);
if(count < 0) {
destroy();
}
emit updated(count);
mutex.unlock();
}
void Database::cancelOperation()
{
QMutexLocker locker(&cancel);
cancel_operation = true;
}
bool Database::continueOperation()
{
QMutexLocker locker(&cancel);
return !cancel_operation;
}
int Database::create() int Database::create()
{ {
int total_objects = 0; int total_objects = 0;
QMutexLocker locker(&mutex); //QMutexLocker locker(&mutex);
const int ohfi_array[] = { VITA_OHFI_MUSIC, VITA_OHFI_PHOTO, VITA_OHFI_VIDEO, const int ohfi_array[] = { VITA_OHFI_MUSIC, VITA_OHFI_PHOTO, VITA_OHFI_VIDEO,
VITA_OHFI_BACKUP, VITA_OHFI_VITAAPP, VITA_OHFI_PSPAPP, VITA_OHFI_BACKUP, VITA_OHFI_VITAAPP, VITA_OHFI_PSPAPP,
VITA_OHFI_PSPSAVE, VITA_OHFI_PSXAPP, VITA_OHFI_PSMAPP VITA_OHFI_PSPSAVE, VITA_OHFI_PSXAPP, VITA_OHFI_PSMAPP
@@ -88,7 +138,14 @@ int Database::create()
root_list list; root_list list;
list << obj; list << obj;
total_objects += recursiveScanRootDirectory(list, obj, ohfi_array[i]); 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; object_list[ohfi_array[i]] = list;
} }
return total_objects; return total_objects;
@@ -112,6 +169,11 @@ int Database::scanRootDirectory(root_list &list, int ohfi_type)
QDirIterator it(dir, QDirIterator::Subdirectories); QDirIterator it(dir, QDirIterator::Subdirectories);
while(it.hasNext()) { while(it.hasNext()) {
if(!continueOperation()) {
return -1;
}
it.next(); it.next();
QFileInfo info = it.fileInfo(); QFileInfo info = it.fileInfo();
@@ -143,14 +205,21 @@ int Database::recursiveScanRootDirectory(root_list &list, CMAObject *parent, int
QFileInfoList qsl = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot); QFileInfoList qsl = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
foreach(const QFileInfo &info, qsl) { foreach(const QFileInfo &info, qsl) {
if(!continueOperation()) {
return -1;
}
if(info.isFile() && !checkFileType(info.absoluteFilePath(), ohfi_type)) { if(info.isFile() && !checkFileType(info.absoluteFilePath(), ohfi_type)) {
//qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());> //qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());>
} else { } else {
CMAObject *obj = new CMAObject(parent); CMAObject *obj = new CMAObject(parent);
obj->initObject(info); obj->initObject(info);
emit fileAdded(obj->path);
//qDebug("Added %s to database with OHFI %d", obj->metadata.name, obj->metadata.ohfi); //qDebug("Added %s to database with OHFI %d", obj->metadata.name, obj->metadata.ohfi);
list << obj; list << obj;
if(info.isDir()) { if(info.isDir()) {
emit directoryAdded(obj->path);
total_objects += recursiveScanRootDirectory(list, obj, ohfi_type); total_objects += recursiveScanRootDirectory(list, obj, ohfi_type);
} else { } else {
total_objects++; total_objects++;
@@ -163,7 +232,7 @@ int Database::recursiveScanRootDirectory(root_list &list, CMAObject *parent, int
void Database::destroy() void Database::destroy()
{ {
QMutexLocker locker(&mutex); //QMutexLocker locker(&mutex);
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
CMARootObject *first = static_cast<CMARootObject *>((*root).takeFirst()); CMARootObject *first = static_cast<CMARootObject *>((*root).takeFirst());

View File

@@ -26,6 +26,7 @@
#include <QMap> #include <QMap>
#include <QMutex> #include <QMutex>
#include <QObject> #include <QObject>
#include <QTimer>
#include <vitamtp.h> #include <vitamtp.h>
@@ -38,13 +39,11 @@ public:
QList<CMAObject *>::const_iterator end; QList<CMAObject *>::const_iterator end;
} find_data; } find_data;
explicit Database(QObject *parent = 0); explicit Database();
~Database(); ~Database();
bool reload();
void destroy();
void setUUID(const QString uuid); void setUUID(const QString uuid);
int create();
void addEntries(CMAObject *root); void addEntries(CMAObject *root);
CMAObject *ohfiToObject(int ohfi); CMAObject *ohfiToObject(int ohfi);
bool find(int ohfi, find_data &data); bool find(int ohfi, find_data &data);
@@ -64,6 +63,9 @@ private:
static const QStringList image_types; static const QStringList image_types;
static const QStringList video_types; static const QStringList video_types;
int create();
void destroy();
int scanRootDirectory(root_list &list,int ohfi_type); int scanRootDirectory(root_list &list,int ohfi_type);
int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type); int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type);
bool hasFilter(const CMARootObject *object,int ohfi); bool hasFilter(const CMARootObject *object,int ohfi);
@@ -74,11 +76,26 @@ private:
static bool lessThanComparator(const CMAObject *a, const CMAObject *b); static bool lessThanComparator(const CMAObject *a, const CMAObject *b);
bool checkFileType(const QString path, int ohfi_root); bool checkFileType(const QString path, int ohfi_root);
void dumpMetadataList(const metadata_t *p_head); void dumpMetadataList(const metadata_t *p_head);
bool continueOperation();
// control variables
QMutex cancel;
bool cancel_operation;
QTimer *timer;
QThread *thread;
map_list object_list; map_list object_list;
signals: signals:
void finished(); void fileAdded(QString);
void directoryAdded(QString);
void updated(int);
protected slots:
void process();
public slots:
void cancelOperation();
}; };
#endif // DATABASE_H #endif // DATABASE_H

View File

@@ -41,16 +41,6 @@ void noMessageOutput(QtMsgType type, const char *msg)
Q_UNUSED(msg); Q_UNUSED(msg);
} }
void loadTranslation(QApplication &app)
{
QTranslator* translator = new QTranslator();
QString locale = QLocale().system().name();
qDebug() << "Current locale:" << locale;
if(translator->load("qcma." + locale, ":/main/resources/translations")) {
app.installTranslator(translator);
}
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if(SingleApplication::sendMessage(QObject::tr("A instance of QCMA is already running"))) { if(SingleApplication::sendMessage(QObject::tr("A instance of QCMA is already running"))) {
@@ -59,7 +49,12 @@ int main(int argc, char *argv[])
SingleApplication app(argc, argv); SingleApplication app(argc, argv);
loadTranslation(app); QTranslator translator;
QString locale = QLocale().system().name();
qDebug() << "Current locale:" << locale;
if(translator.load("qcma." + locale, ":/main/resources/translations")) {
app.installTranslator(&translator);
}
#ifndef Q_OS_WIN32 #ifndef Q_OS_WIN32
// FIXME: libmtp sends SIGPIPE if a socket write fails crashing the whole app // FIXME: libmtp sends SIGPIPE if a socket write fails crashing the whole app

View File

@@ -78,11 +78,6 @@ void MainWidget::deviceDisconnect()
receiveMessage(tr("The device has been disconnected")); receiveMessage(tr("The device has been disconnected"));
} }
void MainWidget::showPin(int pin)
{
receiveMessage(QString(tr("Received PIN: %1").arg(QString::number(pin), 8, QChar('0'))));
}
void MainWidget::prepareApplication() void MainWidget::prepareApplication()
{ {
connectSignals(); connectSignals();
@@ -94,11 +89,11 @@ void MainWidget::connectSignals()
{ {
connect(&dialog, SIGNAL(finished(int)), this, SLOT(dialogResult(int))); connect(&dialog, SIGNAL(finished(int)), this, SLOT(dialogResult(int)));
connect(&manager, SIGNAL(stopped()), qApp, SLOT(quit())); connect(&manager, SIGNAL(stopped()), qApp, SLOT(quit()));
connect(&manager, SIGNAL(receivedPin(int)), this, SLOT(showPin(int)));
connect(&manager, SIGNAL(databaseUpdated(QString)), this, SLOT(receiveMessage(QString)));
connect(&manager, SIGNAL(deviceConnected(QString)), this, SLOT(receiveMessage(QString))); connect(&manager, SIGNAL(deviceConnected(QString)), this, SLOT(receiveMessage(QString)));
connect(&manager, SIGNAL(deviceConnected(QString)), this, SLOT(setTrayTooltip(QString))); connect(&manager, SIGNAL(deviceConnected(QString)), this, SLOT(setTrayTooltip(QString)));
connect(&manager, SIGNAL(deviceDisconnected()), this, SLOT(deviceDisconnect())); connect(&manager, SIGNAL(deviceDisconnected()), this, SLOT(deviceDisconnect()));
connect(&manager, SIGNAL(messageSent(QString)), this, SLOT(receiveMessage(QString)));
form.db = &manager.db; form.db = &manager.db;
} }

View File

@@ -24,6 +24,7 @@
#include "clientmanager.h" #include "clientmanager.h"
#include "backupmanagerform.h" #include "backupmanagerform.h"
#include "cmaclient.h" #include "cmaclient.h"
#include "progressform.h"
#include <QAction> #include <QAction>
#include <QWidget> #include <QWidget>
@@ -46,24 +47,28 @@ private:
void checkSettings(); void checkSettings();
bool first_run; bool first_run;
// forms
ConfigWidget dialog; ConfigWidget dialog;
ClientManager manager;
BackupManagerForm form; BackupManagerForm form;
QSystemTrayIcon *trayIcon;
//system tray
QAction *quit; QAction *quit;
QAction *reload; QAction *reload;
QAction *options; QAction *options;
QAction *backup; QAction *backup;
ClientManager manager; QSystemTrayIcon *trayIcon;
const static QStringList path_list; const static QStringList path_list;
private slots: private slots:
void stopServer();
void openManager();
void deviceDisconnect(); void deviceDisconnect();
void dialogResult(int result); void dialogResult(int result);
void receiveMessage(QString message); void receiveMessage(QString message);
void setTrayTooltip(QString message); void setTrayTooltip(QString message);
void showPin(int pin);
void stopServer();
void openManager();
}; };
#endif // MAINWIDGET_H #endif // MAINWIDGET_H

71
pinform.cpp Normal file
View File

@@ -0,0 +1,71 @@
/*
* 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 "pinform.h"
#include "ui_pinform.h"
#include <QDebug>
#include <QDesktopWidget>
const QString PinForm::pinFormat =
"<html><head/><body>"
"<p><span style=\"font-size:24pt; font-weight:600;\">%1</span></p>"
"</body></html>";
PinForm::PinForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::PinForm)
{
ui->setupUi(this);
move(QApplication::desktop()->screen()->rect().center() - rect().center());
setFixedSize(size());
setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(hide()));
}
void PinForm::setPin(QString name, int pin)
{
qDebug() << "Got pin from user " << name;
ui->deviceLabel->setText(tr("Device: %1 (PS Vita)").arg(name));
ui->pinLabel->setText(pinFormat.arg(QString::number(pin), 8, QChar('0')));
show();
}
void PinForm::startCountdown()
{
timer.setInterval(1000);
counter = 300;
connect(&timer, SIGNAL(timeout()), this, SLOT(decreaseTimer()));
timer.start();
}
void PinForm::decreaseTimer()
{
counter--;
if(counter == 0) {
timer.stop();
hide();
}
ui->timeLabel->setText(tr("Time remaining: %1 seconds").arg(counter));
}
PinForm::~PinForm()
{
delete ui;
}

View File

@@ -17,37 +17,39 @@
* 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 "baseworker.h" #ifndef PINFORM_H
#define PINFORM_H
BaseWorker::BaseWorker(QObject *parent) : #include <QTimer>
QObject(parent) #include <QWidget>
namespace Ui {
class PinForm;
}
class PinForm : public QWidget
{ {
thread = NULL; Q_OBJECT
}
void BaseWorker::start(const char *thread_name) public:
{ explicit PinForm(QWidget *parent = 0);
thread = new QThread(); ~PinForm();
if(thread_name) { private:
thread->setObjectName(thread_name); Ui::PinForm *ui;
}
this->moveToThread(thread); // pin timeout
int counter;
QTimer timer;
connect(thread, SIGNAL(started()), this, SLOT(process())); static const QString pinFormat;
connect(this, SIGNAL(finished()), this, SLOT(onFinished()));
connect(this, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start(); public slots:
} void startCountdown();
void setPin(QString name, int pin);
bool BaseWorker::wait() private slots:
{ void decreaseTimer();
return thread->wait(); };
}
void BaseWorker::onFinished() #endif // PINFORM_H
{
}

115
pinform.ui Normal file
View File

@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PinForm</class>
<widget class="QWidget" name="PinForm">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>526</width>
<height>216</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>An unregistered PS Vita system is connecting with QCMA via Wi-Fi</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="deviceLabel">
<property name="text">
<string>Device: PS Vita</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Input the following number in the PS Vita system to register it with QCMA</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="pinLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:24pt; font-weight:600;&quot;&gt;12345678&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="text">
<string>Time remaining: 300 seconds</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

64
progressform.cpp Normal file
View File

@@ -0,0 +1,64 @@
/*
* 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 "progressform.h"
#include "ui_progressform.h"
#include <QDesktopWidget>
#include <QMessageBox>
ProgressForm::ProgressForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::ProgressForm)
{
ui->setupUi(this);
move(QApplication::desktop()->screen()->rect().center() - rect().center());
setFixedSize(size());
setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(cancelConfirm()));
}
ProgressForm::~ProgressForm()
{
delete ui;
}
void ProgressForm::cancelConfirm()
{
QMessageBox box;
box.setText(tr("Database indexing in progress"));
box.setInformativeText(tr("Are you sure to cancel the database indexing?"));
box.setIcon(QMessageBox::Warning);
box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
if(box.exec() == QMessageBox::Ok) {
emit canceled();
}
}
void ProgressForm::setFileName(QString file)
{
QString elided = ui->fileLabel->fontMetrics().elidedText(file, Qt::ElideMiddle, ui->fileLabel->width(), 0);
ui->fileLabel->setText(elided);
}
void ProgressForm::setDirectoryName(QString dir)
{
QString elided = ui->directoryLabel->fontMetrics().elidedText(dir, Qt::ElideMiddle, ui->directoryLabel->width(), 0);
ui->directoryLabel->setText(elided);
}

View File

@@ -17,33 +17,35 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef BASEWORKER_H #ifndef PROGRESSFORM_H
#define BASEWORKER_H #define PROGRESSFORM_H
#include <QObject> #include <QWidget>
#include <QThread>
class BaseWorker : public QObject namespace Ui {
class ProgressForm;
}
class ProgressForm : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit BaseWorker(QObject *parent = 0); explicit ProgressForm(QWidget *parent = 0);
~ProgressForm();
void start(const char *thread_name = NULL);
bool wait();
private: private:
QThread *thread; Ui::ProgressForm *ui;
signals: signals:
void finished(); void canceled();
private slots:
void cancelConfirm();
public slots: public slots:
virtual void onFinished(); void setDirectoryName(QString dir);
void setFileName(QString file);
protected slots:
virtual void process() = 0;
}; };
#endif // BASEWORKER_H #endif // PROGRESSFORM_H

80
progressform.ui Normal file
View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProgressForm</class>
<widget class="QWidget" name="ProgressForm">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>602</width>
<height>138</height>
</rect>
</property>
<property name="windowTitle">
<string>Refreshing database...</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Reading directory:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="directoryLabel">
<property name="text">
<string>directory name</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Processing file:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="fileLabel">
<property name="text">
<string>file name</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -22,7 +22,6 @@ SOURCES += main.cpp \
mainwidget.cpp \ mainwidget.cpp \
configwidget.cpp \ configwidget.cpp \
singleapplication.cpp \ singleapplication.cpp \
baseworker.cpp \
sforeader.cpp \ sforeader.cpp \
cmaclient.cpp \ cmaclient.cpp \
cmabroadcast.cpp \ cmabroadcast.cpp \
@@ -31,7 +30,9 @@ SOURCES += main.cpp \
clientmanager.cpp \ clientmanager.cpp \
backupmanagerform.cpp \ backupmanagerform.cpp \
backupitem.cpp \ backupitem.cpp \
confirmdialog.cpp confirmdialog.cpp \
progressform.cpp \
pinform.cpp
HEADERS += \ HEADERS += \
capability.h \ capability.h \
@@ -42,7 +43,6 @@ HEADERS += \
mainwidget.h \ mainwidget.h \
configwidget.h \ configwidget.h \
singleapplication.h \ singleapplication.h \
baseworker.h \
sforeader.h \ sforeader.h \
cmaclient.h \ cmaclient.h \
cmabroadcast.h \ cmabroadcast.h \
@@ -51,7 +51,9 @@ HEADERS += \
clientmanager.h \ clientmanager.h \
backupmanagerform.h \ backupmanagerform.h \
backupitem.h \ backupitem.h \
confirmdialog.h confirmdialog.h \
progressform.h \
pinform.h
CONFIG += link_pkgconfig CONFIG += link_pkgconfig
PKGCONFIG += libvitamtp libavformat libavcodec libavutil libswscale PKGCONFIG += libvitamtp libavformat libavcodec libavutil libswscale
@@ -71,7 +73,9 @@ FORMS += \
configwidget.ui \ configwidget.ui \
backupmanagerform.ui \ backupmanagerform.ui \
backupitem.ui \ backupitem.ui \
confirmdialog.ui confirmdialog.ui \
progressform.ui \
pinform.ui
TRANSLATIONS += resources/translations/qcma.es.ts TRANSLATIONS += resources/translations/qcma.es.ts

View File

@@ -95,10 +95,24 @@
<context> <context>
<name>ClientManager</name> <name>ClientManager</name>
<message> <message>
<location filename="../../clientmanager.cpp" line="61"/>
<source>Added %1 entries to the database</source> <source>Added %1 entries to the database</source>
<translation type="obsolete">Agregadas %1 entradas a la base de datos</translation>
</message>
<message>
<location filename="../../clientmanager.cpp" line="33"/>
<source>Added %1 items to the database</source>
<translation>Agregadas %1 entradas a la base de datos</translation> <translation>Agregadas %1 entradas a la base de datos</translation>
</message> </message>
<message>
<location filename="../../clientmanager.cpp" line="35"/>
<source>Database indexing aborted by user</source>
<translation>Actualización de la base de datos cancelada por el usuario</translation>
</message>
<message>
<location filename="../../clientmanager.cpp" line="97"/>
<source>Cannot refresh the database while is in use</source>
<translation>No se puede actualizar la base de datos mientras se encuentre en uso</translation>
</message>
</context> </context>
<context> <context>
<name>CmaClient</name> <name>CmaClient</name>
@@ -227,40 +241,130 @@
<translation>El dispositivo se ha desconectado</translation> <translation>El dispositivo se ha desconectado</translation>
</message> </message>
<message> <message>
<location filename="../../mainwidget.cpp" line="83"/>
<source>Received PIN: %1</source> <source>Received PIN: %1</source>
<translation>PIN recibido: %1</translation> <translation type="obsolete">PIN recibido: %1</translation>
</message> </message>
<message> <message>
<location filename="../../mainwidget.cpp" line="118"/> <location filename="../../mainwidget.cpp" line="113"/>
<source>&amp;Settings</source> <source>&amp;Settings</source>
<translation>&amp;Ajustes</translation> <translation>&amp;Ajustes</translation>
</message> </message>
<message> <message>
<location filename="../../mainwidget.cpp" line="119"/> <location filename="../../mainwidget.cpp" line="114"/>
<source>&amp;Refresh database</source> <source>&amp;Refresh database</source>
<translation>&amp;Refrescar base de datos</translation> <translation>&amp;Refrescar base de datos</translation>
</message> </message>
<message> <message>
<location filename="../../mainwidget.cpp" line="120"/> <location filename="../../mainwidget.cpp" line="115"/>
<source>Backup Manager</source> <source>Backup Manager</source>
<translation>Gestor de Respaldos</translation> <translation>Gestor de Respaldos</translation>
</message> </message>
<message> <message>
<location filename="../../mainwidget.cpp" line="121"/> <location filename="../../mainwidget.cpp" line="116"/>
<source>&amp;Quit</source> <source>&amp;Quit</source>
<translation>&amp;Salir</translation> <translation>&amp;Salir</translation>
</message> </message>
<message> <message>
<location filename="../../mainwidget.cpp" line="146"/> <location filename="../../mainwidget.cpp" line="141"/>
<source>Information</source> <source>Information</source>
<translation>Información</translation> <translation>Información</translation>
</message> </message>
</context> </context>
<context>
<name>PinForm</name>
<message>
<location filename="../../pinform.ui" line="17"/>
<source>Form</source>
<translation>Registro de PIN</translation>
</message>
<message>
<location filename="../../pinform.ui" line="25"/>
<source>An unregistered PS Vita system is connecting with QCMA via Wi-Fi</source>
<translation>Un sistema PS Vita no registrado se intenta conectar con QCMA mediante Wi-Fi</translation>
</message>
<message>
<location filename="../../pinform.ui" line="35"/>
<source>Device: PS Vita</source>
<translation>Dispositivo: PS Vita</translation>
</message>
<message>
<location filename="../../pinform.ui" line="45"/>
<source>Input the following number in the PS Vita system to register it with QCMA</source>
<translation>Introduce el siguiente número en el sistema PS Vita para registrarlo con QCMA</translation>
</message>
<message>
<location filename="../../pinform.ui" line="55"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:24pt; font-weight:600;&quot;&gt;12345678&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation></translation>
</message>
<message>
<location filename="../../pinform.ui" line="65"/>
<source>Time remaining: 300 seconds</source>
<translation>Tiempo restante: 300 segundos</translation>
</message>
<message>
<location filename="../../pinform.ui" line="90"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
<location filename="../../pinform.cpp" line="45"/>
<source>Device: %1 (PS Vita)</source>
<translation>Dispositivo: %1 (PS Vita)</translation>
</message>
<message>
<location filename="../../pinform.cpp" line="65"/>
<source>Time remaining: %1 seconds</source>
<translation>Tiempo restante: %1 segundos</translation>
</message>
</context>
<context>
<name>ProgressForm</name>
<message>
<location filename="../../progressform.ui" line="17"/>
<source>Refreshing database...</source>
<translation>Actualizando base de datos...</translation>
</message>
<message>
<location filename="../../progressform.ui" line="25"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Reading directory:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Leyendo directorio:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../progressform.ui" line="32"/>
<source>directory name</source>
<translation>Cargando nombre de directorio</translation>
</message>
<message>
<location filename="../../progressform.ui" line="39"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Processing file:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Procesando archivo:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../progressform.ui" line="46"/>
<source>file name</source>
<translation>Cargando nombre de archivo</translation>
</message>
<message>
<location filename="../../progressform.ui" line="68"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
<location filename="../../progressform.cpp" line="45"/>
<source>Database indexing in progress</source>
<translation>Actualización de base de datos en progreso</translation>
</message>
<message>
<location filename="../../progressform.cpp" line="46"/>
<source>Are you sure to cancel the database indexing?</source>
<translation>¿Estas seguro de cancelar la actualización a la base de datos?</translation>
</message>
</context>
<context> <context>
<name>QObject</name> <name>QObject</name>
<message> <message>
<location filename="../../main.cpp" line="54"/> <location filename="../../main.cpp" line="46"/>
<source>A instance of QCMA is already running</source> <source>A instance of QCMA is already running</source>
<translation>Otra instancia de QCMA ya se encuentra en ejecución</translation> <translation>Otra instancia de QCMA ya se encuentra en ejecución</translation>
</message> </message>

View File

@@ -46,8 +46,8 @@ public:
#endif #endif
bool removeRecursively(const QString &dirName); bool removeRecursively(const QString &dirName);
QString readable_size(quint64 size, bool use_gib = false);
bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total); bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total);
QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata); QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata);
QString readable_size(quint64 size, bool use_gib = false);
#endif // UTILS_H #endif // UTILS_H