diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml deleted file mode 100644 index 591be35..0000000 --- a/android/AndroidManifest.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/android.pro b/android/android.pro index a677b71..23349ac 100644 --- a/android/android.pro +++ b/android/android.pro @@ -10,20 +10,14 @@ QMAKE_CXXFLAGS += $$system(pkg-config --static --cflags libvitamtp libavformat l LIBS += $$system(pkg-config --static --libs libvitamtp libavformat libavcodec libavutil libswscale) SOURCES += \ - main_android.cpp + main_android.cpp \ + qtandroidservice.cpp # headlessmanager.cpp #HEADERS += \ # headlessmanager.h DISTFILES += \ - ../android-src/gradle/wrapper/gradle-wrapper.jar \ - ../android-src/AndroidManifest.xml \ - ../android-src/gradlew.bat \ - ../android-src/res/values/libs.xml \ - ../android-src/build.gradle \ - ../android-src/gradle/wrapper/gradle-wrapper.properties \ - ../android-src/gradlew \ android-src/gradle/wrapper/gradle-wrapper.jar \ android-src/AndroidManifest.xml \ android-src/gradlew.bat \ diff --git a/android/qtandroidservice.cpp b/android/qtandroidservice.cpp index 8b13789..066d6b9 100644 --- a/android/qtandroidservice.cpp +++ b/android/qtandroidservice.cpp @@ -1 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include + +// Global variables + +static jclass m_applicationClass = NULL; +static jobject m_classLoaderObject = NULL; +static jmethodID m_loadClassMethodID = NULL; +static jobject m_resourcesObj; +static jobject m_activityObject = NULL; + +extern "C" typedef int (*Main)(int, char **); //use the standard main method to start the application +static JavaVM *m_javaVM = NULL; +static Main m_main = NULL; +static void *m_mainLibraryHnd = NULL; + +static const char m_classErrorMsg[] = "Can't find class \"%s\""; +static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; + +// Methods definition + +static jboolean startQtAndroidPlugin(JNIEnv* env, jobject object /*, jobject applicationAssetManager*/) +{ + return 1; +} + +static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, + jint /*widthPixels*/, jint /*heightPixels*/, + jint desktopWidthPixels, jint desktopHeightPixels, + jdouble xdpi, jdouble ydpi, jdouble scaledDensity) +{} + +// Methods definition + +static void *startMainMethod(void *ar) +{ + __android_log_print(ANDROID_LOG_INFO, "Qt", "Calling main method"); + + char *argv[] = { "qcma", "--verbose", "--set-locale", "en"}; + int argc = sizeof(argv) / sizeof(char*); + + int ret = m_main(argc, argv); + + return NULL; +} + +static jboolean startQtApplication(JNIEnv *env, jobject object, jstring paramsString, jstring environmentString) +{ + // Get native + + const char *nativeEnvironmentString = (env)->GetStringUTFChars(environmentString, NULL); // C++ + const char *nativeParamsString = (env)->GetStringUTFChars(paramsString, NULL); // C++ + + // Print info + + __android_log_print(ANDROID_LOG_FATAL, "Qt", "Starting the Qt service"); + + char cwd[1024]; + if (getcwd(cwd, sizeof(cwd)) != NULL) + __android_log_print(ANDROID_LOG_INFO, "Qt", "Current working dir : %s", cwd); + + __android_log_print(ANDROID_LOG_FATAL, "Qt", "Param : %s", nativeParamsString ); + __android_log_print(ANDROID_LOG_FATAL, "Qt", "Env : %s", nativeEnvironmentString ); + + // Start + + m_mainLibraryHnd = NULL; + + // Obtain a handle to the main library (the library that contains the main() function). + // This library should already be loaded, and calling dlopen() will just return a reference to it. + __android_log_print(ANDROID_LOG_INFO, "Qt", "Trying to open %s", nativeParamsString); + m_mainLibraryHnd = dlopen(nativeParamsString, 0); + + if (m_mainLibraryHnd == NULL) { + + __android_log_print(ANDROID_LOG_INFO, "Qt", "No main library was specified; searching entire process (this is slow!)"); + m_main = (Main)dlsym(RTLD_DEFAULT, "main"); + } + else { + + __android_log_print(ANDROID_LOG_INFO, "Qt", "Getting the main method from handler"); + m_main = (Main)dlsym(m_mainLibraryHnd, "main"); + } + + + if (!m_main) { + + __android_log_print(ANDROID_LOG_INFO, "Qt", "Could not find main method"); + return 0; + } + else{ + + __android_log_print(ANDROID_LOG_INFO, "Qt", "Main method found, starting"); + } + + + pthread_t appThread; + return pthread_create(&appThread, NULL, startMainMethod, NULL) == 0; + + //env->ReleaseStringUTFChars(environmentString, nativeString); +} + +static void quitQtAndroidPlugin(JNIEnv *env, jclass clazz) +{ + +} + +static void terminateQt(JNIEnv *env, jclass clazz) +{ + +} + +// Native methods + +static JNINativeMethod methods[] = { + {"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin}, + {"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics}, + {"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication}, + {"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin}, + {"terminateQt", "()V", (void *)terminateQt} +}; + + +// Helpers functions + +#define FIND_AND_CHECK_CLASS(CLASS_NAME) \ +clazz = env->FindClass(CLASS_NAME); \ +if (!clazz) { \ + __android_log_print(ANDROID_LOG_FATAL, "Qt", m_classErrorMsg, CLASS_NAME); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ +VAR = env->GetMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, "Qt", m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ +VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, "Qt", m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \ +VAR = env->GetFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, "Qt", m_methodErrorMsg, FIELD_NAME, FIELD_SIGNATURE); \ + return JNI_FALSE; \ +} + +#define GET_AND_CHECK_STATIC_FIELD(VAR, CLASS, FIELD_NAME, FIELD_SIGNATURE) \ +VAR = env->GetStaticFieldID(CLASS, FIELD_NAME, FIELD_SIGNATURE); \ +if (!VAR) { \ + __android_log_print(ANDROID_LOG_FATAL, "Qt", m_methodErrorMsg, FIELD_NAME, FIELD_SIGNATURE); \ + return JNI_FALSE; \ +} + +// On load + +jint JNICALL JNI_OnLoad(JavaVM *vm, void *ld) +{ + + __android_log_print(ANDROID_LOG_INFO, "Qt", "Qt Android service wrapper start"); + + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + __android_log_print(ANDROID_LOG_FATAL, "Qt", "Can't get env in wrapper start"); \ + return -1; + } + + m_javaVM = vm; + + jclass clazz; + FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative"); + m_applicationClass = static_cast(env->NewGlobalRef(clazz)); + + __android_log_print(ANDROID_LOG_INFO, "Qt", "Registering native classes for service wrapper"); + + if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { + __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed for service wrapper"); + return JNI_FALSE; + } + + return JNI_VERSION_1_4; +} diff --git a/android/res/drawable-hdpi/icon.png b/android/res/drawable-hdpi/icon.png deleted file mode 100644 index 63ae9c7..0000000 Binary files a/android/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/android/res/drawable-ldpi/icon.png b/android/res/drawable-ldpi/icon.png deleted file mode 100644 index d07fc2c..0000000 Binary files a/android/res/drawable-ldpi/icon.png and /dev/null differ diff --git a/android/res/drawable-mdpi/icon.png b/android/res/drawable-mdpi/icon.png deleted file mode 100644 index 477e39c..0000000 Binary files a/android/res/drawable-mdpi/icon.png and /dev/null differ diff --git a/android/res/drawable-xhdpi/icon.png b/android/res/drawable-xhdpi/icon.png deleted file mode 100644 index 0274faa..0000000 Binary files a/android/res/drawable-xhdpi/icon.png and /dev/null differ diff --git a/android/res/drawable-xxhdpi/icon.png b/android/res/drawable-xxhdpi/icon.png deleted file mode 100644 index 99a3a8a..0000000 Binary files a/android/res/drawable-xxhdpi/icon.png and /dev/null differ diff --git a/android/src/com/github/codestation/qcma/QcmaNotification.java b/android/src/com/github/codestation/qcma/QcmaNotification.java deleted file mode 100644 index 3286923..0000000 --- a/android/src/com/github/codestation/qcma/QcmaNotification.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.github.codestation.qcma; - -import android.content.Context; -import android.content.DialogInterface; -import android.widget.Toast; -import android.app.AlertDialog; - -public class QcmaNotification extends org.qtproject.qt5.android.bindings.QtActivity -{ - private static QcmaNotification m_instance; - - public QcmaNotification() - { - m_instance = this; - } - - public static void showToast(String message) - { - Context context = m_instance.getApplicationContext(); - Toast toast = Toast.makeText(context, message, Toast.LENGTH_SHORT); - toast.show(); - } - - public static void showDialog(String message) - { - AlertDialog.Builder builder = new AlertDialog.Builder(m_instance); - builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - } - }); - builder.setMessage(message).setTitle("QCMA message"); - AlertDialog dialog = builder.create(); - } -} diff --git a/cli/cli.pro b/cli/cli.pro index ff89a06..a37bfad 100644 --- a/cli/cli.pro +++ b/cli/cli.pro @@ -15,10 +15,6 @@ HEADERS += \ singlecoreapplication.h \ headlessmanager.h - -# find packages using pkg-config -QT_CONFIG -= no-pkg-config -CONFIG += link_pkgconfig PKGCONFIG = libvitamtp libavformat libavcodec libavutil libswscale # Linux-only config diff --git a/config.pri b/config.pri index 1addc5f..e93ef3b 100644 --- a/config.pri +++ b/config.pri @@ -1,3 +1,14 @@ +VERSION = 0.3.10 + +# enable pkg-config on osx/windows +QT_CONFIG -= no-pkg-config + +# enable pkg-config +CONFIG += link_pkgconfig + +# disable extra debug/release directories +CONFIG -= debug_and_release + CXXFLAGS_WARNINGS = -Wall -Wextra -Wdisabled-optimization -Wformat=2 -Winit-self \ -Wmissing-include-dirs -Woverloaded-virtual -Wundef -Wno-unused \ -Wno-missing-field-initializers -Wno-format-nonliteral @@ -5,12 +16,6 @@ CXXFLAGS_WARNINGS = -Wall -Wextra -Wdisabled-optimization -Wformat=2 -Winit-self # custom CXXFLAGS QMAKE_CXXFLAGS += -Wno-write-strings -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS $$CXXFLAGS_WARNINGS -QT_CONFIG -= no-pkg-config -CONFIG += link_pkgconfig -CONFIG -= debug_and_release - -VERSION = 0.3.10 - #Linux-only config unix:!macx { # largefile support diff --git a/debian/qcma-cli.manpages b/debian/qcma-cli.manpages index bd05367..10b3eb1 100644 --- a/debian/qcma-cli.manpages +++ b/debian/qcma-cli.manpages @@ -1 +1 @@ -man/qcma_cli.1 +cli/qcma_cli.1 diff --git a/debian/qcma.install b/debian/qcma.install index 67c3fbf..df0e87d 100644 --- a/debian/qcma.install +++ b/debian/qcma.install @@ -1,4 +1,4 @@ usr/bin/qcma -resources/qcma.desktop usr/share/applications/qcma -resources/images/qcma.png usr/share/icons/hicolor/64x64/apps +gui/resources/qcma.desktop usr/share/applications/qcma +gui/resources/images/qcma.png usr/share/icons/hicolor/64x64/apps diff --git a/debian/qcma.manpages b/debian/qcma.manpages index c0fdb29..03ff2be 100644 --- a/debian/qcma.manpages +++ b/debian/qcma.manpages @@ -1 +1 @@ -man/qcma.1 +gui/qcma.1 diff --git a/man/qcma.1 b/man/qcma.1 deleted file mode 100644 index ab0bbcc..0000000 --- a/man/qcma.1 +++ /dev/null @@ -1,14 +0,0 @@ -.TH QCMA 1 "MARCH 2015" -.SH NAME -qcma \- Content manager for the PlayStation Vita -.SH SYNOPSIS -.B qcma - -.SH DESCRIPTION -\fBqcma\fR is a cross-platform application to provide an Open Source implementation -of the original Content Manager Assistant that comes with the PS Vita. -.TP -Qcma will let you backup your games, songs, photos & videos via USB or wireless. - -.SH "SEE ALSO" -.I /usr/share/doc/qcma/README.md diff --git a/man/qcma_cli.1 b/man/qcma_cli.1 deleted file mode 100644 index d112a11..0000000 --- a/man/qcma_cli.1 +++ /dev/null @@ -1,33 +0,0 @@ -.TH QCMA-CLI 1 "MARCH 2015" -.SH NAME -qcma-cli \- Content manager for the PlayStation Vita -.SH SYNOPSIS -.B qcma_cli \fR[options] - -.TP -.B \-\-verbose -print detailed output - -.TP -.B \-\-with-debug -print very verbose output (including hexdump transfers) - -.SH DESCRIPTION -\fBqcma_cli\fR is a cross-platform application to provide an Open Source implementation -of the original Content Manager Assistant that comes with the PS Vita. -.TP -Qcma will let you backup your games, songs, photos & videos via USB or wireless. - -.SH SIGNALS -You can control \fBqcma_cli\fR using signals, i.e. using the \fBkill\fR command to send a signal to the process. - -.TP -.B SIGHUP -Refreshes the database. - -.TP -.B SIGTERM or SIGINT -Shuts down the process but waits until the current event is finished. - -.SH "SEE ALSO" -.I /usr/share/doc/qcma/README.md diff --git a/qcma.pro b/qcma.pro index a662209..9e0d623 100644 --- a/qcma.pro +++ b/qcma.pro @@ -5,26 +5,29 @@ #------------------------------------------------- TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = common -android { - SUBDIRS = qcma_android.pro -} else { - SUBDIRS = qcma_gui.pro -} - -# Compile the headless binary only on Linux unix:!macx:!android { - SUBDIRS += qcma_cli.pro + # Compile the headless binary only on Linux + SUBDIRS += cli + cli.depends = common + # The appindicator and kde extensions are linux only too ENABLE_APPINDICATOR { - SUBDIRS += qcma_appindicator.pro + SUBDIRS += appindicator + appindicator.depends = gui } ENABLE_KDENOTIFIER { - SUBDIRS += qcma_kdenotifier.pro + SUBDIRS += kdenotifier + kdenotifier.depends = gui } } -TRANSLATIONS += \ - resources/translations/qcma_es.ts \ - resources/translations/qcma_fr.ts \ - resources/translations/qcma_ja.ts +android { + SUBDIRS += android + android.depends = common +} else { + SUBDIRS += gui + gui.depends = common +} diff --git a/qcma.rc b/qcma.rc deleted file mode 100644 index 856ee88..0000000 --- a/qcma.rc +++ /dev/null @@ -1 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "resources/images/qcma.ico" diff --git a/qcma_appindicator.pro b/qcma_appindicator.pro deleted file mode 100644 index 9a212a1..0000000 --- a/qcma_appindicator.pro +++ /dev/null @@ -1,36 +0,0 @@ -QT += gui widgets - -TARGET = qcma_appindicator -TEMPLATE = lib -CONFIG += plugin link_pkgconfig -DEFINES += QCMA_TRAYINDICATOR_LIBRARY - -QT_CONFIG -= no-pkg-config - -PKGCONFIG = appindicator-0.1 libnotify -INCLUDEPATH += src/ - -SOURCES += \ - src/indicator/unityindicator.cpp - -HEADERS += \ - src/indicator/trayindicator_global.h \ - src/indicator/trayindicator.h \ - src/indicator/unityindicator.h - -CXXFLAGS_WARNINGS = -Wall -Wextra -Wshadow -Wcast-align -Wctor-dtor-privacy \ - -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations \ - -Wmissing-include-dirs -Woverloaded-virtual -Wredundant-decls \ - -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-missing-field-initializers \ - -Wno-format-nonliteral - -QMAKE_CXXFLAGS += -Wno-write-strings -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS $$CXXFLAGS_WARNINGS - -DATADIR = $$PREFIX/share - -actions64.path = $$DATADIR/icons/hicolor/64x64/actions -actions64.files += resources/images/qcma_on.png -actions64.files += resources/images/qcma_off.png - -target.path = /usr/lib/qcma -INSTALLS += target actions64 diff --git a/qcma_cli.pro b/qcma_cli.pro deleted file mode 100644 index ae326fc..0000000 --- a/qcma_cli.pro +++ /dev/null @@ -1,26 +0,0 @@ -include(qcma_common.pri) - -TARGET = qcma_cli - -SOURCES += \ - src/cli/main_cli.cpp \ - src/cli/singlecoreapplication.cpp \ - src/cli/headlessmanager.cpp - -HEADERS += \ - src/cli/singlecoreapplication.h \ - src/cli/headlessmanager.h - -# Linux-only config -unix:!macx { - - DATADIR = $$PREFIX/share - MANDIR = $$DATADIR/man/man1 - - man_cli.files = man/qcma_cli.1 - man_cli.path = $$MANDIR - - target.path = $$BINDIR - - INSTALLS += target man_cli -} diff --git a/qcma_common.pri b/qcma_common.pri deleted file mode 100644 index 4ef42df..0000000 --- a/qcma_common.pri +++ /dev/null @@ -1,121 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2013-07-23T15:34:17 -# -#------------------------------------------------- - -QT += core network sql - -VERSION = 0.3.10 - -TEMPLATE = app - -SOURCES += \ - src/capability.cpp \ - src/cmaobject.cpp \ - src/cmarootobject.cpp \ - src/cmautils.cpp \ - src/sforeader.cpp \ - src/cmaclient.cpp \ - src/cmabroadcast.cpp \ - src/avdecoder.cpp \ - src/cmaevent.cpp \ - src/dds.cpp \ - src/sqlitedb.cpp \ - src/httpdownloader.cpp \ - src/qlistdb.cpp \ - src/database.cpp - -HEADERS += \ - src/capability.h \ - src/cmaobject.h \ - src/cmarootobject.h \ - src/cmautils.h \ - src/sforeader.h \ - src/cmaclient.h \ - src/cmabroadcast.h \ - src/avdecoder.h \ - src/cmaevent.h \ - src/dds.h \ - src/sqlitedb.h \ - src/httpdownloader.h \ - src/qlistdb.h \ - src/database.h - -OTHER_FILES += \ - resources/xml/psp2-updatelist.xml \ - resources/images/psv_icon.png \ - resources/images/psv_icon_16.png \ - resources/images/qcma.png \ - resources/qcma.desktop \ - qcma.rc - -INCLUDEPATH += src/ -QT_CONFIG -= no-pkg-config -RESOURCES += qcmares.qrc translations.qrc - -# find packages using pkg-config -CONFIG += link_pkgconfig -PKGCONFIG = libvitamtp libavformat libavcodec libavutil libswscale - -CXXFLAGS_WARNINGS = -Wall -Wextra -Wcast-align \ - -Wdisabled-optimization -Wformat=2 -Winit-self \ - -Wmissing-include-dirs -Woverloaded-virtual \ - -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-missing-field-initializers \ - -Wno-format-nonliteral - -# custom CXXFLAGS -QMAKE_CXXFLAGS += -Wno-write-strings -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS $$CXXFLAGS_WARNINGS - -#Linux-only config -unix:!macx { - # largefile support - DEFINES += _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE - - # installation prefix - isEmpty(PREFIX) { - PREFIX = /usr/local - } - - BINDIR = $$PREFIX/bin - DATADIR = $$PREFIX/share -} - -# Windows config -win32 { - # Windows icon - RC_FILE = qcma.rc - # avoid alignment issues with newer mingw compiler - QMAKE_CXXFLAGS += -mno-ms-bitfields -} - -# OS X config -macx { - # OS X icon - ICON = resources/images/qcma.icns - # re-enable pkg-config on OS X (brew installs pkg-config files) - QT_CONFIG -= no-pkg-config -} - - -# try to get the current git version + hash -QCMA_GIT_VERSION=$$system(git describe --tags) - -#use the generic version if the above command fails (no git executable or metadata) -isEmpty(QCMA_GIT_VERSION) { - DEFINES += QCMA_VER=\\\"$$VERSION\\\" -} else { - DEFINES += QCMA_VER=\\\"$$QCMA_GIT_VERSION\\\" -} - -GET_HASHES { - # try to get the current git commit and branch - QCMA_GIT_HASH=$$system(git rev-parse --short HEAD) - QCMA_GIT_BRANCH=$$system(git rev-parse --abbrev-ref HEAD) - - # pass the current git commit hash - !isEmpty(QCMA_GIT_HASH):!isEmpty(QCMA_GIT_BRANCH) { - DEFINES += QCMA_BUILD_HASH=\\\"$$QCMA_GIT_HASH\\\" - DEFINES += QCMA_BUILD_BRANCH=\\\"$$QCMA_GIT_BRANCH\\\" - } -} diff --git a/qcma_gui.pro b/qcma_gui.pro deleted file mode 100644 index 9d72ed2..0000000 --- a/qcma_gui.pro +++ /dev/null @@ -1,66 +0,0 @@ -include(qcma_common.pri) - -QT += gui widgets - -TARGET = qcma - -SOURCES += \ - src/gui/main.cpp \ - src/gui/mainwidget.cpp \ - src/gui/singleapplication.cpp \ - src/gui/clientmanager.cpp \ - src/gui/filterlineedit.cpp \ - src/indicator/qtrayicon.cpp \ -# forms - src/forms/backupitem.cpp \ - src/forms/backupmanagerform.cpp \ - src/forms/configwidget.cpp \ - src/forms/confirmdialog.cpp \ - src/forms/pinform.cpp \ - src/forms/progressform.cpp - -HEADERS += \ - src/gui/mainwidget.h \ - src/gui/singleapplication.h \ - src/gui/clientmanager.h \ - src/gui/filterlineedit.h \ - src/indicator/trayindicator_import.h \ - src/indicator/qtrayicon.h \ -# forms - src/forms/backupitem.h \ - src/forms/backupmanagerform.h \ - src/forms/configwidget.h \ - src/forms/confirmdialog.h \ - src/forms/pinform.h \ - src/forms/progressform.h - -FORMS += \ - src/forms/configwidget.ui \ - src/forms/backupmanagerform.ui \ - src/forms/backupitem.ui \ - src/forms/confirmdialog.ui \ - src/forms/progressform.ui \ - src/forms/pinform.ui - -#Linux-only config -unix:!macx { - PKGCONFIG += libnotify - - DATADIR = $$PREFIX/share - - MANDIR = $$DATADIR/man/man1 - - # config for desktop file and icon - desktop.path = $$DATADIR/applications/$${TARGET} - desktop.files += resources/$${TARGET}.desktop - - icon64.path = $$DATADIR/icons/hicolor/64x64/apps - icon64.files += resources/images/$${TARGET}.png - - man.files = man/qcma.1 - man.path = $$MANDIR - - target.path = $$BINDIR - - INSTALLS += target desktop icon64 man -} diff --git a/qcma_kdenotifier.pro b/qcma_kdenotifier.pro deleted file mode 100644 index 5a2bb81..0000000 --- a/qcma_kdenotifier.pro +++ /dev/null @@ -1,38 +0,0 @@ -QT += gui widgets - -TARGET = qcma_kdenotifier -TEMPLATE = lib -CONFIG += plugin -DEFINES += QCMA_TRAYINDICATOR_LIBRARY -PKGCONFIG = -INCLUDEPATH += src/ - -greaterThan(QT_MAJOR_VERSION, 4): ENABLE_KNOTIFICATIONS { - message("Enabling KDE5 notifications") - QT += KNotifications - DEFINES += ENABLE_KNOTIFICATIONS=1 -} else { - QT += widgets - LIBS += -lkdeui -} - -SOURCES += \ - src/indicator/kdenotifier.cpp \ - src/indicator/kdenotifiertray.cpp - -HEADERS += \ - src/indicator/trayindicator.h \ - src/indicator/kdenotifier.h \ - src/indicator/kdenotifiertray.h - -CXXFLAGS_WARNINGS = -Wall -Wextra -Wshadow -Wcast-align -Wctor-dtor-privacy \ - -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations \ - -Wmissing-include-dirs -Woverloaded-virtual -Wredundant-decls \ - -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-missing-field-initializers \ - -Wno-format-nonliteral - -QMAKE_CXXFLAGS += -Wno-write-strings -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS $$CXXFLAGS_WARNINGS - -target.path = /usr/lib/qcma - -INSTALLS += target diff --git a/qcmares.qrc b/qcmares.qrc deleted file mode 100644 index 6c22039..0000000 --- a/qcmares.qrc +++ /dev/null @@ -1,13 +0,0 @@ - - - resources/xml/psp2-updatelist.xml - resources/images/tray/qcma_on.png - resources/images/tray/qcma_on_16.png - resources/images/qcma.png - resources/images/edit-clear-locationbar-rtl.png - resources/images/tray/qcma_off.png - resources/images/tray/qcma_off_16.png - resources/images/qcma_on.png - resources/images/qcma_off.png - - diff --git a/resources/images/edit-clear-locationbar-rtl.png b/resources/images/edit-clear-locationbar-rtl.png deleted file mode 100644 index 2bc48d8..0000000 Binary files a/resources/images/edit-clear-locationbar-rtl.png and /dev/null differ diff --git a/resources/images/qcma.icns b/resources/images/qcma.icns deleted file mode 100644 index 8b483d4..0000000 Binary files a/resources/images/qcma.icns and /dev/null differ diff --git a/resources/images/qcma.ico b/resources/images/qcma.ico deleted file mode 100644 index 094f6ff..0000000 Binary files a/resources/images/qcma.ico and /dev/null differ diff --git a/resources/images/qcma.png b/resources/images/qcma.png deleted file mode 100644 index ce36ce5..0000000 Binary files a/resources/images/qcma.png and /dev/null differ diff --git a/resources/images/qcma_off.png b/resources/images/qcma_off.png deleted file mode 100644 index ff2525f..0000000 Binary files a/resources/images/qcma_off.png and /dev/null differ diff --git a/resources/images/qcma_on.png b/resources/images/qcma_on.png deleted file mode 100644 index ce36ce5..0000000 Binary files a/resources/images/qcma_on.png and /dev/null differ diff --git a/resources/images/tray/qcma_off.png b/resources/images/tray/qcma_off.png deleted file mode 100644 index 399648d..0000000 Binary files a/resources/images/tray/qcma_off.png and /dev/null differ diff --git a/resources/images/tray/qcma_off_16.png b/resources/images/tray/qcma_off_16.png deleted file mode 100644 index 8f1008a..0000000 Binary files a/resources/images/tray/qcma_off_16.png and /dev/null differ diff --git a/resources/images/tray/qcma_on.png b/resources/images/tray/qcma_on.png deleted file mode 100644 index 650ccaf..0000000 Binary files a/resources/images/tray/qcma_on.png and /dev/null differ diff --git a/resources/images/tray/qcma_on_16.png b/resources/images/tray/qcma_on_16.png deleted file mode 100644 index 1784d0a..0000000 Binary files a/resources/images/tray/qcma_on_16.png and /dev/null differ diff --git a/resources/qcma.desktop b/resources/qcma.desktop deleted file mode 100644 index 34e8fac..0000000 --- a/resources/qcma.desktop +++ /dev/null @@ -1,18 +0,0 @@ -[Desktop Entry] -Encoding=UTF-8 -Exec=qcma -GenericName=Content Manager Assistant -GenericName[es]=Asistente del Gestor de Contenido -GenericName[fr]=Gestionnaire de contenu -Comment=Content Manager Assistant for the PS Vita -Comment[es]=Asistente del Gestor de Contenido para PS Vita -Comment[fr]=Gestionnaire de contenu pour la PS Vita -Icon=qcma.png -Name=QCMA -Path= -StartupNotify=false -Terminal=false -Type=Application -Version=1.0 -X-KDE-SubstituteUID=false -Categories=Qt;Utility; diff --git a/resources/translations/qcma_es.ts b/resources/translations/qcma_es.ts deleted file mode 100644 index 4701c70..0000000 --- a/resources/translations/qcma_es.ts +++ /dev/null @@ -1,667 +0,0 @@ - - - - - BackupItem - - - Delete entry - Borrar entrada - - - - Open folder - Abrir directorio - - - - BackupManagerForm - - - Backup Manager - Gestor de Respaldos - - - - Online ID / Username - ID Online / Nombre de usuario - - - - Backup Type - Tipo de respaldo - - - - PS Vita Games - Juegos PS Vita - - - - PSP Games - Juegos PSP - - - - PSM Games - Juegos PSM - - - - PSOne Games - Juegos PSOne - - - - PSP Savedatas - Salvados PSP - - - - Backups - Respaldos - - - - Backup disk usage - Uso de disco en respaldos - - - - - Filter - Filtro - - - - Default account - Cuenta por defecto - - - - Are you sure to remove the backup of the following entry? - ¿Estas seguro de borrar la siguiente entrada? - - - - Backup disk usage: %1 - Uso de disco en respaldos: %1 - - - - [GAME] - [JUEGO] - - - - [SAVE] - [SALVADO] - - - - [UPDATE] - [ACTUALIZACIÓN] - - - - [DLC] - [DLC] - - - - ClientManager - - - 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 initialize VitaMTP library - No se pudo inicializar VitaMTP - - - - This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus. - Este usuario no pertenece al grupo vitamtp, puede haber problemas al leer el bus USB. - - - - You must enable at least USB or Wireless monitoring - Debe habilitar por lo menos el monitoreo USB o inalámbrico - - - - No PS Vita system has been registered - Nigún sistema PS Vita ha sido registrado - - - - CmaClient - - - - Connected to %1 (PS Vita) - Conectado a %1 (PS Vita) - - - - ConfigWidget - - - QCMA Settings - Ajustes QCMA - - - - Folders - Directorios - - - - Specify the folders that the PS Vita will access for each content type. - Especificar los directorios que el sistema PS Vita accederá para cada tipo de contenido. - - - - - This is the location your Screenshots and Pictures are Saved to/Imported from. - Esta es la ubicación donde tus capturas de pantalla e imágenes serán almacenadas o importadas. - - - - Photo Folder - Directorio de Fotos - - - - - - - - - Browse... - Buscar... - - - - - This is the location your Videos are Saved to/Imported from. - Esta es la ubicación donde tus videos serán almacenados o importados. - - - - Video Folder - Directorio de Videos - - - - - This is the location your Music is Saved to/Imported from. - Esta es la ubicación donde tu música será almacenada o importada. - - - - Music Folder - Directorio de Música - - - - - This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from. - Esta es la ubicación donde tus juegos, aplicaciones, partidas salvadas y respaldos del sistema serán almacenados o importados. - - - - Applications / Backups - Aplicaciones / Juegos / Respaldos - - - - This is the location your Software Updates and Browser Data is Saved to/Imported from. - Esta es la ubicación donde el sistema PS Vita leerá los contenidos que intente descargar. - - - - Updates / Web content - Actualizaciones / Contenido Web - - - - This is the location your PS Vita system will read all the content that it tries to download. - Esta es la ubicación donde el sistema PS Vita leerá los contenidos que intente descargar. - - - - Packages - Archivos PKG - - - - Other - Otros - - - - <html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html> - <html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Ajustes Avanzados</span></p></body></html> - - - - Offline Mode - Modo desconectado - - - - Skip metadata extraction - Saltar la extracción de metadatos - - - - Update database automatically when files on the PC are changed - Actualizar la base de datos automaticamente - - - - SQLite - SQLite - - - - Skip photo scanning - Omitir el escaneo de fotos - - - - Skip video scanning - Omitir el escaneo de vídeos - - - - Skip music scanning - Omitir el escaneo de música - - - - CMA protocol version - Versión de protocolo CMA - - - - CMA protocol selection - Uso de protocolo CMA - - - - Latest - Último - - - - Manual - Manual - - - - Custom - Personalizado - - - - CMA custom version - Versión personalizada CMA - - - - Disable USB monitoring - Deshabilitar monitoreo USB - - - - Disable Wi-Fi monitoring - Deshabilitar monitoreo WiFi - - - - Database backend - Almacenaje de base de datos - - - - In Memory - En memoria - - - - Select the folder to be used as a photo source - Seleccione el directorio a ser utilizado como origen de fotos - - - - Select the folder to be used as a music source - Seleccione el directorio a ser utilizado como origen de música - - - - Select the folder to be used as a video source - Seleccione el directorio a ser utilizado como origen de videos - - - - Select the folder to be used to save PS Vita games and backups - Seleccione el directorio a ser utilizado para guardar juegos y respaldos - - - - Select the folder to be used to fetch software updates - Seleccione el directorio a ser utilizado para extraer actualizaciones de software - - - - Select the folder to be used to software packages - Seleccione el directorio a ser utilizado para almacenar archivos pkg - - - - ConfirmDialog - - - Confirmation Message - Mensaje de confirmación - - - - <html><head/><body><p><span style=" font-size:10pt;">Are you sure to delete the backup of the following game?</span></p><p><span style=" font-size:12pt; font-weight:600;">Game Name</span></p></body></html> - - - - - - FilterLineEdit - - - - Filter - Filtro - - - - HTTPDownloader - - - Network error: %1 - Error de red: %1 - - - - HeadlessManager - - - This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus. - Este usuario no pertenece al grupo vitamtp, puede haber problemas al leer el bus USB. - Este usuario no pertenece al grupo vitamtp, puede haber problemas al leer el bus USB. - - - - KDENotifierTray - - - Settings - Ajustes - - - - Refresh database - Refrescar base de datos - - - - Backup Manager - Gestor de Respaldos - - - - About QCMA - Acerca de QCMA - - - - About Qt - Acerca de Qt - - - - Quit - Salir - - - - Qcma status - Estado de Qcma - - - - Disconnected - Desconectado - - - - MainWidget - - - Shutting down... - Cerrando... - - - - Stopping QCMA (disconnect your PS Vita) - Deteniendo QCMA (desconecte su PS Vita) - - - - Disconnected - Desconectado - - - - The device has been disconnected - El dispositivo se ha desconectado - - - - About Qcma - Acerca de Qcma - - - - Copyright (C) 2015 Codestation - Copyright (C) 2015 Codestation - - - - Copyright (C) 2015 Codestation - -build hash: %1 -build branch: %2 - Copyright (C) 2015 Codestation - -Hash de compilación: %1 -Rama de compilación: %2 - - - - Information - Información - - - - PinForm - - - Device pairing - Emparejamiento de dispositivo - - - - 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 - - - An instance of Qcma is already running - Otra instancia de Qcma ya se encuentra en ejecución - - - - QTrayIcon - - - Settings - Ajustes - - - - Refresh database - Refrescar base de datos - - - - Backup Manager - Gestor de Respaldos - - - - About QCMA - Acerca de QCMA - - - - About Qt - Acerca de Qt - - - - Quit - Salir - - - - UnityIndicator - - - Settings - Ajustes - - - - Refresh database - Refrescar base de datos - - - - Backup Manager - Gestor de Respaldos - - - - About QCMA - Acerca de QCMA - - - - About Qt - Acerca de Qt - - - - Quit - Salir - - - diff --git a/resources/translations/qcma_fr.ts b/resources/translations/qcma_fr.ts deleted file mode 100644 index 977fac5..0000000 --- a/resources/translations/qcma_fr.ts +++ /dev/null @@ -1,667 +0,0 @@ - - - - - BackupItem - - - Delete entry - Supprimer l'entrée - - - - Open folder - Ouvrir le répertoire - - - - BackupManagerForm - - - Backup Manager - Gestonaire de Sauvegardes - - - - Online ID / Username - ID Online / Nom d'utilisateur - - - - Backup Type - Type de sauvegarde - - - - PS Vita Games - Jeux PS Vita - - - - PSP Games - Jeux PSP - - - - PSM Games - Jeux PSM - - - - PSOne Games - Jeux PSOne - - - - PSP Savedatas - Sauvegardes PSP - - - - Backups - Sauvegardes - - - - Backup disk usage - Utilisation du disque par les sauvegardes - - - - - Filter - Filtrer - - - - Default account - Compte par défaut - - - - Are you sure to remove the backup of the following entry? - Êtes-vous sur de voulloir supprimer cette sauvegarde? - - - - Backup disk usage: %1 - Utilisation du disque de sauvegarde: %1 - - - - [GAME] - [JEU] - - - - [SAVE] - [SAUVEGARDE] - - - - [UPDATE] - [MISE_A_JOUR] - - - - [DLC] - [DLC] - - - - ClientManager - - - Added %1 items to the database - %1 éléments ont été rajoutés à la base de données - - - - Database indexing aborted by user - Mise à jour de la base de données annulée par l'utilisateur - - - - Cannot initialize VitaMTP library - Impossible d'initaliser la librairie VitaMTP - - - - This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus. - - - - - You must enable at least USB or Wireless monitoring - Vous devez soit activer la connexion par Wifi, soit activer celle par USB - - - - No PS Vita system has been registered - Aucunne PS Vita reconnue - - - - CmaClient - - - - Connected to %1 (PS Vita) - Connecté à %1 (PS Vita) - - - - ConfigWidget - - - QCMA Settings - Configuration de QCMA - - - - Folders - Répertoires - - - - Specify the folders that the PS Vita will access for each content type. - Choisissez les répertoires que la PS Vita va acceder pour chaque type de contenu. - - - - - This is the location your Screenshots and Pictures are Saved to/Imported from. - Emplacement pour Copier/Importer les Copies d'écrans et les Photos. - - - - Photo Folder - Répertoire des Photos - - - - - - - - - Browse... - Selectionner... - - - - - This is the location your Videos are Saved to/Imported from. - Emplacement pour Copier/Importer les Vidéos. - - - - Video Folder - Répertoire des Vidéos - - - - - This is the location your Music is Saved to/Imported from. - Emplacement pour Copier/Importer les Musiques. - - - - Music Folder - Répertoire des Musiques - - - - - This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from. - Emplacement pour Copier/Importer les Jeux, Applications & Sauvegardes - - - - Applications / Backups - Applications / Jeux / Sauvegardes - - - - This is the location your Software Updates and Browser Data is Saved to/Imported from. - Emplacement pour Copier/Importer les mises à jours du logiciel de la Vita - - - - Updates / Web content - Mise à jours / Contenu Web - - - - This is the location your PS Vita system will read all the content that it tries to download. - Emplacement pour Copier/Importer les contenus téléchargés. - - - - Packages - Archive des Packages - - - - Other - Autres - - - - <html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html> - <html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Options Avancées</span></p></body></html> - - - - Offline Mode - Mode déconnecté - - - - Skip metadata extraction - Passer l'extracion de métadonnées - - - - Update database automatically when files on the PC are changed - Mise à jour automatique de la base de données - - - - SQLite - SQLite - - - - Skip photo scanning - Passer le scan des photos - - - - Skip video scanning - Passer le scan des videos - - - - Skip music scanning - Passer le scan des musiques - - - - CMA protocol version - Version du protocol CMA - - - - CMA protocol selection - Utilisation du protocolo CMA - - - - Latest - Dernier - - - - Manual - Manuel - - - - Custom - Personalisé - - - - CMA custom version - Version CMA personalisée - - - - Disable USB monitoring - Désactiver la surveillance USB - - - - Disable Wi-Fi monitoring - Désactiver la surveillance WiFi - - - - Database backend - Moteur de base de données - - - - In Memory - En memoire - - - - Select the folder to be used as a photo source - Choisissez le répertoire à utiliser comme source de photos - - - - Select the folder to be used as a music source - Choisissez le répertoire à utiliser comme source de musiques - - - - Select the folder to be used as a video source - Choisissez le répertoire à utiliser comme source de videos - - - - Select the folder to be used to save PS Vita games and backups - Choisissez le répertoire à utiliser pour sauvegarder les jeux PS Vita - - - - Select the folder to be used to fetch software updates - Choisissez le répertoire à utiliser pour recevoir les mise à jour - - - - Select the folder to be used to software packages - Choisissez le répertoire à utiliser pour ranger les packages de software - - - - ConfirmDialog - - - Confirmation Message - Message de confirmation - - - - <html><head/><body><p><span style=" font-size:10pt;">Are you sure to delete the backup of the following game?</span></p><p><span style=" font-size:12pt; font-weight:600;">Game Name</span></p></body></html> - - - - - - FilterLineEdit - - - - Filter - Filtre - - - - HTTPDownloader - - - Network error: %1 - Erreur réseau: %1 - - - - HeadlessManager - - - This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus. - - - - - KDENotifierTray - - - Settings - Paramètres - - - - Refresh database - Mise à jour de la DB - - - - Backup Manager - Gestonaire de Sauvegards - - - - About QCMA - À propos de QCMA - - - - About Qt - À propos de Qt - - - - Quit - Quitter - - - - Qcma status - État de Qcma - - - - Disconnected - Déconnecté - - - - MainWidget - - - Shutting down... - Fin du programme... - - - - Stopping QCMA (disconnect your PS Vita) - Arrêter QCMA (déconnecte votre PS Vita) - - - - Disconnected - Déconnecté - - - - The device has been disconnected - L'appareil a été déconnecté - - - - About Qcma - - - - - Copyright (C) 2015 Codestation - Copyright (C) 2014 Codestation {2015 ?} - - - - Copyright (C) 2015 Codestation - -build hash: %1 -build branch: %2 - Copyright (C) 2014 Codestation - -Hash de compilación: %1 -Rama de compilación: %2 {2015 ?} {1 -?} - - - - Information - Information - - - - PinForm - - - Device pairing - Pairage d'appareil - - - - An unregistered PS Vita system is connecting with QCMA via Wi-Fi - Un systême PS Vita inconnu essaye de se connecter à QCMA par Wi-Fi - - - - Device: PS Vita - Appareil: PS Vita - - - - Input the following number in the PS Vita system to register it with QCMA - Introduisez ce numero d'identification dans le systême PS Vita pour l'enregistrer avec QCMA - - - - <html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html> - - - - - Time remaining: 300 seconds - Temps restant: 300 secondes - - - - Cancel - Annuler - - - - Device: %1 (PS Vita) - Appareil: %1 (PS Vita) - - - - Time remaining: %1 seconds - Temps restant: %1 secondes - - - - ProgressForm - - - Refreshing database... - Mise à jour de la base de données... - - - - <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;">Lecture du répertoire:</span></p></body></html> - - - - directory name - Nom du répertoire - - - - <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;">Traitement du fichier:</span></p></body></html> - - - - file name - Nom du fichier - - - - Cancel - Annuler - - - - Database indexing in progress - Mise à jour de la base de donnée en cours - - - - Are you sure to cancel the database indexing? - Êtes-vous sur de vouloir annuler la mise à jour de la base de données? - - - - QObject - - - An instance of Qcma is already running - - - - - QTrayIcon - - - Settings - Paramètres - - - - Refresh database - Rafraichir la base de données - - - - Backup Manager - Gestonaire de Sauvegardes - - - - About QCMA - À propos de QCMA - - - - About Qt - À propos de Qt - - - - Quit - Quitter - - - - UnityIndicator - - - Settings - Paramètres - - - - Refresh database - Mise à jour de la base de données - - - - Backup Manager - Gestionaire de Sauvegardes - - - - About QCMA - À propos de QCMA - - - - About Qt - À propos de Qt - - - - Quit - Quitter - - - diff --git a/resources/translations/qcma_ja.ts b/resources/translations/qcma_ja.ts deleted file mode 100644 index f112816..0000000 --- a/resources/translations/qcma_ja.ts +++ /dev/null @@ -1,668 +0,0 @@ - - - - - BackupItem - - - Delete entry - 項目を削除する - - - - Open folder - フォルダを開く - - - - BackupManagerForm - - - Backup Manager - バックアップマネージャー - - - - Online ID / Username - オンラインID / ユーザー名 - - - - Backup Type - バックアップの種類 - - - - PS Vita Games - PS Vitaゲーム - - - - PSP Games - PSPゲーム - - - - PSM Games - PSMゲーム - - - - PSOne Games - PS1ゲーム - - - - PSP Savedatas - PSPセーブデータ - - - - Backups - バックアップ - - - - Backup disk usage - バックアップディスク使用容量 - - - - - Filter - フィルタ - - - - Default account - 標準アカウント - - - - Are you sure to remove the backup of the following entry? - 次の項目のバックアップを削除してもよろしいですか? - - - - Backup disk usage: %1 - バックアップディスク使用容量: %1 - - - - [GAME] - [ゲーム] - - - - [SAVE] - [セーブ] - - - - [UPDATE] - [アップデート] - - - - [DLC] - [DLC] - - - - ClientManager - - - Added %1 items to the database - %1個の項目をデータベースに追加しました - - - - Database indexing aborted by user - データベース構築がユーザーにより中止されました - - - - Cannot initialize VitaMTP library - VitaMTPライブラリを初期化できません - - - - This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus. - - - - - You must enable at least USB or Wireless monitoring - 少なくともUSBと無線のどちらかの監視を有効にする必要があります - - - - No PS Vita system has been registered - PS Vitaが登録されていません - - - - CmaClient - - - - Connected to %1 (PS Vita) - %1 (PS Vita) に接続されました - - - - ConfigWidget - - - QCMA Settings - QCMA設定 - - - - Folders - フォルダ - - - - Specify the folders that the PS Vita will access for each content type. - PS Vitaがアクセスするフォルダーをコンテンツの種類ごとに指定してください。 - - - - - This is the location your Screenshots and Pictures are Saved to/Imported from. - スクリーンショットや画像を保存/インポートする場所です。 - - - - Photo Folder - フォト - - - - - - - - - Browse... - 参照... - - - - - This is the location your Videos are Saved to/Imported from. - ビデオを保存/インポートする場所です。 - - - - Video Folder - ビデオ - - - - - This is the location your Music is Saved to/Imported from. - ミュージックを保存/インポートする場所です。 - - - - Music Folder - ミュージック - - - - - This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from. - ゲームやアプリ、セーブデータ、システムバックアップを保存/インポートする場所です。 - - - - Applications / Backups - アプリケーション/バックアップファイル - - - - This is the location your Software Updates and Browser Data is Saved to/Imported from. - ソフトウェアアップデートとブラウザデータをを保存/インポートする場所です。 - - - - Updates / Web content - アップデート/Webコンテンツ - - - - This is the location your PS Vita system will read all the content that it tries to download. - この場所の全てのコンテンツをPS Vitaシステムが読み込み、ダウンロードを試みます。 - - - - Packages - パッケージ - - - - Other - その他 - - - - <html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html> - <html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">詳細設定</span></p></body></html> - - - - Offline Mode - オフラインモード - - - - Skip metadata extraction - メタデータの展開をスキップする - - - - Update database automatically when files on the PC are changed - PCのファイルが変更された際にデータベースを自動的に更新する - - - - SQLite - SQLite - - - - Skip photo scanning - フォトのスキャンをスキップする - - - - Skip video scanning - ビデオのスキャンをスキップする - - - - Skip music scanning - ミュージックのスキャンをスキップする - - - - CMA protocol version - - - - - CMA protocol selection - - - - - Latest - - - - - Manual - - - - - Custom - - - - - CMA custom version - - - - - Disable USB monitoring - USBの監視を無効にする - - - - Disable Wi-Fi monitoring - Wi-Fiの監視を無効にする - - - - Database backend - データベース保存 - - - - In Memory - メモリ内 - - - - Select the folder to be used as a photo source - フォトの参照先として使用されるフォルダを選択してください - - - - Select the folder to be used as a music source - ミュージックの参照先として使用されるフォルダを選択してください - - - - Select the folder to be used as a video source - ビデオの参照先として使用されるフォルダを選択してください - - - - Select the folder to be used to save PS Vita games and backups - PS Vitaのゲームとバックアップの保存に使用されるフォルダを選択してください - - - - Select the folder to be used to fetch software updates - ソフトウェアアップデートの取得に使用されるフォルダを選択してください - - - - Select the folder to be used to software packages - ソフトウェアパッケージに使うフォルダを選択してください - - - - ConfirmDialog - - - Confirmation Message - 確認メッセージ - - - - <html><head/><body><p><span style=" font-size:10pt;">Are you sure to delete the backup of the following game?</span></p><p><span style=" font-size:12pt; font-weight:600;">Game Name</span></p></body></html> - - <html><head/><body><p><span style=" font-size:10pt;">次のゲームのバックアップを削除してもよろしいですか?</span></p><p><span style=" font-size:12pt; font-weight:600;">ゲーム名</span></p></body></html> - - - - - FilterLineEdit - - - - Filter - フィルタ - - - - HTTPDownloader - - - Network error: %1 - ネットワークエラー: %1 - - - - HeadlessManager - - - This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus. - - - - - KDENotifierTray - - - Settings - 設定 - - - - Refresh database - データベースを更新する - - - - Backup Manager - バックアップマネージャー - - - - About QCMA - QCMAについて - - - - About Qt - Qtについて - - - - Quit - 終了 - - - - Qcma status - QCMAステータス - - - - Disconnected - 切断されました - - - - MainWidget - - - Shutting down... - 終了しています... - - - - Stopping QCMA (disconnect your PS Vita) - QCMAを停止しています (PS Vitaとの接続を切断してください) - - - - Disconnected - 切断されました - - - - The device has been disconnected - デバイスが切断されました - - - - About Qcma - - - - - Copyright (C) 2015 Codestation - Copyright (C) 2014 Codestation {2015 ?} - - - - Copyright (C) 2015 Codestation - -build hash: %1 -build branch: %2 - Copyright (C) 2014 Codestation - -ビルドハッシュ: %1 -ビルドブランチ: %2 {2015 ?} {1 -?} - - - - Information - 情報 - - - - PinForm - - - Device pairing - 端末のペアリング - - - - An unregistered PS Vita system is connecting with QCMA via Wi-Fi - 登録されていないPS VitaがWi-Fi経由でQCMAで接続しています - - - - Device: PS Vita - 端末: PS Vita - - - - Input the following number in the PS Vita system to register it with QCMA - QCMAでPS Vitaを登録するために次の番号をPS Vitaで入力してください - - - - <html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html> - - - - - Time remaining: 300 seconds - 残り時間: 300秒 - - - - Cancel - キャンセル - - - - Device: %1 (PS Vita) - 端末: %1 (PS Vita) - - - - Time remaining: %1 seconds - 残り時間: %1秒 - - - - ProgressForm - - - Refreshing database... - データベースを更新しています... - - - - <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 - ディレクトリ名 - - - - <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 - ファイル名 - - - - Cancel - キャンセル - - - - Database indexing in progress - データベース構築が進行中です - - - - Are you sure to cancel the database indexing? - データベース構築をキャンセルしてもよろしいですか? - - - - QObject - - - An instance of Qcma is already running - - - - - QTrayIcon - - - Settings - 設定 - - - - Refresh database - データベースを更新する - - - - Backup Manager - バックアップマネージャー - - - - About QCMA - QCMAについて - - - - About Qt - Qtについて - - - - Quit - 終了 - - - - UnityIndicator - - - Settings - 設定 - - - - Refresh database - データベースを更新する - - - - Backup Manager - バックアップマネージャー - - - - About QCMA - QCMAについて - - - - About Qt - Qtについて - - - - Quit - 終了 - - - diff --git a/resources/xml/psp2-updatelist.xml b/resources/xml/psp2-updatelist.xml deleted file mode 100644 index 3c853d0..0000000 --- a/resources/xml/psp2-updatelist.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - - - - - - http://www.example.com/PSP2UPDAT.PUP - - - - diff --git a/src/avdecoder.cpp b/src/avdecoder.cpp deleted file mode 100644 index 74ec2d2..0000000 --- a/src/avdecoder.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - * 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 "cmautils.h" -#include "avdecoder.h" -#include "database.h" - -#include -#include -#include -#include - -AVDecoder::AvInit init; - -AVDecoder::AVDecoder() : - pFormatCtx(NULL), pCodecCtx(NULL), av_stream(NULL), av_codec(NULL), stream_index(-1) -{ -} - -AVDecoder::~AVDecoder() -{ - if(pCodecCtx) { - avcodec_close(pCodecCtx); - } - if(pFormatCtx) { - avformat_close_input(&pFormatCtx); - } -} - -bool AVDecoder::open(const QString filename) -{ - if(avformat_open_input(&pFormatCtx, QFile::encodeName(filename).constData(), NULL, NULL) != 0) { - return false; - } - - if(avformat_find_stream_info(pFormatCtx, NULL) < 0) { - avformat_close_input(&pFormatCtx); - return false; - } - - return true; -} - -bool AVDecoder::loadCodec(codec_type codec) -{ - AVDictionary *opts = NULL; - - if((stream_index = av_find_best_stream(pFormatCtx, (AVMediaType)codec, -1, -1, &av_codec, 0)) < 0) { - return false; - } - - av_stream = pFormatCtx->streams[stream_index]; - pCodecCtx = av_stream->codec; - - if(avcodec_open2(pCodecCtx, av_codec, &opts) < 0) { - return false; - } - - return true; -} - -const char *AVDecoder::getMetadataEntry(const char *key, const char *default_value) -{ - AVDictionaryEntry *entry; - - if((entry = av_dict_get(pFormatCtx->metadata, key, NULL, 0)) != NULL) { - return entry->value; - } - return default_value; -} - -void AVDecoder::getAudioMetadata(metadata_t &metadata) -{ - metadata.data.music.artist = strdup(getMetadataEntry("artist", "")); - metadata.data.music.album = strdup(getMetadataEntry("album", "")); - metadata.data.music.title = strdup(getMetadataEntry("title", "")); - - if(loadCodec(CODEC_AUDIO)) { - metadata.data.music.tracks->data.track_audio.bitrate = pCodecCtx->bit_rate; - } else { - metadata.data.music.tracks->data.track_audio.bitrate = pFormatCtx->bit_rate; - } -} - -void AVDecoder::getVideoMetadata(metadata_t &metadata) -{ - metadata.data.video.copyright = strdup(getMetadataEntry("copyright", "")); - metadata.data.video.explanation = strdup(getMetadataEntry("comments", "")); - metadata.data.video.title = strdup(getMetadataEntry("title", metadata.name)); - - if(loadCodec(CODEC_VIDEO)) { - metadata.data.video.tracks->data.track_video.width = pCodecCtx->width; - metadata.data.video.tracks->data.track_video.height = pCodecCtx->height; - metadata.data.video.tracks->data.track_video.bitrate = pCodecCtx->bit_rate; - metadata.data.video.tracks->data.track_video.duration = pFormatCtx->duration / 1000; - - if(strcmp(av_codec->name, "h264") == 0) { - metadata.data.video.tracks->data.track_video.codecType = CODEC_TYPE_AVC; - } else if(strcmp(av_codec->name, "mpeg4") == 0) { - metadata.data.video.tracks->data.track_video.codecType = CODEC_TYPE_MPEG4; - } else { - metadata.data.video.tracks->data.track_video.codecType = 0; - } - } -} - -QByteArray AVDecoder::getAudioThumbnail(int width, int height) -{ - QByteArray data; - - if(!loadCodec(CODEC_VIDEO)) { - return data; - } - - AVPacket pkt; - if(av_read_frame(pFormatCtx, &pkt) >= 0) { - // first frame == first thumbnail (hopefully) - QBuffer imgbuffer(&data); - imgbuffer.open(QIODevice::WriteOnly); - QImage img = QImage::fromData(QByteArray((const char *)pkt.data, pkt.size)); - QImage result = img.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); - result.save(&imgbuffer, "JPEG"); - } - - return data; -} - -AVFrame *AVDecoder::getDecodedFrame(AVCodecContext *codec_ctx, int frame_stream_index) -{ -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) - AVFrame *pFrame = av_frame_alloc(); -#else - AVFrame *pFrame = avcodec_alloc_frame(); -#endif - - AVPacket packet; - int frame_finished = 0; - - while(!frame_finished && av_read_frame(pFormatCtx, &packet)>=0) { - if(packet.stream_index == frame_stream_index) { - avcodec_decode_video2(codec_ctx, pFrame, &frame_finished, &packet); - } - av_free_packet(&packet); - } - - if(frame_finished) { - return pFrame; - } else { -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) - av_frame_free(&pFrame); -#else - av_free(pFrame); -#endif - return NULL; - } -} - -QByteArray AVDecoder::getVideoThumbnail(int width, int height) -{ - QByteArray data; - AVFrame *pFrame; - - int percentage = QSettings().value("videoThumbnailSeekPercentage", 30).toInt(); - - if(!loadCodec(CODEC_VIDEO)) { - return data; - } - - qint64 seek_pos = pFormatCtx->duration * percentage / (AV_TIME_BASE * 100); - qint64 frame = av_rescale(seek_pos, av_stream->time_base.den, av_stream->time_base.num); - - if(avformat_seek_file(pFormatCtx, stream_index, 0, frame, frame, AVSEEK_FLAG_FRAME) < 0) { - avcodec_close(pCodecCtx); - return data; - } - - if((pFrame = getDecodedFrame(pCodecCtx, stream_index)) == NULL) { - avcodec_close(pCodecCtx); - return data; - } - -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) - AVFrame *pFrameRGB = av_frame_alloc(); -#else - AVFrame *pFrameRGB = avcodec_alloc_frame(); -#endif - - int numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); - uint8_t *buffer = (uint8_t *)av_malloc(numBytes); - - avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); - - SwsContext *sws_ctx = sws_getContext( - pCodecCtx->width, - pCodecCtx->height, - pCodecCtx->pix_fmt, - pCodecCtx->width, - pCodecCtx->height, - PIX_FMT_RGB24, - SWS_BICUBIC, - NULL, - NULL, - NULL - ); - - if(!sws_ctx) { - avcodec_close(pCodecCtx); - return data; - } - - sws_scale( - sws_ctx, - pFrame->data, - pFrame->linesize, - 0, - pCodecCtx->height, - pFrameRGB->data, - pFrameRGB->linesize - ); - - QImage image(pCodecCtx->width, pCodecCtx->height, QImage::Format_RGB888); - - for(int y = 0, h = pCodecCtx->height, w = pCodecCtx->width; y < h; y++) { - memcpy(image.scanLine(y), pFrameRGB->data[0] + y * pFrameRGB->linesize[0], w * 3); - } - - QBuffer imgbuffer(&data); - imgbuffer.open(QIODevice::WriteOnly); - QImage result = image.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); - result.save(&imgbuffer, "JPEG"); - - av_free(buffer); - -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55,28,1) - av_frame_free(&pFrameRGB); - av_frame_free(&pFrame); -#else - av_free(pFrameRGB); - av_free(pFrame); -#endif - - avcodec_close(pCodecCtx); - - return data; -} - -void AVDecoder::close() -{ - avformat_close_input(&pFormatCtx); - pFormatCtx = NULL; -} diff --git a/src/avdecoder.h b/src/avdecoder.h deleted file mode 100644 index 586dc98..0000000 --- a/src/avdecoder.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 AVDECODER_H -#define AVDECODER_H - -#include - -extern "C" { -#include -#include -#include -#include -} - -#include - -class AVDecoder -{ -public: - AVDecoder(); - ~AVDecoder(); - - enum codec_type {CODEC_VIDEO = AVMEDIA_TYPE_VIDEO, CODEC_AUDIO = AVMEDIA_TYPE_AUDIO}; - - bool open(const QString filename); - void close(); - bool loadCodec(codec_type codec); - - QByteArray getAudioThumbnail(int width, int height); - QByteArray getVideoThumbnail(int width, int height); - void getAudioMetadata(metadata_t &metadata); - void getVideoMetadata(metadata_t &metadata); - const char *getMetadataEntry(const char *key, const char *default_value = NULL); - - inline int getWidth() { - return pCodecCtx->width; - } - - inline int getHeight() { - return pCodecCtx->height; - } - - inline int getDuration() { - return pFormatCtx->duration / 1000; - } - - inline int getBitrate() { - return pCodecCtx->bit_rate; - } - - // simulate a static constructor to initialize libav only once - class AvInit - { - public: - AvInit() { - av_register_all(); - // hide warning logs - av_log_set_level(AV_LOG_ERROR); - } - }; - - static AvInit init; - -private: - AVFrame *getDecodedFrame(AVCodecContext *pCodecCtx, int stream_index); - - AVFormatContext *pFormatCtx; - AVCodecContext *pCodecCtx; - AVStream *av_stream; - AVCodec *av_codec; - int stream_index; -}; - -#endif // AVDECODER_H diff --git a/src/capability.cpp b/src/capability.cpp deleted file mode 100644 index b41137c..0000000 --- a/src/capability.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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 "capability.h" -#include "cmautils.h" - -#include -#include -#include - -DeviceCapability::DeviceCapability() : - vita_info() -{ -} - -bool DeviceCapability::exchangeInfo(vita_device_t *device) -{ - if(VitaMTP_GetVitaInfo(device, &vita_info) != PTP_RC_OK) { - qWarning("Cannot retreve device information."); - return false; - } - - if(vita_info.protocolVersion > VITAMTP_PROTOCOL_MAX_VERSION) { - qWarning("Vita wants protocol version %08d while we only support %08d. Attempting to continue.", - vita_info.protocolVersion, VITAMTP_PROTOCOL_MAX_VERSION); - } - - QString hostname = QHostInfo::localHostName(); - - int protocol_version = ::getVitaProtocolVersion(); - - qDebug() << "Sending Qcma protocol version:" << protocol_version; - - const initiator_info_t *pc_info = VitaMTP_Data_Initiator_New(hostname.toUtf8().data(), protocol_version); - - // Next, we send the client's (this program) info (discard the const here) - if(VitaMTP_SendInitiatorInfo(device, (initiator_info_t *)pc_info) != PTP_RC_OK) { - qWarning("Cannot send host information."); - return false; - } - - if(vita_info.protocolVersion >= VITAMTP_PROTOCOL_FW_2_10) { - // Get the device's capabilities - capability_info_t *vita_capabilities; - - if(VitaMTP_GetVitaCapabilityInfo(device, &vita_capabilities) != PTP_RC_OK) { - qWarning("Failed to get capability information from Vita."); - return false; - } - - // TODO: vitamtp needs to send the full metadata info to know the expected format - // of thumbnails, for example. Until then lets discard the received info. - - VitaMTP_Data_Free_Capability(vita_capabilities); - // Send the host's capabilities - capability_info_t *pc_capabilities = generate_pc_capability_info(); - - if(VitaMTP_SendPCCapabilityInfo(device, pc_capabilities) != PTP_RC_OK) { - qWarning("Failed to send capability information to Vita."); - free_pc_capability_info(pc_capabilities); - return false; - } - - free_pc_capability_info(pc_capabilities); - } - - // Finally, we tell the Vita we are connected - if(VitaMTP_SendHostStatus(device, VITA_HOST_STATUS_Connected) != PTP_RC_OK) { - qWarning("Cannot send host status."); - return false; - } - - VitaMTP_Data_Free_Initiator(pc_info); - return true; -} - -void DeviceCapability::free_pc_capability_info(capability_info_t *info) -{ - delete[] &info->functions.formats.next_item[-1]; - delete[] &info->functions.next_item[-1]; - delete info; -} - -capability_info_t *DeviceCapability::generate_pc_capability_info() -{ - typedef capability_info::capability_info_function tfunction; - typedef tfunction::capability_info_format tformat; - - // TODO: Actually do this based on QCMA capabilities - capability_info_t *pc_capabilities = new capability_info_t; - pc_capabilities->version = "1.0"; - tfunction *functions = new tfunction[3](); - tformat *game_formats = new tformat[5](); - game_formats[0].contentType = "vitaApp"; - game_formats[0].next_item = &game_formats[1]; - game_formats[1].contentType = "PSPGame"; - game_formats[1].next_item = &game_formats[2]; - game_formats[2].contentType = "PSPSaveData"; - game_formats[2].next_item = &game_formats[3]; - game_formats[3].contentType = "PSGame"; - game_formats[3].next_item = &game_formats[4]; - game_formats[4].contentType = "PSMApp"; - functions[0].type = "game"; - functions[0].formats = game_formats[0]; - functions[0].next_item = &functions[1]; - functions[1].type = "backup"; - functions[1].next_item = &functions[2]; - functions[2].type = "systemUpdate"; - pc_capabilities->functions = functions[0]; - return pc_capabilities; -} - -DeviceCapability::~DeviceCapability() -{ - VitaMTP_Data_Free_VitaInfo(&vita_info); -} diff --git a/src/capability.h b/src/capability.h deleted file mode 100644 index 2b15185..0000000 --- a/src/capability.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 CAPABILITY_H -#define CAPABILITY_H - -#include - -class DeviceCapability -{ -public: - explicit DeviceCapability(); - ~DeviceCapability(); - bool exchangeInfo(vita_device_t *device); - - const char *getVersion() { - return vita_info.responderVersion; - } - int getProtocolVersion() { - return vita_info.protocolVersion; - } - const char *getOnlineId() { - return vita_info.onlineId; - } - const char *getModelInfo() { - return vita_info.modelInfo; - } - -private: - capability_info_t *generate_pc_capability_info(); - void free_pc_capability_info(capability_info_t *info); - - vita_info_t vita_info; -}; - -#endif // CAPABILITY_H diff --git a/src/cli/headlessmanager.cpp b/src/cli/headlessmanager.cpp deleted file mode 100644 index bc6693b..0000000 --- a/src/cli/headlessmanager.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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 "cmaclient.h" -#include "cmautils.h" -#include "sqlitedb.h" -#include "qlistdb.h" -#include "headlessmanager.h" - -#include -#include -#include -#include -#include -#include - -int HeadlessManager::sighup_fd[2]; -int HeadlessManager::sigterm_fd[2]; - -HeadlessManager::HeadlessManager(QObject *obj_parent) : - QObject(obj_parent) -{ - if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighup_fd)) - qFatal("Couldn't create HUP socketpair"); - - if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigterm_fd)) - qFatal("Couldn't create TERM socketpair"); - - sn_hup = new QSocketNotifier(sighup_fd[1], QSocketNotifier::Read, this); - connect(sn_hup, SIGNAL(activated(int)), this, SLOT(handleSigHup())); - sn_term = new QSocketNotifier(sigterm_fd[1], QSocketNotifier::Read, this); - connect(sn_term, SIGNAL(activated(int)), this, SLOT(handleSigTerm())); -} - -HeadlessManager::~HeadlessManager() -{ - VitaMTP_Cleanup(); - delete m_db; -} - -void HeadlessManager::refreshDatabase() -{ - if(m_db->load()) { - return; - } - - QTextStream(stdout) << "Database scan has started" << endl; - - if(!m_db->rescan()) { - qWarning("No PS Vita system has been registered"); - } -} - -void HeadlessManager::start() -{ - if(VitaMTP_Init() < 0) { - qCritical("Cannot initialize VitaMTP library"); - return; - } - - if(QSettings().value("useMemoryStorage", true).toBool()) { - m_db = new QListDB(); - } else { - m_db = new SQLiteDB(); - } - - // initializing database for the first use - refreshDatabase(); - - // send a signal when the update is finished - connect(m_db, SIGNAL(updated(int)), this, SIGNAL(databaseUpdated(int))); - - thread_count = 0; - qDebug("Starting cma threads"); - CmaClient *client; - QSettings settings; - - if(!settings.value("disableUSB", false).toBool()) { - - if(!belongsToGroup("vitamtp")) - qCritical() << tr("This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus."); - - usb_thread = new QThread(); - client = new CmaClient(m_db); - usb_thread->setObjectName("usb_thread"); - connect(usb_thread, SIGNAL(started()), client, SLOT(connectUsb())); - 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())); - connect(usb_thread, SIGNAL(finished()), client, SLOT(deleteLater())); - - connect(client, SIGNAL(refreshDatabase()), this, SLOT(refreshDatabase())); - - client->moveToThread(usb_thread); - usb_thread->start(); - thread_count++; - } - - if(!settings.value("disableWireless", false).toBool()) { - CmaBroadcast *broadcast = new CmaBroadcast(this); - wireless_thread = new QThread(); - client = new CmaClient(m_db, broadcast); - wireless_thread->setObjectName("wireless_thread"); - connect(wireless_thread, SIGNAL(started()), client, SLOT(connectWireless())); - 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(refreshDatabase()), this, SLOT(refreshDatabase())); - - client->moveToThread(wireless_thread); - wireless_thread->start(); - thread_count++; - } - - if(thread_count == 0) { - qCritical("You must enable at least USB or Wireless monitoring"); - } -} - -void HeadlessManager::receiveMessage(QString message) -{ - QTextStream(stdout) << message << endl; -} - -void HeadlessManager::stop() -{ - if(CmaClient::stop() < 0) { - QCoreApplication::quit(); - } -} - -void HeadlessManager::threadStopped() -{ - mutex.lock(); - if(--thread_count == 0) { - QCoreApplication::quit(); - } - mutex.unlock(); -} - -void HeadlessManager::hupSignalHandler(int) -{ - char a = 1; - ::write(sighup_fd[0], &a, sizeof(a)); -} - -void HeadlessManager::termSignalHandler(int) -{ - char a = 1; - ::write(sigterm_fd[0], &a, sizeof(a)); -} - -void HeadlessManager::handleSigTerm() -{ - sn_term->setEnabled(false); - char tmp; - ::read(sigterm_fd[1], &tmp, sizeof(tmp)); - - stop(); - - sn_term->setEnabled(true); -} - -void HeadlessManager::handleSigHup() -{ - sn_hup->setEnabled(false); - char tmp; - ::read(sighup_fd[1], &tmp, sizeof(tmp)); - - refreshDatabase(); - - sn_hup->setEnabled(true); -} diff --git a/src/cli/headlessmanager.h b/src/cli/headlessmanager.h deleted file mode 100644 index 9c21c20..0000000 --- a/src/cli/headlessmanager.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 HEADLESSMANAGER_H -#define HEADLESSMANAGER_H - -#include "database.h" - -#include -#include -#include - -class HeadlessManager : public QObject -{ - Q_OBJECT - -public: - explicit HeadlessManager(QObject *parent = 0); - ~HeadlessManager(); - - void start(); - - // unix signal handlers - static void hupSignalHandler(int); - static void termSignalHandler(int); - -private: - int thread_count; - QMutex mutex; - - Database *m_db; - - QThread *usb_thread; - QThread *wireless_thread; - - // signal handling - static int sighup_fd[2]; - static int sigterm_fd[2]; - - QSocketNotifier *sn_hup; - QSocketNotifier *sn_term; - -signals: - void stopped(); - void databaseUpdated(int count); - -public slots: - void refreshDatabase(); - void stop(); - - // Qt signal handlers - void handleSigHup(); - void handleSigTerm(); - -private slots: - void threadStopped(); - void receiveMessage(QString message); -}; - -#endif // HEADLESSMANAGER_H diff --git a/src/cli/main_cli.cpp b/src/cli/main_cli.cpp deleted file mode 100644 index 1be7b42..0000000 --- a/src/cli/main_cli.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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 Q_OS_WIN32 -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "singlecoreapplication.h" -#include "headlessmanager.h" - -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -static void noDebugOutput(QtMsgType type, const QMessageLogContext &, const QString & msg) -{ - QByteArray localMsg = msg.toLocal8Bit(); - const char *message = localMsg.constData(); -#else -static void noDebugOutput(QtMsgType type, const char *message) -{ -#endif - switch (type) { - case QtDebugMsg: - break; - case QtWarningMsg: - fprintf(stderr, "Warning: %s\n", message); - break; - case QtCriticalMsg: - fprintf(stderr, "Critical: %s\n", message); - break; - case QtFatalMsg: - fprintf(stderr, "Fatal: %s\n", message); - abort(); - } -} - -static bool setup_handlers() -{ - struct sigaction hup, term; - - hup.sa_handler = HeadlessManager::hupSignalHandler; - sigemptyset(&hup.sa_mask); - hup.sa_flags = 0; - hup.sa_flags |= SA_RESTART; - - if (sigaction(SIGHUP, &hup, NULL) != 0) { - qCritical("SIGHUP signal handle failed"); - return false; - } - - term.sa_handler = HeadlessManager::termSignalHandler; - sigemptyset(&term.sa_mask); - term.sa_flags |= SA_RESTART; - - if (sigaction(SIGTERM, &term, NULL) != 0) { - qCritical("SIGTERM signal handle failed"); - return false; - } - - if (sigaction(SIGINT, &term, NULL) != 0) { - qCritical("SIGINT signal handle failed"); - return false; - } - - return true; -} - -int main(int argc, char *argv[]) -{ - if(SingleCoreApplication::sendMessage("Another instance of Qcma tried to start")) { - QTextStream(stdout) << "An instance of Qcma is already running" << endl; - return 0; - } - - SingleCoreApplication app(argc, argv); - - // FIXME: libmtp sends SIGPIPE if a socket write fails crashing the whole app - // the proper fix is to libmtp to handle the cancel properly or ignoring - // SIGPIPE on the socket - signal(SIGPIPE, SIG_IGN); - - if(!setup_handlers()) - return 1; - - if(app.arguments().contains("--with-debug")) { - VitaMTP_Set_Logging(VitaMTP_DEBUG); - } else if(app.arguments().contains("--verbose")) { - VitaMTP_Set_Logging(VitaMTP_VERBOSE); - } else { - VitaMTP_Set_Logging(VitaMTP_NONE); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - qInstallMessageHandler(noDebugOutput); -#else - qInstallMsgHandler(noDebugOutput); -#endif - } - -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); -#endif - - QTextStream(stdout) << "Starting Qcma " << QCMA_VER << endl; - - QTranslator translator; - QString locale = QLocale().system().name(); - qDebug() << "Current locale:" << locale; - - if(app.arguments().contains("--set-locale")) { - int index = app.arguments().indexOf("--set-locale"); - if(index + 1 < app.arguments().length()) { - qDebug("Enforcing locale: %s", app.arguments().at(index + 1).toUtf8().data()); - locale = app.arguments().at(index + 1); - } - } - - if(translator.load("qcma_" + locale, ":/resources/translations")) { - app.installTranslator(&translator); - } else { - qWarning() << "Cannot load translation for locale:" << locale; - } - - QTranslator system_translator; - system_translator.load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&system_translator); - - qDebug("Starting main thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId()); - - // set the organization/application for QSettings to work properly - app.setOrganizationName("codestation"); - app.setApplicationName("qcma"); - - HeadlessManager manager; - - // receive the message from another process - QObject::connect(&app, SIGNAL(messageAvailable(QString)), &manager, SLOT(receiveMessage(QString))); - - manager.start(); - - return app.exec(); -} diff --git a/src/cli/singlecoreapplication.cpp b/src/cli/singlecoreapplication.cpp deleted file mode 100644 index 8b37a58..0000000 --- a/src/cli/singlecoreapplication.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 "singlecoreapplication.h" - -#include - -const int SingleCoreApplication::timeout = 500; -const QString SingleCoreApplication::SHARED_KEY = "QCMA_KEY"; - -SingleCoreApplication::SingleCoreApplication(int &argc, char **argv) : - QCoreApplication(argc, argv) -{ - server = new QLocalServer(this); - connect(server, SIGNAL(newConnection()), this, SLOT(receiveMessage())); - QLocalServer::removeServer(SHARED_KEY); - server->listen(SHARED_KEY); -} - -void SingleCoreApplication::receiveMessage() -{ - QLocalSocket *socket = server->nextPendingConnection(); - - if(!socket->waitForReadyRead(timeout)) { - qDebug() << socket->errorString(); - return; - } - - QByteArray byteArray = socket->readAll(); - QString message = QString::fromUtf8(byteArray.constData()); - emit messageAvailable(message); - socket->disconnectFromServer(); -} - -bool SingleCoreApplication::sendMessage(const QString &message) -{ - QLocalSocket socket; - socket.connectToServer(SHARED_KEY, QIODevice::WriteOnly); - - if(!socket.waitForConnected(timeout)) { - return false; - } - - socket.write(message.toUtf8()); - - if(!socket.waitForBytesWritten(timeout)) { - qDebug() << socket.errorString(); - return false; - } - - socket.disconnectFromServer(); - return true; -} diff --git a/src/cli/singlecoreapplication.h b/src/cli/singlecoreapplication.h deleted file mode 100644 index 4b6a154..0000000 --- a/src/cli/singlecoreapplication.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 SINGLECOREAPPLICATION_H -#define SINGLECOREAPPLICATION_H - -#include -#include -#include -#include - -class SingleCoreApplication : public QCoreApplication -{ - Q_OBJECT -public: - explicit SingleCoreApplication(int &argc, char **argv); - - static bool sendMessage(const QString &message); - -private: - QLocalServer *server; - - static const int timeout; - static const QString SHARED_KEY; - -signals: - void messageAvailable(QString message); - - -public slots: - void receiveMessage(); -}; - -#endif // SINGLECOREAPPLICATION_H diff --git a/src/cmabroadcast.cpp b/src/cmabroadcast.cpp deleted file mode 100644 index 72058ea..0000000 --- a/src/cmabroadcast.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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 "cmabroadcast.h" -#include "cmautils.h" - -#include -#include -#include -#include -#include -#include - -#include - -const QString CmaBroadcast::broadcast_reply = - "%1\r\n" - "host-id:%2\r\n" - "host-type:%3\r\n" - "host-name:%4\r\n" - "host-mtp-protocol-version:%5\r\n" - "host-request-port:%6\r\n" - "host-wireless-protocol-version:%7\r\n" - "host-supported-device:PS Vita, PS Vita TV\r\n"; - -const char *CmaBroadcast::broadcast_query_start = "SRCH"; -const char *CmaBroadcast::broadcast_query_end = " * HTTP/1.1\r\n"; - -const char *CmaBroadcast::broadcast_ok = "HTTP/1.1 200 OK"; -const char *CmaBroadcast::broadcast_unavailable = "HTTP/1.1 503 NG"; - -CmaBroadcast::CmaBroadcast(QObject *obj_parent) : - QObject(obj_parent) -{ - QSettings settings; - // generate a GUID if doesn't exist yet in settings - uuid = settings.value("guid").toString(); - if(uuid.isEmpty()) { - uuid = QUuid::createUuid().toString().mid(1,36); - settings.setValue("guid", uuid); - } - - hostname = QHostInfo::localHostName(); - setAvailable(); - - socket = new QUdpSocket(this); - connect(socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); - -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - QHostAddress host_address(QHostAddress::Any); -#else - QHostAddress host_address(QHostAddress::AnyIPv4); -#endif - - if(!socket->bind(host_address, QCMA_REQUEST_PORT, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) { - qCritical() << "Failed to bind address for UDP broadcast"; - } -} - -void CmaBroadcast::readPendingDatagrams() -{ - if(socket->hasPendingDatagrams()) { - QByteArray datagram; - datagram.resize(socket->pendingDatagramSize()); - - QHostAddress cma_sender; - quint16 senderPort; - - socket->readDatagram(datagram.data(), datagram.size(), &cma_sender, &senderPort); - - if(datagram.startsWith(broadcast_query_start) && datagram.contains(broadcast_query_end)) { - QMutexLocker locker(&mutex); - socket->writeDatagram(reply, cma_sender, senderPort); - } else { - qWarning("Unknown request: %.*s\n", datagram.length(), datagram.constData()); - } - } -} - -void CmaBroadcast::setAvailable() -{ - QMutexLocker locker(&mutex); - int protocol_version = ::getVitaProtocolVersion(); - - reply.clear(); - reply.insert(0, broadcast_reply - .arg(broadcast_ok, uuid, "win", hostname) - .arg(protocol_version, 8, 10, QChar('0')) - .arg(QCMA_REQUEST_PORT) - .arg(VITAMTP_WIRELESS_MAX_VERSION, 8, 10, QChar('0'))); - reply.append('\0'); -} - -void CmaBroadcast::setUnavailable() -{ - QMutexLocker locker(&mutex); - int protocol_version = ::getVitaProtocolVersion(); - - reply.clear(); - reply.insert(0, broadcast_reply - .arg(broadcast_unavailable, uuid, "win", hostname) - .arg(protocol_version, 8, 10, QChar('0')) - .arg(QCMA_REQUEST_PORT) - .arg(VITAMTP_WIRELESS_MAX_VERSION, 8, 10, QChar('0'))); - reply.append('\0'); -} diff --git a/src/cmabroadcast.h b/src/cmabroadcast.h deleted file mode 100644 index 14cbaf1..0000000 --- a/src/cmabroadcast.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 CMABROADCAST_H -#define CMABROADCAST_H - -#include -#include -#include - -#define QCMA_REQUEST_PORT 9309 - -class CmaBroadcast : public QObject -{ - Q_OBJECT -public: - explicit CmaBroadcast(QObject *parent = 0); - -private: - void replyBroadcast(const QByteArray &datagram); - - QMutex mutex; - QString uuid; - QByteArray reply; - QString hostname; - QUdpSocket *socket; - - static const QString broadcast_reply; - static const char *broadcast_query_start; - static const char *broadcast_query_end; - static const char *broadcast_ok; - static const char *broadcast_unavailable; - -public slots: - void setAvailable(); - void setUnavailable(); - -private slots: - void readPendingDatagrams(); -}; - -#endif // CMABROADCAST_H diff --git a/src/cmaclient.cpp b/src/cmaclient.cpp deleted file mode 100644 index 650b420..0000000 --- a/src/cmaclient.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 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 "cmaclient.h" -#include "capability.h" -#include "avdecoder.h" -#include "cmaevent.h" -#include "cmautils.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -QMutex CmaClient::mutex; -QMutex CmaClient::runner; -QWaitCondition CmaClient::usbcondition; -QMutex CmaClient::usbwait; -QSemaphore CmaClient::sema; - -QString CmaClient::tempOnlineId = QString(); - -bool CmaClient::is_active = false; -bool CmaClient::in_progress = false; - -CmaClient *CmaClient::this_object = NULL; - -CmaClient::CmaClient(Database *db, QObject *obj_parent) : - QObject(obj_parent), m_db(db), m_broadcast(NULL) -{ - this_object = this; -} - - -CmaClient::CmaClient(Database *db, CmaBroadcast *broadcast, QObject *obj_parent) : - QObject(obj_parent), m_db(db), m_broadcast(broadcast) -{ - this_object = this; -} - -void CmaClient::connectUsb() -{ - vita_device_t *vita; - - qDebug("Starting usb_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId()); - - setActive(true); - usbwait.lock(); - - do { - if((vita = VitaMTP_Get_First_USB_Vita()) != NULL) { - qDebug("Starting new USB connection"); - processNewConnection(vita); - } else { - //TODO: replace this with an event-driven setup - usbcondition.wait(&usbwait, 2000); - mutex.lock(); - if(in_progress) { - sema.acquire(); - } - mutex.unlock(); - } - } while(isActive()); - - usbwait.unlock(); - qDebug("Finishing usb_thread"); - emit finished(); -} - -void CmaClient::connectWireless() -{ - vita_device_t *vita; - wireless_host_info_t host = {NULL, NULL, NULL, QCMA_REQUEST_PORT}; - typedef CmaClient CC; - - QTime now = QTime::currentTime(); - qsrand(now.msec()); - - qDebug("Starting wireless_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId()); - - setActive(true); - - do { - qDebug("Waiting for wireless connection"); - if((vita = VitaMTP_Get_First_Wireless_Vita(&host, 0, CC::deviceRegistered, CC::generatePin, CC::registrationComplete)) != NULL) { - qDebug("Starting new wireless connection"); - m_broadcast->setUnavailable(); - processNewConnection(vita); - m_broadcast->setAvailable(); - } else { - mutex.lock(); - if(in_progress) { - sema.acquire(); - } - mutex.unlock(); - - // if is active then something happened while setting the socket, wait a little and try again - if(isActive()) { - qDebug("Error getting wireless connection"); - Sleeper::sleep(2000); - } else { - qDebug("Wireless connection cancelled by the user"); - } - } - } while(isActive()); - - qDebug("Finishing wireless_thread"); - emit finished(); -} - -void CmaClient::processNewConnection(vita_device_t *device) -{ - QMutexLocker locker(&mutex); - in_progress = true; - - QTextStream(stdout) << "Vita connected, id: " << VitaMTP_Get_Identification(device) << endl; - DeviceCapability vita_info; - - if(!vita_info.exchangeInfo(device)) { - qCritical("Error while exchanging info with the vita"); - if(VitaMTP_Get_Device_Type(device) == VitaDeviceUSB) { - // reset the device - VitaMTP_USB_Reset(device); - } - } else { - QSettings settings; - - // Conection successful, inform the user - if(vita_info.getOnlineId() != NULL) { - settings.setValue("lastOnlineId", vita_info.getOnlineId()); - emit deviceConnected(QString(tr("Connected to %1 (PS Vita)")).arg(vita_info.getOnlineId())); - } else { - QString onlineId = settings.value("lastOnlineId", "default").toString(); - emit deviceConnected(QString(tr("Connected to %1 (PS Vita)")).arg(onlineId)); - } - - enterEventLoop(device); - } - - VitaMTP_SendHostStatus(device, VITA_HOST_STATUS_EndConnection); - qDebug("Releasing device..."); - VitaMTP_Release_Device(device); - - emit deviceDisconnected(); - - in_progress = false; - sema.release(); -} - -void CmaClient::registrationComplete() -{ - QSettings settings; - qDebug("Registration completed"); - settings.setValue("lastOnlineId", tempOnlineId); - emit this_object->pinComplete(); -} - -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; -} - -int CmaClient::generatePin(wireless_vita_info_t *info, int *p_err) -{ - // save the device name in a temporal variable, just in case the pin is rejected - tempOnlineId = QString(info->name); - qDebug("Registration request from %s (MAC: %s)", info->name, info->mac_addr); - int pin = rand() % 10000 * 10000 | rand() % 10000; - QTextStream out(stdout); - out << "Your registration PIN for " << info->name << " is: "; - out.setFieldWidth(8); - out.setPadChar('0'); - out << pin << endl; - - *p_err = 0; - emit this_object->receivedPin(info->name, pin); - return pin; -} - -void CmaClient::enterEventLoop(vita_device_t *device) -{ - vita_event_t obj_event; - - qDebug("Starting event loop"); - - CmaEvent eventLoop(m_db, device); - QThread obj_thread; - obj_thread.setObjectName("event_thread"); - - eventLoop.moveToThread(&obj_thread); - connect(&obj_thread, SIGNAL(started()), &eventLoop, SLOT(process())); - connect(&eventLoop, SIGNAL(refreshDatabase()), this, SIGNAL(refreshDatabase()), Qt::DirectConnection); - connect(&eventLoop, SIGNAL(finishedEventLoop()), &obj_thread, SLOT(quit()), Qt::DirectConnection); - connect(&eventLoop, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString)), Qt::DirectConnection); - obj_thread.start(); - - while(isActive()) { - if(VitaMTP_Read_Event(device, &obj_event) < 0) { - qWarning("Error reading event from Vita."); - break; - } - - // do not create a event for this since there aren't more events to read - if(obj_event.Code == PTP_EC_VITA_RequestTerminate) { - qDebug("Terminating event thread"); - break; - - // this one shuold be processed inmediately - } else if(obj_event.Code == PTP_EC_VITA_RequestCancelTask) { - eventLoop.vitaEventCancelTask(&obj_event, obj_event.Param1); - qDebug("Ended event, code: 0x%x, id: %d", obj_event.Code, obj_event.Param1); - continue; - } - - // the events are processed synchronously except for cancel/terminate - qDebug("Sending new event"); - eventLoop.setEvent(obj_event); - } - - eventLoop.stop(); - obj_thread.wait(); - qDebug("Finishing event loop"); -} - -int CmaClient::stop() -{ - QTextStream(stdout) << "Stopping Qcma" << endl; - - if(!isActive()) { - return -1; - } - CmaClient::setActive(false); - qDebug("Cancelling wireless server thread"); - VitaMTP_Cancel_Get_Wireless_Vita(); - usbcondition.wakeAll(); - return 0; -} - -bool CmaClient::isActive() -{ - QMutexLocker locker(&runner); - return is_active; -} - -void CmaClient::setActive(bool state) -{ - QMutexLocker locker(&runner); - is_active = state; -} - -bool CmaClient::isRunning() -{ - bool ret; - if(mutex.tryLock()) { - ret = in_progress; - mutex.unlock(); - } else { - ret = true; - } - return ret; -} - diff --git a/src/cmaclient.h b/src/cmaclient.h deleted file mode 100644 index 46c5297..0000000 --- a/src/cmaclient.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 CMACLIENT_H -#define CMACLIENT_H - -#include "qlistdb.h" -#include "cmaevent.h" -#include "cmabroadcast.h" - -#include -#include -#include -#include - -#include - -class CmaClient : public QObject -{ - Q_OBJECT -public: - explicit CmaClient(Database *db, QObject *obj_parent = 0); - explicit CmaClient(Database *db, CmaBroadcast *broadcast, QObject *obj_parent = 0); - - static bool isRunning(); - void launch(); - -private: - static bool isActive(); - static void setActive(bool state); - static bool isEventLoopEnabled(); - static void setEventLoop(bool state); - void enterEventLoop(vita_device_t *device); - - void processNewConnection(vita_device_t *device); - - static int deviceRegistered(const char *deviceid); - static int generatePin(wireless_vita_info_t *info, int *p_err); - static int cancelCallback(); - static void registrationComplete(); - - Database *m_db; - CmaBroadcast *m_broadcast; - static QString tempOnlineId; - - //TODO: move all the control variables to the client manager class - static bool is_active; - static bool in_progress; - static CmaClient *this_object; - static QMutex mutex; - static QMutex runner; - static QMutex usbwait; - static QWaitCondition usbcondition; - static QSemaphore sema; - -signals: - void newEvent(vita_event_t event); - void receivedPin(QString, int); - void pinComplete(); - void deviceDetected(); - void deviceConnected(QString); - void messageSent(QString); - void deviceDisconnected(); - void refreshDatabase(); - void finished(); - -public slots: - static int stop(); - -private slots: - void connectUsb(); - void connectWireless(); -}; - -#endif // CMACLIENT_H diff --git a/src/cmaevent.cpp b/src/cmaevent.cpp deleted file mode 100644 index f601cc6..0000000 --- a/src/cmaevent.cpp +++ /dev/null @@ -1,1009 +0,0 @@ -/* - * 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 "cmautils.h" - -#include -#include -#include -#include -#include -#include -#include - -QFile *CmaEvent::m_file = 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(Database *db, vita_device_t *s_device) : - m_device(s_device), m_db(db), is_active(true) -{ -} - -void CmaEvent::process() -{ - qDebug("Starting event_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId()); - - while(true) { - sema.acquire(); - if(!isActive()) { - break; - } - - QMutexLocker locker(&mutex); - processEvent(); - } - qDebug("Finishing event_thread"); - emit finishedEventLoop(); -} - -bool CmaEvent::isActive() -{ - QMutexLocker locker(&active); - return is_active; -} - -void CmaEvent::stop() -{ - QMutexLocker locker(&active); - is_active = false; - sema.release(); -} - -void CmaEvent::setDevice(vita_device_t *device) -{ - QMutexLocker locker(&mutex); - m_device = device; -} - -void CmaEvent::setEvent(vita_event_t cma_event) -{ - QMutexLocker locker(&mutex); - m_event = cma_event; - locker.unlock(); - sema.release(); -} - -void CmaEvent::processEvent() -{ - switch(m_event.Code) { - case PTP_EC_VITA_RequestSendNumOfObject: - vitaEventSendNumOfObject(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendObjectMetadata: - vitaEventSendObjectMetadata(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendObject: - vitaEventSendObject(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendHttpObjectFromURL: - vitaEventSendHttpObjectFromURL(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_Unknown1: // unimplemented - vitaEventUnimplementated(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendObjectStatus: - vitaEventSendObjectStatus(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendObjectThumb: - vitaEventSendObjectThumb(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestDeleteObject: - vitaEventDeleteObject(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestGetSettingInfo: - vitaEventGetSettingInfo(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendHttpObjectPropFromURL: - vitaEventSendHttpObjectPropFromURL(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendPartOfObject: - vitaEventSendPartOfObject(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestOperateObject: - vitaEventOperateObject(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestGetPartOfObject: - vitaEventGetPartOfObject(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendStorageSize: - vitaEventSendStorageSize(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestCheckExistance: - vitaEventCheckExistance(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestGetTreatObject: - vitaEventGetTreatObject(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendCopyConfirmationInfo: - vitaEventSendCopyConfirmationInfo(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendObjectMetadataItems: - vitaEventSendObjectMetadataItems(&m_event, m_event.Param1); - break; - case PTP_EC_VITA_RequestSendNPAccountInfo: - vitaEventSendNPAccountInfo(&m_event, m_event.Param1); - break; - default: - vitaEventUnimplementated(&m_event, m_event.Param1); - } - qDebug("Ended event, code: 0x%x, id: %d", m_event.Code, m_event.Param1); -} - -quint16 CmaEvent::processAllObjects(metadata_t &parent_metadata, quint32 handle) -{ - qDebug("Called %s, handle: %d, parent name: %s", Q_FUNC_INFO, handle, parent_metadata.name); - - char *name; - int dataType; - quint32 *p_handles; - unsigned int p_len; - - if(VitaMTP_GetObject_Info(m_device, handle, &name, &dataType) != PTP_RC_OK) { - qWarning("Cannot get object for handle %d", handle); - return PTP_RC_VITA_Invalid_Data; - } - - if(dataType & Folder) { - if(VitaMTP_GetObject_Folder(m_device, handle, &p_handles, &p_len) != PTP_RC_OK) { - qWarning("Cannot get folder handles for handle %d", handle); - return PTP_RC_VITA_Invalid_Data; - } - } else { - - } - - int ohfi = m_db->getPathId(name, parent_metadata.ohfi); - - if(ohfi > 0) { - const QString fullpath = m_db->getAbsolutePath(ohfi); - qDebug() << "Deleting" << fullpath; - removeRecursively(fullpath); - m_db->deleteEntry(ohfi); - } - - QString fullpath = m_db->getAbsolutePath(parent_metadata.ohfi); - QDir dir(fullpath); - - if(dataType & Folder) { - if(!dir.mkpath(name)) { - qWarning("Cannot create directory: %s", name); - free(name); - return PTP_RC_VITA_Failed_Operate_Object; - } - } else { - m_file = new QFile(dir.absoluteFilePath(name)); - - if(!m_file->open(QIODevice::WriteOnly)) { - qWarning("Cannot write to %s", name); - free(name); - delete m_file; - return PTP_RC_VITA_Invalid_Permission; - } else { - // the size gets ignored because we can also get it via info.size() - uint64_t size; - - VitaMTP_GetObject_Callback(m_device, handle, &size, CmaEvent::writeCallback); - m_file->close(); - delete m_file; - } - } - - int new_ohfi = m_db->insertObjectEntry(fullpath, name, parent_metadata.ohfi); - qDebug("Added object %s with OHFI %i to database", name, new_ohfi); - free(name); - - 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++) { - quint16 ret = processAllObjects(folder_metadata, p_handles[i]); - - if(ret != PTP_RC_OK) { - qDebug("Deleteting object with OHFI %d", new_ohfi); - m_db->deleteEntry(new_ohfi); - return ret; - } - } - } - - return PTP_RC_OK; -} - -void CmaEvent::vitaEventGetTreatObject(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - treat_object_t treatObject; - - if(VitaMTP_GetTreatObject(m_device, eventId, &treatObject) != PTP_RC_OK) { - qWarning("Cannot get information on object to get"); - return; - } - - QMutexLocker locker(&m_db->mutex); - - metadata_t metadata; - - if(!m_db->getObjectMetadata(treatObject.ohfiParent, metadata)) { - qWarning("Cannot find parent OHFI %d", treatObject.ohfiParent); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_OHFI); - return; - } - - VitaMTP_ReportResult(m_device, eventId, processAllObjects(metadata, treatObject.handle)); -} - -void CmaEvent::vitaEventSendCopyConfirmationInfo(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - copy_confirmation_info_t *info; - if(VitaMTP_SendCopyConfirmationInfoInit(m_device, eventId, &info) != PTP_RC_OK) { - qWarning("Error receiving initial information."); - return; - } - - QMutexLocker locker(&m_db->mutex); - - qint64 total_size = 0; - - // check if the item is a single folder - if(info->count == 1) { - metadata_t obj_meta; - if(m_db->getObjectMetadata(info->ohfi[0], obj_meta)) { - // got a folder - if(obj_meta.dataType & Folder) { - metadata_t *meta_list = NULL; - if(m_db->getObjectList(info->ohfi[0], &meta_list)) { - int count = 0; - metadata_t *single_meta = meta_list; - // count files - while(single_meta) { - if(single_meta->dataType & File) { - count++; - } - single_meta = single_meta->next_metadata; - } - // create struct to hold all the file identifiers - info = (copy_confirmation_info_t *)malloc(sizeof(uint32_t) * count + sizeof(copy_confirmation_info_t)); - single_meta = meta_list; - info->count = 0; - // copy all the file ohfi - while(single_meta) { - if(single_meta->dataType & File) { - info->ohfi[info->count] = single_meta->ohfi; - total_size += single_meta->size; - info->count++; - } - single_meta = single_meta->next_metadata; - } - - } - m_db->freeMetadata(meta_list); - } - } - } else { - qint64 size; - - for(quint32 i = 0; i < info->count; i++) { - if((size = m_db->getObjectSize(info->ohfi[i])) < 0) { - qWarning("Cannot find OHFI %d", info->ohfi[i]); - free(info); - return; - } - - total_size += size; - } - } - - if(VitaMTP_SendCopyConfirmationInfo(m_device, eventId, info, total_size) != PTP_RC_OK) { - qWarning("Error sending copy confirmation"); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - - free(info); -} - -void CmaEvent::vitaEventSendObjectMetadataItems(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - quint32 ohfi; - if(VitaMTP_SendObjectMetadataItems(m_device, eventId, &ohfi) != PTP_RC_OK) { - qWarning("Cannot get OHFI for retreving metadata"); - return; - } - - QMutexLocker locker(&m_db->mutex); - - metadata_t metadata; - - if(!m_db->getObjectMetadata(ohfi, metadata)) { - qWarning("Cannot find OHFI %d in database", ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_OHFI); - return; - } - - metadata.next_metadata = NULL; - qDebug("Sending metadata for OHFI %d (%s)", ohfi, metadata.path); - - quint16 ret = VitaMTP_SendObjectMetadata(m_device, eventId, &metadata); - if(ret != PTP_RC_OK) { - qWarning("Error sending metadata. Code: %04X", ret); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } -} - -void CmaEvent::vitaEventSendNPAccountInfo(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - // AFAIK, Sony hasn't even implemented this in their CMA - qWarning("Event 0x%x unimplemented!", cma_event->Code); -} - -void CmaEvent::vitaEventUnimplementated(vita_event_t *cma_event, int eventId) -{ - qWarning("Unknown event not handled, code: 0x%x, id: %d", cma_event->Code, eventId); - qWarning("Param1: 0x%08X, Param2: 0x%08X, Param3: 0x%08X", cma_event->Param1, cma_event->Param2, cma_event->Param3); -} - -void CmaEvent::vitaEventCancelTask(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - quint32 eventIdToCancel = cma_event->Param2; - qDebug("Cancelling event %d", eventIdToCancel); - quint16 ret = VitaMTP_CancelTask(m_device, eventIdToCancel); - - // wait until the current event finishes so we can report the result to the device - - qDebug("Waiting for send event to finish"); - QMutexLocker locker(&mutex); - if(ret == PTP_RC_OK) { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } -} - -void CmaEvent::vitaEventSendNumOfObject(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - QMutexLocker locker(&m_db->mutex); - - int ohfi = cma_event->Param2; - int items = m_db->childObjectCount(ohfi); - - if(VitaMTP_SendNumOfObject(m_device, eventId, items) != PTP_RC_OK) { - qWarning("Error occured receiving object count for OHFI parent %d", ohfi); - } else { - qDebug("Returned count of %d objects for OHFI parent %d", items, ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } -} - -void CmaEvent::vitaEventSendObjectMetadata(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - browse_info_t browse; - - if(VitaMTP_GetBrowseInfo(m_device, eventId, &browse) != PTP_RC_OK) { - qWarning("GetBrowseInfo failed"); - return; - } - QMutexLocker locker(&m_db->mutex); - - metadata_t *meta = NULL; - - 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); - - if(VitaMTP_SendObjectMetadata(m_device, eventId, meta) != PTP_RC_OK) { // send all objects with OHFI parent - qWarning("Sending metadata for OHFI parent %d failed", browse.ohfiParent); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - m_db->freeMetadata(meta); -} - -void CmaEvent::vitaEventSendObject(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - int ohfi = cma_event->Param2; - - QMutexLocker locker(&m_db->mutex); - - qDebug("Searching object with OHFI %d", ohfi); - - metadata_t *metadata = NULL; - if(!m_db->getObjectList(ohfi, &metadata)) { - qWarning("Failed to find OHFI %d", ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_OHFI); - return; - } - - metadata_t *start = metadata; - quint32 parentHandle = cma_event->Param3; - bool send_folder = metadata->dataType & Folder; - quint32 handle; - - do { - quint64 len = metadata->size; - m_file = new QFile(m_db->getAbsolutePath(metadata->ohfi)); - - // 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(metadata->dataType & File) { - if(!m_file->open(QIODevice::ReadOnly)) { - qWarning() << "Failed to read" << m_file->fileName(); - delete m_file; - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Not_Exist_Object); - return; - } - } - - // get the PTP object ID for the parent to put the object - // we know the parent has to be before the current node - // the first time this is called, parentHandle is left untouched - - if(start != metadata) { - metadata_t parent_metadata; - m_db->getObjectMetadata(metadata->ohfiParent, parent_metadata); - parentHandle = parent_metadata.handle; - } - - // send the data over - qDebug("Sending %s of %llu bytes to device", metadata->name, len); - qDebug("OHFI %d with handle 0x%08X", metadata->ohfi, parentHandle); - - VitaMTP_RegisterCancelEventId(eventId); - quint16 ret = VitaMTP_SendObject_Callback(m_device, &parentHandle, &handle, metadata, &CmaEvent::readCallback); - if(ret != PTP_RC_OK) { - qWarning("Sending of %s failed. Code: %04X", metadata->name, ret); - if(ret == PTP_ERROR_CANCEL) { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_GeneralError); - } - m_file->close(); - delete m_file; - return; - } - - metadata->handle = handle; - - if(metadata->dataType & File) { - m_file->close(); - delete m_file; - } - - // break early if only a file needs to be sent - if(!send_folder) { - break; - } - - metadata = metadata->next_metadata; - - } while(metadata && metadata->ohfiParent >= OHFI_BASE_VALUE); // get everything under this "folder" - - m_db->freeMetadata(start); - - VitaMTP_ReportResultWithParam(m_device, eventId, PTP_RC_OK, handle); - - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_Data); // TODO: Send thumbnail -} - -void CmaEvent::vitaEventSendHttpObjectFromURL(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - char *url; - if(VitaMTP_GetUrl(m_device, eventId, &url) != PTP_RC_OK) { - qWarning("Failed to receive URL"); - return; - } - - QString urlpath = QSettings().value("urlPath").toString(); - QString basename = QFileInfo(QUrl(url).path()).fileName(); - QFile file(QDir(urlpath).absoluteFilePath(basename)); - - QByteArray data; - QSettings settings; - - bool offlineMode = settings.value("offlineMode", true).toBool(); - - if(!file.open(QIODevice::ReadOnly)) { - if(offlineMode && basename == "psp2-updatelist.xml") { - qDebug("Found request for update list. Sending cached data"); - QFile res(":/main/resources/xml/psp2-updatelist.xml"); - res.open(QIODevice::ReadOnly); - data = res.readAll(); - - } else if(!offlineMode) { - qDebug("URL: %s", url); - HTTPDownloader downloader(url); - QThread *http_thread = new QThread(); - http_thread->setObjectName("http_thread"); - connect(http_thread, SIGNAL(started()), &downloader, SLOT(downloadFile())); - connect(&downloader, SIGNAL(messageSent(QString)), SIGNAL(messageSent(QString)), Qt::DirectConnection); - downloader.moveToThread(http_thread); - http_thread->start(); - - int remote_size = (int)downloader.getFileSize(); - - if(remote_size != -1) { - // add the size of the file length to the total filesize - remote_size += 8; - qDebug("Sending %i bytes of data for HTTP request %s", remote_size, url); - - if(VitaMTP_SendData_Callback(m_device, eventId, PTP_OC_VITA_SendHttpObjectFromURL, remote_size, HTTPDownloader::readCallback) != PTP_RC_OK) { - qWarning("Failed to send HTTP object"); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - - } else { - qWarning("No valid content-length in header, aborting"); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Failed_Download); - } - - free(url); - http_thread->quit(); - http_thread->deleteLater(); - return; - } - } else { - qDebug("Reading from local file"); - data = file.readAll(); - } - - qDebug("Sending %i bytes of data for HTTP request %s", data.size(), url); - - if(VitaMTP_SendHttpObjectFromURL(m_device, eventId, data.data(), data.size()) != PTP_RC_OK) { - qWarning("Failed to send HTTP object"); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - - free(url); -} - -void CmaEvent::vitaEventSendObjectStatus(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - object_status_t objectstatus; - - if(VitaMTP_SendObjectStatus(m_device, eventId, &objectstatus) != PTP_RC_OK) { - qWarning("Failed to get information for object status."); - return; - } - - QMutexLocker locker(&m_db->mutex); - - qDebug("Checking for path %s under ohfi %i", objectstatus.title, objectstatus.ohfiRoot); - int ohfi = m_db->getPathId(objectstatus.title, objectstatus.ohfiRoot); - - 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); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } else { - metadata_t metadata = metadata_t(); - m_db->getObjectMetadata(ohfi, metadata); - metadata.next_metadata = NULL; - qDebug("Sending metadata for OHFI %d", ohfi); - - if(VitaMTP_SendObjectMetadata(m_device, eventId, &metadata) != PTP_RC_OK) { - qWarning("Error sending metadata for %d", ohfi); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - } - - free(objectstatus.title); -} - -void CmaEvent::vitaEventSendObjectThumb(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - QMutexLocker locker(&m_db->mutex); - - int ohfi = cma_event->Param2; - metadata_t metadata; - - if(!m_db->getObjectMetadata(ohfi, metadata)) { - qWarning("Cannot find OHFI %d in database.", ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_OHFI); - return; - } - - QString fullpath = m_db->getAbsolutePath(ohfi); - QByteArray data = getThumbnail(fullpath, metadata.dataType, &g_thumbmeta); - - if(data.size() == 0) { - qWarning() << "Cannot find/read thumbnail for" << fullpath; - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_Data); - return; - } - - //FIXME: remove this after fixing vitamtp - - // workaround for the vitamtp locale bug - char *locale = strdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, "C"); - - if(VitaMTP_SendObjectThumb(m_device, eventId, (metadata_t *)&g_thumbmeta, (uchar *)data.data(), data.size()) != PTP_RC_OK) { - qWarning("Error sending thumbnail"); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - - // restore locale - setlocale(LC_ALL, locale); - free(locale); -} - -void CmaEvent::vitaEventDeleteObject(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - QMutexLocker locker(&m_db->mutex); - - int ohfi = cma_event->Param2; - metadata_t metadata; - - if(!m_db->getObjectMetadata(ohfi, metadata)) { - qWarning("OHFI %d not found", ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_OHFI); - return; - } - - QString fullpath = m_db->getAbsolutePath(ohfi); - qDebug() << QString("Deleting %1, OHFI: %2").arg(fullpath, QString::number(ohfi)); - removeRecursively(fullpath); - m_db->deleteEntry(ohfi); - - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); -} - -void CmaEvent::vitaEventGetSettingInfo(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - settings_info_t *settingsinfo; - if(VitaMTP_GetSettingInfo(m_device, eventId, &settingsinfo) != PTP_RC_OK) { - qWarning("Failed to get setting info from Vita."); - return; - } - - qDebug("Current account id: %s", settingsinfo->current_account.accountId); - - QSettings settings; - - if(settings.value("lastAccountId").toString() != settingsinfo->current_account.accountId) { - m_db->setUUID(settingsinfo->current_account.accountId); - // set the database to be updated ASAP - emit refreshDatabase(); - } - - // free all the information - VitaMTP_Data_Free_Settings(settingsinfo); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); -} - -void CmaEvent::vitaEventSendHttpObjectPropFromURL(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - char *url; - if(VitaMTP_GetUrl(m_device, eventId, &url) != PTP_RC_OK) { - qWarning("Failed to get URL"); - return; - } - - QString urlpath = QSettings().value("urlPath").toString(); - QString basename = QFileInfo(url).fileName(); - QFileInfo file(QDir(urlpath).absoluteFilePath(basename)); - - if(!file.exists()) { - qWarning("The file %s is not accesible", url); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Failed_Download); - free(url); - return; - } - - QString timestamp = file.lastModified().toString(); - - http_object_prop_t httpobjectprop; - httpobjectprop.timestamp = timestamp.toUtf8().data(); - httpobjectprop.timestamp_len = timestamp.toUtf8().size(); - - if(VitaMTP_SendHttpObjectPropFromURL(m_device, eventId, &httpobjectprop) != PTP_RC_OK) { - qWarning("Failed to send object properties"); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - - free(url); -} - -void CmaEvent::vitaEventSendPartOfObject(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - send_part_init_t part_init; - - if(VitaMTP_SendPartOfObjectInit(m_device, eventId, &part_init) != PTP_RC_OK) { - qWarning("Cannot get information on object to send"); - return; - } - - QMutexLocker locker(&m_db->mutex); - - QString fullpath = m_db->getAbsolutePath(part_init.ohfi); - - if(fullpath.isNull()) { - qWarning("Cannot find object for OHFI %d", part_init.ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_Context); - return; - } - - QFile file(fullpath); - - if(!file.open(QIODevice::ReadOnly)) { - qWarning() << "Cannot read" << fullpath; - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Not_Exist_Object); - return; - } else { - file.seek(part_init.offset); - QByteArray data = file.read(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(m_device, eventId, (unsigned char *)data.data(), data.size()) != PTP_RC_OK) { - qWarning("Failed to send part of object OHFI %d", part_init.ohfi); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - } -} - -void CmaEvent::vitaEventOperateObject(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - operate_object_t operateobject; - - if(VitaMTP_OperateObject(m_device, eventId, &operateobject) != PTP_RC_OK) { - qWarning("Cannot get information on object to operate"); - return; - } - - QMutexLocker locker(&m_db->mutex); - - QString fullpath = m_db->getAbsolutePath(operateobject.ohfi); - - // end for renaming only - if(fullpath.isNull()) { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Not_Exist_Object); - return; - } - - switch(operateobject.cmd) { - case VITA_OPERATE_CREATE_FOLDER: { - qDebug("Operate command %d: Create folder %s", operateobject.cmd, operateobject.title); - - QDir dir(fullpath); - if(!dir.mkdir(operateobject.title)) { - qWarning("Unable to create temporary folder: %s", operateobject.title); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Failed_Operate_Object); - } else { - int new_ohfi = m_db->insertObjectEntry(fullpath, operateobject.title, operateobject.ohfi); - qDebug("Created folder %s with OHFI %d", operateobject.title, new_ohfi); - VitaMTP_ReportResultWithParam(m_device, eventId, PTP_RC_OK, new_ohfi); - } - break; - } - case VITA_OPERATE_CREATE_FILE: { - qDebug("Operate command %d: Create file %s", operateobject.cmd, operateobject.title); - - QFile file(fullpath + QDir::separator() + operateobject.title); - if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - qWarning("Unable to create temporary file: %s", operateobject.title); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Failed_Operate_Object); - } else { - int new_ohfi = m_db->insertObjectEntry(fullpath, operateobject.title, operateobject.ohfi); - //qDebug("Created file %s with OHFI %d under parent %s", newobj->metadata.path, new_ohfi, root->metadata.path); - VitaMTP_ReportResultWithParam(m_device, eventId, PTP_RC_OK, new_ohfi); - } - break; - } - case VITA_OPERATE_RENAME: { - //qDebug("Operate command %d: Rename %s to %s", operateobject.cmd, root->metadata.name, operateobject.title); - - m_db->renameObject(operateobject.ohfi, operateobject.title); - QString newpath = m_db->getAbsolutePath(operateobject.ohfi); - - // rename in filesystem - if(!QFile(fullpath).rename(newpath)) { - qWarning("Unable to rename %s to %s", fullpath.toLocal8Bit().constData(), operateobject.title); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Failed_Operate_Object); - break; - } - - qDebug("Renamed OHFI %d from %s to %s", operateobject.ohfi, fullpath.toLocal8Bit().constData(), newpath.toLocal8Bit().constData()); - VitaMTP_ReportResultWithParam(m_device, eventId, PTP_RC_OK, operateobject.ohfi); - break; - } - - default: - qWarning("Operate command %d: Not implemented", operateobject.cmd); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Failed_Operate_Object); - break; - } - - free(operateobject.title); -} - -void CmaEvent::vitaEventGetPartOfObject(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - unsigned char *data; - send_part_init_t part_init; - - if(VitaMTP_GetPartOfObject(m_device, eventId, &part_init, &data) != PTP_RC_OK) { - qWarning("Cannot get object from device"); - return; - } - - QMutexLocker locker(&m_db->mutex); - QString fullpath = m_db->getAbsolutePath(part_init.ohfi); - - if(fullpath.isNull()) { - qWarning("Cannot find OHFI %d", part_init.ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_OHFI); - free(data); - return; - } - - qDebug() << QString("Receiving %1 at offset %2 for %3 bytes").arg( - fullpath, QString::number(part_init.offset), QString::number(part_init.size) - ); - - QFile file(fullpath); - if(!file.open(QIODevice::ReadWrite)) { - qWarning() << "Cannot write to file" << fullpath; - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_Permission); - } else { - file.seek(part_init.offset); - file.write((const char *)data, part_init.size); - m_db->setObjectSize(part_init.ohfi, part_init.size); - - qDebug() << QString("Written %1 bytes to %2 at offset %3").arg( - QString::number(part_init.size), fullpath, QString::number(part_init.offset) - ); - - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } - - free(data); -} - -void CmaEvent::vitaEventSendStorageSize(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - QMutexLocker locker(&m_db->mutex); - - int ohfi = cma_event->Param2; - QString fullpath = m_db->getAbsolutePath(ohfi); - - if(fullpath.isNull()) { - qWarning("Error: Cannot find OHFI %d", ohfi); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_OHFI); - return; - } else { - QFile file(fullpath); - - if(!file.exists()) { - // create the directory if doesn't exist so the query don't fail - qDebug() << "Creating" << fullpath; - - if(!QDir(QDir::root()).mkpath(QDir(fullpath).absolutePath())) { - qWarning("Create directory failed"); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_Permission); - return; - } - } - } - - quint64 total; - quint64 free; - - if(!getDiskSpace(fullpath, &free, &total)) { - qWarning("Cannot get disk space"); - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Invalid_Permission); - return; - } - - qDebug("Storage stats for drive containing OHFI %d, free: %llu, total: %llu", ohfi, free, total); - - if(VitaMTP_SendStorageSize(m_device, eventId, total, free) != PTP_RC_OK) { - qWarning("Send storage size failed"); - } else { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); - } -} - -void CmaEvent::vitaEventCheckExistance(vita_event_t *cma_event, int eventId) -{ - qDebug("Event received in %s, code: 0x%x, id: %d", Q_FUNC_INFO, cma_event->Code, eventId); - - int handle = cma_event->Param2; - existance_object_t existance; - - if(VitaMTP_CheckExistance(m_device, handle, &existance) != PTP_RC_OK) { - qWarning("Cannot read information on object to be sent"); - return; - } - - QMutexLocker locker(&m_db->mutex); - - int ohfi = m_db->getPathId(existance.name, 0); - - if(ohfi == 0) { - VitaMTP_ReportResult(m_device, eventId, PTP_RC_VITA_Different_Object); - } else { - VitaMTP_ReportResultWithParam(m_device, eventId, PTP_RC_VITA_Same_Object, ohfi); - } - - VitaMTP_ReportResult(m_device, eventId, PTP_RC_OK); -} - -int CmaEvent::readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen) -{ - int ret = m_file->read((char *)data, wantlen); - - if(ret != -1) { - *gotlen = ret; - ret = PTP_RC_OK; - } - - return ret; -} - -int CmaEvent::writeCallback(const unsigned char *data, unsigned long size, unsigned long *written) -{ - int ret = m_file->write((const char *)data, size); - - if(ret != -1) { - *written = ret; - ret = PTP_RC_OK; - } - - return ret; -} diff --git a/src/cmaevent.h b/src/cmaevent.h deleted file mode 100644 index 46bf7c5..0000000 --- a/src/cmaevent.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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 "database.h" -#include "httpdownloader.h" - -#include -#include -#include -#include - -#include - -class CmaEvent : public QObject -{ - Q_OBJECT -public: - explicit CmaEvent(Database *db, vita_device_t *s_device); - void vitaEventCancelTask(vita_event_t *event, int eventId); - -private: - uint16_t processAllObjects(metadata_t &metadata, uint32_t handle); - void vitaEventSendObject(vita_event_t *event, int eventId); - void vitaEventSendObjectMetadata(vita_event_t *event, int eventId); - void vitaEventSendNumOfObject(vita_event_t *event, int eventId); - void vitaEventSendHttpObjectFromURL(vita_event_t *event, int eventId); - void vitaEventUnimplementated(vita_event_t *event, int eventId); - void vitaEventSendObjectStatus(vita_event_t *event, int eventId); - void vitaEventSendObjectThumb(vita_event_t *event, int eventId); - void vitaEventDeleteObject(vita_event_t *event, int eventId); - void vitaEventGetSettingInfo(vita_event_t *event, int eventId); - void vitaEventSendHttpObjectPropFromURL(vita_event_t *event, int eventId); - void vitaEventSendPartOfObject(vita_event_t *event, int eventId); - void vitaEventOperateObject(vita_event_t *event, int eventId); - void vitaEventGetPartOfObject(vita_event_t *event, int eventId); - void vitaEventSendStorageSize(vita_event_t *event, int eventId); - void vitaEventCheckExistance(vita_event_t *event, int eventId); - void vitaEventGetTreatObject(vita_event_t *event, int eventId); - void vitaEventSendCopyConfirmationInfo(vita_event_t *event, int eventId); - void vitaEventSendObjectMetadataItems(vita_event_t *event, int eventId); - void vitaEventSendNPAccountInfo(vita_event_t *event, int eventId); - - static int readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen); - static int writeCallback(const unsigned char *data, unsigned long size, unsigned long *written); - - void processEvent(); - bool isActive(); - void setDevice(vita_device_t *m_device); - - vita_device_t *m_device; - vita_event_t m_event; - - Database *m_db; - - // control variables - bool is_active; - QMutex mutex; - QMutex active; - QSemaphore sema; - - static QFile *m_file; - -signals: - void finishedEventLoop(); - void refreshDatabase(); - void messageSent(QString); - -public slots: - void process(); - void setEvent(vita_event_t event); - void stop(); -}; - -#endif // CMAEVENT_H diff --git a/src/cmaobject.cpp b/src/cmaobject.cpp deleted file mode 100644 index 8aec53f..0000000 --- a/src/cmaobject.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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 "cmaobject.h" -#include "sforeader.h" -#include "avdecoder.h" -#include "database.h" -#include "cmautils.h" - -#include -#include -#include -#include - -int CMAObject::ohfi_count = OHFI_OFFSET; - -CMAObject::CMAObject(CMAObject *obj_parent) : - parent(obj_parent), metadata() -{ -} - -CMAObject::~CMAObject() -{ - free(metadata.name); - free(metadata.path); - - if(MASK_SET(metadata.dataType, SaveData | Folder)) { - free(metadata.data.saveData.title); - free(metadata.data.saveData.detail); - free(metadata.data.saveData.dirName); - free(metadata.data.saveData.savedataTitle); - } else if(MASK_SET(metadata.dataType, Photo | File)) { - free(metadata.data.photo.title); - free(metadata.data.photo.fileName); - delete metadata.data.photo.tracks; - } else if(MASK_SET(metadata.dataType, Music | File)) { - free(metadata.data.music.title); - free(metadata.data.music.fileName); - free(metadata.data.music.album); - free(metadata.data.music.artist); - delete metadata.data.music.tracks; - } else if(MASK_SET(metadata.dataType, Video | File)) { - free(metadata.data.video.title); - free(metadata.data.video.explanation); - free(metadata.data.video.fileName); - free(metadata.data.video.copyright); - delete metadata.data.video.tracks; - } -} - -void CMAObject::loadSfoMetadata(const QString &path) -{ - QString sfo = QDir(path).absoluteFilePath("PARAM.SFO"); - bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); - SfoReader reader; - - if(!skipMetadata && reader.load(sfo)) { - metadata.data.saveData.title = strdup(reader.value("TITLE", "")); - //FIXME: disable savedata detail for now - //QString detail(reader.value("SAVEDATA_DETAIL", "")); - - // libxml follow the spec and normalizes the newlines (and others) but - // the PS Vita chokes on contiguous codes and crashes the CMA app on - // the device. Of course, the "fix" would be that libxml doesn't - // normalize newlines but that is aganist the XML spec that the PS Vita - // doesn't respect >_> - - // convert DOS to UNIX newlines - //detail.replace("\r\n", "\n"); - // separate newlines from quotes - //detail.replace("\n\"", "\n \""); - //detail.replace("\"\n", "\" \n"); - // merge consecutive newlines - //detail.replace("\n\n", "\n"); - //while(detail.endsWith('\n')) { - // detail.chop(1); - //} - //metadata.data.saveData.detail = strdup(detail.toStdString().c_str()); - metadata.data.saveData.detail = strdup(""); - - // remove newlines from savedata title - QString title(reader.value("SAVEDATA_TITLE", "")); - while(title.endsWith('\n')) { - title.chop(1); - } - metadata.data.saveData.savedataTitle = strdup(title.toStdString().c_str()); - metadata.data.saveData.dateTimeUpdated = QFileInfo(sfo).created().toUTC().toTime_t(); - } else { - metadata.data.saveData.title = strdup(metadata.name); - metadata.data.saveData.detail = strdup(""); - metadata.data.saveData.savedataTitle = strdup(""); - metadata.data.saveData.dateTimeUpdated = 0; - } -} - -void CMAObject::initObject(const QFileInfo &file, int obj_file_type) -{ - metadata.name = strdup(file.fileName().toUtf8().data()); - metadata.ohfiParent = parent->metadata.ohfi; - metadata.ohfi = ohfi_count++; - - metadata.type = VITA_DIR_TYPE_MASK_REGULAR; // ignored for files - metadata.dateTimeCreated = file.created().toUTC().toTime_t(); - metadata.size = 0; - DataType type = file.isFile() ? File : Folder; - metadata.dataType = (DataType)(type | (parent->metadata.dataType & ~Folder)); - - // create additional metadata - if(MASK_SET(metadata.dataType, SaveData | Folder)) { - metadata.data.saveData.dirName = strdup(metadata.name); - metadata.data.saveData.statusType = 1; - loadSfoMetadata(file.absoluteFilePath()); - } else if(MASK_SET(metadata.dataType, Music | File)) { - - if(obj_file_type < 0) { - qWarning("Invalid file type for music: %i, setting it to zero", obj_file_type); - obj_file_type = 0; - } - - metadata.data.music.fileName = strdup(metadata.name); - metadata.data.music.fileFormatType = audio_list[obj_file_type].file_format; - metadata.data.music.statusType = 1; - metadata.data.music.numTracks = 1; - metadata.data.music.tracks = new media_track(); - metadata.data.music.tracks->type = VITA_TRACK_TYPE_AUDIO; - metadata.data.music.tracks->data.track_photo.codecType = audio_list[obj_file_type].file_codec; - Database::loadMusicMetadata(file.absoluteFilePath(), metadata); - } else if(MASK_SET(metadata.dataType, Video | File)) { - metadata.data.video.fileName = strdup(metadata.name); - metadata.data.video.dateTimeUpdated = file.created().toUTC().toTime_t(); - metadata.data.video.statusType = 1; - metadata.data.video.fileFormatType = FILE_FORMAT_MP4; - metadata.data.video.parentalLevel = 0; - metadata.data.video.numTracks = 1; - metadata.data.video.tracks = new media_track(); - metadata.data.video.tracks->type = VITA_TRACK_TYPE_VIDEO; - Database::loadVideoMetadata(file.absoluteFilePath(), metadata); - } else if(MASK_SET(metadata.dataType, Photo | File)) { - - if(obj_file_type < 0) { - qWarning("Invalid file type for photos: %i, setting it to zero", obj_file_type); - obj_file_type = 0; - } - - metadata.data.photo.fileName = strdup(metadata.name); - metadata.data.photo.fileFormatType = photo_list[obj_file_type].file_format; - metadata.data.photo.statusType = 1; - metadata.data.photo.dateTimeOriginal = file.created().toUTC().toTime_t(); - metadata.data.photo.numTracks = 1; - metadata.data.photo.tracks = new media_track(); - metadata.data.photo.tracks->type = VITA_TRACK_TYPE_PHOTO; - metadata.data.photo.tracks->data.track_photo.codecType = photo_list[obj_file_type].file_codec; - Database::loadPhotoMetadata(file.absoluteFilePath(), metadata); - } - - m_path = file.absoluteFilePath(); - - if(parent->metadata.path == NULL) { - metadata.path = strdup(metadata.name); - } else { - QString newpath = QString(parent->metadata.path) + "/" + metadata.name; - metadata.path = strdup(newpath.toUtf8().data()); - } - - updateObjectSize(file.size()); -} - -void CMAObject::updateObjectSize(qint64 size) -{ - if(parent) { - parent->updateObjectSize(size); - } - metadata.size += size; -} - -void CMAObject::rename(const QString &newname) -{ - free(metadata.name); - metadata.name = strdup(newname.toUtf8().data()); - - if(metadata.path) { - QStringList metadata_path(QString(metadata.path).split("/")); - metadata_path.replace(metadata_path.count() - 1, newname); - free(metadata.path); - metadata.path = strdup(metadata_path.join("/").toUtf8().data()); - } - - m_path = QFileInfo(m_path).absoluteDir().path() + "/" + newname; -} - -void CMAObject::refreshPath() -{ - if(parent) { - free(metadata.path); - QString newpath(QString(parent->metadata.path) + "/" + metadata.name); - metadata.path = strdup(newpath.toUtf8().data()); - m_path = parent->m_path + "/" + metadata.name; - } -} - -bool CMAObject::hasParent(const CMAObject *obj) -{ - if(parent) { - if(metadata.ohfiParent == obj->metadata.ohfi) { - return true; - } else { - return parent->hasParent(obj); - } - } - return false; -} - -bool CMAObject::operator==(const CMAObject &obj) -{ - return metadata.ohfi == obj.metadata.ohfi; -} - -bool CMAObject::operator!=(const CMAObject &obj) -{ - return metadata.ohfi != obj.metadata.ohfi; -} - -bool CMAObject::operator<(const CMAObject &obj) -{ - return metadata.ohfi < obj.metadata.ohfi; -} diff --git a/src/cmaobject.h b/src/cmaobject.h deleted file mode 100644 index 6a9b53d..0000000 --- a/src/cmaobject.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 CMAOBJECT_H -#define CMAOBJECT_H - -#include -#include - -#include - -#define OHFI_OFFSET 256 - -class CMAObject -{ -public: - explicit CMAObject(CMAObject *parent = 0); - ~CMAObject(); - - void refreshPath(); - void rename(const QString &name); - void updateObjectSize(qint64 size); - bool hasParent(const CMAObject *obj); - void initObject(const QFileInfo &file, int file_type = -1); - - bool operator==(const CMAObject &obj); - bool operator!=(const CMAObject &obj); - bool operator<(const CMAObject &obj); - - inline void setOhfi(int ohfi) { - metadata.ohfi = ohfi; - } - - inline static void resetOhfiCounter() { - ohfi_count = OHFI_OFFSET; - } - - QString m_path; - CMAObject *parent; - metadata_t metadata; - -protected: - static int ohfi_count; - -private: - void loadSfoMetadata(const QString &path); -}; - -#endif // CMAOBJECT_H diff --git a/src/cmarootobject.cpp b/src/cmarootobject.cpp deleted file mode 100644 index 935e926..0000000 --- a/src/cmarootobject.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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 "cmarootobject.h" - -#include - -QString CMARootObject::uuid = "ffffffffffffffff"; - -CMARootObject::CMARootObject(int ohfi) : - num_filters(0), filters(NULL), root_ohfi(ohfi) -{ -} - -void CMARootObject::initObject(const QString &path) -{ - metadata.ohfi = root_ohfi; - metadata.type = VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_REGULAR; - - switch(root_ohfi) { - case VITA_OHFI_MUSIC: - metadata.dataType = Music; - m_path = path; - num_filters = 5; - filters = new metadata_t[5]; - createFilter(&filters[0], "Artists", VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_ARTISTS); - createFilter(&filters[1], "Albums", VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_ALBUMS); - createFilter(&filters[2], "Songs", VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_SONGS); - createFilter(&filters[3], "Genres", VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_GENRES); - createFilter(&filters[4], "Playlists", VITA_DIR_TYPE_MASK_MUSIC | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_PLAYLISTS); - break; - - case VITA_OHFI_PHOTO: - metadata.dataType = Photo; - m_path = path; - num_filters = 3; - filters = new metadata_t[3]; - createFilter(&filters[0], "All", VITA_DIR_TYPE_MASK_PHOTO | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_ALL); - createFilter(&filters[1], "Month", VITA_DIR_TYPE_MASK_PHOTO | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_MONTH); - createFilter(&filters[2], "Folders", VITA_DIR_TYPE_MASK_PHOTO | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_REGULAR); - break; - - case VITA_OHFI_VIDEO: - metadata.dataType = Video; - m_path = path; - num_filters = 2; - filters = new metadata_t[2]; - createFilter(&filters[0], "All", VITA_DIR_TYPE_MASK_VIDEO | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_ALL); - createFilter(&filters[1], "Folders", VITA_DIR_TYPE_MASK_VIDEO | VITA_DIR_TYPE_MASK_ROOT | VITA_DIR_TYPE_MASK_REGULAR); - break; - - case VITA_OHFI_VITAAPP: - metadata.dataType = App; - m_path = QDir(QDir(path).absoluteFilePath("APP")).absoluteFilePath(uuid); - num_filters = 0; - break; - - case VITA_OHFI_PSPAPP: - metadata.dataType = App; - m_path = QDir(QDir(path).absoluteFilePath("PGAME")).absoluteFilePath(uuid); - num_filters = 0; - break; - - case VITA_OHFI_PSPSAVE: - metadata.dataType = SaveData; - m_path = QDir(QDir(path).absoluteFilePath("PSAVEDATA")).absoluteFilePath(uuid); - num_filters = 0; - break; - - case VITA_OHFI_PSXAPP: - metadata.dataType = App; - m_path = QDir(QDir(path).absoluteFilePath("PSGAME")).absoluteFilePath(uuid); - num_filters = 0; - break; - - case VITA_OHFI_PSMAPP: - metadata.dataType = App; - m_path = QDir(QDir(path).absoluteFilePath("PSM")).absoluteFilePath(uuid); - num_filters = 0; - break; - - case VITA_OHFI_BACKUP: - metadata.dataType = App; - m_path = QDir(QDir(path).absoluteFilePath("SYSTEM")).absoluteFilePath(uuid); - num_filters = 0; - break; - - case VITA_OHFI_PACKAGE: - metadata.dataType = Package; - m_path = path; - num_filters = 0; - } - - // create the backup directories - QDir dir(m_path); - dir.mkpath(dir.absolutePath()); -} - -CMARootObject::~CMARootObject() -{ - for(int i = 0; i < num_filters; i++) { - free(filters[i].name); - free(filters[i].path); - } - - delete[] filters; -} - -void CMARootObject::createFilter(metadata_t *filter, const char *name, int type) -{ - filter->ohfiParent = metadata.ohfi; - filter->ohfi = ohfi_count++; - filter->name = strdup(name); - filter->path = strdup(metadata.path ? metadata.path : ""); - filter->type = type; - filter->dateTimeCreated = 0; - filter->size = 0; - filter->dataType = static_cast(Folder | Special); - filter->next_metadata = NULL; - //qDebug("Added filter %s to database with OHFI %d (%s)", name, filter->ohfi, metadata.name); -} - -int CMARootObject::getFilters(metadata_t **p_head) -{ - int numObjects = num_filters; - - for(int i = 0; i < numObjects; i++) { - filters[i].next_metadata = &filters[i + 1]; - } - - filters[numObjects - 1].next_metadata = NULL; - - if(p_head != NULL) { - *p_head = filters; - } - - return numObjects; -} diff --git a/src/cmarootobject.h b/src/cmarootobject.h deleted file mode 100644 index 51ae8df..0000000 --- a/src/cmarootobject.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 CMAROOTOBJECT_H -#define CMAROOTOBJECT_H - -#include "cmaobject.h" - -#include - -#include - -class CMARootObject : public CMAObject -{ -public: - explicit CMARootObject(int ohfi); - ~CMARootObject(); - - void initObject(const QString &path); - void remove(const CMAObject *obj); - int getFilters(metadata_t **p_head); - - int num_filters; - metadata_t *filters; - static QString uuid; - -private: - void createFilter(metadata_t *filter, const char *name, int type); - - int root_ohfi; -}; - -#endif // CMAROOTOBJECT_H diff --git a/src/cmautils.cpp b/src/cmautils.cpp deleted file mode 100644 index e080746..0000000 --- a/src/cmautils.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - * 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 "cmautils.h" -#include "avdecoder.h" - -#include -#include -#include -#include -#include - -#ifdef Q_OS_WIN32 -#include -#elif defined Q_OS_ANDROID -#include -#define statvfs statfs -#else -#include -#endif - -#ifdef Q_OS_LINUX -#include -#include -#include -#include -#endif - -bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total) -{ -#ifdef Q_OS_WIN32 - - if(GetDiskFreeSpaceEx(dir.toStdWString().c_str(), (ULARGE_INTEGER *)free, (ULARGE_INTEGER *)total, NULL) != 0) { - return true; - } - -#else - struct statvfs stat; - - if(statvfs(dir.toUtf8().data(), &stat) == 0) { - *total = stat.f_frsize * stat.f_blocks; - *free = stat.f_frsize * stat.f_bfree; - return true; - } - -#endif - return false; -} - -bool removeRecursively(const QString &path) -{ - QFileInfo file_info(path); - - if(file_info.isDir()) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - return QDir(path).removeRecursively(); -#else - bool result = false; - QDir dir(path); - - QDir::Filters filter = QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files; - - if(dir.exists(path)) { - foreach(QFileInfo info, dir.entryInfoList(filter, QDir::DirsFirst)) { - if(info.isDir()) { - result = removeRecursively(info.absoluteFilePath()); - } else { - result = QFile::remove(info.absoluteFilePath()); - } - - if(!result) { - return result; - } - } - result = dir.rmdir(path); - } - - return result; -#endif - } else { - return QFile::remove(path); - } -} - -static QByteArray findFolderAlbumArt(const QString path, metadata_t *metadata) -{ - QByteArray data; - QDir folder(path); - - QStringList files = folder.entryList(QDir::Files | QDir::Readable); - const QStringList cover_list = QStringList() << "album" << "cover" << "front"; - const QStringList ext_list = QStringList() << "jpg" << "jpeg" << "png" << "gif"; - - foreach(const QString &file, files) { - foreach(const QString &cover, cover_list) { - foreach(const QString &ext, ext_list) { - if(file.compare(QString("%1.%2").arg(cover, ext), Qt::CaseInsensitive) == 0) { - qDebug() << "Trying to load album art from" << folder.absoluteFilePath(file); - QImage img; - if(img.load(folder.absoluteFilePath(file))) { - QBuffer buffer(&data); - buffer.open(QIODevice::WriteOnly); - QImage result = img.scaled(256, 250, Qt::KeepAspectRatio, Qt::SmoothTransformation); - result.save(&buffer, "JPEG"); - metadata->data.thumbnail.width = result.width(); - metadata->data.thumbnail.height = result.height(); - } - // only try with the first match - break; - } - } - } - } - return data; -} - -QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata) -{ - QByteArray data; - - if(MASK_SET(type, SaveData)) { - QFile file(QDir(path).absoluteFilePath("ICON0.PNG")); - - if(file.open(QIODevice::ReadOnly)) { - data = file.readAll(); - } - } else if(MASK_SET(type, Photo)) { - QImage img; - - if(img.load(path)) { - QBuffer buffer(&data); - buffer.open(QIODevice::WriteOnly); - QImage result = img.scaled(240, 136, Qt::KeepAspectRatio, Qt::FastTransformation); - result.save(&buffer, "JPEG"); - metadata->data.thumbnail.width = result.width(); - metadata->data.thumbnail.height = result.height(); - } - } else if(MASK_SET(type, Music)) { - if(MASK_SET(type, Folder)) { - // TODO: try to load an album cover from one of the audio files. - data = findFolderAlbumArt(path, metadata); - } else { - AVDecoder decoder; - - if(decoder.open(path)) { - data = decoder.getAudioThumbnail(256, 256); - metadata->data.thumbnail.width = 256; - metadata->data.thumbnail.height = 256; - } - } - } else if(MASK_SET(type, Video)) { - AVDecoder decoder; - if(decoder.open(path)) { - data = decoder.getVideoThumbnail(256, 256); - metadata->data.thumbnail.width = 256; - metadata->data.thumbnail.height = 256; - } - } - return data; -} - -QString readable_size(qint64 size, bool use_gib) -{ - QStringList list; - list << "KiB" << "MiB"; - if(use_gib) { - list << "GiB"; - } - - QStringListIterator i(list); - QString unit("bytes"); - - float size_f = size; - - while(size_f >= 1024.0 && i.hasNext()) { - unit = i.next(); - size_f /= 1024.0; - } - return QString().setNum(size_f,'f',2) + " " + unit; -} - -int getVitaProtocolVersion() -{ - QString protocol_mode = QSettings().value("protocolMode", "automatic").toString(); - qDebug() << "Using protocol mode: " << protocol_mode; - - int protocol; - - if(protocol_mode == "manual") - { - int index = QSettings().value("protocolIndex").toInt(); - - switch(index) - { - case 0: - protocol = VITAMTP_PROTOCOL_FW_3_30; - break; - case 1: - protocol = VITAMTP_PROTOCOL_FW_3_10; - break; - case 2: - protocol = VITAMTP_PROTOCOL_FW_3_00; - break; - case 3: - protocol = VITAMTP_PROTOCOL_FW_2_60; - break; - case 4: - protocol = VITAMTP_PROTOCOL_FW_2_10; - break; - case 5: - protocol = VITAMTP_PROTOCOL_FW_2_00; - break; - case 6: - protocol = VITAMTP_PROTOCOL_FW_1_80; - break; - case 7: - protocol = VITAMTP_PROTOCOL_FW_1_60; - break; - case 8: - protocol = VITAMTP_PROTOCOL_FW_1_50; - break; - case 9: - protocol = VITAMTP_PROTOCOL_FW_1_00; - break; - default: - protocol = VITAMTP_PROTOCOL_MAX_VERSION; - break; - } - } - else if(protocol_mode == "custom") - { - bool ok; - protocol = QSettings().value("protocolVersion").toInt(&ok); - - if(!ok || protocol <= 0) - protocol = VITAMTP_PROTOCOL_MAX_VERSION; - } - else - protocol = VITAMTP_PROTOCOL_MAX_VERSION; - - return protocol; -} - -#ifdef Q_OS_LINUX -bool belongsToGroup(const char *groupname) -{ - int size_max = sysconf(_SC_GETGR_R_SIZE_MAX); - - if(size_max == -1) - size_max = 1024; - - QByteArray buf(size_max, Qt::Uninitialized); - - group *result = NULL; - group entry; - - getgrnam_r(groupname, &entry, buf.data(), buf.size(), &result); - - if(result != NULL && *result->gr_mem != NULL) { - char **user_list = result->gr_mem; - - int user_size_max = sysconf(_SC_GETPW_R_SIZE_MAX); - - if(user_size_max == -1) - user_size_max = 1024; - - std::vector user_buf(user_size_max); - - uid_t user_id = getuid(); - - while(*user_list != NULL) { - char *user_name = *user_list; - - passwd *pw = NULL; - passwd entry; - - getpwnam_r(user_name, &entry, user_buf.data(), user_buf.size(), &pw); - - if(pw != NULL && pw->pw_uid == user_id) { - return true; - } - - user_list++; - } - } - - return false; -} -#endif diff --git a/src/cmautils.h b/src/cmautils.h deleted file mode 100644 index d89ac00..0000000 --- a/src/cmautils.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 UTILS_H -#define UTILS_H - -#include -#include -#include - -#include - -// Qt4 doesn't have public methods for Thread::*sleep -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -typedef QThread Sleeper; -#else -class Sleeper : QThread -{ -public: - static void sleep(unsigned long secs) { - QThread::sleep(secs); - } - static void msleep(unsigned long msecs) { - QThread::msleep(msecs); - } - static void usleep(unsigned long usecs) { - QThread::usleep(usecs); - } -}; -#endif - -bool removeRecursively(const QString &path); -QString readable_size(qint64 size, bool use_gib = false); -bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total); -QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata); -int getVitaProtocolVersion(); - -#ifdef Q_OS_LINUX -bool belongsToGroup(const char *groupname); -#endif - - -#endif // UTILS_H diff --git a/src/database.cpp b/src/database.cpp deleted file mode 100644 index 896ee88..0000000 --- a/src/database.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 "database.h" -#include "avdecoder.h" - -#include -#include -#include -#include -#include - -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 *obj_parent) : - QObject(obj_parent), - mutex(QMutex::Recursive) -{ -} - -void Database::process() -{ - qDebug("Starting database_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId()); - clear(); - cancel_operation = false; - int count = create(); - cancel_operation = false; - QTextStream(stdout) << "Total entries added to the database: " << count << endl; - if(count < 0) { - clear(); - } - 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::checkFileType(const QString path, int ohfi_root) -{ - switch(ohfi_root) { - case VITA_OHFI_MUSIC: - for(int i = 0, max = sizeof(audio_list) / sizeof(file_type); i < max; i++) { - if(path.endsWith(audio_list[i].file_ext, Qt::CaseInsensitive)) { - return i; - } - } - break; - case VITA_OHFI_PHOTO: - for(int i = 0, max = sizeof(photo_list) / sizeof(file_type); i< max; i++) { - if(path.endsWith(photo_list[i].file_ext, Qt::CaseInsensitive)) { - return i; - } - } - break; - case VITA_OHFI_VIDEO: - for(int i = 0, max = sizeof(video_list) / sizeof(file_type); i< max; i++) { - if(path.endsWith(video_list[i].file_ext, Qt::CaseInsensitive)) { - return i; - } - } - break; - default: - return 0; - } - return -1; -} - -void Database::loadMusicMetadata(const QString &path, metadata_t &metadata) -{ - AVDecoder decoder; - bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); - - if(!skipMetadata && decoder.open(path)) { - decoder.getAudioMetadata(metadata); - } else { - metadata.data.music.album = strdup(""); - metadata.data.music.artist = strdup(""); - metadata.data.music.title = strdup(metadata.name); - } -} - -void Database::loadVideoMetadata(const QString &path, metadata_t &metadata) -{ - AVDecoder decoder; - bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); - - if(!skipMetadata && decoder.open(path)) { - decoder.getVideoMetadata(metadata); - } else { - metadata.data.video.title = strdup(metadata.name); - metadata.data.video.explanation = strdup(""); - metadata.data.video.copyright = strdup(""); - // default to H264 video codec - metadata.data.video.tracks->data.track_video.codecType = CODEC_TYPE_AVC; - } -} - -void Database::loadPhotoMetadata(const QString &path, metadata_t &metadata) -{ - QImage img; - bool skipMetadata = QSettings().value("skipMetadata", false).toBool(); - - if(!skipMetadata && img.load(path)) { - metadata.data.photo.tracks->data.track_photo.width = img.width(); - metadata.data.photo.tracks->data.track_photo.height = img.height(); - } - metadata.data.photo.title = strdup(metadata.name); -} diff --git a/src/database.h b/src/database.h deleted file mode 100644 index 35ca211..0000000 --- a/src/database.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 DATABASE_H -#define DATABASE_H - -#include -#include - -#include - -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 -{ - Q_OBJECT -public: - explicit Database(QObject *parent = 0); - - virtual bool load() = 0; - virtual bool rescan() = 0; - virtual void setUUID(const QString &uuid) = 0; - - virtual int childObjectCount(int parent_ohfi) = 0; - virtual bool deleteEntry(int ohfi, int root_ohfi = 0) = 0; - virtual QString getAbsolutePath(int ohfi) = 0; - virtual QString getRelativePath(int ohfi) = 0; - virtual bool getObjectList(int ohfi, metadata_t **metadata) = 0; - virtual bool getObjectMetadata(int ohfi, metadata_t &metadata) = 0; - virtual int getObjectMetadatas(int parent_ohfi, metadata_t **metadata, int index = 0, int max_number = 0) = 0; - virtual qint64 getObjectSize(int ohfi) = 0; - virtual int getPathId(const char *name, int ohfi) = 0; - virtual int insertObjectEntry(const QString &path, const QString &name, int parent_ohfi) = 0; - 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 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; - -protected: - bool continueOperation(); - -private: - - virtual void clear() = 0; - virtual int create() = 0; - - // control variables - QMutex cancel; - bool cancel_operation; - -signals: - void fileAdded(QString); - void directoryAdded(QString); - void updated(int); - -protected slots: - void process(); - -public slots: - void cancelOperation(); -}; - -#endif // DATABASE_H diff --git a/src/dds.cpp b/src/dds.cpp deleted file mode 100644 index b0900e1..0000000 --- a/src/dds.cpp +++ /dev/null @@ -1,1032 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2003 Ignacio Castaño - - This program is free software; you can redistribute it and/or - modify it under the terms of the Lesser GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - Almost all this code is based on nVidia's DDS-loading example - and the DevIl's source code by Denton Woods. - - Modified by codestation for inclusion in QCMA -*/ - -/* this code supports: - * reading: - * rgb and dxt dds files - * cubemap dds files - * volume dds files -- TODO - * writing: - * rgb dds files only -- TODO - */ - -#include "dds.h" - -#include -#include -#include -#include -#include - -#include // sqrtf - -#ifndef __USE_ISOC99 -#define sqrtf(x) ((float)sqrt(x)) -#endif - -typedef quint32 uint; -typedef quint16 ushort; -typedef quint8 uchar; - -#if !defined(MAKEFOURCC) -# define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - (uint(uchar(ch0)) | (uint(uchar(ch1)) << 8) | \ - (uint(uchar(ch2)) << 16) | (uint(uchar(ch3)) << 24 )) -#endif - -#define HORIZONTAL 1 -#define VERTICAL 2 -#define CUBE_LAYOUT HORIZONTAL - -struct Color8888 { - uchar r, g, b, a; -}; - -union Color565 { - struct { - ushort b : 5; - ushort g : 6; - ushort r : 5; - } c; - ushort u; -}; - -union Color1555 { - struct { - ushort b : 5; - ushort g : 5; - ushort r : 5; - ushort a : 1; - } c; - ushort u; -}; - -union Color4444 { - struct { - ushort b : 4; - ushort g : 4; - ushort r : 4; - ushort a : 4; - } c; - ushort u; -}; - - -static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' '); -static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'); -static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'); -static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'); -static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'); -static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'); -static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B'); -static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2'); - -static const uint DDSD_CAPS = 0x00000001l; -static const uint DDSD_PIXELFORMAT = 0x00001000l; -static const uint DDSD_WIDTH = 0x00000004l; -static const uint DDSD_HEIGHT = 0x00000002l; -static const uint DDSD_PITCH = 0x00000008l; - -static const uint DDSCAPS_TEXTURE = 0x00001000l; -static const uint DDSCAPS2_VOLUME = 0x00200000l; -static const uint DDSCAPS2_CUBEMAP = 0x00000200l; - -static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400l; -static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800l; -static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000l; -static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000l; -static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000l; -static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000l; - -static const uint DDPF_RGB = 0x00000040l; -static const uint DDPF_FOURCC = 0x00000004l; -static const uint DDPF_ALPHAPIXELS = 0x00000001l; - -enum DDSType { - DDS_A8R8G8B8 = 0, - DDS_A1R5G5B5 = 1, - DDS_A4R4G4B4 = 2, - DDS_R8G8B8 = 3, - DDS_R5G6B5 = 4, - DDS_DXT1 = 5, - DDS_DXT2 = 6, - DDS_DXT3 = 7, - DDS_DXT4 = 8, - DDS_DXT5 = 9, - DDS_RXGB = 10, - DDS_ATI2 = 11, - DDS_UNKNOWN -}; - - -struct DDSPixelFormat { - uint size; - uint flags; - uint fourcc; - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; -}; - -static QDataStream & operator>> ( QDataStream & s, DDSPixelFormat & pf ) -{ - s >> pf.size; - s >> pf.flags; - s >> pf.fourcc; - s >> pf.bitcount; - s >> pf.rmask; - s >> pf.gmask; - s >> pf.bmask; - s >> pf.amask; - return s; -} - -struct DDSCaps { - uint caps1; - uint caps2; - uint caps3; - uint caps4; -}; - -static QDataStream & operator>> ( QDataStream & s, DDSCaps & caps ) -{ - s >> caps.caps1; - s >> caps.caps2; - s >> caps.caps3; - s >> caps.caps4; - return s; -} - -struct DDSHeader { - uint size; - uint flags; - uint height; - uint width; - uint pitch; - uint depth; - uint mipmapcount; - uint reserved[11]; - DDSPixelFormat pf; - DDSCaps caps; - uint notused; -}; - -static QDataStream & operator>> ( QDataStream & s, DDSHeader & header ) -{ - s >> header.size; - s >> header.flags; - s >> header.height; - s >> header.width; - s >> header.pitch; - s >> header.depth; - s >> header.mipmapcount; - for( int i = 0; i < 11; i++ ) { - s >> header.reserved[i]; - } - s >> header.pf; - s >> header.caps; - s >> header.notused; - return s; -} - -static bool IsValid( const DDSHeader & header ) -{ - if( header.size != 124 ) { - return false; - } - const uint required = (DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT); - if( (header.flags & required) != required ) { - return false; - } - if( header.pf.size != 32 ) { - return false; - } - if( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) { - return false; - } - return true; -} - - -// Get supported type. We currently support 10 different types. -static DDSType GetType( const DDSHeader & header ) -{ - if( header.pf.flags & DDPF_RGB ) { - if( header.pf.flags & DDPF_ALPHAPIXELS ) { - switch( header.pf.bitcount ) { - case 16: - return (header.pf.amask == 0x8000) ? DDS_A1R5G5B5 : DDS_A4R4G4B4; - case 32: - return DDS_A8R8G8B8; - } - } else { - switch( header.pf.bitcount ) { - case 16: - return DDS_R5G6B5; - case 24: - return DDS_R8G8B8; - } - } - } else if( header.pf.flags & DDPF_FOURCC ) { - switch( header.pf.fourcc ) { - case FOURCC_DXT1: - return DDS_DXT1; - case FOURCC_DXT2: - return DDS_DXT2; - case FOURCC_DXT3: - return DDS_DXT3; - case FOURCC_DXT4: - return DDS_DXT4; - case FOURCC_DXT5: - return DDS_DXT5; - case FOURCC_RXGB: - return DDS_RXGB; - case FOURCC_ATI2: - return DDS_ATI2; - } - } - return DDS_UNKNOWN; -} - -static bool HasAlpha( const DDSHeader & header ) -{ - return header.pf.flags & DDPF_ALPHAPIXELS; -} - -static bool IsCubeMap( const DDSHeader & header ) -{ - return header.caps.caps2 & DDSCAPS2_CUBEMAP; -} - -static bool IsSupported( const DDSHeader & header ) -{ - if( header.caps.caps2 & DDSCAPS2_VOLUME ) { - return false; - } - if( GetType(header) == DDS_UNKNOWN ) { - return false; - } - return true; -} - -static bool LoadA8R8G8B8( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - for( uint y = 0; y < h; y++ ) { - QRgb * scanline = (QRgb *) img.scanLine( y ); - for( uint x = 0; x < w; x++ ) { - uchar r, g, b, a; - s >> b >> g >> r >> a; - scanline[x] = qRgba(r, g, b, a); - } - } - - return true; -} - -static bool LoadR8G8B8( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - for( uint y = 0; y < h; y++ ) { - QRgb * scanline = (QRgb *) img.scanLine( y ); - for( uint x = 0; x < w; x++ ) { - uchar r, g, b; - s >> b >> g >> r; - scanline[x] = qRgb(r, g, b); - } - } - - return true; -} - -static bool LoadA1R5G5B5( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - for( uint y = 0; y < h; y++ ) { - QRgb * scanline = (QRgb *) img.scanLine( y ); - for( uint x = 0; x < w; x++ ) { - Color1555 color; - s >> color.u; - uchar a = (color.c.a != 0) ? 0xFF : 0; - uchar r = (color.c.r << 3) | (color.c.r >> 2); - uchar g = (color.c.g << 3) | (color.c.g >> 2); - uchar b = (color.c.b << 3) | (color.c.b >> 2); - scanline[x] = qRgba(r, g, b, a); - } - } - - return true; -} - -static bool LoadA4R4G4B4( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - for( uint y = 0; y < h; y++ ) { - QRgb * scanline = (QRgb *) img.scanLine( y ); - for( uint x = 0; x < w; x++ ) { - Color4444 color; - s >> color.u; - uchar a = (color.c.a << 4) | color.c.a; - uchar r = (color.c.r << 4) | color.c.r; - uchar g = (color.c.g << 4) | color.c.g; - uchar b = (color.c.b << 4) | color.c.b; - scanline[x] = qRgba(r, g, b, a); - } - } - - return true; -} - -static bool LoadR5G6B5( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - for( uint y = 0; y < h; y++ ) { - QRgb * scanline = (QRgb *) img.scanLine( y ); - for( uint x = 0; x < w; x++ ) { - Color565 color; - s >> color.u; - uchar r = (color.c.r << 3) | (color.c.r >> 2); - uchar g = (color.c.g << 2) | (color.c.g >> 4); - uchar b = (color.c.b << 3) | (color.c.b >> 2); - scanline[x] = qRgb(r, g, b); - } - } - - return true; -} - -static QDataStream & operator>> ( QDataStream & s, Color565 & c ) -{ - return s >> c.u; -} - - -struct BlockDXT { - Color565 col0; - Color565 col1; - uchar row[4]; - - void GetColors( Color8888 color_array[4] ) { - color_array[0].r = (col0.c.r << 3) | (col0.c.r >> 2); - color_array[0].g = (col0.c.g << 2) | (col0.c.g >> 4); - color_array[0].b = (col0.c.b << 3) | (col0.c.b >> 2); - color_array[0].a = 0xFF; - - color_array[1].r = (col1.c.r << 3) | (col1.c.r >> 2); - color_array[1].g = (col1.c.g << 2) | (col1.c.g >> 4); - color_array[1].b = (col1.c.b << 3) | (col1.c.b >> 2); - color_array[1].a = 0xFF; - - if( col0.u > col1.u ) { - // Four-color block: derive the other two colors. - color_array[2].r = (2 * color_array[0].r + color_array[1].r) / 3; - color_array[2].g = (2 * color_array[0].g + color_array[1].g) / 3; - color_array[2].b = (2 * color_array[0].b + color_array[1].b) / 3; - color_array[2].a = 0xFF; - - color_array[3].r = (2 * color_array[1].r + color_array[0].r) / 3; - color_array[3].g = (2 * color_array[1].g + color_array[0].g) / 3; - color_array[3].b = (2 * color_array[1].b + color_array[0].b) / 3; - color_array[3].a = 0xFF; - } else { - // Three-color block: derive the other color. - color_array[2].r = (color_array[0].r + color_array[1].r) / 2; - color_array[2].g = (color_array[0].g + color_array[1].g) / 2; - color_array[2].b = (color_array[0].b + color_array[1].b) / 2; - color_array[2].a = 0xFF; - - // Set all components to 0 to match DXT specs. - color_array[3].r = 0x00; // color_array[2].r; - color_array[3].g = 0x00; // color_array[2].g; - color_array[3].b = 0x00; // color_array[2].b; - color_array[3].a = 0x00; - } - } -}; - - -static QDataStream & operator>> ( QDataStream & s, BlockDXT & c ) -{ - return s >> c.col0 >> c.col1 >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3]; -} - -struct BlockDXTAlphaExplicit { - ushort row[4]; -}; - -static QDataStream & operator>> ( QDataStream & s, BlockDXTAlphaExplicit & c ) -{ - return s >> c.row[0] >> c.row[1] >> c.row[2] >> c.row[3]; -} - -struct BlockDXTAlphaLinear { - uchar alpha0; - uchar alpha1; - uchar bits[6]; - - void GetAlphas( uchar alpha_array[8] ) { - alpha_array[0] = alpha0; - alpha_array[1] = alpha1; - - // 8-alpha or 6-alpha block? - if( alpha_array[0] > alpha_array[1] ) { - // 8-alpha block: derive the other 6 alphas. - // 000 = alpha_0, 001 = alpha_1, others are interpolated - - alpha_array[2] = ( 6 * alpha0 + alpha1) / 7; // bit code 010 - alpha_array[3] = ( 5 * alpha0 + 2 * alpha1) / 7; // Bit code 011 - alpha_array[4] = ( 4 * alpha0 + 3 * alpha1) / 7; // Bit code 100 - alpha_array[5] = ( 3 * alpha0 + 4 * alpha1) / 7; // Bit code 101 - alpha_array[6] = ( 2 * alpha0 + 5 * alpha1) / 7; // Bit code 110 - alpha_array[7] = ( alpha0 + 6 * alpha1) / 7; // Bit code 111 - } else { - // 6-alpha block: derive the other alphas. - // 000 = alpha_0, 001 = alpha_1, others are interpolated - - alpha_array[2] = (4 * alpha0 + alpha1) / 5; // Bit code 010 - alpha_array[3] = (3 * alpha0 + 2 * alpha1) / 5; // Bit code 011 - alpha_array[4] = (2 * alpha0 + 3 * alpha1) / 5; // Bit code 100 - alpha_array[5] = ( alpha0 + 4 * alpha1) / 5; // Bit code 101 - alpha_array[6] = 0x00; // Bit code 110 - alpha_array[7] = 0xFF; // Bit code 111 - } - } - - void GetBits( uchar bit_array[16] ) { - // Split 24 packed bits into 8 bytes, 3 bits at a time. - uint b = bits[0] | bits[1] << 8 | bits[2] << 16; - bit_array[0] = uchar(b & 0x07); - b >>= 3; - bit_array[1] = uchar(b & 0x07); - b >>= 3; - bit_array[2] = uchar(b & 0x07); - b >>= 3; - bit_array[3] = uchar(b & 0x07); - b >>= 3; - bit_array[4] = uchar(b & 0x07); - b >>= 3; - bit_array[5] = uchar(b & 0x07); - b >>= 3; - bit_array[6] = uchar(b & 0x07); - b >>= 3; - bit_array[7] = uchar(b & 0x07); - - b = bits[3] | bits[4] << 8 | bits[5] << 16; - bit_array[8] = uchar(b & 0x07); - b >>= 3; - bit_array[9] = uchar(b & 0x07); - b >>= 3; - bit_array[10] = uchar(b & 0x07); - b >>= 3; - bit_array[11] = uchar(b & 0x07); - b >>= 3; - bit_array[12] = uchar(b & 0x07); - b >>= 3; - bit_array[13] = uchar(b & 0x07); - b >>= 3; - bit_array[14] = uchar(b & 0x07); - b >>= 3; - bit_array[15] = uchar(b & 0x07); - } -}; - -static QDataStream & operator>> ( QDataStream & s, BlockDXTAlphaLinear & c ) -{ - s >> c.alpha0 >> c.alpha1; - return s >> c.bits[0] >> c.bits[1] >> c.bits[2] >> c.bits[3] >> c.bits[4] >> c.bits[5]; -} - -static bool LoadDXT1( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - QRgb * scanline[4]; - - for( uint y = 0; y < h; y += 4 ) { - for( uint j = 0; j < 4; j++ ) { - scanline[j] = (QRgb *) img.scanLine( y + j ); - } - for( uint x = 0; x < w; x += 4 ) { - - // Read 64bit color block. - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for( uint j = 0; j < 4; j++ ) { - for( uint i = 0; i < 4; i++ ) { - if( img.valid( x+i, y+j ) ) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - scanline[j][x+i] = qRgba(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a); - } - } - } - } - } - return true; -} - -static bool LoadDXT3( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - BlockDXTAlphaExplicit alpha; - QRgb * scanline[4]; - - for( uint y = 0; y < h; y += 4 ) { - for( uint j = 0; j < 4; j++ ) { - scanline[j] = (QRgb *) img.scanLine( y + j ); - } - for( uint x = 0; x < w; x += 4 ) { - - // Read 128bit color block. - s >> alpha; - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for( uint j = 0; j < 4; j++ ) { - ushort a = alpha.row[j]; - for( uint i = 0; i < 4; i++ ) { - if( img.valid( x+i, y+j ) ) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - color_array[idx].a = a & 0x0f; - color_array[idx].a = color_array[idx].a | (color_array[idx].a << 4); - scanline[j][x+i] = qRgba(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a); - } - a >>= 4; - } - } - } - } - return true; -} - -static bool LoadDXT2( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - if( !LoadDXT3(s, header, img) ) { - return false; - } - //UndoPremultiplyAlpha(img); - return true; -} - -static bool LoadDXT5( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - BlockDXTAlphaLinear alpha; - QRgb * scanline[4]; - - for( uint y = 0; y < h; y += 4 ) { - for( uint j = 0; j < 4; j++ ) { - scanline[j] = (QRgb *) img.scanLine( y + j ); - } - for( uint x = 0; x < w; x += 4 ) { - - // Read 128bit color block. - s >> alpha; - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - uchar alpha_array[8]; - alpha.GetAlphas(alpha_array); - - uchar bit_array[16]; - alpha.GetBits(bit_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for( uint j = 0; j < 4; j++ ) { - for( uint i = 0; i < 4; i++ ) { - if( img.valid( x+i, y+j ) ) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - color_array[idx].a = alpha_array[bit_array[j*4+i]]; - scanline[j][x+i] = qRgba(color_array[idx].r, color_array[idx].g, color_array[idx].b, color_array[idx].a); - } - } - } - } - } - - return true; -} -static bool LoadDXT4( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - if( !LoadDXT5(s, header, img) ) { - return false; - } - //UndoPremultiplyAlpha(img); - return true; -} - -static bool LoadRXGB( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXT block; - BlockDXTAlphaLinear alpha; - QRgb * scanline[4]; - - for( uint y = 0; y < h; y += 4 ) { - for( uint j = 0; j < 4; j++ ) { - scanline[j] = (QRgb *) img.scanLine( y + j ); - } - for( uint x = 0; x < w; x += 4 ) { - - // Read 128bit color block. - s >> alpha; - s >> block; - - // Decode color block. - Color8888 color_array[4]; - block.GetColors(color_array); - - uchar alpha_array[8]; - alpha.GetAlphas(alpha_array); - - uchar bit_array[16]; - alpha.GetBits(bit_array); - - // bit masks = 00000011, 00001100, 00110000, 11000000 - const uint masks[4] = { 3, 3<<2, 3<<4, 3<<6 }; - const int shift[4] = { 0, 2, 4, 6 }; - - // Write color block. - for( uint j = 0; j < 4; j++ ) { - for( uint i = 0; i < 4; i++ ) { - if( img.valid( x+i, y+j ) ) { - uint idx = (block.row[j] & masks[i]) >> shift[i]; - color_array[idx].a = alpha_array[bit_array[j*4+i]]; - scanline[j][x+i] = qRgb(color_array[idx].a, color_array[idx].g, color_array[idx].b); - } - } - } - } - } - - return true; -} - -static bool LoadATI2( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - const uint w = header.width; - const uint h = header.height; - - BlockDXTAlphaLinear xblock; - BlockDXTAlphaLinear yblock; - QRgb * scanline[4]; - - for( uint y = 0; y < h; y += 4 ) { - for( uint j = 0; j < 4; j++ ) { - scanline[j] = (QRgb *) img.scanLine( y + j ); - } - for( uint x = 0; x < w; x += 4 ) { - - // Read 128bit color block. - s >> xblock; - s >> yblock; - - // Decode color block. - uchar xblock_array[8]; - xblock.GetAlphas(xblock_array); - - uchar xbit_array[16]; - xblock.GetBits(xbit_array); - - uchar yblock_array[8]; - yblock.GetAlphas(yblock_array); - - uchar ybit_array[16]; - yblock.GetBits(ybit_array); - - // Write color block. - for( uint j = 0; j < 4; j++ ) { - for( uint i = 0; i < 4; i++ ) { - if( img.valid( x+i, y+j ) ) { - const uchar nx = xblock_array[xbit_array[j*4+i]]; - const uchar ny = yblock_array[ybit_array[j*4+i]]; - - const float fx = float(nx) / 127.5f - 1.0f; - const float fy = float(ny) / 127.5f - 1.0f; - const float fz = sqrtf(1.0f - fx*fx - fy*fy); - const uchar nz = uchar((fz + 1.0f) * 127.5f); - - scanline[j][x+i] = qRgb(nx, ny, nz); - } - } - } - } - } - - return true; -} - - - -typedef bool (* TextureLoader)( QDataStream & s, const DDSHeader & header, QImage & img ); - -// Get an appropriate texture loader for the given type. -static TextureLoader GetTextureLoader( DDSType type ) -{ - switch( type ) { - case DDS_A8R8G8B8: - return LoadA8R8G8B8; - case DDS_A1R5G5B5: - return LoadA1R5G5B5; - case DDS_A4R4G4B4: - return LoadA4R4G4B4; - case DDS_R8G8B8: - return LoadR8G8B8; - case DDS_R5G6B5: - return LoadR5G6B5; - case DDS_DXT1: - return LoadDXT1; - case DDS_DXT2: - return LoadDXT2; - case DDS_DXT3: - return LoadDXT3; - case DDS_DXT4: - return LoadDXT4; - case DDS_DXT5: - return LoadDXT5; - case DDS_RXGB: - return LoadRXGB; - case DDS_ATI2: - return LoadATI2; - default: - return NULL; - }; -} - - -// Load a 2d texture. -static bool LoadTexture( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - // Create dst image. - img = QImage( header.width, header.height, QImage::Format_RGB32 ); - - // Read image. - DDSType type = GetType( header ); - - // Enable alpha buffer for transparent or DDS images. - if( HasAlpha( header ) || type >= DDS_DXT1 ) { - img = img.convertToFormat( QImage::Format_ARGB32 ); - } - - TextureLoader loader = GetTextureLoader( type ); - if( loader == NULL ) { - return false; - } - - return loader( s, header, img ); -} - - -static int FaceOffset( const DDSHeader & header ) -{ - - DDSType type = GetType( header ); - - int mipmap = qMax(header.mipmapcount, 1U); - int size = 0; - int w = header.width; - int h = header.height; - - if( type >= DDS_DXT1 ) { - int multiplier = (type == DDS_DXT1) ? 8 : 16; - do { - int face_size = qMax(w/4,1) * qMax(h/4,1) * multiplier; - size += face_size; - w >>= 1; - h >>= 1; - } while( --mipmap ); - } else { - int multiplier = header.pf.bitcount / 8; - do { - int face_size = w * h * multiplier; - size += face_size; - w = qMax( w>>1, 1 ); - h = qMax( h>>1, 1 ); - } while( --mipmap ); - } - - return size; -} - -#if CUBE_LAYOUT == HORIZONTAL -static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {3, 1} }; -#elif CUBE_LAYOUT == VERTICAL -static int face_offset[6][2] = { {2, 1}, {0, 1}, {1, 0}, {1, 2}, {1, 1}, {1, 3} }; -#endif -static int face_flags[6] = { - DDSCAPS2_CUBEMAP_POSITIVEX, - DDSCAPS2_CUBEMAP_NEGATIVEX, - DDSCAPS2_CUBEMAP_POSITIVEY, - DDSCAPS2_CUBEMAP_NEGATIVEY, - DDSCAPS2_CUBEMAP_POSITIVEZ, - DDSCAPS2_CUBEMAP_NEGATIVEZ -}; - -// Load unwrapped cube map. -static bool LoadCubeMap( QDataStream & s, const DDSHeader & header, QImage & img ) -{ - // Create dst image. -#if CUBE_LAYOUT == HORIZONTAL - img = QImage( 4 * header.width, 3 * header.height, QImage::Format_RGB32 ); -#elif CUBE_LAYOUT == VERTICAL - img = QImage( 3 * header.width, 4 * header.height, QImage::Format_RGB32 ); -#endif - - DDSType type = GetType( header ); - - // Enable alpha buffer for transparent or DDS images. - if( HasAlpha( header ) || type >= DDS_DXT1 ) { - img = img.convertToFormat( QImage::Format_ARGB32 ); - } - - // Select texture loader. - TextureLoader loader = GetTextureLoader( type ); - if( loader == NULL ) { - return false; - } - - // Clear background. - img.fill( 0 ); - - // Create face image. - QImage face(header.width, header.height, QImage::Format_RGB32); - - int offset = s.device()->pos(); - int size = FaceOffset( header ); - - for( int i = 0; i < 6; i++ ) { - - if( !(header.caps.caps2 & face_flags[i]) ) { - // Skip face. - continue; - } - - // Seek device. - s.device()->seek( offset ); - offset += size; - - // Load face from stream. - if( !loader( s, header, face ) ) { - return false; - } - -#if CUBE_LAYOUT == VERTICAL - if( i == 5 ) { - face = face.mirror(true, true); - } -#endif - - // Compute face offsets. - int offset_x = face_offset[i][0] * header.width; - int offset_y = face_offset[i][1] * header.height; - - // Copy face on the image. - for( uint y = 0; y < header.height; y++ ) { - QRgb * src = (QRgb *) face.scanLine( y ); - QRgb * dst = (QRgb *) img.scanLine( y + offset_y ) + offset_x; - memcpy( dst, src, sizeof(QRgb) * header.width ); - } - } - - return true; -} - -static bool canReadDDS(QIODevice *device) -{ - if (!device) { - qWarning("DDSHandler::canRead() called with no device"); - return false; - } - - qint64 oldPos = device->pos(); - - char head[3]; - qint64 readBytes = device->read(head, sizeof(head)); - if (readBytes != sizeof(head)) { - if (device->isSequential()) { - while (readBytes > 0) { - device->ungetChar(head[readBytes-- - 1]); - } - } else { - device->seek(oldPos); - } - return false; - } - - if (device->isSequential()) { - while (readBytes > 0) { - device->ungetChar(head[readBytes-- - 1]); - } - } else { - device->seek(oldPos); - } - - return qstrncmp(head, "DDS", 3) == 0; -} - - -bool loadDDS(const QString &filename, QImage *image) -{ - QFile file(filename); - - if(!file.open(QIODevice::ReadOnly)) { - return false; - } - - if(!canReadDDS(&file)) { - return false; - } - - QDataStream s(&file); - s.setByteOrder(QDataStream::LittleEndian); - - // Validate header. - uint fourcc; - s >> fourcc; - if( fourcc != FOURCC_DDS ) { - qDebug("This is not a DDS file."); - return false; - } - - // Read image header. - DDSHeader header; - s >> header; - - // Check image file format. - if( s.atEnd() || !IsValid( header ) ) { - qDebug("This DDS file is not valid."); - return false; - } - - // Determine image type, by now, we only support 2d textures. - if( !IsSupported( header ) ) { - qDebug("This DDS file is not supported."); - return false; - } - - bool result; - - if( IsCubeMap( header ) ) { - result = LoadCubeMap( s, header, *image ); - } else { - result = LoadTexture( s, header, *image ); - } - - return result; -} diff --git a/src/dds.h b/src/dds.h deleted file mode 100644 index 4a682fd..0000000 --- a/src/dds.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 KIMG_DDS_H -#define KIMG_DDS_H - -#include -#include - -bool loadDDS(const QString &filename, QImage *image); - -#endif - - diff --git a/src/forms/backupitem.cpp b/src/forms/backupitem.cpp deleted file mode 100644 index 8ad2035..0000000 --- a/src/forms/backupitem.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 "backupitem.h" -#include "ui_backupitem.h" -#include "cmautils.h" -#include "dds.h" - -#include -#include - -const QString BackupItem::gameTemplate = "" - "

%1

" - ""; - -const QString BackupItem::sizeTemplate = "" - "

%1

" - ""; - -const QString BackupItem::infoTemplate = "" - "

 %1

" - ""; - -BackupItem::BackupItem(QWidget *obj_parent) : - QWidget(obj_parent), - ui(new Ui::BackupItem) -{ - ui->setupUi(this); - // connect the buttons - connect(ui->openButton, SIGNAL(clicked()), this, SLOT(openDirectory())); - connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(removeEntry())); -} - -BackupItem::~BackupItem() -{ - delete ui; -} - -void BackupItem::openDirectory() -{ - QDesktopServices::openUrl(QUrl("file:///" + m_path)); -} - -void BackupItem::removeEntry() -{ - emit deleteEntry(this); -} - -const QPixmap *BackupItem::getIconPixmap() -{ - return ui->itemPicture->pixmap(); -} - -void BackupItem::setDirectory(const QString &path) -{ - m_path = path; -} - -void BackupItem::setItemInfo(const QString &name, const QString &item_size, const QString &extra) -{ - ui->gameLabel->setText(gameTemplate.arg(name)); - ui->sizeLabel->setText(sizeTemplate.arg(item_size)); - ui->infoLabel->setText(infoTemplate.arg(extra)); -} - -int BackupItem::getIconWidth() -{ - return ui->itemPicture->width(); -} - -void BackupItem::setItemIcon(const QString &path, int item_width, bool try_dds) -{ - ui->itemPicture->setMinimumWidth(item_width); - QPixmap pixmap(path); - if((pixmap.width() <= 0 || pixmap.height() <= 0) && try_dds) { - QImage image; - if(loadDDS(path, &image)) { - pixmap = QPixmap::fromImage(image); - } - } - ui->itemPicture->setPixmap(pixmap); -} - -bool BackupItem::lessThan(const BackupItem *s1, const BackupItem *s2) -{ - return s1->title.compare(s2->title) < 0; -} - diff --git a/src/forms/backupitem.h b/src/forms/backupitem.h deleted file mode 100644 index b68b5bb..0000000 --- a/src/forms/backupitem.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 BACKUPITEM_H -#define BACKUPITEM_H - -#include - -namespace Ui { -class BackupItem; -} - -class BackupItem : public QWidget -{ - Q_OBJECT - -public: - explicit BackupItem(QWidget *parent = 0); - ~BackupItem(); - - void setItemInfo(const QString &name, const QString &size, const QString &extra); - void setItemIcon(const QString &m_path, int width = 48, bool try_dds = false); - void setDirectory(const QString &m_path); - const QPixmap *getIconPixmap(); - int getIconWidth(); - - static bool lessThan(const BackupItem *s1, const BackupItem *s2); - - int ohfi; - QString title; - -private: - QString m_path; - Ui::BackupItem *ui; - static const QString gameTemplate; - static const QString sizeTemplate; - static const QString infoTemplate; - -signals: - void deleteEntry(BackupItem *entry); - -private slots: - void openDirectory(); - void removeEntry(); -}; - -#endif // BACKUPITEM_H diff --git a/src/forms/backupitem.ui b/src/forms/backupitem.ui deleted file mode 100644 index 0197067..0000000 --- a/src/forms/backupitem.ui +++ /dev/null @@ -1,154 +0,0 @@ - - - BackupItem - - - - 0 - 0 - 638 - 75 - - - - - 0 - 0 - - - - - - - - - - - - - 48 - 48 - - - - - 0 - 48 - - - - - - - true - - - Qt::AlignCenter - - - - - - - 5 - - - - - <p><span style=" font-size:12pt; font-weight:600;">Game Name</span></p> - - - - - - - - - - 0 - 0 - - - - - 90 - 0 - - - - <p><span style=" font-size:10pt;">0.00 GiB</span></p> - - - - - - - - 0 - 0 - - - - <html><head/><body><p><span style=" font-size:9pt;">[APP] [SAVE] [UPDATE] [DLC]</span></p></body></html> - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 0 - 32 - - - - Delete entry - - - - - - - - 0 - 32 - - - - Open folder - - - - - - - - - - diff --git a/src/forms/backupmanagerform.cpp b/src/forms/backupmanagerform.cpp deleted file mode 100644 index 72dfeff..0000000 --- a/src/forms/backupmanagerform.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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 "backupmanagerform.h" -#include "ui_backupmanagerform.h" -#include "cmaobject.h" -#include "sforeader.h" -#include "confirmdialog.h" -#include "cmautils.h" -#include "gui/filterlineedit.h" - -#include -#include -#include -#include - -#include - -BackupManagerForm::BackupManagerForm(Database *db, QWidget *obj_parent) : - QDialog(obj_parent), m_db(db), - ui(new Ui::BackupManagerForm) -{ - ui->setupUi(this); - setupForm(); -} - -BackupManagerForm::~BackupManagerForm() -{ - delete ui; -} - -void BackupManagerForm::setupForm() -{ - this->resize(800, 480); - connect(ui->backupComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(loadBackupListing(int))); - ui->tableWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - ui->tableWidget->horizontalHeader()->hide(); -} - -void BackupManagerForm::removeEntry(BackupItem *item) -{ - ConfirmDialog msgBox; - - msgBox.setMessageText(tr("Are you sure to remove the backup of the following entry?"), item->title); - msgBox.setMessagePixmap(*item->getIconPixmap(), item->getIconWidth()); - - if(msgBox.exec() == 0) { - return; - } - - QMutexLocker locker(&m_db->mutex); - - int parent_ohfi = m_db->getParentId(item->ohfi); - removeRecursively(m_db->getAbsolutePath(item->ohfi)); - m_db->deleteEntry(item->ohfi); - - for(int i = 0; i < ui->tableWidget->rowCount(); ++i) { - BackupItem *iter_item = static_cast(ui->tableWidget->cellWidget(i, 0)); - if(iter_item == item) { - ui->tableWidget->removeRow(i); - break; - } - } - - if(parent_ohfi > 0) { - setBackupUsage(m_db->getObjectSize(parent_ohfi)); - } -} - -void BackupManagerForm::setBackupUsage(qint64 usage_size) -{ - ui->usageLabel->setText(tr("Backup disk usage: %1").arg(readable_size(usage_size, true))); -} - -void BackupManagerForm::loadBackupListing(int index) -{ - int ohfi; - bool sys_dir; - int img_width; - - //TODO: load all the accounts in the combobox - ui->accountBox->clear(); - ui->accountBox->addItem(QSettings().value("lastOnlineId", tr("Default account")).toString()); - - if(index < 0) { - index = ui->backupComboBox->currentIndex(); - } - - ui->tableWidget->clear(); - - switch(index) { - case 0: - ohfi = VITA_OHFI_VITAAPP; - img_width = 48; - sys_dir = true; - break; - case 1: - ohfi = VITA_OHFI_PSPAPP; - img_width = 80; - sys_dir = true; - break; - case 2: - ohfi = VITA_OHFI_PSMAPP; - img_width = 48; - sys_dir = true; - break; - case 3: - ohfi = VITA_OHFI_PSXAPP; - img_width = 48; - sys_dir = true; - break; - case 4: - ohfi = VITA_OHFI_PSPSAVE; - img_width = 80; - sys_dir = false; - break; - case 5: - ohfi = VITA_OHFI_BACKUP; - img_width = 48; - sys_dir = false; - break; - default: - ohfi = VITA_OHFI_VITAAPP; - img_width = 48; - sys_dir = true; - } - - m_db->mutex.lock(); - - // get the item list - metadata_t *meta = NULL; - int row_count = m_db->getObjectMetadatas(ohfi, &meta); - ui->tableWidget->setRowCount(row_count); - - // exit if there aren't any items - if(row_count == 0) { - setBackupUsage(0); - m_db->mutex.unlock(); - return; - } - - // adjust the table item width to fill all the widget - QHeaderView *vert_header = ui->tableWidget->verticalHeader(); - QHeaderView *horiz_header = ui->tableWidget->horizontalHeader(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - horiz_header->setSectionResizeMode(QHeaderView::Stretch); -#else - horiz_header->setResizeMode(QHeaderView::Stretch); -#endif - qint64 backup_size = m_db->getObjectSize(ohfi); - setBackupUsage(backup_size); - QString path = m_db->getAbsolutePath(ohfi); - QList item_list; - - metadata_t *first = meta; - while(meta) { - QString base_path = path + QDir::separator() + meta->name; - QString parent_path = sys_dir ? base_path + QDir::separator() + "sce_sys" : base_path; - SfoReader reader; - QString game_name; - - // retrieve the game name from the SFO - if(reader.load(QDir(parent_path).absoluteFilePath(sys_dir ? "param.sfo" : "PARAM.SFO"))) { - game_name = QString::fromUtf8(reader.value("TITLE", meta->name)); - } else { - game_name = QString(meta->name); - } - - BackupItem *item = new BackupItem(); - // save the game title and ohfi for sorting/deleting - item->ohfi = meta->ohfi; - item->title = game_name; - - connect(item, SIGNAL(deleteEntry(BackupItem*)), this, SLOT(removeEntry(BackupItem*))); - - // show better size info for multi GiB backups - bool use_gb = ohfi == VITA_OHFI_BACKUP && meta->size > 1024*1024*1024; - QString read_size = readable_size(meta->size, use_gb); - - QString info; - - // check if is listing PS Vita games - if(index == 0) { - if(QDir(base_path + QDir::separator() + "app").exists()) { - info.append(tr(" [GAME]")); - } - if(QDir(base_path + QDir::separator() + "savedata").exists()) { - info.append(tr(" [SAVE]")); - } - if(QDir(base_path + QDir::separator() + "patch").exists()) { - info.append(tr(" [UPDATE]")); - } - if(QDir(base_path + QDir::separator() + "addcont").exists()) { - info.append(tr(" [DLC]")); - } - } - - item->setItemInfo(game_name, read_size, info); - item->setItemIcon(QDir(parent_path).absoluteFilePath(sys_dir ? "icon0.png" : "ICON0.PNG"), img_width, ohfi == VITA_OHFI_PSMAPP); - item->setDirectory(path + QDir::separator() + meta->name); - item->resize(646, 68); - - item_list << item; - meta = meta->next_metadata; - } - - m_db->freeMetadata(first); - - qSort(item_list.begin(), item_list.end(), BackupItem::lessThan); - - int row; - QList::iterator it; - vert_header->setUpdatesEnabled(false); - - // insert the sorted items into the table - for(it = item_list.begin(), row = 0; it != item_list.end(); ++it, ++row) { - ui->tableWidget->setCellWidget(row, 0, *it); - vert_header->resizeSection(row, 68); - } - - vert_header->setUpdatesEnabled(true); - m_db->mutex.unlock(); - - // apply filter - this->on_filterLineEdit_textChanged(ui->filterLineEdit->text()); -} - -void BackupManagerForm::on_filterLineEdit_textChanged(const QString &arg1) -{ - if(arg1 != tr("Filter")) { - for(int i = 0; i < ui->tableWidget->rowCount(); ++i) { - BackupItem *item = (BackupItem*) ui->tableWidget->cellWidget(i, 0); - - if(item->title.contains(arg1, Qt::CaseInsensitive)) { - ui->tableWidget->setRowHidden(i, false); - } else { - ui->tableWidget->setRowHidden(i, true); - } - } - } -} diff --git a/src/forms/backupmanagerform.h b/src/forms/backupmanagerform.h deleted file mode 100644 index 2613df3..0000000 --- a/src/forms/backupmanagerform.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 BACKUPMANAGERFORM_H -#define BACKUPMANAGERFORM_H - -#include "database.h" -#include "backupitem.h" - -#include - -namespace Ui { -class BackupManagerForm; -} - -class BackupManagerForm : public QDialog -{ - Q_OBJECT - -public: - explicit BackupManagerForm(Database *db, QWidget *parent = 0); - ~BackupManagerForm(); - - Database *m_db; - -private: - void setupForm(); - void setBackupUsage(qint64 size); - - Ui::BackupManagerForm *ui; - -public slots: - void loadBackupListing(int index); - void removeEntry(BackupItem *item); -private slots: - void on_filterLineEdit_textChanged(const QString &arg1); -}; - -#endif // BACKUPMANAGERFORM_H diff --git a/src/forms/backupmanagerform.ui b/src/forms/backupmanagerform.ui deleted file mode 100644 index 20ef02c..0000000 --- a/src/forms/backupmanagerform.ui +++ /dev/null @@ -1,139 +0,0 @@ - - - BackupManagerForm - - - - 0 - 0 - 857 - 478 - - - - Backup Manager - - - - - - - - - - Online ID / Username - - - - - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Backup Type - - - 2 - - - - - - - - PS Vita Games - - - - - PSP Games - - - - - PSM Games - - - - - PSOne Games - - - - - PSP Savedatas - - - - - Backups - - - - - - - - - - - - 1 - - - - - - - - - - Backup disk usage - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - FilterLineEdit { color:gray; font-style:italic; } - - - Filter - - - - - - - - - - FilterLineEdit - QLineEdit -
gui/filterlineedit.h
-
-
- - -
diff --git a/src/forms/configwidget.cpp b/src/forms/configwidget.cpp deleted file mode 100644 index b8833ec..0000000 --- a/src/forms/configwidget.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * 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 "configwidget.h" -#include "ui_configwidget.h" - -extern "C" { -#include -} - -#include -#include - -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -#include -#else -#include -#define QStandardPaths QDesktopServices -#define writableLocation storageLocation -#endif - -ConfigWidget::ConfigWidget(QWidget *obj_parent) : - QDialog(obj_parent), - ui(new Ui::ConfigWidget) -{ - ui->setupUi(this); - connectSignals(); - setDefaultData(); -} - -void ConfigWidget::connectSignals() -{ - QSignalMapper *mapper = new QSignalMapper(this); - mapper->setMapping(ui->photoBtn, BTN_PHOTO); - mapper->setMapping(ui->musicBtn, BTN_MUSIC); - mapper->setMapping(ui->videoBtn, BTN_VIDEO); - mapper->setMapping(ui->appBtn, BTN_APPS); - mapper->setMapping(ui->urlBtn, BTN_URL); - mapper->setMapping(ui->pkgBtn, BTN_PKG); - connect(ui->photoBtn, SIGNAL(clicked()), mapper, SLOT(map())); - connect(ui->musicBtn, SIGNAL(clicked()), mapper, SLOT(map())); - connect(ui->videoBtn, SIGNAL(clicked()), mapper, SLOT(map())); - connect(ui->appBtn, SIGNAL(clicked()), mapper, SLOT(map())); - connect(ui->urlBtn, SIGNAL(clicked()), mapper, SLOT(map())); - connect(ui->pkgBtn, SIGNAL(clicked()), mapper, SLOT(map())); - connect(mapper, SIGNAL(mapped(int)), this, SLOT(browseBtnPressed(int))); - connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - connect(ui->protocolModeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolModeChanged(int))); -} - -void ConfigWidget::protocolModeChanged(int index) -{ - switch(index) - { - case 0: - ui->protocolBox->setEnabled(false); - ui->protocolEdit->setEnabled(false); - break; - case 1: - ui->protocolBox->setEnabled(true); - ui->protocolEdit->setEnabled(false); - break; - case 2: - ui->protocolBox->setEnabled(false); - ui->protocolEdit->setEnabled(true); - break; - default: - ui->protocolBox->setEnabled(false); - ui->protocolEdit->setEnabled(false); - break; - } - -} - -void ConfigWidget::setDefaultData() -{ - QString defaultdir; - QSettings settings; - defaultdir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); - ui->photoPath->setText(QDir::toNativeSeparators(settings.value("photoPath", defaultdir).toString())); - - defaultdir = QStandardPaths::writableLocation(QStandardPaths::MusicLocation); - ui->musicPath->setText(QDir::toNativeSeparators(settings.value("musicPath", defaultdir).toString())); - - defaultdir = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); - ui->videoPath->setText(QDir::toNativeSeparators(settings.value("videoPath", defaultdir).toString())); - - defaultdir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); - defaultdir.append(QDir::separator()).append("PS Vita"); - ui->appPath->setText(QDir::toNativeSeparators(settings.value("appsPath", defaultdir).toString())); - - defaultdir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); - defaultdir.append(QDir::separator()).append("PSV Updates"); - ui->urlPath->setText(QDir::toNativeSeparators(settings.value("urlPath", defaultdir).toString())); - - defaultdir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); - defaultdir.append(QDir::separator()).append("PSV Packages"); - ui->pkgPath->setText(QDir::toNativeSeparators(settings.value("pkgPath", defaultdir).toString())); - - ui->offlineCheck->setChecked(settings.value("offlineMode", true).toBool()); - ui->metadataCheck->setChecked(settings.value("skipMetadata", false).toBool()); - ui->usbCheck->setChecked(settings.value("disableUSB", false).toBool()); - ui->wifiCheck->setChecked(settings.value("disableWireless", false).toBool()); - ui->databaseSelect->setCurrentIndex(settings.value("useMemoryStorage", true).toBool() ? 0 : 1); - - ui->photoSkipCheck->setChecked(settings.value("photoSkip", false).toBool()); - ui->videoSkipCheck->setChecked(settings.value("videoSkip", false).toBool()); - ui->musicSkipCheck->setChecked(settings.value("musicSkip", false).toBool()); - - QString protocol_mode = settings.value("protocolMode", "automatic").toString(); - - if(protocol_mode == "manual") - ui->protocolModeBox->setCurrentIndex(1); - else if(protocol_mode == "custom") - ui->protocolModeBox->setCurrentIndex(2); - else - ui->protocolModeBox->setCurrentIndex(0); - - protocolModeChanged(ui->protocolModeBox->currentIndex()); - - ui->protocolBox->setCurrentIndex(settings.value("protocolIndex", 0).toInt()); - - bool ok; - int protocol_version = settings.value("protocolVersion", VITAMTP_PROTOCOL_MAX_VERSION).toInt(&ok); - - if(ok && protocol_version > 0) - ui->protocolEdit->setText(QString::number(protocol_version)); - else - ui->protocolEdit->setText(QString::number(VITAMTP_PROTOCOL_MAX_VERSION)); -} - -ConfigWidget::~ConfigWidget() -{ - delete ui; -} - -void ConfigWidget::browseBtnPressed(int btn) -{ - QString msg; - QLineEdit *lineedit; - - switch(btn) { - case BTN_PHOTO: - lineedit = ui->photoPath; - msg = tr("Select the folder to be used as a photo source"); - break; - - case BTN_MUSIC: - lineedit = ui->musicPath; - msg = tr("Select the folder to be used as a music source"); - break; - - case BTN_VIDEO: - lineedit = ui->videoPath; - msg = tr("Select the folder to be used as a video source"); - break; - - case BTN_APPS: - lineedit = ui->appPath; - msg = tr("Select the folder to be used to save PS Vita games and backups"); - break; - - case BTN_URL: - lineedit = ui->urlPath; - msg = tr("Select the folder to be used to fetch software updates"); - break; - - case BTN_PKG: - lineedit = ui->pkgPath; - msg = tr("Select the folder to be used to software packages"); - break; - - default: - return; - } - - QString selected = QFileDialog::getExistingDirectory(this, msg, lineedit->text(), QFileDialog::ShowDirsOnly); - - if(!selected.isEmpty()) { - lineedit->setText(QDir::toNativeSeparators((selected))); - } -} - -void ConfigWidget::savePath(QSettings &settings, const QLineEdit *edit, const QString &key) -{ - QString path = edit->text(); - if(path.endsWith(QDir::separator())) { - path.chop(1); - } - settings.setValue(key, QDir::fromNativeSeparators(path)); - QDir(QDir::root()).mkpath(path); -} - -void ConfigWidget::accept() -{ - QSettings settings; - savePath(settings, ui->photoPath, "photoPath"); - savePath(settings, ui->musicPath, "musicPath"); - savePath(settings, ui->videoPath, "videoPath"); - savePath(settings, ui->appPath, "appsPath"); - savePath(settings, ui->urlPath, "urlPath"); - savePath(settings, ui->pkgPath, "pkgPath"); - settings.setValue("offlineMode", ui->offlineCheck->isChecked()); - settings.setValue("skipMetadata", ui->metadataCheck->isChecked()); - settings.setValue("disableUSB", ui->usbCheck->isChecked()); - settings.setValue("disableWireless", ui->wifiCheck->isChecked()); - settings.setValue("useMemoryStorage", ui->databaseSelect->currentIndex() == 0); - settings.setValue("photoSkip", ui->photoSkipCheck->isChecked()); - settings.setValue("videoSkip", ui->videoSkipCheck->isChecked()); - settings.setValue("musicSkip", ui->musicSkipCheck->isChecked()); - settings.setValue("protocolIndex", ui->protocolBox->currentIndex()); - - if(ui->protocolModeBox->currentIndex() == 0) - settings.setValue("protocolMode", "automatic"); - else if(ui->protocolModeBox->currentIndex() == 1) - settings.setValue("protocolMode", "manual"); - else if(ui->protocolModeBox->currentIndex() == 2) - settings.setValue("protocolMode", "custom"); - - bool ok; - int protocol = ui->protocolEdit->text().toInt(&ok); - - if(ok && protocol > 0) - settings.setValue("protocolVersion", protocol); - else - settings.setValue("protocolVersion", VITAMTP_PROTOCOL_MAX_VERSION); - - settings.sync(); - - done(Accepted); -} diff --git a/src/forms/configwidget.h b/src/forms/configwidget.h deleted file mode 100644 index 068c044..0000000 --- a/src/forms/configwidget.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 CONFIGWIDGET_H -#define CONFIGWIDGET_H - -#include -#include -#include -#include - -namespace Ui { -class ConfigWidget; -} - -class ConfigWidget : public QDialog -{ - Q_OBJECT - -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - -private: - enum browse_buttons {BTN_PHOTO, BTN_MUSIC, BTN_VIDEO, BTN_APPS, BTN_URL, BTN_PKG}; - - void connectSignals(); - void setDefaultData(); - void savePath(QSettings &settings, const QLineEdit *edit, const QString &key); - - Ui::ConfigWidget *ui; - -private slots: - void protocolModeChanged(int index); - void browseBtnPressed(int from); - void accept(); -}; - -#endif // CONFIGWIDGET_H diff --git a/src/forms/configwidget.ui b/src/forms/configwidget.ui deleted file mode 100644 index 917df70..0000000 --- a/src/forms/configwidget.ui +++ /dev/null @@ -1,525 +0,0 @@ - - - ConfigWidget - - - - 0 - 0 - 519 - 525 - - - - QCMA Settings - - - - - - - - 0 - - - - Folders - - - - - - - - - 10 - - - - Specify the folders that the PS Vita will access for each content type. - - - true - - - - - - - - - This is the location your Screenshots and Pictures are Saved to/Imported from. - - - Photo Folder - - - - - - - - - This is the location your Screenshots and Pictures are Saved to/Imported from. - - - true - - - - - - - Browse... - - - - - - - - - - - - - This is the location your Videos are Saved to/Imported from. - - - Video Folder - - - - - - - - - This is the location your Videos are Saved to/Imported from. - - - true - - - - - - - Browse... - - - - - - - - - - - - - This is the location your Music is Saved to/Imported from. - - - Music Folder - - - - - - - - - This is the location your Music is Saved to/Imported from. - - - true - - - - - - - Browse... - - - - - - - - - - - - - This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from. - - - Applications / Backups - - - - - - - - - This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from. - - - true - - - - - - - Browse... - - - - - - - - - - - - - This is the location your Software Updates and Browser Data is Saved to/Imported from. - - - Updates / Web content - - - - - - - - - This is the location your PS Vita system will read all the content that it tries to download. - - - true - - - - - - - Browse... - - - - - - - - - - - - - Packages - - - - - - - - - - - - Browse... - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - Other - - - - - - - - <html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html> - - - - - - - Offline Mode - - - true - - - - - - - Skip metadata extraction - - - - - - - Disable USB monitoring - - - - - - - Disable Wi-Fi monitoring - - - - - - - false - - - Update database automatically when files on the PC are changed - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Database backend - - - - - - - false - - - - In Memory - - - - - SQLite - - - - - - - - - - Skip photo scanning - - - - - - - Skip video scanning - - - - - - - Skip music scanning - - - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - CMA protocol version - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - 200 - 0 - - - - - FW 3.30 - 1900010 - - - - - FW 3.10 - 1800010 - - - - - FW 3.00 - 1700010 - - - - - FW 2.60 - 1600010 - - - - - FW 2.10 - 1500010 - - - - - FW 2.00 - 1400010 - - - - - FW 1.80 - 1300010 - - - - - FW 1.60 - 1200010 - - - - - FW 1.50 - 1100010 - - - - - FW 1.00 - 1000010 - - - - - - - - 9999999 - - - - - - - - - - CMA protocol selection - - - - - - - - Latest - - - - - Manual - - - - - Custom - - - - - - - - CMA custom version - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - diff --git a/src/forms/confirmdialog.cpp b/src/forms/confirmdialog.cpp deleted file mode 100644 index ef77ed6..0000000 --- a/src/forms/confirmdialog.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 "confirmdialog.h" -#include "ui_confirmdialog.h" - -const QString ConfirmDialog::messageTemplate = "" - "

%1

" - "

%2

" - ""; - -ConfirmDialog::ConfirmDialog(QWidget *obj_parent) : - QDialog(obj_parent), - ui(new Ui::ConfirmDialog) -{ - ui->setupUi(this); - this->layout()->setSizeConstraint(QLayout::SetFixedSize); -} - -void ConfirmDialog::setMessageText(const QString message, const QString game_title) -{ - ui->confirmText->setText(messageTemplate.arg(message, game_title)); -} - -void ConfirmDialog::setMessagePixmap(const QPixmap &pixmap, int dialog_width) -{ - ui->itemPicture->setPixmap(pixmap); - ui->itemPicture->setMinimumWidth(dialog_width); -} - -ConfirmDialog::~ConfirmDialog() -{ - delete ui; -} diff --git a/src/forms/confirmdialog.h b/src/forms/confirmdialog.h deleted file mode 100644 index f9be667..0000000 --- a/src/forms/confirmdialog.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 CONFIRMDIALOG_H -#define CONFIRMDIALOG_H - -#include - -namespace Ui { -class ConfirmDialog; -} - -class ConfirmDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ConfirmDialog(QWidget *parent = 0); - ~ConfirmDialog(); - - void setMessageText(const QString message, const QString game_title); - void setMessagePixmap(const QPixmap &pixmap, int width); - - static const QString messageTemplate; - -private: - Ui::ConfirmDialog *ui; -}; - -#endif // CONFIRMDIALOG_H diff --git a/src/forms/confirmdialog.ui b/src/forms/confirmdialog.ui deleted file mode 100644 index 7eae756..0000000 --- a/src/forms/confirmdialog.ui +++ /dev/null @@ -1,120 +0,0 @@ - - - ConfirmDialog - - - - 0 - 0 - 519 - 106 - - - - Confirmation Message - - - true - - - - - - - - - 48 - 48 - - - - - 0 - 48 - - - - - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 10 - 0 - - - - - - - - <html><head/><body><p><span style=" font-size:10pt;">Are you sure to delete the backup of the following game?</span></p><p><span style=" font-size:12pt; font-weight:600;">Game Name</span></p></body></html> - - - - 0 - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - ConfirmDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - ConfirmDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/src/forms/pinform.cpp b/src/forms/pinform.cpp deleted file mode 100644 index 85eeb8a..0000000 --- a/src/forms/pinform.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 *obj_parent) : - QWidget(obj_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/src/forms/pinform.h b/src/forms/pinform.h deleted file mode 100644 index 0b534c9..0000000 --- a/src/forms/pinform.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 PINFORM_H -#define PINFORM_H - -#include -#include - -namespace Ui { -class PinForm; -} - -class PinForm : public QWidget -{ - Q_OBJECT - -public: - explicit PinForm(QWidget *parent = 0); - ~PinForm(); - -private: - Ui::PinForm *ui; - - // pin timeout - int counter; - QTimer timer; - - static const QString pinFormat; - -public slots: - void startCountdown(); - void setPin(QString name, int pin); - -private slots: - void decreaseTimer(); -}; - -#endif // PINFORM_H diff --git a/src/forms/pinform.ui b/src/forms/pinform.ui deleted file mode 100644 index c10e74b..0000000 --- a/src/forms/pinform.ui +++ /dev/null @@ -1,115 +0,0 @@ - - - PinForm - - - Qt::ApplicationModal - - - - 0 - 0 - 526 - 216 - - - - Device pairing - - - - - - - - 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/src/forms/progressform.cpp b/src/forms/progressform.cpp deleted file mode 100644 index 5ecac28..0000000 --- a/src/forms/progressform.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 *obj_parent) : - QWidget(obj_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); -} - -void ProgressForm::showDelayed(int msec) -{ - timer.setSingleShot(true); - timer.setInterval(msec); - connect(&timer, SIGNAL(timeout()), this, SLOT(show())); - timer.start(); -} - -void ProgressForm::interruptShow() -{ - timer.stop(); -} diff --git a/src/forms/progressform.h b/src/forms/progressform.h deleted file mode 100644 index 12fc292..0000000 --- a/src/forms/progressform.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 PROGRESSFORM_H -#define PROGRESSFORM_H - -#include -#include - -namespace Ui { -class ProgressForm; -} - -class ProgressForm : public QWidget -{ - Q_OBJECT - -public: - explicit ProgressForm(QWidget *parent = 0); - ~ProgressForm(); - - void showDelayed(int msec = 1000); - void interruptShow(); - -private: - Ui::ProgressForm *ui; - - QTimer timer; - -signals: - void canceled(); - -private slots: - void cancelConfirm(); - -public slots: - void setDirectoryName(QString dir); - void setFileName(QString file); -}; - -#endif // PROGRESSFORM_H diff --git a/src/forms/progressform.ui b/src/forms/progressform.ui deleted file mode 100644 index 1138f36..0000000 --- a/src/forms/progressform.ui +++ /dev/null @@ -1,80 +0,0 @@ - - - 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/src/gui/clientmanager.cpp b/src/gui/clientmanager.cpp deleted file mode 100644 index 4d50aca..0000000 --- a/src/gui/clientmanager.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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 "cmaclient.h" -#include "cmautils.h" -#include "forms/progressform.h" - -#include - -#include - -#ifdef Q_OS_UNIX -#include -#include - -int ClientManager::sighup_fd[2]; -int ClientManager::sigterm_fd[2]; -#endif - -ClientManager::ClientManager(Database *db, QObject *obj_parent) : - QObject(obj_parent), m_db(db) -{ -#ifdef Q_OS_UNIX - if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighup_fd)) - qFatal("Couldn't create HUP socketpair"); - - if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigterm_fd)) - qFatal("Couldn't create TERM socketpair"); - - sn_hup = new QSocketNotifier(sighup_fd[1], QSocketNotifier::Read, this); - connect(sn_hup, SIGNAL(activated(int)), this, SLOT(handleSigHup())); - sn_term = new QSocketNotifier(sigterm_fd[1], QSocketNotifier::Read, this); - connect(sn_term, SIGNAL(activated(int)), this, SLOT(handleSigTerm())); -#endif -} - -ClientManager::~ClientManager() -{ - VitaMTP_Cleanup(); -} - -void ClientManager::databaseUpdated(int count) -{ - progress.interruptShow(); - 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")); - } - emit updated(count); -} - -void ClientManager::showPinDialog(QString name, int pin) -{ - pinForm.setPin(name, pin); - pinForm.startCountdown(); -} - -void ClientManager::start() -{ - if(VitaMTP_Init() < 0) { - emit messageSent(tr("Cannot initialize VitaMTP library")); - return; - } - - // initializing database for the first use - refreshDatabase(); - - connect(m_db, SIGNAL(fileAdded(QString)), &progress, SLOT(setFileName(QString))); - connect(m_db, SIGNAL(directoryAdded(QString)), &progress, SLOT(setDirectoryName(QString))); - connect(m_db, SIGNAL(updated(int)), this, SLOT(databaseUpdated(int))); - connect(&progress, SIGNAL(canceled()), m_db, SLOT(cancelOperation()), Qt::DirectConnection); - - thread_count = 0; - qDebug("Starting cma threads"); - CmaClient *client; - QSettings settings; - - if(!settings.value("disableUSB", false).toBool()) { - -#ifdef Q_OS_LINUX - if(!belongsToGroup("vitamtp")) - emit messageSent(tr("This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus.")); -#endif - - usb_thread = new QThread(); - client = new CmaClient(m_db); - usb_thread->setObjectName("usb_thread"); - connect(usb_thread, SIGNAL(started()), client, SLOT(connectUsb())); - connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString))); - 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())); - connect(usb_thread, SIGNAL(finished()), client, SLOT(deleteLater())); - - connect(client, SIGNAL(deviceConnected(QString)), this, SIGNAL(deviceConnected(QString))); - connect(client, SIGNAL(deviceDisconnected()), this, SIGNAL(deviceDisconnected())); - connect(client, SIGNAL(refreshDatabase()), this, SLOT(refreshDatabase())); - - client->moveToThread(usb_thread); - usb_thread->start(); - thread_count++; - } - - if(!settings.value("disableWireless", false).toBool()) { - CmaBroadcast *broadcast = new CmaBroadcast(this); - wireless_thread = new QThread(); - client = new CmaClient(m_db, broadcast); - wireless_thread->setObjectName("wireless_thread"); - connect(wireless_thread, SIGNAL(started()), client, SLOT(connectWireless())); - connect(client, SIGNAL(messageSent(QString)), this, SIGNAL(messageSent(QString))); - 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(pinComplete()), &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())); - - client->moveToThread(wireless_thread); - wireless_thread->start(); - thread_count++; - } - - if(thread_count == 0) { - emit messageSent(tr("You must enable at least USB or Wireless monitoring")); - } -} - -void ClientManager::refreshDatabase() -{ - if(m_db->load()) { - return; - } - - if(!m_db->rescan()) { - emit messageSent(tr("No PS Vita system has been registered")); - } else { - progress.showDelayed(1000); - } -} - -void ClientManager::stop() -{ - if(CmaClient::stop() < 0) { - emit stopped(); - } -} - -void ClientManager::threadStopped() -{ - mutex.lock(); - if(--thread_count == 0) { - emit stopped(); - } - mutex.unlock(); -} - -#ifdef Q_OS_UNIX -void ClientManager::hupSignalHandler(int) -{ - char a = 1; - ::write(sighup_fd[0], &a, sizeof(a)); -} - -void ClientManager::termSignalHandler(int) -{ - char a = 1; - ::write(sigterm_fd[0], &a, sizeof(a)); -} - -void ClientManager::handleSigTerm() -{ - sn_term->setEnabled(false); - char tmp; - ::read(sigterm_fd[1], &tmp, sizeof(tmp)); - - stop(); - - sn_term->setEnabled(true); -} - -void ClientManager::handleSigHup() -{ - sn_hup->setEnabled(false); - char tmp; - ::read(sighup_fd[1], &tmp, sizeof(tmp)); - - refreshDatabase(); - - sn_hup->setEnabled(true); -} -#endif diff --git a/src/gui/clientmanager.h b/src/gui/clientmanager.h deleted file mode 100644 index 07acee1..0000000 --- a/src/gui/clientmanager.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 "database.h" -#include "forms/pinform.h" -#include "forms/progressform.h" - -#include -#include - -#ifdef Q_OS_UNIX -#include -#endif - -class ClientManager : public QObject -{ - Q_OBJECT -public: - explicit ClientManager(Database *db, QObject *parent = 0); - ~ClientManager(); - - void start(); - void stop(); - -#ifdef Q_OS_UNIX - // unix signal handlers - static void hupSignalHandler(int); - static void termSignalHandler(int); -#endif - -private: - int thread_count; - QMutex mutex; - - Database *m_db; - - PinForm pinForm; - ProgressForm progress; - - QThread *usb_thread; - QThread *wireless_thread; - -#ifdef Q_OS_UNIX - // signal handling - static int sighup_fd[2]; - static int sigterm_fd[2]; - - QSocketNotifier *sn_hup; - QSocketNotifier *sn_term; -#endif - -signals: - void updated(int); - void stopped(); - void receivedPin(int); - void deviceDisconnected(); - void messageSent(QString); - void deviceConnected(QString); - -public slots: - void refreshDatabase(); - -#ifdef Q_OS_UNIX - // Qt signal handlers - void handleSigHup(); - void handleSigTerm(); -#endif - -private slots: - void threadStopped(); - void databaseUpdated(int count); - void showPinDialog(QString name, int pin); -}; - -#endif // CLIENTMANAGER_H diff --git a/src/gui/filterlineedit.cpp b/src/gui/filterlineedit.cpp deleted file mode 100644 index a396bab..0000000 --- a/src/gui/filterlineedit.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * QCMA: Cross-platform content manager assistant for the PS Vita - * - * Copyright (C) 2013 Xian Nox - * - * 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 "filterlineedit.h" - -#include -#include - -FilterLineEdit::FilterLineEdit(QWidget *obj_parent) : - QLineEdit(obj_parent) -{ - int frame_width = frameWidth(); - clearButton = new QToolButton(this); - QIcon clearIcon(":/main/resources/images/edit-clear-locationbar-rtl.png"); - clearButton->setIcon(clearIcon); - clearButton->setIconSize(QSize(sizeHint().height() - 4 * frame_width, - sizeHint().height() - 4 * frame_width)); - clearButton->setCursor(Qt::ArrowCursor); - clearButton->setStyleSheet("QToolButton { border:none; padding:0px; }"); - clearButton->hide(); - connect(clearButton, SIGNAL(clicked()), this, SLOT(clear())); - connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&))); - - setStyleSheet(QString("LineEdit { color:black; font-style:normal; padding-right:%1px; }").arg( - clearButton->sizeHint().width() + frame_width + 1)); - - QSize min_size_hint = minimumSizeHint(); - setMinimumSize(qMax(min_size_hint.width(), clearButton->sizeHint().height() + frame_width), - qMax(min_size_hint.height(), clearButton->sizeHint().height() + frame_width)); -} - -void FilterLineEdit::updateCloseButton(const QString& filter_text) -{ - if(filter_text.isEmpty() || filter_text == tr("Filter")) { - clearButton->setVisible(false); - } else { - clearButton->setVisible(true); - } -} - -void FilterLineEdit::focusInEvent(QFocusEvent *e) -{ - if(this->styleSheet() == "FilterLineEdit { color:gray; font-style:italic; }") { - this->clear(); - } - - setStyleSheet(QString("FilterLineEdit { color:black; font-style:normal; padding-right:%1px; }").arg(clearButton->sizeHint().width() + frameWidth() + 1)); - - QLineEdit::focusInEvent(e); -} - -void FilterLineEdit::focusOutEvent(QFocusEvent *e) -{ - if(this->text().isEmpty()) { - this->setText(tr("Filter")); - this->setStyleSheet("FilterLineEdit { color:gray; font-style:italic; }"); - } - - QLineEdit::focusOutEvent(e); -} - -int FilterLineEdit::frameWidth() const -{ - return style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this); -} - -void FilterLineEdit::resizeEvent(QResizeEvent *e) -{ - QSize sz = clearButton->sizeHint(); - clearButton->move(rect().right() - sz.width(), rect().bottom() - sz.height() + frameWidth()); - - QLineEdit::resizeEvent(e); -} diff --git a/src/gui/filterlineedit.h b/src/gui/filterlineedit.h deleted file mode 100644 index c576829..0000000 --- a/src/gui/filterlineedit.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * QCMA: Cross-platform content manager assistant for the PS Vita - * - * Copyright (C) 2013 Xian Nox - * - * 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 FILTERLINEEDIT_H -#define FILTERLINEEDIT_H - -#include -#include - -class FilterLineEdit : public QLineEdit -{ - Q_OBJECT - -public: - explicit FilterLineEdit(QWidget *parent = 0); - -protected: - void focusInEvent(QFocusEvent *e); - void focusOutEvent(QFocusEvent *e); - void resizeEvent(QResizeEvent *e); - int frameWidth() const; - -private: - QToolButton *clearButton; - -private slots: - void updateCloseButton(const QString &text); - -}; - -#endif // FILTERLINEEDIT_H diff --git a/src/gui/main.cpp b/src/gui/main.cpp deleted file mode 100644 index cf29db4..0000000 --- a/src/gui/main.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 Q_OS_WIN32 -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "singleapplication.h" -#include "mainwidget.h" - -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -static void noMessageOutput(QtMsgType type, const QMessageLogContext &, const QString & str) -{ - const char * msg = str.toStdString().c_str(); -#else -static void noMessageOutput(QtMsgType type, const char *msg) -{ -#endif - Q_UNUSED(type); - Q_UNUSED(msg); -} - - -static bool setup_handlers() -{ - struct sigaction hup, term; - - hup.sa_handler = ClientManager::hupSignalHandler; - sigemptyset(&hup.sa_mask); - hup.sa_flags = 0; - hup.sa_flags |= SA_RESTART; - - if (sigaction(SIGHUP, &hup, NULL) != 0) { - qCritical("SIGHUP signal handle failed"); - return false; - } - - term.sa_handler = ClientManager::termSignalHandler; - sigemptyset(&term.sa_mask); - term.sa_flags |= SA_RESTART; - - if (sigaction(SIGTERM, &term, NULL) != 0) { - qCritical("SIGTERM signal handle failed"); - return false; - } - - return true; -} - -int main(int argc, char *argv[]) -{ - if(SingleApplication::sendMessage(QObject::tr("An instance of Qcma is already running"))) { - return 0; - } - - SingleApplication app(argc, argv); - -#ifndef Q_OS_WIN32 - // FIXME: libmtp sends SIGPIPE if a socket write fails crashing the whole app - // the proper fix is to libmtp to handle the cancel properly or ignoring - // SIGPIPE on the socket - signal(SIGPIPE, SIG_IGN); -#endif - - setup_handlers(); - - if(app.arguments().contains("--with-debug")) { - VitaMTP_Set_Logging(VitaMTP_DEBUG); - } else if(app.arguments().contains("--verbose")) { - VitaMTP_Set_Logging(VitaMTP_VERBOSE); - } else { - VitaMTP_Set_Logging(VitaMTP_NONE); -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - qInstallMessageHandler(noMessageOutput); -#else - qInstallMsgHandler(noMessageOutput); -#endif - } - -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); -#endif - - QTextStream(stdout) << "Starting Qcma " << QCMA_VER << endl; - - QTranslator translator; - QString locale = QLocale().system().name(); - qDebug() << "Current locale:" << locale; - - if(app.arguments().contains("--set-locale")) { - int index = app.arguments().indexOf("--set-locale"); - if(index + 1 < app.arguments().length()) { - qDebug("Enforcing locale: %s", app.arguments().at(index + 1).toUtf8().data()); - locale = app.arguments().at(index + 1); - } - } - - if(translator.load("qcma_" + locale, ":/resources/translations")) { - app.installTranslator(&translator); - } else { - qWarning() << "Cannot load translation for locale:" << locale; - } - - QTranslator system_translator; - system_translator.load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&system_translator); - - qDebug("Starting main thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId()); - - // set the organization/application for QSettings to work properly - app.setOrganizationName("codestation"); - app.setApplicationName("qcma"); - - //TODO: check if this is actually needed since we don't have a main window by default - QApplication::setQuitOnLastWindowClosed(false); - - bool showSystray = !app.arguments().contains("--no-systray"); - - MainWidget widget; - widget.prepareApplication(showSystray); - - // receive the message from another process - QObject::connect(&app, SIGNAL(messageAvailable(QString)), &widget, SLOT(receiveMessage(QString))); - - return app.exec(); -} diff --git a/src/gui/mainwidget.cpp b/src/gui/mainwidget.cpp deleted file mode 100644 index efbb3bb..0000000 --- a/src/gui/mainwidget.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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 "mainwidget.h" -#include "cmaclient.h" -#include "cmautils.h" - -#include "qlistdb.h" -#include "sqlitedb.h" - -#include "indicator/qtrayicon.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const QStringList MainWidget::path_list = QStringList() << "photoPath" << "musicPath" << "videoPath" << "appsPath" << "urlPath"; - -bool sleptOnce = false; - -MainWidget::MainWidget(QWidget *obj_parent) : - QWidget(obj_parent), db(NULL), configForm(NULL), managerForm(NULL), backupForm(NULL) -{ - trayIcon = NULL; -} - -void MainWidget::checkSettings() -{ - QSettings settings; - // make sure that all the paths are set, else show the config dialog - foreach(const QString &path, path_list) { - if(!settings.contains(path)) { - first_run = true; - configForm->show(); - return; - } - } - first_run = false; - managerForm->start(); -} - -void MainWidget::dialogResult(int result) -{ - if(result == QDialog::Accepted) { - if(first_run) { - first_run = false; - managerForm->start(); - } - } else if(first_run) { - qApp->quit(); - } -} - -void MainWidget::stopServer() -{ - setTrayTooltip(tr("Shutting down...")); - if(CmaClient::isRunning()) { - receiveMessage(tr("Stopping QCMA (disconnect your PS Vita)")); - } - managerForm->stop(); -} - -void MainWidget::deviceDisconnect() -{ -#ifndef Q_OS_WIN32 - trayIcon->setIcon("qcma_off"); -#else - trayIcon->setIcon("tray/qcma_off_16"); -#endif - qDebug("Icon changed - disconnected"); - setTrayTooltip(tr("Disconnected")); - receiveMessage(tr("The device has been disconnected")); -} - -void MainWidget::deviceConnect(QString message) -{ -#ifndef Q_OS_WIN32 - trayIcon->setIcon("qcma_on"); -#else - trayIcon->setIcon("tray/qcma_on_16"); -#endif - qDebug("Icon changed - connected"); - setTrayTooltip(message); - receiveMessage(message); -} - -void MainWidget::prepareApplication(bool showSystray) -{ - //TODO: delete database before exit - if(QSettings().value("useMemoryStorage", true).toBool()) { - db = new QListDB(); - } else { - db = new SQLiteDB(); - } - - configForm = new ConfigWidget(); - backupForm = new BackupManagerForm(db, this); - managerForm = new ClientManager(db, this); - connectSignals(); - - if(showSystray) { - createTrayIcon(); - } - - checkSettings(); -} - -void MainWidget::connectSignals() -{ - connect(configForm, SIGNAL(finished(int)), this, SLOT(dialogResult(int))); - connect(managerForm, SIGNAL(stopped()), qApp, SLOT(quit())); - connect(managerForm, SIGNAL(deviceConnected(QString)), this, SIGNAL(deviceConnected(QString))); - connect(managerForm, SIGNAL(deviceDisconnected()), this, SIGNAL(deviceDisconnected())); - connect(managerForm, SIGNAL(messageSent(QString)), this, SIGNAL(messageReceived(QString))); - connect(managerForm, SIGNAL(updated(int)), this, SIGNAL(databaseUpdated(int))); -} - -void MainWidget::setTrayTooltip(QString message) -{ - if(trayIcon) { - trayIcon->setToolTip(message); - } -} - -void MainWidget::openManager() -{ - backupForm->loadBackupListing(-1); - backupForm->show(); -} - -void MainWidget::showAboutDialog() -{ - QMessageBox about; - - about.setText(QString("Qcma ") + QCMA_VER); - about.setWindowTitle(tr("About Qcma")); -#ifndef QCMA_BUILD_HASH - about.setInformativeText(tr("Copyright (C) 2015 Codestation") + "\n"); -#else - about.setInformativeText(tr("Copyright (C) 2015 Codestation\n\nbuild hash: %1\nbuild branch: %2").arg(QCMA_BUILD_HASH).arg(QCMA_BUILD_BRANCH)); -#endif - about.setStandardButtons(QMessageBox::Ok); - about.setIconPixmap(QPixmap(":/main/resources/images/qcma.png")); - about.setDefaultButton(QMessageBox::Ok); - - // hack to expand the messagebox minimum size - QSpacerItem* horizontalSpacer = new QSpacerItem(300, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); - QGridLayout* widget_layout = (QGridLayout*)about.layout(); - widget_layout->addItem(horizontalSpacer, widget_layout->rowCount(), 0, 1, widget_layout->columnCount()); - - about.show(); - about.exec(); -} - -void MainWidget::showAboutQt() -{ - QMessageBox::aboutQt(this); -} - -void MainWidget::openConfig() -{ - configForm->open(); -} - -void MainWidget::refreshDatabase() -{ - managerForm->refreshDatabase(); -} - -TrayIndicator *MainWidget::createTrayObject(QWidget *obj_parent) -{ - TrayFunctionPointer create_tray = NULL; - -#ifdef Q_OS_LINUX - QString desktop = getenv("XDG_CURRENT_DESKTOP"); - qDebug() << "Current desktop: " << desktop; - -#ifdef QT_DEBUG - QString library_path = QApplication::applicationDirPath(); -#else - QString library_path = "/usr/lib/qcma"; -#endif - - if(desktop.toLower() == "kde") - { - // KDENotifier - QLibrary library(library_path + "/libqcma_kdenotifier.so"); - if(library.load()) - create_tray = reinterpret_cast(library.resolve("createTrayIndicator")); - else - qWarning() << "Cannot load libqcma_kdenotifier plugin"; - } - else - // try to use the appindicator if is available - // if(desktop.toLower() == "unity") - { - // AppIndicator - QLibrary library(library_path + "/libqcma_appindicator.so"); - if(library.load()) - create_tray = reinterpret_cast(library.resolve("createTrayIndicator")); - else - qWarning() << "Cannot load libqcma_appindicator plugin"; - } -#endif - // else QSystemTrayIcon - return (create_tray != NULL) ? create_tray(obj_parent) : createTrayIndicator(obj_parent); -} - -void MainWidget::createTrayIcon() -{ - trayIcon = createTrayObject(this); - trayIcon->init(); - -#ifndef Q_OS_WIN32 - trayIcon->setIcon("qcma_off"); -#else - trayIcon->setIcon("tray/qcma_off_16"); -#endif - trayIcon->show(); - - connect(trayIcon, SIGNAL(openConfig()), this, SLOT(openConfig())); - connect(trayIcon, SIGNAL(openManager()), this, SLOT(openManager())); - connect(trayIcon, SIGNAL(refreshDatabase()), this, SLOT(refreshDatabase())); - connect(trayIcon, SIGNAL(showAboutDialog()), this, SLOT(showAboutDialog())); - connect(trayIcon, SIGNAL(showAboutQt()), this, SLOT(showAboutQt())); - connect(trayIcon, SIGNAL(stopServer()), this, SLOT(stopServer())); - - connect(managerForm, SIGNAL(deviceConnected(QString)), this, SLOT(deviceConnect(QString))); - connect(managerForm, SIGNAL(deviceDisconnected()), this, SLOT(deviceDisconnect())); - connect(managerForm, SIGNAL(messageSent(QString)), this, SLOT(receiveMessage(QString))); -} - -void MainWidget::receiveMessage(QString message) -{ - // a timeout is added before the popups are displayed to prevent them from - // appearing in the wrong location - if(!sleptOnce) { - Sleeper::sleep(1); - sleptOnce = true; - } - - if(trayIcon->isVisible()) - trayIcon->showMessage(tr("Information"), message); -} - -MainWidget::~MainWidget() -{ - if(trayIcon) { - trayIcon->hide(); - } - delete db; -} diff --git a/src/gui/mainwidget.h b/src/gui/mainwidget.h deleted file mode 100644 index 4b40775..0000000 --- a/src/gui/mainwidget.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 MAINWIDGET_H -#define MAINWIDGET_H - -#include "cmaclient.h" -#include "clientmanager.h" -#include "forms/configwidget.h" -#include "forms/backupmanagerform.h" -#include "forms/progressform.h" - -#include -#include - -#include - -#include - -class TrayIndicator; - -class MainWidget : public QWidget -{ - Q_OBJECT - -public: - explicit MainWidget(QWidget *parent = 0); - ~MainWidget(); - - void prepareApplication(bool showSystray); - -private: - void connectSignals(); - void createTrayIcon(); - void checkSettings(); - TrayIndicator *createTrayObject(QWidget *parent); - - bool first_run; - - // database - Database *db; - - // forms - ConfigWidget *configForm; - ClientManager *managerForm; - BackupManagerForm *backupForm; - - TrayIndicator *trayIcon; - - const static QStringList path_list; - -signals: - void deviceConnected(QString); - void deviceDisconnected(); - void databaseUpdated(int count); - void messageReceived(QString message); - -public slots: - void openConfig(); - void openManager(); - void showAboutQt(); - void showAboutDialog(); - void refreshDatabase(); - void stopServer(); - -private slots: - void deviceConnect(QString message); - void deviceDisconnect(); - void dialogResult(int result); - void receiveMessage(QString message); - void setTrayTooltip(QString message); -}; - -#endif // MAINWIDGET_H diff --git a/src/gui/singleapplication.cpp b/src/gui/singleapplication.cpp deleted file mode 100644 index 277a985..0000000 --- a/src/gui/singleapplication.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 "singleapplication.h" - -#include - -const int SingleApplication::timeout = 500; -const QString SingleApplication::SHARED_KEY = "QCMA_KEY"; - -SingleApplication::SingleApplication(int &s_argc, char **s_argv) : - QApplication(s_argc, s_argv) -{ - server = new QLocalServer(this); - connect(server, SIGNAL(newConnection()), this, SLOT(receiveMessage())); - QLocalServer::removeServer(SHARED_KEY); - server->listen(SHARED_KEY); -} - -void SingleApplication::receiveMessage() -{ - QLocalSocket *socket = server->nextPendingConnection(); - - if(!socket->waitForReadyRead(timeout)) { - qDebug() << socket->errorString(); - return; - } - - QByteArray byteArray = socket->readAll(); - QString message = QString::fromUtf8(byteArray.constData()); - emit messageAvailable(message); - socket->disconnectFromServer(); -} - -bool SingleApplication::sendMessage(const QString &message) -{ - QLocalSocket socket; - socket.connectToServer(SHARED_KEY, QIODevice::WriteOnly); - - if(!socket.waitForConnected(timeout)) { - return false; - } - - socket.write(message.toUtf8()); - - if(!socket.waitForBytesWritten(timeout)) { - qDebug() << socket.errorString(); - return false; - } - - socket.disconnectFromServer(); - return true; -} diff --git a/src/gui/singleapplication.h b/src/gui/singleapplication.h deleted file mode 100644 index 1fee13a..0000000 --- a/src/gui/singleapplication.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 SINGLEAPPLICATION_H -#define SINGLEAPPLICATION_H - -#include -#include -#include -#include - -class SingleApplication : public QApplication -{ - Q_OBJECT -public: - explicit SingleApplication(int &argc, char **argv); - - static bool sendMessage(const QString &message); - -private: - QLocalServer *server; - - static const int timeout; - static const QString SHARED_KEY; - -signals: - void messageAvailable(QString message); - - -public slots: - void receiveMessage(); -}; - -#endif // SINGLEAPPLICATION_H diff --git a/src/httpdownloader.cpp b/src/httpdownloader.cpp deleted file mode 100644 index 338b6c8..0000000 --- a/src/httpdownloader.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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 . - */ - -#include "httpdownloader.h" - -#include -#include - -#include - -QNetworkReply *HTTPDownloader::reply = NULL; -volatile qint64 HTTPDownloader::m_contentLength = -1; - -QMutex HTTPDownloader::dataAvailable; -QMutex HTTPDownloader::dataRead; - -QByteArray HTTPDownloader::buffer; -bool HTTPDownloader::bufferReady = false; -qint64 HTTPDownloader::downloadLeft = 0; - -HTTPDownloader::HTTPDownloader(const QString &url, QObject *obj_parent) : - QObject(obj_parent), remote_url(url), firstRead(true) -{ - lengthMutex.lock(); -} - -HTTPDownloader::~HTTPDownloader() -{ - lengthMutex.unlock(); - dataAvailable.unlock(); -} - -void HTTPDownloader::downloadFile() -{ - dataAvailable.lock(); - qDebug("Starting http_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId()); - request = new QNetworkAccessManager(this); - reply = request->get(QNetworkRequest(QUrl(remote_url))); - connect(reply, SIGNAL(metaDataChanged()), this, SLOT(metadataChanged())); - connect(reply, SIGNAL(readyRead()), this, SLOT(readyRead())); - connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), - this, SLOT(error(QNetworkReply::NetworkError))); - connect(reply, SIGNAL(finished()), reply, SLOT(deleteLater())); - connect(reply, SIGNAL(finished()), request, SLOT(deleteLater())); -} - -void HTTPDownloader::metadataChanged() -{ - QVariant len = reply->header(QNetworkRequest::ContentLengthHeader); - if(len.isValid()) { - m_contentLength = len.toInt(); - buffer.resize(8); - *(uint64_t *)buffer.data() = m_contentLength; - downloadLeft = m_contentLength; - } else { - m_contentLength = -1; - } - lengthMutex.unlock(); -} - -qint64 HTTPDownloader::getFileSize() -{ - lengthMutex.lock(); - return m_contentLength; -} - -void HTTPDownloader::readyRead() -{ - QMutexLocker locker(&dataRead); - - downloadLeft -= reply->bytesAvailable(); - - buffer.append(reply->readAll()); - - if(buffer.size() >= 16 * 1024 || downloadLeft == 0) { - dataAvailable.unlock(); - } - - if(downloadLeft == 0) - qDebug() << "remote download complete"; -} - -int HTTPDownloader::readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen) -{ - if(downloadLeft && !dataAvailable.tryLock(30000)) { - qWarning("Connection timeout while receiving data from network, aborting"); - return -1; - } - - QMutexLocker locker(&dataRead); - - if(buffer.size() == 0) - return -1; - - int read_size = wantlen > (unsigned long)buffer.size() ? buffer.size() : wantlen; - - memcpy(data, buffer.data(), read_size); - buffer.remove(0, read_size); - - qDebug() << "sending data: " << read_size << ", left in buffer: " << buffer.size(); - - *gotlen = read_size; - - return PTP_RC_OK; -} - -void HTTPDownloader::error(QNetworkReply::NetworkError errorCode) -{ - Q_UNUSED(errorCode); - QString str_error = reply->errorString(); - - qWarning() << "Network error:" << str_error; - emit messageSent(tr("Network error: %1").arg(str_error)); - - lengthMutex.unlock(); - - // clear the buffer so a read callback can be aborted - QMutexLocker locker(&dataRead); - buffer.clear(); -} diff --git a/src/httpdownloader.h b/src/httpdownloader.h deleted file mode 100644 index 1d5c404..0000000 --- a/src/httpdownloader.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 . - */ - -#ifndef HTTPDOWNLOADER_H -#define HTTPDOWNLOADER_H - -#include -#include -#include -#include -#include - -#include - -class HTTPDownloader : public QObject -{ - Q_OBJECT -public: - explicit HTTPDownloader(const QString &url, QObject *parent = 0); - ~HTTPDownloader(); - qint64 getFileSize(); - -signals: - void messageSent(QString); - -public slots: - void downloadFile(); - static int readCallback(unsigned char *data, unsigned long wantlen, unsigned long *gotlen); - void metadataChanged(); - void readyRead(); - void error(QNetworkReply::NetworkError); - -private: - QString remote_url; - QNetworkAccessManager *request; - QMutex lengthMutex; - bool firstRead; - - static QMutex dataAvailable; - static QMutex dataRead; - - static QNetworkReply *reply; - volatile static qint64 m_contentLength; - - static QByteArray buffer; - static bool bufferReady; - static qint64 downloadLeft; -}; - -#endif // HTTPDOWNLOADER_H diff --git a/src/indicator/kdenotifier.cpp b/src/indicator/kdenotifier.cpp deleted file mode 100644 index a69fba1..0000000 --- a/src/indicator/kdenotifier.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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 . - */ - -#include "kdenotifier.h" - -KDENotifier::KDENotifier(const QString ¬ifier_id, QObject *obj_parent) : - KStatusNotifierItem(notifier_id, obj_parent) -{ -} diff --git a/src/indicator/kdenotifier.h b/src/indicator/kdenotifier.h deleted file mode 100644 index bfec040..0000000 --- a/src/indicator/kdenotifier.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 . - */ - -#ifndef KDENOTIFIER_H -#define KDENOTIFIER_H - -#include -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -#include -#endif - -class KDENotifier : public KStatusNotifierItem -{ - Q_OBJECT -public: - explicit KDENotifier(const QString &id, QObject *parent = 0); - -signals: - -public slots: - // block left click because it shows the default widget - virtual void activate (const QPoint &pos=QPoint()) { - Q_UNUSED(pos); - } -}; - -#endif // KDENOTIFIER_H diff --git a/src/indicator/kdenotifiertray.cpp b/src/indicator/kdenotifiertray.cpp deleted file mode 100644 index 3fcf0fa..0000000 --- a/src/indicator/kdenotifiertray.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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 . - */ - -#include "kdenotifiertray.h" -#ifndef ENABLE_KNOTIFICATIONS -#include -#else -#include -#endif - -KDENotifierTray::KDENotifierTray(QWidget *obj_parent) - : TrayIndicator(obj_parent) -{ -} - -void KDENotifierTray::init() -{ - options = new QAction(tr("Settings"), this); - reload = new QAction(tr("Refresh database"), this); - backup = new QAction(tr("Backup Manager"), this); - about = new QAction(tr("About QCMA"), this); - about_qt = new QAction(tr("About Qt"), this); - quit = new QAction(tr("Quit"), this); - - connect(options, SIGNAL(triggered()), this, SIGNAL(openConfig())); - connect(backup, SIGNAL(triggered()), this, SIGNAL(openManager())); - connect(reload, SIGNAL(triggered()), this, SIGNAL(refreshDatabase())); - connect(about, SIGNAL(triggered()), this, SIGNAL(showAboutDialog())); - connect(about_qt, SIGNAL(triggered()), this, SIGNAL(showAboutQt())); - connect(quit, SIGNAL(triggered()), this, SIGNAL(stopServer())); - -#ifndef ENABLE_KNOTIFICATIONS - KMenu *tray_icon_menu = new KMenu(this); -#else - QMenu *tray_icon_menu = new QMenu(this); -#endif - - tray_icon_menu->addAction(options); - tray_icon_menu->addAction(reload); - tray_icon_menu->addAction(backup); - tray_icon_menu->addSeparator(); - tray_icon_menu->addAction(about); - tray_icon_menu->addAction(about_qt); - tray_icon_menu->addSeparator(); - tray_icon_menu->addAction(quit); - - m_notifier_item = new KDENotifier("QcmaNotifier", this); - m_notifier_item->setContextMenu(tray_icon_menu); - m_notifier_item->setTitle("Qcma"); - m_notifier_item->setCategory(KStatusNotifierItem::ApplicationStatus); - m_notifier_item->setIconByPixmap(QIcon(":/main/resources/images/qcma_off.png")); - m_notifier_item->setStatus(KStatusNotifierItem::Active); - m_notifier_item->setToolTipTitle(tr("Qcma status")); - m_notifier_item->setToolTipIconByPixmap(QIcon(":/main/resources/images/qcma.png")); - m_notifier_item->setToolTipSubTitle(tr("Disconnected")); - m_notifier_item->setStandardActionsEnabled(false); -} - -void KDENotifierTray::showMessage(const QString &title, const QString &message) -{ - m_notifier_item->showMessage(title, message, "dialog-information", 3000); -} - -bool KDENotifierTray::isVisible() -{ - return true; -} - -void KDENotifierTray::setIcon(const QString &icon) -{ - m_notifier_item->setIconByPixmap(QIcon(":/main/resources/images/" + icon)); -} - -void KDENotifierTray::show() -{ -} - -void KDENotifierTray::hide() -{ -} - -// exported library function -TrayIndicator *createTrayIndicator(QWidget *parent) -{ - return new KDENotifierTray(parent); -} diff --git a/src/indicator/kdenotifiertray.h b/src/indicator/kdenotifiertray.h deleted file mode 100644 index 7333466..0000000 --- a/src/indicator/kdenotifiertray.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 . - */ - -#ifndef KDENOTIFIERTRAY_H -#define KDENOTIFIERTRAY_H - -#include "trayindicator.h" -#include "kdenotifier.h" - -class QAction; -class QSystemTrayIcon; - -class KDENotifierTray : public TrayIndicator -{ - Q_OBJECT -public: - explicit KDENotifierTray(QWidget *parent = 0); - void init(); - void setIcon(const QString &icon); - bool isVisible(); - void show(); - void hide(); - void showMessage(const QString &title, const QString &message); - -private: - //system tray - QAction *quit; - QAction *reload; - QAction *options; - QAction *backup; - QAction *about; - QAction *about_qt; - - KDENotifier *m_notifier_item; - -public slots: - -}; - -#endif // KDENOTIFIERTRAY_H diff --git a/src/indicator/qtrayicon.cpp b/src/indicator/qtrayicon.cpp deleted file mode 100644 index ff3036a..0000000 --- a/src/indicator/qtrayicon.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 . - */ - -#include "qtrayicon.h" - -#include -#include -#include - -#ifdef Q_OS_LINUX -#undef signals -extern "C" { -#include -} -#define signals public -#endif - -QTrayIcon::QTrayIcon(QWidget *obj_parent) - : TrayIndicator(obj_parent) -{ -#ifdef Q_OS_LINUX - notify_init("qcma"); -#endif -} - -QTrayIcon::~QTrayIcon() -{ -#ifdef Q_OS_LINUX - notify_uninit(); -#endif -} - -void QTrayIcon::init() -{ - options = new QAction(tr("Settings"), this); - reload = new QAction(tr("Refresh database"), this); - backup = new QAction(tr("Backup Manager"), this); - about = new QAction(tr("About QCMA"), this); - about_qt = new QAction(tr("About Qt"), this); - quit = new QAction(tr("Quit"), this); - - connect(options, SIGNAL(triggered()), this, SIGNAL(openConfig())); - connect(backup, SIGNAL(triggered()), this, SIGNAL(openManager())); - connect(reload, SIGNAL(triggered()), this, SIGNAL(refreshDatabase())); - connect(about, SIGNAL(triggered()), this, SIGNAL(showAboutDialog())); - connect(about_qt, SIGNAL(triggered()), this, SIGNAL(showAboutQt())); - connect(quit, SIGNAL(triggered()), this, SIGNAL(stopServer())); - - QMenu *tray_icon_menu = new QMenu(this); - - tray_icon_menu->addAction(options); - tray_icon_menu->addAction(reload); - tray_icon_menu->addAction(backup); - tray_icon_menu->addSeparator(); - tray_icon_menu->addAction(about); - tray_icon_menu->addAction(about_qt); - tray_icon_menu->addSeparator(); - tray_icon_menu->addAction(quit); - - m_tray_icon = new QSystemTrayIcon(this); - m_tray_icon->setContextMenu(tray_icon_menu); -} - - -void QTrayIcon::showMessage(const QString &title, const QString &message) -{ -#ifdef Q_OS_LINUX - NotifyNotification *notif = notify_notification_new(qPrintable(title), qPrintable(message), "dialog-information"); - notify_notification_show(notif, NULL); - g_object_unref(G_OBJECT(notif)); -#else - m_tray_icon->showMessage(title, message); -#endif -} - -bool QTrayIcon::isVisible() -{ - return m_tray_icon->isVisible(); -} - -void QTrayIcon::setIcon(const QString &icon) -{ - QIcon qicon(":/main/resources/images/" + icon + ".png"); - m_tray_icon->setIcon(qicon); -} - -void QTrayIcon::show() -{ - m_tray_icon->show(); -} - -void QTrayIcon::hide() -{ - m_tray_icon->hide(); -} - -// exported library function -TrayIndicator *createTrayIndicator(QWidget *parent) -{ - return new QTrayIcon(parent); -} diff --git a/src/indicator/qtrayicon.h b/src/indicator/qtrayicon.h deleted file mode 100644 index 14392e2..0000000 --- a/src/indicator/qtrayicon.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 . - */ - -#ifndef QTRAYICON_H -#define QTRAYICON_H - -#include "trayindicator.h" - -class QAction; -class QSystemTrayIcon; - -class QTrayIcon : public TrayIndicator -{ - Q_OBJECT -public: - explicit QTrayIcon(QWidget *parent = 0); - ~QTrayIcon(); - void init(); - void setIcon(const QString &icon); - bool isVisible(); - void show(); - void hide(); - void showMessage(const QString &title, const QString &message); - -private: - //system tray - QAction *quit; - QAction *reload; - QAction *options; - QAction *backup; - QAction *about; - QAction *about_qt; - - QSystemTrayIcon *m_tray_icon; -}; - -#endif // QTRAYICON_H diff --git a/src/indicator/trayindicator.h b/src/indicator/trayindicator.h deleted file mode 100644 index 1934ee7..0000000 --- a/src/indicator/trayindicator.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 . - */ - -#ifndef TRAYINDICATOR_H -#define TRAYINDICATOR_H - -#include -#include - -#include "trayindicator_global.h" - -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -// in Qt4 signals are protected -#undef signals -#define signals public -#endif - -class TrayIndicator : public QWidget -{ - Q_OBJECT -public: - ~TrayIndicator() {} - virtual void init() = 0; - virtual bool isVisible() = 0; - virtual void setIcon(const QString &icon) = 0; - virtual void showMessage(const QString &title, const QString &message) = 0; - virtual void show() = 0; - virtual void hide() = 0; - -protected: - TrayIndicator(QWidget *obj_parent = 0) : QWidget(obj_parent) {} - -signals: - void openConfig(); - void openManager(); - void refreshDatabase(); - void showAboutDialog(); - void showAboutQt(); - void stopServer(); - -}; - -typedef TrayIndicator *(*TrayFunctionPointer)(QWidget *parent); -extern "C" TRAYINDICATORSHARED_EXPORT TrayIndicator *createTrayIndicator(QWidget *parent = 0); - -#endif // TRAYINDICATOR_H diff --git a/src/indicator/trayindicator_global.h b/src/indicator/trayindicator_global.h deleted file mode 100644 index 3033fc6..0000000 --- a/src/indicator/trayindicator_global.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 . - */ - -#ifndef TRAYINDICATOR_GLOBAL_H -#define TRAYINDICATOR_GLOBAL_H - -#include - -#ifdef Q_OS_LINUX -#if defined(QCMA_TRAYINDICATOR_LIBRARY) -# define TRAYINDICATORSHARED_EXPORT Q_DECL_EXPORT -#else -# define TRAYINDICATORSHARED_EXPORT Q_DECL_IMPORT -#endif -#else -# define TRAYINDICATORSHARED_EXPORT -#endif - -#endif // TRAYINDICATOR_GLOBAL_H diff --git a/src/indicator/trayindicator_import.h b/src/indicator/trayindicator_import.h deleted file mode 120000 index 886a438..0000000 --- a/src/indicator/trayindicator_import.h +++ /dev/null @@ -1 +0,0 @@ -trayindicator.h \ No newline at end of file diff --git a/src/indicator/unityindicator.cpp b/src/indicator/unityindicator.cpp deleted file mode 100644 index dc67bcf..0000000 --- a/src/indicator/unityindicator.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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 . - */ - -#include "unityindicator.h" - -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -#include -#else -#include -#define QStandardPaths QDesktopServices -#define writableLocation storageLocation -#endif - -#include -#include -#include - -#undef signals - -extern "C" { - -#include - -void optionsIndicator(GtkMenu *menu, gpointer data); -void reloadIndicator(GtkMenu *menu, gpointer data); -void backupIndicator(GtkMenu *menu, gpointer data); -void aboutIndicator(GtkMenu *menu, gpointer data); -void aboutQtIndicator(GtkMenu *menu, gpointer data); -void quitIndicator(GtkMenu *menu, gpointer data); -} - -#define signals public - -UnityIndicator::UnityIndicator(QWidget *obj_parent) : - TrayIndicator(obj_parent) -{ - notify_init("qcma"); -} - -UnityIndicator::~UnityIndicator() -{ - notify_uninit(); - for(QVector >::iterator it = m_handlers.begin(); it != m_handlers.end(); ++it) - { - g_signal_handler_disconnect(it->first, it->second); - } -} - -void optionsIndicator(GtkMenu *, gpointer data) -{ - UnityIndicator *m_this = reinterpret_cast(data); - emit m_this->openConfig(); -} - -void reloadIndicator(GtkMenu *, gpointer data) -{ - UnityIndicator *m_this = reinterpret_cast(data); - emit m_this->refreshDatabase(); -} - -void backupIndicator(GtkMenu *, gpointer data) -{ - UnityIndicator *m_this = reinterpret_cast(data); - emit m_this->openManager(); -} - -void aboutIndicator(GtkMenu *, gpointer data) -{ - UnityIndicator *m_this = reinterpret_cast(data); - emit m_this->showAboutDialog(); -} - -void aboutQtIndicator(GtkMenu *, gpointer data) -{ - UnityIndicator *m_this = reinterpret_cast(data); - emit m_this->showAboutQt(); -} - -void quitIndicator(GtkMenu *, gpointer data) -{ - UnityIndicator *m_this = reinterpret_cast(data); - emit m_this->stopServer(); -} - -void UnityIndicator::init() -{ - GtkWidget *menu = gtk_menu_new(); - - GtkWidget *options = gtk_menu_item_new_with_label(qPrintable(tr("Settings"))); - GtkWidget *reload = gtk_menu_item_new_with_label(qPrintable(tr("Refresh database"))); - GtkWidget *backup = gtk_menu_item_new_with_label(qPrintable(tr("Backup Manager"))); - GtkWidget *separator1 = gtk_separator_menu_item_new(); - GtkWidget *about = gtk_menu_item_new_with_label(qPrintable(tr("About QCMA"))); - GtkWidget *about_qt = gtk_menu_item_new_with_label(qPrintable(tr("About Qt"))); - GtkWidget *separator2 = gtk_separator_menu_item_new(); - GtkWidget *quit = gtk_menu_item_new_with_label(qPrintable(tr("Quit"))); - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), options); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), reload); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), backup); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator1); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), about); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), about_qt); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator2); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit); - - gulong gobject_handler; - gobject_handler = g_signal_connect(options, "activate", G_CALLBACK(optionsIndicator), this); - m_handlers.append(QPair(options, gobject_handler)); - gobject_handler = g_signal_connect(reload, "activate", G_CALLBACK(reloadIndicator), this); - m_handlers.append(QPair(reload, gobject_handler)); - gobject_handler = g_signal_connect(backup, "activate", G_CALLBACK(backupIndicator), this); - m_handlers.append(QPair(backup, gobject_handler)); - gobject_handler = g_signal_connect(about, "activate", G_CALLBACK(aboutIndicator), this); - m_handlers.append(QPair(about, gobject_handler)); - gobject_handler = g_signal_connect(about_qt, "activate", G_CALLBACK(aboutQtIndicator), this); - m_handlers.append(QPair(about_qt, gobject_handler)); - gobject_handler = g_signal_connect(quit, "activate", G_CALLBACK(quitIndicator), this); - m_handlers.append(QPair(quit, gobject_handler)); - - gtk_widget_show(options); - gtk_widget_show(reload); - gtk_widget_show(backup); - gtk_widget_show(separator1); - gtk_widget_show(about); - gtk_widget_show(about_qt); - gtk_widget_show(separator2); - gtk_widget_show(quit); - - m_indicator = app_indicator_new( - "qcma-appindicator", - "qcma-messages", - APP_INDICATOR_CATEGORY_APPLICATION_STATUS - ); - - QString icon_path; - QString icon_name = "share/icons/hicolor/64x64/actions/qcma_on.png"; - - if(QFile("/usr/" + icon_name).exists()) - icon_path = QFileInfo("/usr/" + icon_name).absolutePath(); - else if(QFile("/usr/local" + icon_name).exists()) - icon_path = QFileInfo("/usr/" + icon_name).absolutePath(); - - if(!icon_path.isEmpty()) - { - qDebug() << "Using " << icon_path << " as icon theme path"; - app_indicator_set_icon_theme_path(m_indicator, qPrintable(icon_path)); - } - else - qWarning() << "Cannot find qcma icons."; - - app_indicator_set_status(m_indicator, APP_INDICATOR_STATUS_ACTIVE); - app_indicator_set_menu(m_indicator, GTK_MENU(menu)); -} - -bool UnityIndicator::isVisible() -{ - return true; -} - -void UnityIndicator::setIcon(const QString &icon) -{ - app_indicator_set_icon_full(m_indicator, qPrintable(icon), "icon"); -} - -void UnityIndicator::show() -{ -} - -void UnityIndicator::hide() -{ -} - -void UnityIndicator::showMessage(const QString &title, const QString &message) -{ - NotifyNotification *notif = notify_notification_new(qPrintable(title), qPrintable(message), "dialog-information"); - notify_notification_show(notif, NULL); - g_object_unref(G_OBJECT(notif)); -} - -// exported library function -TrayIndicator *createTrayIndicator(QWidget *parent) -{ - return new UnityIndicator(parent); -} diff --git a/src/indicator/unityindicator.h b/src/indicator/unityindicator.h deleted file mode 100644 index 0dc56d3..0000000 --- a/src/indicator/unityindicator.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 . - */ - -#ifndef UNITYINDICATOR_H -#define UNITYINDICATOR_H - -#include "trayindicator.h" - -#include - -#undef signals - -extern "C" { -#include -#include -} - -#define signals public - -class UnityIndicator : public TrayIndicator -{ - Q_OBJECT -public: - explicit UnityIndicator(QWidget *parent = 0); - ~UnityIndicator(); - void init(); - void setIcon(const QString &icon); - bool isVisible(); - void show(); - void hide(); - void showMessage(const QString &title, const QString &message); - -private: - AppIndicator *m_indicator; - QVector > m_handlers; -}; - -#endif // UNITYINDICATOR_H diff --git a/src/qlistdb.cpp b/src/qlistdb.cpp deleted file mode 100644 index 97eec42..0000000 --- a/src/qlistdb.cpp +++ /dev/null @@ -1,610 +0,0 @@ -/* - * 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 "cmautils.h" -#include "qlistdb.h" -#include "cmaobject.h" - -#include -#include -#include -#include -#include -#include - -QListDB::QListDB(QObject *obj_parent) : - Database(obj_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((*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_PACKAGE, 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]); - bool skipCurrent = false; - int dir_count; - - switch(ohfi_array[i]) { - case VITA_OHFI_MUSIC: - obj->initObject(settings.value("musicPath").toString()); - skipCurrent = settings.value("musicSkip", false).toBool(); - break; - - case VITA_OHFI_PHOTO: - obj->initObject(settings.value("photoPath").toString()); - skipCurrent = settings.value("photoSkip", false).toBool(); - break; - - case VITA_OHFI_VIDEO: - obj->initObject(settings.value("videoPath").toString()); - skipCurrent = settings.value("videoSkip", false).toBool(); - 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()); - break; - - case VITA_OHFI_PACKAGE: - obj->initObject(settings.value("pkgPath").toString()); - } - - root_list list; - list << obj; - emit directoryAdded(obj->m_path); - - if(!skipCurrent) { - dir_count = recursiveScanRootDirectory(list, obj, ohfi_array[i]); - } else { - dir_count = 0; - } - - 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->m_path) { - last_dir = last_dir->parent; - } - - return last_dir; -} - -int QListDB::scanRootDirectory(root_list &list, int ohfi_type) -{ - int obj_file_type = -1; - int total_objects = 0; - CMAObject *last_dir = list.first(); - QDir dir(last_dir->m_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((obj_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, obj_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 *obj_parent, int ohfi_type) -{ - int obj_file_type = -1; - int total_objects = 0; - - QDir dir(obj_parent->m_path); - dir.setSorting(QDir::Name | QDir::DirsFirst); - QFileInfoList qsl = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot, QDir::Time); - - foreach(const QFileInfo &info, qsl) { - - if(!continueOperation()) { - return -1; - } - - if(info.isFile() && (obj_file_type = checkFileType(info.absoluteFilePath(), ohfi_type)) < 0) { - //qDebug("Excluding %s from database", info.absoluteFilePath().toStdString().c_str());> - } else { - CMAObject *obj = new CMAObject(obj_parent); - obj->initObject(info, obj_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->m_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::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(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 *obj_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(MASK_SET(type, VITA_DIR_TYPE_MASK_ARTISTS)) { - // unimplemented - return 0; - } else if(MASK_SET(type, VITA_DIR_TYPE_MASK_GENRES)) { - // unimplemented - return 0; - } else if(MASK_SET(type, VITA_DIR_TYPE_MASK_PLAYLISTS)) { - // unimplemented - return 0; - } else if(MASK_SET(type, VITA_DIR_TYPE_MASK_MONTH)) { - // 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 = (obj_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; -} - -bool QListDB::getObjectList(int ohfi, metadata_t **metadata) -{ - find_data iters; - if(find(ohfi, iters)) { - CMAObject *object; - do { - object = *iters.it; - *metadata = &object->metadata; - metadata = &(*metadata)->next_metadata; - *metadata = NULL; - object = *++iters.it; - } while(iters.it != iters.end && object->metadata.ohfiParent >= OHFI_OFFSET); - return true; - } - return false; -} - - -int QListDB::getObjectMetadatas(int parent_ohfi, metadata_t **metadata, int index, int max_number) -{ - QMutexLocker locker(&mutex); - - CMARootObject *obj_parent = static_cast(ohfiToObject(parent_ohfi)); - - if(obj_parent == NULL) { - return 0; - } - - if(obj_parent->metadata.dataType & File) { - *metadata = &obj_parent->metadata; - return 1; - } - - int type = obj_parent->metadata.type; - - if(obj_parent->metadata.ohfi < OHFI_OFFSET && obj_parent->filters) { // if we have filters - if(parent_ohfi == obj_parent->metadata.ohfi) { // if we are looking at root - return obj_parent->getFilters(metadata); - } else { // we are looking at a filter - for(int j = 0; j < obj_parent->num_filters; j++) { - if(obj_parent->filters[j].ohfi == parent_ohfi) { - type = obj_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(obj_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->m_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; -} diff --git a/src/qlistdb.h b/src/qlistdb.h deleted file mode 100644 index 2d9d357..0000000 --- a/src/qlistdb.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 QLISTDB_H -#define QLISTDB_H - -#include "database.h" -#include "cmarootobject.h" - -#include -#include -#include -#include -#include - -#include - -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 getObjectList(int ohfi, metadata_t **metadata); - 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::const_iterator it; - QList::const_iterator end; - } find_data; - - typedef QList root_list; - typedef QMap 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 diff --git a/src/sforeader.cpp b/src/sforeader.cpp deleted file mode 100644 index d3982c7..0000000 --- a/src/sforeader.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 "sforeader.h" - -#include - -SfoReader::SfoReader() -{ -} - -bool SfoReader::load(const QString &path) -{ - QFile file(path); - if(file.open(QIODevice::ReadOnly)) { - data = file.readAll(); - key_offset = data.constData(); - header = (sfo_header *)key_offset; - index = (sfo_index *)(key_offset + sizeof(sfo_header)); - return true; - } - return false; -} - -const char *SfoReader::value(const char *key, const char *defaultValue) -{ - const char *base_key = key_offset + header->key_offset; - for(uint i = 0; i < header->pair_count; i++) { - const char *curr_key = base_key + index[i].key_offset; - if(strcmp(key, curr_key) == 0) { - return key_offset + header->value_offset + index[i].data_offset; - } - } - return defaultValue; -} diff --git a/src/sforeader.h b/src/sforeader.h deleted file mode 100644 index e387aa2..0000000 --- a/src/sforeader.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 SFOREADER_H -#define SFOREADER_H - -#include - -class SfoReader -{ -public: - SfoReader(); - bool load(const QString &path); - const char *value(const char *key, const char *defaultValue); - -private: - typedef struct { - quint16 key_offset; - uchar alignment; - uchar data_type; - quint32 value_size; - quint32 value_size_with_padding; - quint32 data_offset; - } __attribute__((packed)) sfo_index; - - typedef struct { - char id[4]; - quint32 version; - quint32 key_offset; - quint32 value_offset; - quint32 pair_count; - } __attribute__((packed)) sfo_header; - - QByteArray data; - const char *key_offset; - const sfo_header *header; - const sfo_index *index; -}; - -#endif // SFOREADER_H diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp deleted file mode 100644 index fa874a7..0000000 --- a/src/sqlitedb.cpp +++ /dev/null @@ -1,1318 +0,0 @@ -/* - * 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 . - */ - -#include "cmautils.h" -#include "sqlitedb.h" -#include "sforeader.h" -#include "avdecoder.h" - -#include -#include -#include -#include -#include - -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -#include -#else -#include -#define QStandardPaths QDesktopServices -#define writableLocation storageLocation -#endif - -#include -#include - -static const char create_adjacent[] = "CREATE TABLE IF NOT EXISTS adjacent_objects (" - "parent_id INTEGER NOT NULL REFERENCES object_node(object_id) ON DELETE CASCADE," - "child_id INTEGER NOT NULL REFERENCES object_node(object_id) ON DELETE CASCADE)"; - -static const char create_obj_node[] = "CREATE TABLE IF NOT EXISTS object_node (" - "object_id INTEGER PRIMARY KEY AUTOINCREMENT," - "type INTEGER NOT NULL," - "data_type INTEGER NOT NULL," - "title TEXT," - "child_count INTEGER NOT NULL DEFAULT 0," - "reference_count INTEGER NOT NULL DEFAULT 0);"; - -static const char create_sources[] = "CREATE TABLE IF NOT EXISTS sources (" - "object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE," - "path TEXT NOT NULL CHECK (LENGTH(path) > 0)," - "size INTEGER," - "date_created TIMESTAMP," - "date_modified TIMESTAMP)"; - -static const char create_music[] = "CREATE TABLE IF NOT EXISTS music (" - "object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE," - "file_format INTEGER," - "audio_bitrate INTEGER," - "audio_codec INTEGER," - "duration INTEGER," - "genre_id INTEGER REFERENCES object_node(object_id) ON DELETE SET NULL," - "track_id INTEGER REFERENCES object_node(object_id) ON DELETE SET NULL," - "artist_id INTEGER REFERENCES object_node(object_id) ON DELETE SET NULL," - "album_id INTEGER REFERENCES object_node(object_id) ON DELETE SET NULL," - "artist TEXT," - "album TEXT," - "track_number INTEGER)"; - -static const char create_apps[] = "CREATE TABLE IF NOT EXISTS application (" - "object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE," - "title TEXT NOT NULL CHECK (LENGTH(title) > 0)," - "app_type INTEGER)"; - -static const char create_virtual[] = "CREATE TABLE IF NOT EXISTS virtual_nodes (" - "object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE," - "app_type INTEGER)"; - -static const char create_photos[] = "CREATE TABLE IF NOT EXISTS photos (" - "object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE," - "date_created TIMESTAMP," - "month_created TEXT," - "file_format INTEGER," - "photo_codec INTEGER," - "width INTEGER," - "height INTEGER)"; - -static const char create_videos[] = "CREATE TABLE IF NOT EXISTS videos (" - "object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE," - "file_format INTEGER," - "parental_level INTEGER," - "explanation TEXT," - "copyright TEXT," - "width INTEGER," - "height INTEGER," - "video_codec INTEGER," - "video_bitrate INTEGER," - "audio_codec INTEGER," - "audio_bitrate INTEGER," - "duration INTEGER)"; - -static const char create_savedata[] = "CREATE TABLE IF NOT EXISTS savedata (" - "object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE," - "detail TEXT," - "dir_name TEXT," - "title TEXT," - "date_updated TIMESTAMP)"; - -static const char create_trigger_node[] = "CREATE TRIGGER IF NOT EXISTS trg_objnode_deletechilds BEFORE DELETE ON object_node " - "FOR EACH ROW BEGIN " - "DELETE FROM object_node WHERE object_id IN " - "(SELECT child_id FROM adjacent_objects WHERE parent_id == OLD.object_id);" - "END"; - -static const char create_trigger_adjins[] = "CREATE TRIGGER IF NOT EXISTS trg_adjacentobjects_ins AFTER INSERT ON adjacent_objects " - "FOR EACH ROW BEGIN " - "UPDATE object_node SET child_count = child_count + 1 WHERE object_id = NEW.parent_id;" - "UPDATE object_node SET reference_count = reference_count + 1 WHERE object_id = NEW.child_id;" - "END"; - -static const char create_trigger_adjdel[] = "CREATE TRIGGER IF NOT EXISTS trg_adjacentobjects_del AFTER DELETE ON adjacent_objects " - "FOR EACH ROW BEGIN " - "UPDATE object_node SET child_count = child_count - 1 WHERE object_id = OLD.parent_id;" - "UPDATE object_node SET reference_count = reference_count - 1 WHERE object_id = OLD.child_id;" - "DELETE FROM object_node WHERE object_id = OLD.parent_id AND child_count <= 0;" - "DELETE FROM object_node WHERE object_id = OLD.child_id AND reference_count <= 0;" - "END"; - -static const char *table_list[] = { - create_adjacent, create_obj_node, create_sources, - create_music, create_photos, create_videos, create_savedata, create_apps, create_virtual -}; - -static const char *trigger_list[] = { - create_trigger_node, create_trigger_adjins, create_trigger_adjdel -}; - -static 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 - }; - -SQLiteDB::SQLiteDB(QObject *obj_parent) : - Database(obj_parent) -{ - m_uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString(); - thread = new QThread(); - moveToThread(thread); - timer = new QTimer(); - thread->start(); - timer->setInterval(0); - timer->setSingleShot(true); - connect(timer, SIGNAL(timeout()), this, SLOT(process())); - - // fetch a configured database path if it exists - QString db_path = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - db_path = QSettings().value("databasePath", db_path).toString(); - QDir(QDir::root()).mkpath(db_path); - - db = QSqlDatabase::addDatabase("QSQLITE"); - db.setDatabaseName(db_path + QDir::separator() + "qcma.sqlite"); -} - -SQLiteDB::~SQLiteDB() -{ - db.close(); - timer->stop(); - delete timer; - thread->quit(); - thread->wait(); - delete thread; -} - - -void SQLiteDB::setUUID(const QString &uuid) -{ - m_uuid = uuid; - QSettings().setValue("lastAccountId", uuid); -} - -bool SQLiteDB::load() -{ - bool success = false; - - if(db.open()) { - QSqlQuery query; - query.exec("PRAGMA foreign_keys = ON"); - query.exec("PRAGMA synchronous = OFF"); - query.exec("PRAGMA user_version = 1"); - query.exec("PRAGMA journal_mode = MEMORY"); - query.exec("PRAGMA recursive_triggers = true"); - query.exec("PRAGMA vacuum_db.synchronous = OFF"); - - qDebug() << "Database created/registered"; - success = !initialize(); - } else { - const QSqlError error = db.lastError(); - qWarning() << "Error opening connection to the database:" << error.text(); - } - - return success; -} - -bool SQLiteDB::rescan() -{ - if(mutex.tryLock(1000)) { - if(m_uuid != "ffffffffffffffff") { - timer->start(); - return true; - } else { - mutex.unlock(); - return false; - } - } - return false; -} - -void SQLiteDB::clear() -{ - db.close(); - //QSqlDatabase::removeDatabase("QSQLITE"); - QString db_path = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - db_path = QSettings().value("databasePath", db_path).toString(); - QFile(db_path + QDir::separator() + "qcma.sqlite").remove(); - load(); -} - -bool SQLiteDB::initialize() -{ - QSqlQuery query; - - for(unsigned int i = 0; i < sizeof(table_list) / sizeof(const char *); i++) { - if(!query.exec(table_list[i])) { - qDebug() << query.lastError(); - return false; - } - } - - for(unsigned int i = 0; i < sizeof(trigger_list) / sizeof(const char *); i++) { - if(!query.exec(trigger_list[i])) { - qDebug() << query.lastError(); - return false; - } - } - - // force object_id to start at 256 - if(query.exec("INSERT INTO object_node (object_id, data_type, type) VALUES (255, 0, 0)")) { - query.exec("DELETE FROM object_node WHERE object_id = 255"); - } - return true; -} - -QSqlError SQLiteDB::getLastError() -{ - return db.lastError(); -} - -int SQLiteDB::create() -{ - int total_objects = 0; - - db.transaction(); - - if(!insertVirtualEntries()) { - db.rollback(); - return -1; - } - - for(int i = 0, max = sizeof(ohfi_array) / sizeof(int); i < max; i++) { - QString base_path = getBasePath(ohfi_array[i]); - int dir_count = recursiveScanRootDirectory(base_path, NULL, ohfi_array[i], ohfi_array[i]); - - if(dir_count < 0) { - db.rollback(); - return -1; - } - - //qDebug("Added %i objects for OHFI %#02X", dir_count, ohfi_array[i]); - - total_objects += dir_count; - } - db.commit(); - return total_objects; -} - -QString SQLiteDB::getBasePath(int root_ohfi) -{ - QString base_path; - QSettings settings; - - switch(root_ohfi) { - case VITA_OHFI_MUSIC: - base_path = settings.value("musicPath").toString(); - break; - case VITA_OHFI_VIDEO: - base_path = settings.value("videoPath").toString(); - break; - case VITA_OHFI_PHOTO: - base_path = settings.value("photoPath").toString(); - break; - case VITA_OHFI_BACKUP: - base_path = settings.value("appsPath").toString() + "/SYSTEM/" + m_uuid; - break; - case VITA_OHFI_VITAAPP: - base_path = settings.value("appsPath").toString() + "/APP/" + m_uuid; - break; - case VITA_OHFI_PSPAPP: - base_path = settings.value("appsPath").toString() + "/PGAME/" + m_uuid; - break; - case VITA_OHFI_PSPSAVE: - base_path = settings.value("appsPath").toString() + "/PSAVEDATA/" + m_uuid; - break; - case VITA_OHFI_PSXAPP: - base_path = settings.value("appsPath").toString() + "/PSGAME/" + m_uuid; - break; - case VITA_OHFI_PSMAPP: - base_path = settings.value("appsPath").toString() + "/PSM/" + m_uuid; - break; - } - return base_path; -} - -int SQLiteDB::recursiveScanRootDirectory(const QString &base_path, const QString &rel_path, int parent_ohfi, int root_ohfi) -{ - int total_objects = 0; - - QDir dir(base_path + "/" + rel_path); - dir.setSorting(QDir::Name); - QFileInfoList qsl = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot); - - foreach(const QFileInfo &info, qsl) { - - if(!continueOperation()) { - return -1; - } - - //qDebug() << "Processing " << info.fileName(); - - QString rel_name = rel_path.isNull() ? info.fileName() : rel_path + "/" + info.fileName(); - - int ohfi = insertObjectEntryInternal(base_path, rel_name, parent_ohfi, root_ohfi); - - if(ohfi > 0) { - // update progress dialog - if(info.isDir()) { - emit directoryAdded(base_path + "/" + rel_name); - int inserted = recursiveScanRootDirectory(base_path, rel_name, ohfi, root_ohfi); - if(inserted < 0) { - return -1; - } - - total_objects += inserted; - qint64 dirsize = getChildenTotalSize(ohfi); - setObjectSize(ohfi, dirsize); - } else if(info.isFile()) { - emit fileAdded(info.fileName()); - total_objects++; - } - } - } - - return total_objects; -} - -int SQLiteDB::insertObjectEntry(const QString &path, const QString &name, int parent_ohfi) -{ - int ohfi; - int type; - - if((type = getObjectType(parent_ohfi)) == 0) { - return 0; - } - db.transaction(); - if((ohfi = insertObjectEntryInternal(path, name, parent_ohfi, type)) == 0) { - db.rollback(); - } - db.commit(); - - return ohfi; -} - -int SQLiteDB::insertObjectEntryInternal(const QString &path, const QString &name, int parent_ohfi, int root_ohfi) -{ - int ohfi = 0; - QFileInfo info(path, name); - - if(info.isDir()) { - ohfi = insertDefaultEntry(path, name, info.fileName(), parent_ohfi, Folder); - switch(parent_ohfi) { - case VITA_OHFI_VITAAPP: - case VITA_OHFI_PSPAPP: - case VITA_OHFI_PSXAPP: - case VITA_OHFI_PSMAPP: - case VITA_OHFI_BACKUP: - insertApplicationEntry(name, ohfi, parent_ohfi); - } - } else { - switch(root_ohfi) { - case VITA_OHFI_MUSIC: - ohfi = insertMusicEntry(path, name, parent_ohfi, File | Music); - break; - case VITA_OHFI_PHOTO: - ohfi = insertPhotoEntry(path, name, parent_ohfi, File | Photo); - break; - case VITA_OHFI_VIDEO: - ohfi = insertVideoEntry(path, name, parent_ohfi, File | Video); - break; - case VITA_OHFI_PSPSAVE: - ohfi = insertSavedataEntry(path, name, parent_ohfi, File | SaveData); - break; - case VITA_OHFI_VITAAPP: - case VITA_OHFI_PSPAPP: - case VITA_OHFI_PSXAPP: - case VITA_OHFI_PSMAPP: - case VITA_OHFI_BACKUP: - ohfi = insertDefaultEntry(path, name, info.fileName(), parent_ohfi, File | App); - } - } - return ohfi; -} - - -int SQLiteDB::getPathId(const QString &path) -{ - QSqlQuery query(QString("SELECT object_id from sources WHERE path = %1").arg(path)); - if(query.next()) { - return query.value(0).toInt(); - } else { - qDebug() << query.lastError(); - return -1; - } -} - -QString SQLiteDB::getPathFromId(int ohfi) -{ - QSqlQuery query(QString("SELECT path FROM sources WHERE object_id = %1").arg(ohfi)); - if(query.next()) { - return query.value(0).toString(); - } else { - qDebug() << query.lastError(); - return QString(); - } -} - -bool SQLiteDB::updateSize(int ohfi, quint64 size) -{ - QSqlQuery query(QString("UPDATE sources SET size = %1 WHERE object_id == %2").arg(size).arg(ohfi)); - return query.exec(); -} - -bool SQLiteDB::deleteEntry(int ohfi) -{ - QSqlQuery query(QString("DELETE FROM object_node WHERE object_id == %1").arg(ohfi)); - bool ret = query.exec(); - if(!ret) { - qDebug() << query.lastError(); - } - return ret; -} - -bool SQLiteDB::updateAdjacencyList(int ohfi, int id_parent) -{ - QSqlQuery query; - query.prepare("SELECT * FROM adjacent_objects WHERE parent_id == :parent_id AND child_id == :child_id"); - query.bindValue(0, id_parent); - query.bindValue(1, ohfi); - - if(query.exec() && query.next()) { - return true; - } - - query.prepare("INSERT INTO adjacent_objects (parent_id, child_id)" - "VALUES (:parentid, :child_id)"); - query.bindValue(0, id_parent); - query.bindValue(1, ohfi); - bool ret = query.exec(); - if(!ret) { - qDebug() << query.lastError(); - } - return ret; -} - -int SQLiteDB::insertDefaultEntry(const QString &path, const QString &name, const QString &title, int id_parent, int type) -{ - int ohfi = 0; - - if((ohfi = insertNodeEntry(title, VITA_DIR_TYPE_MASK_REGULAR, type)) == 0) { - return 0; - } - - if(id_parent >= OHFI_BASE_VALUE && !updateAdjacencyList(ohfi, id_parent)) { - return 0; - } - - if(!name.isNull() && !insertSourceEntry(ohfi, path, name)) { - return 0; - } - return ohfi; -} - -int SQLiteDB::insertNodeEntry(const QString &title, int type, int data_type) -{ - QSqlQuery query; - - query.prepare("INSERT INTO object_node (type, data_type, title) VALUES (:type, :data_type, :title)"); - query.bindValue(0, type); - query.bindValue(1, data_type); - query.bindValue(2, title); - - if(!query.exec() || !query.exec("SELECT last_insert_rowid()") || !query.next()) { - qDebug() << query.lastError(); - return 0; - } - - return query.value(0).toInt(); -} - -bool SQLiteDB::insertSourceEntry(uint object_id, const QString &path, const QString &name) -{ - QVariant size, date_created, date_modified; - - QFileInfo info(path, name); - if(info.isFile()) { - size = QVariant(info.size()); - date_created = QVariant(info.created().toUTC().toTime_t()); - } else { - size = QVariant(QVariant::LongLong); - date_created = QVariant(QVariant::UInt); - } - - date_modified = QVariant(info.lastModified().toUTC().toTime_t()); - - QSqlQuery query; - query.prepare("REPLACE INTO sources (object_id, path, size, date_created, date_modified)" - "VALUES (:object_id, :path, :size, :date_created, :date_modified)"); - query.bindValue(0, object_id); - query.bindValue(1, name); - query.bindValue(2, size); - query.bindValue(3, date_created); - query.bindValue(4, date_modified); - bool ret = query.exec(); - if(!ret) { - qDebug() << query.lastError(); - } - return ret; -} - -uint SQLiteDB::insertMusicEntry(const QString &path, const QString &name, int id_parent, int type) -{ - bool ok; - int ohfi; - AVDecoder decoder; - quint64 duration; - const char *artist, *album, *albumartist, *genre, *track, *title; - int file_format, audio_codec, audio_bitrate, genre_id, artist_id, track_id, album_id, track_number; - - int cma_file_type = checkFileType(name, VITA_OHFI_MUSIC); - if(cma_file_type < 0) { - //qDebug() << "Excluding from database:" << path; - return 0; - } - - if(!decoder.open(path + "/" + name)) { - return 0; - } - - album = decoder.getMetadataEntry("album"); - genre = decoder.getMetadataEntry("genre"); - artist = decoder.getMetadataEntry("artist"); - albumartist = decoder.getMetadataEntry("album_artist"); - track = decoder.getMetadataEntry("track"); - - track_number = QString(track).split("/")[0].toInt(&ok); - if(!ok) { - // set track number to 1 by default - track_number = 1; - } - - if(decoder.loadCodec(AVDecoder::CODEC_AUDIO)) { - audio_bitrate = decoder.getBitrate(); - } else { - audio_bitrate = 0; - } - - duration = decoder.getDuration(); - - file_format = audio_list[cma_file_type].file_format; - audio_codec = audio_list[cma_file_type].file_codec; - - QByteArray basename = QFileInfo(name).baseName().toUtf8(); - title = decoder.getMetadataEntry("title", basename.constData()); - - if((ohfi = insertDefaultEntry(path, name, title, id_parent, type)) == 0) { - return 0; - } - - if(genre) { - genre_id = insertNodeEntry(genre, VITA_DIR_TYPE_MASK_GENRES, type); - if(!updateAdjacencyList(ohfi, genre_id)) { - return 0; - } - } else { - genre_id = 0; - } - - if(artist) { - track_id = insertNodeEntry(artist, VITA_DIR_TYPE_MASK_ARTISTS, type); - if(!updateAdjacencyList(ohfi, track_id)) { - return 0; - } - } else { - track_id = 0; - } - - if(albumartist) { - artist_id = insertNodeEntry(albumartist, VITA_DIR_TYPE_MASK_REGULAR, type); - if(!updateAdjacencyList(ohfi, artist_id)) { - return 0; - } - } else { - artist_id = 0; - } - - if(album) { - album_id = insertNodeEntry(album, VITA_DIR_TYPE_MASK_ALBUMS, type); - - if(track_id && !updateAdjacencyList(ohfi, album_id)) { - return 0; - } - if(track_id && !updateAdjacencyList(album_id, track_id)) { - return 0; - } - if(artist_id && !updateAdjacencyList(album_id, artist_id)) { - return 0; - } - } else { - album_id = 0; - } - - QSqlQuery query; - query.prepare("REPLACE INTO music" - "(object_id, file_format, audio_codec, audio_bitrate, duration, genre_id, artist_id, album_id, track_id, artist, album, track_number)" - "VALUES (:object_id, :file_format, :audio_codec, :audio_bitrate, :duration, :genre_id, :artist_id, :album_id, :track_id, :artist, :album, :track_number)"); - - query.bindValue(0, ohfi); - query.bindValue(1, file_format); - query.bindValue(2, audio_codec); - query.bindValue(3, audio_bitrate); - query.bindValue(4, duration); - query.bindValue(5, genre_id ? genre_id : QVariant(QVariant::Int)); - query.bindValue(6, artist_id ? artist_id : QVariant(QVariant::Int)); - query.bindValue(7, album_id ? album_id : QVariant(QVariant::Int)); - query.bindValue(8, track_id ? track_id : QVariant(QVariant::Int)); - query.bindValue(9, artist); - query.bindValue(10, album); - query.bindValue(11, track_number); - - if(!query.exec()) { - return 0; - } - - return ohfi; -} - -uint SQLiteDB::insertVideoEntry(const QString &path, const QString &name, int id_parent, int type) -{ - int ohfi; - AVDecoder decoder; - quint64 duration; - int file_format, parental_level, width, height, video_codec, video_bitrate, audio_codec, audio_bitrate; - const char *explanation, *copyright, *title; - - if(!decoder.open(path + "/" + name) || !decoder.loadCodec(AVDecoder::CODEC_VIDEO)) { - return 0; - } - - int cma_file_type = checkFileType(name, VITA_OHFI_VIDEO); - if(cma_file_type < 0) { - //qDebug() << "Excluding from database:" << path; - return 0; - } - - parental_level = 0; - explanation = decoder.getMetadataEntry("comments", ""); - copyright = decoder.getMetadataEntry("copyright", ""); - width = decoder.getWidth(); - height = decoder.getHeight(); - duration = decoder.getDuration(); - video_codec = CODEC_TYPE_AVC; - video_bitrate = decoder.getBitrate(); - file_format = video_list[cma_file_type].file_format; - - if(decoder.loadCodec(AVDecoder::CODEC_AUDIO)) { - audio_codec = CODEC_TYPE_AAC; - audio_bitrate = decoder.getBitrate(); - } else { - audio_codec = 0; - audio_bitrate = 0; - } - - QByteArray basename = QFileInfo(name).baseName().toUtf8(); - //title = decoder.getMetadataEntry("title", basename.constData()); - title = basename.constData(); - - - if((ohfi = insertDefaultEntry(path, name, title, id_parent, type)) == 0) { - return 0; - } - - QSqlQuery query; - query.prepare("REPLACE INTO videos" - "(object_id, file_format, parental_level, explanation, copyright, width, height, video_codec, video_bitrate, audio_codec, audio_bitrate, duration)" - "VALUES (:object_id, :file_format, :parental_level, :explanation, :copyright, :width, :height, :video_codec, :video_bitrate, :audio_codec, :audio_bitrate, :duration)"); - - query.bindValue(0, ohfi); - query.bindValue(1, file_format); - query.bindValue(2, parental_level); - query.bindValue(3, explanation); - query.bindValue(4, copyright); - query.bindValue(5, width); - query.bindValue(6, height); - query.bindValue(7, video_codec); - query.bindValue(8, video_bitrate); - query.bindValue(9, audio_codec); - query.bindValue(10, audio_bitrate); - query.bindValue(11, duration); - - if(!query.exec()) { - qDebug() << query.lastError().text(); - return 0; - } - - return ohfi; -} - -uint SQLiteDB::insertPhotoEntry(const QString &path, const QString &name, int id_parent, int type) -{ - int ohfi; - QImage img; - uint date_created; - int width, height, file_format, photo_codec; - - int cma_file_type = checkFileType(name, VITA_OHFI_PHOTO); - if(cma_file_type < 0) { - //qDebug() << "Excluding from database:" << path; - return 0; - } - - if(!img.load(path + "/" + name)) { - return 0; - } - - QDateTime date = QFileInfo(path + "/" + name).created(); - date_created = date.toUTC().toTime_t(); - QString month_created = date.toString("yyyy/MM"); - - width = img.width(); - height = img.height(); - file_format = photo_list[cma_file_type].file_format; - photo_codec = photo_list[cma_file_type].file_codec; - - QByteArray basename = QFileInfo(name).baseName().toUtf8(); - - if((ohfi = insertDefaultEntry(path, name, basename, id_parent, type)) == 0) { - return 0; - } - - QSqlQuery query; - query.prepare("REPLACE INTO photos" - "(object_id, date_created, file_format, photo_codec, width, height, month_created)" - "VALUES (:object_id, :date_created, :file_format, :photo_codec, :width, :height, :month_created)"); - - query.bindValue(0, ohfi); - query.bindValue(1, date_created); - query.bindValue(2, file_format); - query.bindValue(3, photo_codec); - query.bindValue(4, width); - query.bindValue(5, height); - query.bindValue(6, month_created); - - if(!query.exec()) { - return 0; - } - - return ohfi; -} - -uint SQLiteDB::insertSavedataEntry(const QString &path, const QString &name, int id_parent, int type) -{ - int ohfi; - SfoReader reader; - uint date_updated = 0; - const char *title = NULL; - const char *savedata_detail = NULL; - const char *savedata_directory = NULL; - - QString file_name = QFileInfo(name).fileName(); - QByteArray utf8name = file_name.toUtf8(); - - if(file_name.endsWith(".sfo", Qt::CaseInsensitive) && reader.load(path + "/" + name)) { - title = reader.value("TITLE", utf8name.constData()); - savedata_detail = reader.value("SAVEDATA_DETAIL", ""); - savedata_directory = reader.value("SAVEDATA_DIRECTORY", utf8name.constData()); - date_updated = QFileInfo(path + "/" + name).lastModified().toUTC().toTime_t(); - } - - if((ohfi = insertDefaultEntry(path, name, title, id_parent, type)) == 0) { - return 0; - } - - if(!title) { - return ohfi; - } - - QSqlQuery query; - query.prepare("REPLACE INTO savedata" - "(object_id, detail, dir_name, title, date_updated)" - "VALUES (:object_id, :detail, :dir_name, :title, :updated)"); - - query.bindValue(0, id_parent); - query.bindValue(1, savedata_detail); - query.bindValue(2, savedata_directory); - query.bindValue(3, title); - query.bindValue(4, date_updated); - - if(!query.exec()) { - return 0; - } - - return ohfi; -} - - -bool SQLiteDB::insertApplicationEntry(const QString &name, int ohfi, int app_type) -{ - QString title_id = QFileInfo(name).fileName(); - - QSqlQuery query; - query.prepare("REPLACE INTO application" - "(object_id, title, app_type)" - "VALUES (:object_id, :title, :app_type)"); - - query.bindValue(0, ohfi); - query.bindValue(1, title_id); - query.bindValue(2, app_type); - - if(!query.exec()) { - return false; - } - - return true; -} - -int SQLiteDB::childObjectCount(int parent_ohfi) -{ - QSqlQuery query; - query.prepare("SELECT count(child_id) FROM adjacent_objects WHERE parent_id = :object_id"); - query.bindValue(0, parent_ohfi); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - return -1; - } else { - return query.value(0).toInt(); - } -} - -bool SQLiteDB::deleteEntry(int ohfi, int root_ohfi) -{ - Q_UNUSED(root_ohfi); - qDebug("Deleting node: %i", ohfi); - - QSqlQuery query("DELETE FROM object_node WHERE object_id = :object_id"); - query.bindValue(0, ohfi); - return query.exec(); -} - -void SQLiteDB::fillMetadata(const QSqlQuery &query, metadata_t &metadata) -{ - metadata.ohfi = query.value(0).toInt(); // ohfi - metadata.ohfiParent = query.value(1).toInt(); // parent - metadata.path = strdup(query.value(2).toByteArray().constData()); // path - metadata.name = strdup(query.value(3).toByteArray().constData()); // name - metadata.type = VITA_DIR_TYPE_MASK_REGULAR; - metadata.dataType = (DataType)query.value(5).toInt(); // data_type - metadata.size = query.value(6).toULongLong(); // size - metadata.dateTimeCreated = query.value(7).toInt(); // date_created - metadata.next_metadata = NULL; - //TODO: fill the rest of the metadata -} - -bool SQLiteDB::getObjectMetadata(int ohfi, metadata_t &metadata) -{ - QSqlQuery query( - "SELECT " - "t0.object_id as ohfi," - "t1.parent_id as parent," - "t2.path as path," - "t0.title as name," - "t0.type as type," - "t0.data_type as data_type," - "t2.size as size," - "t2.date_created as date_created " - "FROM object_node t0 " - "JOIN adjacent_objects t1 ON t1.child_id = t0.object_id " - "JOIN sources t2 ON t2.object_id = t0.object_id " - "WHERE t0.object_id = :object_id"); - query.bindValue(0, ohfi); - - if(query.exec() && query.next()) { - fillMetadata(query, metadata); - return true; - } else { - qDebug() << query.lastError(); - return false; - } -} - -int SQLiteDB::getObjectMetadatas(int parent_ohfi, metadata_t **metadata, int index, int max_number) -{ - if(metadata == NULL) { - return childObjectCount(parent_ohfi); - } - - if(parent_ohfi < OHFI_BASE_VALUE) { - return getRootItems(parent_ohfi, metadata); - } - - int count = 0; - QString query_str( - "SELECT " - "t0.child_id as ohfi," - "t0.parent_id as parent," - "t2.path as path," - "t1.title as name," - "t1.type as type," - "t1.data_type as data_type," - "t2.size as size," - "t2.date_created as date_created " - "FROM adjacent_objects t0 " - "JOIN object_node t1 ON t0.child_id = t1.object_id " - "JOIN sources t2 ON t0.child_id = t2.object_id " - "WHERE t0.parent_id = :parent_id "); - - if(max_number > 0) { - query_str += "LIMIT :limit OFFSET :offset"; - } - - QSqlQuery query(query_str); - query.bindValue(0, parent_ohfi); - - if(max_number > 0) { - query.bindValue(1, max_number); - query.bindValue(2, index); - } - - if(query.exec()) { - metadata_t **last = &*metadata; - while(query.next()) { - metadata_t *meta = new metadata_t(); - fillMetadata(query, *meta); - *last = meta; - last = &meta->next_metadata; - count++; - } - } else { - qDebug() << query.lastError(); - } - return count; -} - -qint64 SQLiteDB::getObjectSize(int ohfi) -{ - if(ohfi < OHFI_BASE_VALUE) { - return getChildenTotalSize(ohfi); - } - - QSqlQuery query; - query.prepare("SELECT size FROM sources WHERE object_id = :object_id"); - query.bindValue(0, ohfi); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - return -1; - } else { - return query.value(0).toInt(); - } -} - -int SQLiteDB::getPathId(const char *name, int ohfi) -{ - //FIXME: use ohfi to filter by category - Q_UNUSED(ohfi); - QSqlQuery query; - - query.prepare("SELECT object_id FROM sources WHERE path = :path"); - query.bindValue(0, name); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - return 0; - } else { - return query.value(0).toInt(); - } -} - -QString SQLiteDB::getAbsolutePath(int ohfi) -{ - int root_ohfi = ohfi < OHFI_BASE_VALUE ? ohfi : getRootId(ohfi); - QString base_path = getBasePath(root_ohfi); - QString rel_path = getRelativePath(ohfi); - return rel_path.isNull() ? base_path : base_path + "/" + rel_path; -} - -QString SQLiteDB::getRelativePath(int ohfi) -{ - QSqlQuery query; - query.prepare("SELECT path FROM sources WHERE object_id = :object_id"); - query.bindValue(0, ohfi); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - return NULL; - } else { - return query.value(0).toString(); - } -} - -bool SQLiteDB::updateObjectPath(int ohfi, const QString &name) -{ - int parent_ohfi = getParentId(ohfi); - QString parent_path, file; - - if(name.isNull()) { - QSqlQuery name_query("SELECT title FROM object_node WHERE object_id = :object_id"); - name_query.bindValue(0, ohfi); - if(!name_query.exec() || !name_query.next()) { - return false; - } - file = name_query.value(0).toString(); - } else { - file = name; - } - - if(parent_ohfi >= OHFI_BASE_VALUE) { - parent_path = getRelativePath(parent_ohfi); - if(parent_path.isNull()) { - parent_path = file; - } else { - parent_path += "/" + file; - } - } else { - parent_path = file; - } - - QSqlQuery query("UPDATE sources SET path = :path WHERE object_id = :object_id"); - query.bindValue(0, parent_path); - query.bindValue(1, ohfi); - - if(!query.exec()) { - return false; - } - - DataType type = (DataType)getObjectType(ohfi); - - if(type & Folder) { - QSqlQuery child_query("SELECT child_id, data_type FROM adjacent_objects " - "JOIN object_node ON object_id = child_id" - "WHERE parent_id = :parent_id"); - child_query.bindValue(0, ohfi); - - if(query.exec()) { - while(query.next()) { - int child_ohfi = query.value(0).toInt(); - if(!updateObjectPath(child_ohfi, NULL)) { - return false; - } - } - } - } - - return true; -} - -bool SQLiteDB::renameObject(int ohfi, const QString &name) -{ - QSqlQuery query("UPDATE object_node SET title = :title WHERE object_id = :object_id"); - query.bindValue(0, name); - query.bindValue(1, ohfi); - - if(!query.exec()) { - return false; - } - - return updateObjectPath(ohfi, name); -} - -void SQLiteDB::setObjectSize(int ohfi, qint64 size) -{ - QSqlQuery query; - query.prepare("UPDATE sources SET size = :size WHERE object_id = :object_id"); - query.bindValue(0, size); - query.bindValue(1, ohfi); - if(!query.exec()) { - qDebug() << query.lastError(); - } -} - -qint64 SQLiteDB::getChildenTotalSize(int ohfi) -{ - QSqlQuery query; - query.prepare("SELECT SUM(t0.size) FROM sources t0 " - "JOIN adjacent_objects t1 ON t0.object_id = t1.child_id " - "where t1.parent_id = :parent_id"); - query.bindValue(0, ohfi); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - return -1; - } else { - return query.value(0).toLongLong(); - } -} - -int SQLiteDB::getRootId(int ohfi) -{ - QSqlQuery query; - int root_ohfi = ohfi; - - query.prepare("SELECT parent_id FROM adjacent_objects WHERE child_id = :child_id"); - while(root_ohfi >= OHFI_BASE_VALUE) { - query.bindValue(0, root_ohfi); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - root_ohfi = 0; - } else { - root_ohfi = query.value(0).toInt(); - } - } - return root_ohfi; -} - -int SQLiteDB::getObjectType(int ohfi) -{ - QSqlQuery query; - query.prepare("SELECT type FROM object_node WHERE object_id = :object_id"); - query.bindValue(0, ohfi); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - return 0; - } else { - return query.value(0).toInt(); - } -} - -int SQLiteDB::getParentId(int ohfi) -{ - QSqlQuery query; - query.prepare("SELECT parent_id FROM adjacent_objects WHERE child_id = :child_id"); - query.bindValue(0, ohfi); - if(!query.exec() || !query.next()) { - qDebug() << query.lastError(); - return 0; - } else { - return query.value(0).toInt(); - } -} - -void SQLiteDB::freeMetadata(metadata_t *metadata) -{ - while(metadata) { - metadata_t *current = metadata; - metadata = metadata->next_metadata; - delete current; - } -} - -int SQLiteDB::getRootItems(int root_ohfi, metadata_t **metadata) -{ - QSqlQuery query; - int count = 0; - - switch(root_ohfi) { - case VITA_OHFI_MUSIC: - //query = QSqlQuery("SELECT * FROM music"); - break; - case VITA_OHFI_PHOTO: - //query = QSqlQuery("SELECT * FROM photos"); - break; - case VITA_OHFI_VIDEO: - //query = QSqlQuery("SELECT * FROM videos"); - break; - case VITA_OHFI_PSPSAVE: - //query = QSqlQuery("SELECT * FROM savedata"); - break; - case VITA_OHFI_VITAAPP: - case VITA_OHFI_PSPAPP: - case VITA_OHFI_PSXAPP: - case VITA_OHFI_PSMAPP: - case VITA_OHFI_BACKUP: - query = QSqlQuery("SELECT " - "t0.object_id as ohfi," - ":app_type as parent," - "t3.path as path," - "t0.title as name," - "t1.type as type," - "t1.data_type as data_type," - "t3.size as size," - "t3.date_created as date_created " - "FROM application t0 " - "JOIN object_node t1 on t0.object_id = t1.object_id " - "JOIN sources t3 ON t3.object_id = t0.object_id " - "WHERE app_type = :app_type"); - query.bindValue(0, root_ohfi); - if(query.exec()) { - metadata_t **last = &*metadata; - while(query.next()) { - metadata_t *meta = new metadata_t(); - fillMetadata(query, *meta); - *last = meta; - last = &meta->next_metadata; - count++; - } - } - break; - default: - qFatal("Invalid root ohfi type"); - } - - return count; -} - -bool SQLiteDB::insertVirtualEntry(int ohfi) -{ - QSqlQuery query; - query.prepare("REPLACE INTO virtual_nodes (object_id)" - "VALUES (:object_id)"); - query.bindValue(0, ohfi); - bool ret = query.exec(); - if(!ret) { - qDebug() << query.lastError(); - } - return ret; -} - -bool SQLiteDB::insertVirtualEntries() -{ - int ohfi; - - if((ohfi = insertNodeEntry("Folders", VITA_DIR_TYPE_MASK_REGULAR, Video)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("All", VITA_DIR_TYPE_MASK_ALL, Video)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("Folders", VITA_DIR_TYPE_MASK_REGULAR, Photo)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("Month", VITA_DIR_TYPE_MASK_MONTH, Photo)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("All", VITA_DIR_TYPE_MASK_ALL, Photo)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("Artists", VITA_DIR_TYPE_MASK_ARTISTS, Music)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("Albums", VITA_DIR_TYPE_MASK_ALBUMS, Music)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("Songs", VITA_DIR_TYPE_MASK_SONGS, Music)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("Genres", VITA_DIR_TYPE_MASK_GENRES, Music)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - if((ohfi = insertNodeEntry("Playlists", VITA_DIR_TYPE_MASK_PLAYLISTS, Music)) > 0) { - insertVirtualEntry(ohfi); - } else { - return false; - } - - return true; -} - -bool SQLiteDB::getObjectList(int ohfi, metadata_t **metadata) -{ - Q_UNUSED(ohfi); - Q_UNUSED(metadata); - return false; -} diff --git a/src/sqlitedb.h b/src/sqlitedb.h deleted file mode 100644 index 26f11d2..0000000 --- a/src/sqlitedb.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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 . - */ - -#ifndef SQLITEDB_H -#define SQLITEDB_H - -#include "database.h" - -#include - -#include -#include -#include -#include -#include - -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 &m_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 getObjectList(int ohfi, metadata_t **metadata); - 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 m_uuid; - QSqlDatabase db; -}; - -#endif // SQLITEDB_H diff --git a/translations.qrc b/translations.qrc deleted file mode 100644 index 931ee4f..0000000 --- a/translations.qrc +++ /dev/null @@ -1,7 +0,0 @@ - - - resources/translations/qcma_es.qm - resources/translations/qcma_fr.qm - resources/translations/qcma_ja.qm - - diff --git a/version_bump.sh b/version_bump.sh index ef30027..c6d7b2a 100755 --- a/version_bump.sh +++ b/version_bump.sh @@ -3,5 +3,5 @@ [ $# -eq 0 ] && { echo "Usage: $0 "; exit 1; } sed -i "s/%define _version.*/%define _version $1/" rpmbuild/qcma.spec -sed -i "s/VERSION = .*/VERSION = $1/" qcma_common.pri +sed -i "s/VERSION = .*/VERSION = $1/" config.pri echo "Don't forget to update the changelog and nsis script"