diff --git a/avdecoder.h b/avdecoder.h index 7459056..d4d08fc 100644 --- a/avdecoder.h +++ b/avdecoder.h @@ -36,14 +36,17 @@ class AVDecoder public: AVDecoder(); ~AVDecoder(); + bool open(const QString filename); + void close(); + QByteArray getAudioThumbnail(int width, int height); QByteArray getVideoThumbnail(int width, int height); void getPictureMetadata(metadata_t &metadata); void getAudioMetadata(metadata_t &metadata); void getVideoMetadata(metadata_t &metadata); - void close(); + // simulate a static constructor to initialize libav only once class AvInit { public: diff --git a/backupitem.cpp b/backupitem.cpp index 9a0e54d..810c92a 100644 --- a/backupitem.cpp +++ b/backupitem.cpp @@ -25,9 +25,9 @@ #include const QString BackupItem::nameTemplate = "" -"

%1

" -"

%2

" -""; + "

%1

" + "

%2

" + ""; BackupItem::BackupItem(QWidget *parent) : QWidget(parent), diff --git a/backupitem.h b/backupitem.h index a7f4c0d..485b0ba 100644 --- a/backupitem.h +++ b/backupitem.h @@ -29,7 +29,7 @@ class BackupItem; class BackupItem : public QWidget { Q_OBJECT - + public: explicit BackupItem(QWidget *parent = 0); ~BackupItem(); @@ -42,8 +42,8 @@ public: static bool lessThan(const BackupItem *s1, const BackupItem *s2); - int ohfi; int row; + int ohfi; QString title; private: diff --git a/backupmanagerform.cpp b/backupmanagerform.cpp index c7ca6d1..687fada 100644 --- a/backupmanagerform.cpp +++ b/backupmanagerform.cpp @@ -47,7 +47,7 @@ BackupManagerForm::~BackupManagerForm() void BackupManagerForm::setupForm() { this->resize(800, 480); - connect(ui->backupComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(loadBackupListing(int))); + connect(ui->backupComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(loadBackupListing(int))); ui->tableWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); ui->tableWidget->horizontalHeader()->hide(); // the the account name when vitamtp returns this value @@ -133,7 +133,7 @@ void BackupManagerForm::loadBackupListing(int index) // get the item list metadata_t *meta; - int row_count = db->filterObjects(ohfi, &meta); + int row_count = db->filterObjects(ohfi, &meta); ui->tableWidget->setRowCount(row_count); // adjust the table item width to fill all the widget diff --git a/clientmanager.cpp b/clientmanager.cpp index 3930a06..a93be90 100644 --- a/clientmanager.cpp +++ b/clientmanager.cpp @@ -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 . + */ +#include "clientmanager.h" +#include "progressform.h" #include "cmaclient.h" 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() { // initializing database for the first use refreshDatabase(); 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; qDebug("Starting cma threads"); @@ -21,7 +60,6 @@ void ClientManager::start() client = new CmaClient(); usb_thread->setObjectName("usb_thread"); 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(usb_thread, SIGNAL(finished()), usb_thread, SLOT(deleteLater())); connect(usb_thread, SIGNAL(finished()), this, SLOT(threadStopped())); @@ -38,11 +76,13 @@ void ClientManager::start() client = new CmaClient(); wireless_thread->setObjectName("wireless_thread"); 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(wireless_thread, SIGNAL(finished()), wireless_thread, SLOT(deleteLater())); connect(wireless_thread, SIGNAL(finished()), this, SLOT(threadStopped())); 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(deviceDisconnected()), this, SIGNAL(deviceDisconnected())); connect(client, SIGNAL(refreshDatabase()), this, SLOT(refreshDatabase())); @@ -53,12 +93,11 @@ void ClientManager::start() void ClientManager::refreshDatabase() { - QMutexLocker locker(&db.mutex); - - db.destroy(); - int count = db.create(); - qDebug("Added %i entries to the database", count); - emit databaseUpdated(tr("Added %1 entries to the database").arg(count)); + if(!db.reload()) { + emit messageSent(tr("Cannot refresh the database while is in use")); + } else { + progress.show(); + } } void ClientManager::stop() diff --git a/clientmanager.h b/clientmanager.h index 1e7602c..b15b873 100644 --- a/clientmanager.h +++ b/clientmanager.h @@ -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 . + */ + #ifndef CLIENTMANAGER_H #define CLIENTMANAGER_H +#include "pinform.h" #include "database.h" +#include "progressform.h" #include #include @@ -15,25 +36,30 @@ public: void start(); void stop(); - Database db; + Database db; private: int thread_count; QMutex mutex; + PinForm pinForm; + ProgressForm progress; + QThread *usb_thread; QThread *wireless_thread; signals: - void deviceConnected(QString); - void deviceDisconnected(); - void receivedPin(int); - void databaseUpdated(QString); void stopped(); + void receivedPin(int); + void deviceDisconnected(); + void messageSent(QString); + void deviceConnected(QString); private slots: - void refreshDatabase(); void threadStopped(); + void refreshDatabase(); + void databaseUpdated(int count); + void showPinDialog(QString name, int pin); }; #endif // CLIENTMANAGER_H diff --git a/cmabroadcast.h b/cmabroadcast.h index fae9b34..b0e8c08 100644 --- a/cmabroadcast.h +++ b/cmabroadcast.h @@ -40,6 +40,7 @@ private: QByteArray reply; QString hostname; QUdpSocket *socket; + static const QString broadcast_reply; static const char *broadcast_query; static const char *broadcast_ok; diff --git a/cmaclient.cpp b/cmaclient.cpp index df6356a..364e6ff 100644 --- a/cmaclient.cpp +++ b/cmaclient.cpp @@ -128,6 +128,7 @@ void CmaClient::processNewConnection(vita_device_t *device) int CmaClient::deviceRegistered(const char *deviceid) { qDebug("Got connection request from %s", deviceid); + // TODO: check the device to see if is already registered return 1; } @@ -137,7 +138,7 @@ int CmaClient::generatePin(wireless_vita_info_t *info, int *p_err) int pin = qrand() % 100000000; qDebug("Your registration PIN for %s is: %08d", info->name, pin); *p_err = 0; - emit this_object->receivedPin(pin); + emit this_object->receivedPin(info->name, pin); return pin; } @@ -153,8 +154,14 @@ void CmaClient::enterEventLoop(vita_device_t *device) qDebug("Starting event loop"); - CmaEvent eventLoop(device); - eventLoop.start("event_thread"); + CmaEvent eventLoop (device); + 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()) { if(VitaMTP_Read_Event(device, &event) < 0) { @@ -167,7 +174,7 @@ void CmaClient::enterEventLoop(vita_device_t *device) qDebug("Terminating event thread"); break; - // this one shuold be processed inmediately + // this one shuold be processed inmediately } else if(event.Code == PTP_EC_VITA_RequestCancelTask) { quint32 eventIdToCancel = event.Param2; qDebug("Cancelling event %d", eventIdToCancel); @@ -181,7 +188,7 @@ void CmaClient::enterEventLoop(vita_device_t *device) } eventLoop.stop(); - eventLoop.wait(); + thread.wait(); qDebug("Finishing event loop"); } diff --git a/cmaclient.h b/cmaclient.h index 2de9aa4..b9c45b8 100644 --- a/cmaclient.h +++ b/cmaclient.h @@ -20,11 +20,10 @@ #ifndef CMACLIENT_H #define CMACLIENT_H -#include "baseworker.h" -#include "cmabroadcast.h" -#include "cmaobject.h" #include "database.h" #include "cmaevent.h" +#include "cmaobject.h" +#include "cmabroadcast.h" #include #include @@ -54,6 +53,8 @@ private: static int cancelCallback(); CmaBroadcast broadcast; + + //TODO: move all the control variables to the client manager class static bool is_active; static bool in_progress; static int is_cancelled; @@ -65,7 +66,7 @@ private: signals: void newEvent(vita_event_t event); - void receivedPin(int); + void receivedPin(QString, int); void deviceDetected(); void deviceConnected(QString); void deviceDisconnected(); diff --git a/cmaevent.cpp b/cmaevent.cpp index 925f29c..5a7ba22 100644 --- a/cmaevent.cpp +++ b/cmaevent.cpp @@ -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 . + */ + #include "cmaevent.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}; -CmaEvent::CmaEvent(vita_device_t *s_device, QObject *parent) : - BaseWorker(parent), device(s_device), is_active(true) +CmaEvent::CmaEvent(vita_device_t *s_device) : + device(s_device), is_active(true) { } @@ -29,7 +48,7 @@ void CmaEvent::process() mutex.unlock(); } qDebug("Finishing event_thread"); - emit finished(); + emit finishedEventLoop(); } bool CmaEvent::isActive() diff --git a/cmaevent.h b/cmaevent.h index fc3cff2..d94f3b4 100644 --- a/cmaevent.h +++ b/cmaevent.h @@ -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 . + */ + #ifndef CMAEVENT_H #define CMAEVENT_H #include "cmaobject.h" #include "database.h" -#include "baseworker.h" #include #include #include -class CmaEvent : public BaseWorker +class CmaEvent : public QObject { Q_OBJECT 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; private: @@ -46,6 +65,8 @@ private: vita_device_t *device; vita_event_t t_event; + + // control variables bool is_active; QMutex mutex; QMutex active; @@ -54,7 +75,6 @@ private: static metadata_t g_thumbmeta; signals: - void finished(); void finishedEventLoop(); void refreshDatabase(); diff --git a/cmaobject.h b/cmaobject.h index 8411314..2d99123 100644 --- a/cmaobject.h +++ b/cmaobject.h @@ -34,21 +34,21 @@ public: ~CMAObject(); void refreshPath(); - void rename(const QString &name); bool removeReferencedObject(); - void initObject(const QFileInfo &file); + void rename(const QString &name); void updateObjectSize(qint64 size); 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); - void setOhfi(int ohfi) { + inline void setOhfi(int ohfi) { metadata.ohfi = ohfi; } - static void resetOhfiCounter() { + inline static void resetOhfiCounter() { ohfi_count = OHFI_OFFSET; } diff --git a/confirmdialog.cpp b/confirmdialog.cpp index 7aea061..8815876 100644 --- a/confirmdialog.cpp +++ b/confirmdialog.cpp @@ -21,9 +21,9 @@ #include "ui_confirmdialog.h" const QString ConfirmDialog::messageTemplate = "" -"

%1

" -"

%2

" -""; + "

%1

" + "

%2

" + ""; ConfirmDialog::ConfirmDialog(QWidget *parent) : QDialog(parent), diff --git a/database.cpp b/database.cpp index edd407d..c410648 100644 --- a/database.cpp +++ b/database.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #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::video_types = QStringList() << "mp4"; -Database::Database(QObject *parent) : - QObject(parent), mutex(QMutex::Recursive) +Database::Database() : + 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())); } Database::~Database() { destroy(); + timer->stop(); + delete timer; + thread->quit(); + thread->wait(); + delete thread; } void Database::setUUID(const QString uuid) @@ -49,10 +63,46 @@ void Database::setUUID(const QString 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 total_objects = 0; - QMutexLocker locker(&mutex); + //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 @@ -88,7 +138,14 @@ int Database::create() root_list list; 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; } return total_objects; @@ -112,6 +169,11 @@ int Database::scanRootDirectory(root_list &list, int ohfi_type) QDirIterator it(dir, QDirIterator::Subdirectories); while(it.hasNext()) { + + if(!continueOperation()) { + return -1; + } + it.next(); 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); foreach(const QFileInfo &info, qsl) { + + if(!continueOperation()) { + return -1; + } + if(info.isFile() && !checkFileType(info.absoluteFilePath(), ohfi_type)) { //qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());> } else { CMAObject *obj = new CMAObject(parent); obj->initObject(info); + emit fileAdded(obj->path); //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++; @@ -163,7 +232,7 @@ int Database::recursiveScanRootDirectory(root_list &list, CMAObject *parent, int void Database::destroy() { - QMutexLocker locker(&mutex); + //QMutexLocker locker(&mutex); for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) { CMARootObject *first = static_cast((*root).takeFirst()); diff --git a/database.h b/database.h index e74348d..ad565c7 100644 --- a/database.h +++ b/database.h @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -38,13 +39,11 @@ public: QList::const_iterator end; } find_data; - explicit Database(QObject *parent = 0); + explicit Database(); ~Database(); - - void destroy(); + bool reload(); void setUUID(const QString uuid); - int create(); void addEntries(CMAObject *root); CMAObject *ohfiToObject(int ohfi); bool find(int ohfi, find_data &data); @@ -64,6 +63,9 @@ private: 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); @@ -74,11 +76,26 @@ private: static bool lessThanComparator(const CMAObject *a, const CMAObject *b); bool checkFileType(const QString path, int ohfi_root); void dumpMetadataList(const metadata_t *p_head); + bool continueOperation(); + // control variables + QMutex cancel; + bool cancel_operation; + + QTimer *timer; + QThread *thread; map_list object_list; signals: - void finished(); + void fileAdded(QString); + void directoryAdded(QString); + void updated(int); + +protected slots: + void process(); + +public slots: + void cancelOperation(); }; #endif // DATABASE_H diff --git a/main.cpp b/main.cpp index 65100de..a9c05c4 100644 --- a/main.cpp +++ b/main.cpp @@ -41,16 +41,6 @@ void noMessageOutput(QtMsgType type, const char *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[]) { 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); - 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 // FIXME: libmtp sends SIGPIPE if a socket write fails crashing the whole app diff --git a/mainwidget.cpp b/mainwidget.cpp index 10c98a1..17f940c 100644 --- a/mainwidget.cpp +++ b/mainwidget.cpp @@ -78,11 +78,6 @@ void MainWidget::deviceDisconnect() 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() { connectSignals(); @@ -94,11 +89,11 @@ void MainWidget::connectSignals() { connect(&dialog, SIGNAL(finished(int)), this, SLOT(dialogResult(int))); 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(setTrayTooltip(QString))); connect(&manager, SIGNAL(deviceDisconnected()), this, SLOT(deviceDisconnect())); + connect(&manager, SIGNAL(messageSent(QString)), this, SLOT(receiveMessage(QString))); + form.db = &manager.db; } diff --git a/mainwidget.h b/mainwidget.h index 4c6f9af..119a347 100644 --- a/mainwidget.h +++ b/mainwidget.h @@ -24,6 +24,7 @@ #include "clientmanager.h" #include "backupmanagerform.h" #include "cmaclient.h" +#include "progressform.h" #include #include @@ -46,24 +47,28 @@ private: void checkSettings(); bool first_run; + + // forms ConfigWidget dialog; + ClientManager manager; BackupManagerForm form; - QSystemTrayIcon *trayIcon; + + //system tray QAction *quit; QAction *reload; QAction *options; QAction *backup; - ClientManager manager; + QSystemTrayIcon *trayIcon; + const static QStringList path_list; private slots: + void stopServer(); + void openManager(); void deviceDisconnect(); void dialogResult(int result); void receiveMessage(QString message); void setTrayTooltip(QString message); - void showPin(int pin); - void stopServer(); - void openManager(); }; #endif // MAINWIDGET_H diff --git a/pinform.cpp b/pinform.cpp new file mode 100644 index 0000000..3573edd --- /dev/null +++ b/pinform.cpp @@ -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 . + */ + +#include "pinform.h" +#include "ui_pinform.h" + +#include +#include + +const QString PinForm::pinFormat = + "" + "

%1

" + ""; + +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; +} diff --git a/baseworker.cpp b/pinform.h similarity index 53% rename from baseworker.cpp rename to pinform.h index 38cc8e7..0b534c9 100644 --- a/baseworker.cpp +++ b/pinform.h @@ -17,37 +17,39 @@ * along with this program. If not, see . */ -#include "baseworker.h" +#ifndef PINFORM_H +#define PINFORM_H -BaseWorker::BaseWorker(QObject *parent) : - QObject(parent) -{ - thread = NULL; +#include +#include + +namespace Ui { +class PinForm; } -void BaseWorker::start(const char *thread_name) +class PinForm : public QWidget { - thread = new QThread(); + Q_OBJECT - if(thread_name) { - thread->setObjectName(thread_name); - } +public: + explicit PinForm(QWidget *parent = 0); + ~PinForm(); - this->moveToThread(thread); +private: + Ui::PinForm *ui; - connect(thread, SIGNAL(started()), this, SLOT(process())); - connect(this, SIGNAL(finished()), this, SLOT(onFinished())); - connect(this, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + // pin timeout + int counter; + QTimer timer; - thread->start(); -} + static const QString pinFormat; -bool BaseWorker::wait() -{ - return thread->wait(); -} +public slots: + void startCountdown(); + void setPin(QString name, int pin); -void BaseWorker::onFinished() -{ -} +private slots: + void decreaseTimer(); +}; + +#endif // PINFORM_H diff --git a/pinform.ui b/pinform.ui new file mode 100644 index 0000000..43283bd --- /dev/null +++ b/pinform.ui @@ -0,0 +1,115 @@ + + + PinForm + + + Qt::ApplicationModal + + + + 0 + 0 + 526 + 216 + + + + Form + + + + + + + + An unregistered PS Vita system is connecting with QCMA via Wi-Fi + + + Qt::AlignCenter + + + + + + + Device: PS Vita + + + Qt::AlignCenter + + + + + + + Input the following number in the PS Vita system to register it with QCMA + + + Qt::AlignCenter + + + + + + + <html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html> + + + Qt::AlignCenter + + + + + + + Time remaining: 300 seconds + + + Qt::AlignCenter + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + diff --git a/progressform.cpp b/progressform.cpp new file mode 100644 index 0000000..88468bf --- /dev/null +++ b/progressform.cpp @@ -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 . + */ + +#include "progressform.h" +#include "ui_progressform.h" + +#include +#include + +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); +} diff --git a/baseworker.h b/progressform.h similarity index 67% rename from baseworker.h rename to progressform.h index af94ca5..4c0a4b3 100644 --- a/baseworker.h +++ b/progressform.h @@ -17,33 +17,35 @@ * along with this program. If not, see . */ -#ifndef BASEWORKER_H -#define BASEWORKER_H +#ifndef PROGRESSFORM_H +#define PROGRESSFORM_H -#include -#include +#include -class BaseWorker : public QObject +namespace Ui { +class ProgressForm; +} + +class ProgressForm : public QWidget { Q_OBJECT public: - explicit BaseWorker(QObject *parent = 0); - - void start(const char *thread_name = NULL); - bool wait(); + explicit ProgressForm(QWidget *parent = 0); + ~ProgressForm(); private: - QThread *thread; + Ui::ProgressForm *ui; signals: - void finished(); + void canceled(); + +private slots: + void cancelConfirm(); public slots: - virtual void onFinished(); - -protected slots: - virtual void process() = 0; + void setDirectoryName(QString dir); + void setFileName(QString file); }; -#endif // BASEWORKER_H +#endif // PROGRESSFORM_H diff --git a/progressform.ui b/progressform.ui new file mode 100644 index 0000000..1138f36 --- /dev/null +++ b/progressform.ui @@ -0,0 +1,80 @@ + + + ProgressForm + + + Qt::ApplicationModal + + + + 0 + 0 + 602 + 138 + + + + Refreshing database... + + + + + + + + <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Reading directory:</span></p></body></html> + + + + + + + directory name + + + + + + + <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Processing file:</span></p></body></html> + + + + + + + file name + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + + + + + + diff --git a/qcma.pro b/qcma.pro index 2d9e852..d134ee5 100644 --- a/qcma.pro +++ b/qcma.pro @@ -22,7 +22,6 @@ SOURCES += main.cpp \ mainwidget.cpp \ configwidget.cpp \ singleapplication.cpp \ - baseworker.cpp \ sforeader.cpp \ cmaclient.cpp \ cmabroadcast.cpp \ @@ -31,7 +30,9 @@ SOURCES += main.cpp \ clientmanager.cpp \ backupmanagerform.cpp \ backupitem.cpp \ - confirmdialog.cpp + confirmdialog.cpp \ + progressform.cpp \ + pinform.cpp HEADERS += \ capability.h \ @@ -42,7 +43,6 @@ HEADERS += \ mainwidget.h \ configwidget.h \ singleapplication.h \ - baseworker.h \ sforeader.h \ cmaclient.h \ cmabroadcast.h \ @@ -51,7 +51,9 @@ HEADERS += \ clientmanager.h \ backupmanagerform.h \ backupitem.h \ - confirmdialog.h + confirmdialog.h \ + progressform.h \ + pinform.h CONFIG += link_pkgconfig PKGCONFIG += libvitamtp libavformat libavcodec libavutil libswscale @@ -71,7 +73,9 @@ FORMS += \ configwidget.ui \ backupmanagerform.ui \ backupitem.ui \ - confirmdialog.ui + confirmdialog.ui \ + progressform.ui \ + pinform.ui TRANSLATIONS += resources/translations/qcma.es.ts diff --git a/resources/translations/qcma.es.ts b/resources/translations/qcma.es.ts index d2653ad..d174504 100644 --- a/resources/translations/qcma.es.ts +++ b/resources/translations/qcma.es.ts @@ -95,10 +95,24 @@ ClientManager - Added %1 entries to the database + Agregadas %1 entradas a la base de datos + + + + Added %1 items to the database Agregadas %1 entradas a la base de datos + + + Database indexing aborted by user + Actualización de la base de datos cancelada por el usuario + + + + Cannot refresh the database while is in use + No se puede actualizar la base de datos mientras se encuentre en uso + CmaClient @@ -227,40 +241,130 @@ El dispositivo se ha desconectado - Received PIN: %1 - PIN recibido: %1 + PIN recibido: %1 - + &Settings &Ajustes - + &Refresh database &Refrescar base de datos - + Backup Manager Gestor de Respaldos - + &Quit &Salir - + Information Información + + PinForm + + + Form + Registro de PIN + + + + An unregistered PS Vita system is connecting with QCMA via Wi-Fi + Un sistema PS Vita no registrado se intenta conectar con QCMA mediante Wi-Fi + + + + Device: PS Vita + Dispositivo: PS Vita + + + + Input the following number in the PS Vita system to register it with QCMA + Introduce el siguiente número en el sistema PS Vita para registrarlo con QCMA + + + + <html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html> + + + + + Time remaining: 300 seconds + Tiempo restante: 300 segundos + + + + Cancel + Cancelar + + + + Device: %1 (PS Vita) + Dispositivo: %1 (PS Vita) + + + + Time remaining: %1 seconds + Tiempo restante: %1 segundos + + + + ProgressForm + + + Refreshing database... + Actualizando base de datos... + + + + <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Reading directory:</span></p></body></html> + <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Leyendo directorio:</span></p></body></html> + + + + directory name + Cargando nombre de directorio + + + + <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Processing file:</span></p></body></html> + <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Procesando archivo:</span></p></body></html> + + + + file name + Cargando nombre de archivo + + + + Cancel + Cancelar + + + + Database indexing in progress + Actualización de base de datos en progreso + + + + Are you sure to cancel the database indexing? + ¿Estas seguro de cancelar la actualización a la base de datos? + + QObject - + A instance of QCMA is already running Otra instancia de QCMA ya se encuentra en ejecución diff --git a/utils.h b/utils.h index b1614e7..8d8deba 100644 --- a/utils.h +++ b/utils.h @@ -46,8 +46,8 @@ public: #endif bool removeRecursively(const QString &dirName); +QString readable_size(quint64 size, bool use_gib = false); bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total); QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata); -QString readable_size(quint64 size, bool use_gib = false); #endif // UTILS_H