Added rest of file modifications. (oops)
@@ -1,40 +0,0 @@
 | 
			
		||||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.2.5" android:installLocation="auto" package="com.github.codestation.qcma" android:versionCode="1">
 | 
			
		||||
    <application android:label="qcma" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:icon="@drawable/icon">
 | 
			
		||||
        <activity android:screenOrientation="unspecified" android:label="@string/app_name" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.intent.action.MAIN"/>
 | 
			
		||||
                <category android:name="android.intent.category.LAUNCHER"/>
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
            <meta-data android:value="qcma" android:name="android.app.lib_name"/>
 | 
			
		||||
            <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
 | 
			
		||||
            <meta-data android:value="default" android:name="android.app.repository"/>
 | 
			
		||||
            <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
 | 
			
		||||
            <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
 | 
			
		||||
            <!-- Deploy Qt libs as part of package -->
 | 
			
		||||
            <meta-data android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --" android:name="android.app.bundle_local_qt_libs"/>
 | 
			
		||||
            <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
 | 
			
		||||
            <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
 | 
			
		||||
            <!-- Run with local libs -->
 | 
			
		||||
            <meta-data android:value="-- %%USE_LOCAL_QT_LIBS%% --" android:name="android.app.use_local_qt_libs"/>
 | 
			
		||||
            <meta-data android:value="/data/local/tmp/qt/" android:name="android.app.libs_prefix"/>
 | 
			
		||||
            <meta-data android:value="-- %%INSERT_LOCAL_LIBS%% --" android:name="android.app.load_local_libs"/>
 | 
			
		||||
            <meta-data android:value="-- %%INSERT_LOCAL_JARS%% --" android:name="android.app.load_local_jars"/>
 | 
			
		||||
            <meta-data android:value="-- %%INSERT_INIT_CLASSES%% --" android:name="android.app.static_init_classes"/>
 | 
			
		||||
            <!--  Messages maps -->
 | 
			
		||||
            <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
 | 
			
		||||
            <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
 | 
			
		||||
            <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
 | 
			
		||||
            <!--  Messages maps -->
 | 
			
		||||
            <!-- Splash screen -->
 | 
			
		||||
            <meta-data android:name="android.app.splash_screen" android:resource="@layout/splash"/>
 | 
			
		||||
            <!-- Splash screen -->
 | 
			
		||||
        </activity>
 | 
			
		||||
    </application>
 | 
			
		||||
    <uses-sdk android:targetSdkVersion="19" android:minSdkVersion="10"/>
 | 
			
		||||
    <supports-screens android:normalScreens="true" android:smallScreens="true" android:largeScreens="true" android:anyDensity="true"/>
 | 
			
		||||
    <!-- %%INSERT_PERMISSIONS -->
 | 
			
		||||
    <!-- %%INSERT_FEATURES -->
 | 
			
		||||
    <uses-permission android:name="android.permission.INTERNET"/>
 | 
			
		||||
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 | 
			
		||||
</manifest>
 | 
			
		||||
@@ -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 \
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1,194 @@
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include <android/log.h>
 | 
			
		||||
#include <android/api-level.h>
 | 
			
		||||
 | 
			
		||||
// 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<void**>(&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<jclass>(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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.0 KiB  | 
| 
		 Before Width: | Height: | Size: 555 B  | 
| 
		 Before Width: | Height: | Size: 755 B  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 2.2 KiB  | 
@@ -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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/qcma-cli.manpages
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1 +1 @@
 | 
			
		||||
man/qcma_cli.1
 | 
			
		||||
cli/qcma_cli.1
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								debian/qcma.install
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								debian/qcma.manpages
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1 +1 @@
 | 
			
		||||
man/qcma.1
 | 
			
		||||
gui/qcma.1
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								man/qcma.1
									
									
									
									
									
								
							
							
						
						@@ -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
 | 
			
		||||
@@ -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
 | 
			
		||||
							
								
								
									
										31
									
								
								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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
							
								
								
									
										26
									
								
								qcma_cli.pro
									
									
									
									
									
								
							
							
						
						@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										121
									
								
								qcma_common.pri
									
									
									
									
									
								
							
							
						
						@@ -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\\\"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								qcma_gui.pro
									
									
									
									
									
								
							
							
						
						@@ -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
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
							
								
								
									
										13
									
								
								qcmares.qrc
									
									
									
									
									
								
							
							
						
						@@ -1,13 +0,0 @@
 | 
			
		||||
<RCC>
 | 
			
		||||
    <qresource prefix="/main">
 | 
			
		||||
        <file>resources/xml/psp2-updatelist.xml</file>
 | 
			
		||||
        <file>resources/images/tray/qcma_on.png</file>
 | 
			
		||||
        <file>resources/images/tray/qcma_on_16.png</file>
 | 
			
		||||
        <file>resources/images/qcma.png</file>
 | 
			
		||||
        <file>resources/images/edit-clear-locationbar-rtl.png</file>
 | 
			
		||||
        <file>resources/images/tray/qcma_off.png</file>
 | 
			
		||||
        <file>resources/images/tray/qcma_off_16.png</file>
 | 
			
		||||
        <file>resources/images/qcma_on.png</file>
 | 
			
		||||
        <file>resources/images/qcma_off.png</file>
 | 
			
		||||
    </qresource>
 | 
			
		||||
</RCC>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 859 B  | 
| 
		 Before Width: | Height: | Size: 34 KiB  | 
| 
		 Before Width: | Height: | Size: 994 B  | 
| 
		 Before Width: | Height: | Size: 984 B  | 
| 
		 Before Width: | Height: | Size: 994 B  | 
| 
		 Before Width: | Height: | Size: 336 B  | 
| 
		 Before Width: | Height: | Size: 301 B  | 
| 
		 Before Width: | Height: | Size: 387 B  | 
| 
		 Before Width: | Height: | Size: 344 B  | 
@@ -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;
 | 
			
		||||
@@ -1,667 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!DOCTYPE TS>
 | 
			
		||||
<TS version="2.1" language="es_ES">
 | 
			
		||||
<context>
 | 
			
		||||
    <name>BackupItem</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupitem.ui" line="131"/>
 | 
			
		||||
        <source>Delete entry</source>
 | 
			
		||||
        <translation>Borrar entrada</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupitem.ui" line="144"/>
 | 
			
		||||
        <source>Open folder</source>
 | 
			
		||||
        <translation>Abrir directorio</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>BackupManagerForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="14"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestor de Respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="24"/>
 | 
			
		||||
        <source>Online ID / Username</source>
 | 
			
		||||
        <translation>ID Online / Nombre de usuario</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="41"/>
 | 
			
		||||
        <source>Backup Type</source>
 | 
			
		||||
        <translation>Tipo de respaldo</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="52"/>
 | 
			
		||||
        <source>PS Vita Games</source>
 | 
			
		||||
        <translation>Juegos PS Vita</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="57"/>
 | 
			
		||||
        <source>PSP Games</source>
 | 
			
		||||
        <translation>Juegos PSP</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="62"/>
 | 
			
		||||
        <source>PSM Games</source>
 | 
			
		||||
        <translation>Juegos PSM</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="67"/>
 | 
			
		||||
        <source>PSOne Games</source>
 | 
			
		||||
        <translation>Juegos PSOne</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="72"/>
 | 
			
		||||
        <source>PSP Savedatas</source>
 | 
			
		||||
        <translation>Salvados PSP</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="77"/>
 | 
			
		||||
        <source>Backups</source>
 | 
			
		||||
        <translation>Respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="99"/>
 | 
			
		||||
        <source>Backup disk usage</source>
 | 
			
		||||
        <translation>Uso de disco en respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="122"/>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="246"/>
 | 
			
		||||
        <source>Filter</source>
 | 
			
		||||
        <translation>Filtro</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="99"/>
 | 
			
		||||
        <source>Default account</source>
 | 
			
		||||
        <translation>Cuenta por defecto</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="60"/>
 | 
			
		||||
        <source>Are you sure to remove the backup of the following entry?</source>
 | 
			
		||||
        <translation>¿Estas seguro de borrar la siguiente entrada?</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="88"/>
 | 
			
		||||
        <source>Backup disk usage: %1</source>
 | 
			
		||||
        <translation>Uso de disco en respaldos: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="201"/>
 | 
			
		||||
        <source> [GAME]</source>
 | 
			
		||||
        <translation> [JUEGO]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="204"/>
 | 
			
		||||
        <source> [SAVE]</source>
 | 
			
		||||
        <translation> [SALVADO]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="207"/>
 | 
			
		||||
        <source> [UPDATE]</source>
 | 
			
		||||
        <translation> [ACTUALIZACIÓN]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="210"/>
 | 
			
		||||
        <source> [DLC]</source>
 | 
			
		||||
        <translation> [DLC]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ClientManager</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="64"/>
 | 
			
		||||
        <source>Added %1 items to the database</source>
 | 
			
		||||
        <translation>Agregadas %1 entradas a la base de datos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="66"/>
 | 
			
		||||
        <source>Database indexing aborted by user</source>
 | 
			
		||||
        <translation>Actualización de la base de datos cancelada por el usuario</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="80"/>
 | 
			
		||||
        <source>Cannot initialize VitaMTP library</source>
 | 
			
		||||
        <translation>No se pudo inicializar VitaMTP</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="101"/>
 | 
			
		||||
        <source>This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus.</source>
 | 
			
		||||
        <translation>Este usuario no pertenece al grupo vitamtp, puede haber problemas al leer el bus USB.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="147"/>
 | 
			
		||||
        <source>You must enable at least USB or Wireless monitoring</source>
 | 
			
		||||
        <translation>Debe habilitar por lo menos el monitoreo USB o inalámbrico</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="158"/>
 | 
			
		||||
        <source>No PS Vita system has been registered</source>
 | 
			
		||||
        <translation>Nigún sistema PS Vita ha sido registrado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>CmaClient</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/cmaclient.cpp" line="151"/>
 | 
			
		||||
        <location filename="../../src/cmaclient.cpp" line="154"/>
 | 
			
		||||
        <source>Connected to %1 (PS Vita)</source>
 | 
			
		||||
        <translation>Conectado a %1 (PS Vita)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ConfigWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="14"/>
 | 
			
		||||
        <source>QCMA Settings</source>
 | 
			
		||||
        <translation>Ajustes QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="26"/>
 | 
			
		||||
        <source>Folders</source>
 | 
			
		||||
        <translation>Directorios</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="39"/>
 | 
			
		||||
        <source>Specify the folders that the PS Vita will access for each content type.</source>
 | 
			
		||||
        <translation>Especificar los directorios que el sistema PS Vita accederá para cada tipo de contenido.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="51"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="63"/>
 | 
			
		||||
        <source>This is the location your Screenshots and Pictures are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Esta es la ubicación donde tus capturas de pantalla e imágenes serán almacenadas o importadas.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="54"/>
 | 
			
		||||
        <source>Photo Folder</source>
 | 
			
		||||
        <translation>Directorio de Fotos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="73"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="108"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="143"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="178"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="213"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="238"/>
 | 
			
		||||
        <source>Browse...</source>
 | 
			
		||||
        <translation>Buscar...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="86"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="98"/>
 | 
			
		||||
        <source>This is the location your Videos are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Esta es la ubicación donde tus videos serán almacenados o importados.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="89"/>
 | 
			
		||||
        <source>Video Folder</source>
 | 
			
		||||
        <translation>Directorio de Videos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="121"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="133"/>
 | 
			
		||||
        <source>This is the location your Music is Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Esta es la ubicación donde tu música será almacenada o importada.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="124"/>
 | 
			
		||||
        <source>Music Folder</source>
 | 
			
		||||
        <translation>Directorio de Música</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="156"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="168"/>
 | 
			
		||||
        <source>This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Esta es la ubicación donde tus juegos, aplicaciones, partidas salvadas y respaldos del sistema serán almacenados o importados.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="159"/>
 | 
			
		||||
        <source>Applications / Backups</source>
 | 
			
		||||
        <translation>Aplicaciones / Juegos / Respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="191"/>
 | 
			
		||||
        <source>This is the location your Software Updates and Browser Data is Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Esta es la ubicación donde el sistema PS Vita leerá los contenidos que intente descargar.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="194"/>
 | 
			
		||||
        <source>Updates / Web content</source>
 | 
			
		||||
        <translation>Actualizaciones / Contenido Web</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="203"/>
 | 
			
		||||
        <source>This is the location your PS Vita system will read all the content that it tries to download.</source>
 | 
			
		||||
        <translation>Esta es la ubicación donde el sistema PS Vita leerá los contenidos que intente descargar.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="226"/>
 | 
			
		||||
        <source>Packages</source>
 | 
			
		||||
        <translation>Archivos PKG</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="265"/>
 | 
			
		||||
        <source>Other</source>
 | 
			
		||||
        <translation>Otros</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="273"/>
 | 
			
		||||
        <source><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Ajustes Avanzados</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="280"/>
 | 
			
		||||
        <source>Offline Mode</source>
 | 
			
		||||
        <translation>Modo desconectado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="290"/>
 | 
			
		||||
        <source>Skip metadata extraction</source>
 | 
			
		||||
        <translation>Saltar la extracción de metadatos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="314"/>
 | 
			
		||||
        <source>Update database automatically when files on the PC are changed</source>
 | 
			
		||||
        <translation>Actualizar la base de datos automaticamente</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="342"/>
 | 
			
		||||
        <source>SQLite</source>
 | 
			
		||||
        <translation>SQLite</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="352"/>
 | 
			
		||||
        <source>Skip photo scanning</source>
 | 
			
		||||
        <translation>Omitir el escaneo de fotos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="359"/>
 | 
			
		||||
        <source>Skip video scanning</source>
 | 
			
		||||
        <translation>Omitir el escaneo de vídeos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="366"/>
 | 
			
		||||
        <source>Skip music scanning</source>
 | 
			
		||||
        <translation>Omitir el escaneo de música</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="381"/>
 | 
			
		||||
        <source>CMA protocol version</source>
 | 
			
		||||
        <translation>Versión de protocolo CMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="461"/>
 | 
			
		||||
        <source>CMA protocol selection</source>
 | 
			
		||||
        <translation>Uso de protocolo CMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="469"/>
 | 
			
		||||
        <source>Latest</source>
 | 
			
		||||
        <translation>Último</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="474"/>
 | 
			
		||||
        <source>Manual</source>
 | 
			
		||||
        <translation>Manual</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="479"/>
 | 
			
		||||
        <source>Custom</source>
 | 
			
		||||
        <translation>Personalizado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="487"/>
 | 
			
		||||
        <source>CMA custom version</source>
 | 
			
		||||
        <translation>Versión personalizada CMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="297"/>
 | 
			
		||||
        <source>Disable USB monitoring</source>
 | 
			
		||||
        <translation>Deshabilitar monitoreo USB</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="304"/>
 | 
			
		||||
        <source>Disable Wi-Fi monitoring</source>
 | 
			
		||||
        <translation>Deshabilitar monitoreo WiFi</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="326"/>
 | 
			
		||||
        <source>Database backend</source>
 | 
			
		||||
        <translation>Almacenaje de base de datos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="337"/>
 | 
			
		||||
        <source>In Memory</source>
 | 
			
		||||
        <translation>En memoria</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="163"/>
 | 
			
		||||
        <source>Select the folder to be used as a photo source</source>
 | 
			
		||||
        <translation>Seleccione el directorio a ser utilizado como origen de fotos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="168"/>
 | 
			
		||||
        <source>Select the folder to be used as a music source</source>
 | 
			
		||||
        <translation>Seleccione el directorio a ser utilizado como origen de música</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="173"/>
 | 
			
		||||
        <source>Select the folder to be used as a video source</source>
 | 
			
		||||
        <translation>Seleccione el directorio a ser utilizado como origen de videos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="178"/>
 | 
			
		||||
        <source>Select the folder to be used to save PS Vita games and backups</source>
 | 
			
		||||
        <translation>Seleccione el directorio a ser utilizado para guardar juegos y respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="183"/>
 | 
			
		||||
        <source>Select the folder to be used to fetch software updates</source>
 | 
			
		||||
        <translation>Seleccione el directorio a ser utilizado para extraer actualizaciones de software</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="188"/>
 | 
			
		||||
        <source>Select the folder to be used to software packages</source>
 | 
			
		||||
        <translation>Seleccione el directorio a ser utilizado para almacenar archivos pkg</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ConfirmDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/confirmdialog.ui" line="14"/>
 | 
			
		||||
        <source>Confirmation Message</source>
 | 
			
		||||
        <translation>Mensaje de confirmación</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/confirmdialog.ui" line="63"/>
 | 
			
		||||
        <source><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>
 | 
			
		||||
</source>
 | 
			
		||||
        <translation></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>FilterLineEdit</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/filterlineedit.cpp" line="50"/>
 | 
			
		||||
        <location filename="../../src/gui/filterlineedit.cpp" line="71"/>
 | 
			
		||||
        <source>Filter</source>
 | 
			
		||||
        <translation>Filtro</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HTTPDownloader</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/httpdownloader.cpp" line="129"/>
 | 
			
		||||
        <source>Network error: %1</source>
 | 
			
		||||
        <translation>Error de red: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HeadlessManager</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/cli/headlessmanager.cpp" line="97"/>
 | 
			
		||||
        <source>This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus.</source>
 | 
			
		||||
        <translatorcomment>Este usuario no pertenece al grupo vitamtp, puede haber problemas al leer el bus USB.</translatorcomment>
 | 
			
		||||
        <translation>Este usuario no pertenece al grupo vitamtp, puede haber problemas al leer el bus USB.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>KDENotifierTray</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="34"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>Ajustes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="35"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>Refrescar base de datos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="36"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestor de Respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="37"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>Acerca de QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="38"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>Acerca de Qt</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="39"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>Salir</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="69"/>
 | 
			
		||||
        <source>Qcma status</source>
 | 
			
		||||
        <translation>Estado de Qcma</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="71"/>
 | 
			
		||||
        <source>Disconnected</source>
 | 
			
		||||
        <translation>Desconectado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MainWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="79"/>
 | 
			
		||||
        <source>Shutting down...</source>
 | 
			
		||||
        <translation>Cerrando...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="81"/>
 | 
			
		||||
        <source>Stopping QCMA (disconnect your PS Vita)</source>
 | 
			
		||||
        <translation>Deteniendo QCMA (desconecte su PS Vita)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="94"/>
 | 
			
		||||
        <source>Disconnected</source>
 | 
			
		||||
        <translation>Desconectado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="95"/>
 | 
			
		||||
        <source>The device has been disconnected</source>
 | 
			
		||||
        <translation>El dispositivo se ha desconectado</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="159"/>
 | 
			
		||||
        <source>About Qcma</source>
 | 
			
		||||
        <translation>Acerca de Qcma</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="161"/>
 | 
			
		||||
        <source>Copyright (C) 2015  Codestation</source>
 | 
			
		||||
        <translation>Copyright (C) 2015  Codestation</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="163"/>
 | 
			
		||||
        <source>Copyright (C) 2015  Codestation
 | 
			
		||||
 | 
			
		||||
build hash: %1
 | 
			
		||||
build branch: %2</source>
 | 
			
		||||
        <translation>Copyright (C) 2015  Codestation
 | 
			
		||||
 | 
			
		||||
Hash de compilación: %1
 | 
			
		||||
Rama de compilación: %2</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="266"/>
 | 
			
		||||
        <source>Information</source>
 | 
			
		||||
        <translation>Información</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>PinForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="17"/>
 | 
			
		||||
        <source>Device pairing</source>
 | 
			
		||||
        <translation>Emparejamiento de dispositivo</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="25"/>
 | 
			
		||||
        <source>An unregistered PS Vita system is connecting with QCMA via Wi-Fi</source>
 | 
			
		||||
        <translation>Un sistema PS Vita no registrado se intenta conectar con QCMA mediante Wi-Fi</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="35"/>
 | 
			
		||||
        <source>Device: PS Vita</source>
 | 
			
		||||
        <translation>Dispositivo: PS Vita</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="45"/>
 | 
			
		||||
        <source>Input the following number in the PS Vita system to register it with QCMA</source>
 | 
			
		||||
        <translation>Introduce el siguiente número en el sistema PS Vita para registrarlo con QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="55"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html></source>
 | 
			
		||||
        <translation></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="65"/>
 | 
			
		||||
        <source>Time remaining: 300 seconds</source>
 | 
			
		||||
        <translation>Tiempo restante: 300 segundos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="90"/>
 | 
			
		||||
        <source>Cancel</source>
 | 
			
		||||
        <translation>Cancelar</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.cpp" line="45"/>
 | 
			
		||||
        <source>Device: %1 (PS Vita)</source>
 | 
			
		||||
        <translation>Dispositivo: %1 (PS Vita)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.cpp" line="65"/>
 | 
			
		||||
        <source>Time remaining: %1 seconds</source>
 | 
			
		||||
        <translation>Tiempo restante: %1 segundos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ProgressForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="17"/>
 | 
			
		||||
        <source>Refreshing database...</source>
 | 
			
		||||
        <translation>Actualizando base de datos...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="25"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Reading directory:</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Leyendo directorio:</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="32"/>
 | 
			
		||||
        <source>directory name</source>
 | 
			
		||||
        <translation>Cargando nombre de directorio</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="39"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Processing file:</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Procesando archivo:</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="46"/>
 | 
			
		||||
        <source>file name</source>
 | 
			
		||||
        <translation>Cargando nombre de archivo</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="68"/>
 | 
			
		||||
        <source>Cancel</source>
 | 
			
		||||
        <translation>Cancelar</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.cpp" line="45"/>
 | 
			
		||||
        <source>Database indexing in progress</source>
 | 
			
		||||
        <translation>Actualización de base de datos en progreso</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.cpp" line="46"/>
 | 
			
		||||
        <source>Are you sure to cancel the database indexing?</source>
 | 
			
		||||
        <translation>¿Estas seguro de cancelar la actualización a la base de datos?</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>QObject</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/main.cpp" line="78"/>
 | 
			
		||||
        <source>An instance of Qcma is already running</source>
 | 
			
		||||
        <translation>Otra instancia de Qcma ya se encuentra en ejecución</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>QTrayIcon</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="51"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>Ajustes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="52"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>Refrescar base de datos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="53"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestor de Respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="54"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>Acerca de QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="55"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>Acerca de Qt</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="56"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>Salir</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>UnityIndicator</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="105"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>Ajustes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="106"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>Refrescar base de datos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="107"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestor de Respaldos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="109"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>Acerca de QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="110"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>Acerca de Qt</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="112"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>Salir</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
</TS>
 | 
			
		||||
@@ -1,667 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!DOCTYPE TS>
 | 
			
		||||
<TS version="2.1" language="fr_FR">
 | 
			
		||||
<context>
 | 
			
		||||
    <name>BackupItem</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupitem.ui" line="131"/>
 | 
			
		||||
        <source>Delete entry</source>
 | 
			
		||||
        <translation>Supprimer l'entrée</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupitem.ui" line="144"/>
 | 
			
		||||
        <source>Open folder</source>
 | 
			
		||||
        <translation>Ouvrir le répertoire</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>BackupManagerForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="14"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestonaire de Sauvegardes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="24"/>
 | 
			
		||||
        <source>Online ID / Username</source>
 | 
			
		||||
        <translation>ID Online / Nom d'utilisateur</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="41"/>
 | 
			
		||||
        <source>Backup Type</source>
 | 
			
		||||
        <translation>Type de sauvegarde</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="52"/>
 | 
			
		||||
        <source>PS Vita Games</source>
 | 
			
		||||
        <translation>Jeux PS Vita</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="57"/>
 | 
			
		||||
        <source>PSP Games</source>
 | 
			
		||||
        <translation>Jeux PSP</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="62"/>
 | 
			
		||||
        <source>PSM Games</source>
 | 
			
		||||
        <translation>Jeux PSM</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="67"/>
 | 
			
		||||
        <source>PSOne Games</source>
 | 
			
		||||
        <translation>Jeux PSOne</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="72"/>
 | 
			
		||||
        <source>PSP Savedatas</source>
 | 
			
		||||
        <translation>Sauvegardes PSP</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="77"/>
 | 
			
		||||
        <source>Backups</source>
 | 
			
		||||
        <translation>Sauvegardes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="99"/>
 | 
			
		||||
        <source>Backup disk usage</source>
 | 
			
		||||
        <translation>Utilisation du disque par les sauvegardes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="122"/>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="246"/>
 | 
			
		||||
        <source>Filter</source>
 | 
			
		||||
        <translation>Filtrer</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="99"/>
 | 
			
		||||
        <source>Default account</source>
 | 
			
		||||
        <translation>Compte par défaut</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="60"/>
 | 
			
		||||
        <source>Are you sure to remove the backup of the following entry?</source>
 | 
			
		||||
        <translation>Êtes-vous sur de voulloir supprimer cette sauvegarde?</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="88"/>
 | 
			
		||||
        <source>Backup disk usage: %1</source>
 | 
			
		||||
        <translation>Utilisation du disque de sauvegarde: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="201"/>
 | 
			
		||||
        <source> [GAME]</source>
 | 
			
		||||
        <translation> [JEU]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="204"/>
 | 
			
		||||
        <source> [SAVE]</source>
 | 
			
		||||
        <translation> [SAUVEGARDE]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="207"/>
 | 
			
		||||
        <source> [UPDATE]</source>
 | 
			
		||||
        <translation> [MISE_A_JOUR]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="210"/>
 | 
			
		||||
        <source> [DLC]</source>
 | 
			
		||||
        <translation> [DLC]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ClientManager</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="64"/>
 | 
			
		||||
        <source>Added %1 items to the database</source>
 | 
			
		||||
        <translation>%1 éléments ont été rajoutés à la base de données</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="66"/>
 | 
			
		||||
        <source>Database indexing aborted by user</source>
 | 
			
		||||
        <translation>Mise à jour de la base de données annulée par l'utilisateur</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="80"/>
 | 
			
		||||
        <source>Cannot initialize VitaMTP library</source>
 | 
			
		||||
        <translation>Impossible d'initaliser la librairie VitaMTP</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="101"/>
 | 
			
		||||
        <source>This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="147"/>
 | 
			
		||||
        <source>You must enable at least USB or Wireless monitoring</source>
 | 
			
		||||
        <translation>Vous devez soit activer la connexion par Wifi, soit activer celle par USB</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="158"/>
 | 
			
		||||
        <source>No PS Vita system has been registered</source>
 | 
			
		||||
        <translation>Aucunne PS Vita reconnue</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>CmaClient</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/cmaclient.cpp" line="151"/>
 | 
			
		||||
        <location filename="../../src/cmaclient.cpp" line="154"/>
 | 
			
		||||
        <source>Connected to %1 (PS Vita)</source>
 | 
			
		||||
        <translation>Connecté à %1 (PS Vita)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ConfigWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="14"/>
 | 
			
		||||
        <source>QCMA Settings</source>
 | 
			
		||||
        <translation>Configuration de QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="26"/>
 | 
			
		||||
        <source>Folders</source>
 | 
			
		||||
        <translation>Répertoires</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="39"/>
 | 
			
		||||
        <source>Specify the folders that the PS Vita will access for each content type.</source>
 | 
			
		||||
        <translation>Choisissez les répertoires que la PS Vita va acceder pour chaque type de contenu.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="51"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="63"/>
 | 
			
		||||
        <source>This is the location your Screenshots and Pictures are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Emplacement pour Copier/Importer les Copies d'écrans et les Photos.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="54"/>
 | 
			
		||||
        <source>Photo Folder</source>
 | 
			
		||||
        <translation>Répertoire des Photos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="73"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="108"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="143"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="178"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="213"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="238"/>
 | 
			
		||||
        <source>Browse...</source>
 | 
			
		||||
        <translation>Selectionner...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="86"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="98"/>
 | 
			
		||||
        <source>This is the location your Videos are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Emplacement pour Copier/Importer les Vidéos.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="89"/>
 | 
			
		||||
        <source>Video Folder</source>
 | 
			
		||||
        <translation>Répertoire des Vidéos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="121"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="133"/>
 | 
			
		||||
        <source>This is the location your Music is Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Emplacement pour Copier/Importer les Musiques.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="124"/>
 | 
			
		||||
        <source>Music Folder</source>
 | 
			
		||||
        <translation>Répertoire des Musiques</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="156"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="168"/>
 | 
			
		||||
        <source>This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Emplacement pour Copier/Importer les Jeux, Applications & Sauvegardes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="159"/>
 | 
			
		||||
        <source>Applications / Backups</source>
 | 
			
		||||
        <translation>Applications / Jeux / Sauvegardes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="191"/>
 | 
			
		||||
        <source>This is the location your Software Updates and Browser Data is Saved to/Imported from.</source>
 | 
			
		||||
        <translation>Emplacement pour Copier/Importer les mises à jours du logiciel de la Vita</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="194"/>
 | 
			
		||||
        <source>Updates / Web content</source>
 | 
			
		||||
        <translation>Mise à jours / Contenu Web</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="203"/>
 | 
			
		||||
        <source>This is the location your PS Vita system will read all the content that it tries to download.</source>
 | 
			
		||||
        <translation>Emplacement pour Copier/Importer les contenus téléchargés.</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="226"/>
 | 
			
		||||
        <source>Packages</source>
 | 
			
		||||
        <translation>Archive des Packages</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="265"/>
 | 
			
		||||
        <source>Other</source>
 | 
			
		||||
        <translation>Autres</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="273"/>
 | 
			
		||||
        <source><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Options Avancées</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="280"/>
 | 
			
		||||
        <source>Offline Mode</source>
 | 
			
		||||
        <translation>Mode déconnecté</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="290"/>
 | 
			
		||||
        <source>Skip metadata extraction</source>
 | 
			
		||||
        <translation>Passer l'extracion de métadonnées</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="314"/>
 | 
			
		||||
        <source>Update database automatically when files on the PC are changed</source>
 | 
			
		||||
        <translation>Mise à jour automatique de la base de données</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="342"/>
 | 
			
		||||
        <source>SQLite</source>
 | 
			
		||||
        <translation>SQLite</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="352"/>
 | 
			
		||||
        <source>Skip photo scanning</source>
 | 
			
		||||
        <translation>Passer le scan des photos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="359"/>
 | 
			
		||||
        <source>Skip video scanning</source>
 | 
			
		||||
        <translation>Passer le scan des videos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="366"/>
 | 
			
		||||
        <source>Skip music scanning</source>
 | 
			
		||||
        <translation>Passer le scan des musiques</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="381"/>
 | 
			
		||||
        <source>CMA protocol version</source>
 | 
			
		||||
        <translation>Version du protocol CMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="461"/>
 | 
			
		||||
        <source>CMA protocol selection</source>
 | 
			
		||||
        <translation>Utilisation du protocolo CMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="469"/>
 | 
			
		||||
        <source>Latest</source>
 | 
			
		||||
        <translation>Dernier</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="474"/>
 | 
			
		||||
        <source>Manual</source>
 | 
			
		||||
        <translation>Manuel</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="479"/>
 | 
			
		||||
        <source>Custom</source>
 | 
			
		||||
        <translation>Personalisé</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="487"/>
 | 
			
		||||
        <source>CMA custom version</source>
 | 
			
		||||
        <translation>Version CMA personalisée</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="297"/>
 | 
			
		||||
        <source>Disable USB monitoring</source>
 | 
			
		||||
        <translation>Désactiver la surveillance USB</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="304"/>
 | 
			
		||||
        <source>Disable Wi-Fi monitoring</source>
 | 
			
		||||
        <translation>Désactiver la surveillance WiFi</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="326"/>
 | 
			
		||||
        <source>Database backend</source>
 | 
			
		||||
        <translation>Moteur de base de données</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="337"/>
 | 
			
		||||
        <source>In Memory</source>
 | 
			
		||||
        <translation>En memoire</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="163"/>
 | 
			
		||||
        <source>Select the folder to be used as a photo source</source>
 | 
			
		||||
        <translation>Choisissez le répertoire à utiliser comme source de photos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="168"/>
 | 
			
		||||
        <source>Select the folder to be used as a music source</source>
 | 
			
		||||
        <translation>Choisissez le répertoire à utiliser comme source de musiques</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="173"/>
 | 
			
		||||
        <source>Select the folder to be used as a video source</source>
 | 
			
		||||
        <translation>Choisissez le répertoire à utiliser comme source de videos</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="178"/>
 | 
			
		||||
        <source>Select the folder to be used to save PS Vita games and backups</source>
 | 
			
		||||
        <translation>Choisissez le répertoire à utiliser pour sauvegarder les jeux PS Vita</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="183"/>
 | 
			
		||||
        <source>Select the folder to be used to fetch software updates</source>
 | 
			
		||||
        <translation>Choisissez le répertoire à utiliser pour recevoir les mise à jour</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="188"/>
 | 
			
		||||
        <source>Select the folder to be used to software packages</source>
 | 
			
		||||
        <translation>Choisissez le répertoire à utiliser pour ranger les packages de software</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ConfirmDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/confirmdialog.ui" line="14"/>
 | 
			
		||||
        <source>Confirmation Message</source>
 | 
			
		||||
        <translation>Message de confirmation</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/confirmdialog.ui" line="63"/>
 | 
			
		||||
        <source><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>
 | 
			
		||||
</source>
 | 
			
		||||
        <translation></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>FilterLineEdit</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/filterlineedit.cpp" line="50"/>
 | 
			
		||||
        <location filename="../../src/gui/filterlineedit.cpp" line="71"/>
 | 
			
		||||
        <source>Filter</source>
 | 
			
		||||
        <translation>Filtre</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HTTPDownloader</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/httpdownloader.cpp" line="129"/>
 | 
			
		||||
        <source>Network error: %1</source>
 | 
			
		||||
        <translation>Erreur réseau: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HeadlessManager</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/cli/headlessmanager.cpp" line="97"/>
 | 
			
		||||
        <source>This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>KDENotifierTray</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="34"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>Paramètres</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="35"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>Mise à jour de la DB</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="36"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestonaire de Sauvegards</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="37"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>À propos de QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="38"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>À propos de Qt</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="39"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>Quitter</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="69"/>
 | 
			
		||||
        <source>Qcma status</source>
 | 
			
		||||
        <translation>État de Qcma</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="71"/>
 | 
			
		||||
        <source>Disconnected</source>
 | 
			
		||||
        <translation>Déconnecté</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MainWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="79"/>
 | 
			
		||||
        <source>Shutting down...</source>
 | 
			
		||||
        <translation>Fin du programme...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="81"/>
 | 
			
		||||
        <source>Stopping QCMA (disconnect your PS Vita)</source>
 | 
			
		||||
        <translation>Arrêter QCMA (déconnecte votre PS Vita)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="94"/>
 | 
			
		||||
        <source>Disconnected</source>
 | 
			
		||||
        <translation>Déconnecté</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="95"/>
 | 
			
		||||
        <source>The device has been disconnected</source>
 | 
			
		||||
        <translation>L'appareil a été déconnecté</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="159"/>
 | 
			
		||||
        <source>About Qcma</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="161"/>
 | 
			
		||||
        <source>Copyright (C) 2015  Codestation</source>
 | 
			
		||||
        <translation type="unfinished">Copyright (C) 2014  Codestation {2015 ?}</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="163"/>
 | 
			
		||||
        <source>Copyright (C) 2015  Codestation
 | 
			
		||||
 | 
			
		||||
build hash: %1
 | 
			
		||||
build branch: %2</source>
 | 
			
		||||
        <translation type="unfinished">Copyright (C) 2014  Codestation
 | 
			
		||||
 | 
			
		||||
Hash de compilación: %1
 | 
			
		||||
Rama de compilación: %2 {2015 ?} {1
 | 
			
		||||
?}</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="266"/>
 | 
			
		||||
        <source>Information</source>
 | 
			
		||||
        <translation>Information</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>PinForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="17"/>
 | 
			
		||||
        <source>Device pairing</source>
 | 
			
		||||
        <translation>Pairage d'appareil</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="25"/>
 | 
			
		||||
        <source>An unregistered PS Vita system is connecting with QCMA via Wi-Fi</source>
 | 
			
		||||
        <translation>Un systême PS Vita inconnu essaye de se connecter à QCMA par Wi-Fi</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="35"/>
 | 
			
		||||
        <source>Device: PS Vita</source>
 | 
			
		||||
        <translation>Appareil: PS Vita</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="45"/>
 | 
			
		||||
        <source>Input the following number in the PS Vita system to register it with QCMA</source>
 | 
			
		||||
        <translation>Introduisez ce numero d'identification dans le systême PS Vita pour l'enregistrer avec QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="55"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html></source>
 | 
			
		||||
        <translation></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="65"/>
 | 
			
		||||
        <source>Time remaining: 300 seconds</source>
 | 
			
		||||
        <translation>Temps restant: 300 secondes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="90"/>
 | 
			
		||||
        <source>Cancel</source>
 | 
			
		||||
        <translation>Annuler</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.cpp" line="45"/>
 | 
			
		||||
        <source>Device: %1 (PS Vita)</source>
 | 
			
		||||
        <translation>Appareil: %1 (PS Vita)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.cpp" line="65"/>
 | 
			
		||||
        <source>Time remaining: %1 seconds</source>
 | 
			
		||||
        <translation>Temps restant: %1 secondes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ProgressForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="17"/>
 | 
			
		||||
        <source>Refreshing database...</source>
 | 
			
		||||
        <translation>Mise à jour de la base de données...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="25"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Reading directory:</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Lecture du répertoire:</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="32"/>
 | 
			
		||||
        <source>directory name</source>
 | 
			
		||||
        <translation>Nom du répertoire</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="39"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Processing file:</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Traitement du fichier:</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="46"/>
 | 
			
		||||
        <source>file name</source>
 | 
			
		||||
        <translation>Nom du fichier</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="68"/>
 | 
			
		||||
        <source>Cancel</source>
 | 
			
		||||
        <translation>Annuler</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.cpp" line="45"/>
 | 
			
		||||
        <source>Database indexing in progress</source>
 | 
			
		||||
        <translation>Mise à jour de la base de donnée en cours</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.cpp" line="46"/>
 | 
			
		||||
        <source>Are you sure to cancel the database indexing?</source>
 | 
			
		||||
        <translation>Êtes-vous sur de vouloir annuler la mise à jour de la base de données?</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>QObject</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/main.cpp" line="78"/>
 | 
			
		||||
        <source>An instance of Qcma is already running</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>QTrayIcon</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="51"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>Paramètres</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="52"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>Rafraichir la base de données</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="53"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestonaire de Sauvegardes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="54"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>À propos de QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="55"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>À propos de Qt</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="56"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>Quitter</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>UnityIndicator</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="105"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>Paramètres</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="106"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>Mise à jour de la base de données</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="107"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>Gestionaire de Sauvegardes</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="109"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>À propos de QCMA</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="110"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>À propos de Qt</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="112"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>Quitter</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
</TS>
 | 
			
		||||
@@ -1,668 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!DOCTYPE TS>
 | 
			
		||||
<TS version="2.1" language="ja_JP">
 | 
			
		||||
<context>
 | 
			
		||||
    <name>BackupItem</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupitem.ui" line="131"/>
 | 
			
		||||
        <source>Delete entry</source>
 | 
			
		||||
        <translation>項目を削除する</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupitem.ui" line="144"/>
 | 
			
		||||
        <source>Open folder</source>
 | 
			
		||||
        <translation>フォルダを開く</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>BackupManagerForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="14"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>バックアップマネージャー</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="24"/>
 | 
			
		||||
        <source>Online ID / Username</source>
 | 
			
		||||
        <translation>オンラインID / ユーザー名</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="41"/>
 | 
			
		||||
        <source>Backup Type</source>
 | 
			
		||||
        <translation>バックアップの種類</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="52"/>
 | 
			
		||||
        <source>PS Vita Games</source>
 | 
			
		||||
        <translation>PS Vitaゲーム</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="57"/>
 | 
			
		||||
        <source>PSP Games</source>
 | 
			
		||||
        <translation>PSPゲーム</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="62"/>
 | 
			
		||||
        <source>PSM Games</source>
 | 
			
		||||
        <translation>PSMゲーム</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="67"/>
 | 
			
		||||
        <source>PSOne Games</source>
 | 
			
		||||
        <translation>PS1ゲーム</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="72"/>
 | 
			
		||||
        <source>PSP Savedatas</source>
 | 
			
		||||
        <translation>PSPセーブデータ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="77"/>
 | 
			
		||||
        <source>Backups</source>
 | 
			
		||||
        <translation>バックアップ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="99"/>
 | 
			
		||||
        <source>Backup disk usage</source>
 | 
			
		||||
        <translation>バックアップディスク使用容量</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.ui" line="122"/>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="246"/>
 | 
			
		||||
        <source>Filter</source>
 | 
			
		||||
        <translation>フィルタ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="99"/>
 | 
			
		||||
        <source>Default account</source>
 | 
			
		||||
        <translation>標準アカウント</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="60"/>
 | 
			
		||||
        <source>Are you sure to remove the backup of the following entry?</source>
 | 
			
		||||
        <translation>次の項目のバックアップを削除してもよろしいですか?</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="88"/>
 | 
			
		||||
        <source>Backup disk usage: %1</source>
 | 
			
		||||
        <translation>バックアップディスク使用容量: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="201"/>
 | 
			
		||||
        <source> [GAME]</source>
 | 
			
		||||
        <translation> [ゲーム]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="204"/>
 | 
			
		||||
        <source> [SAVE]</source>
 | 
			
		||||
        <translation> [セーブ]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="207"/>
 | 
			
		||||
        <source> [UPDATE]</source>
 | 
			
		||||
        <translation> [アップデート]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/backupmanagerform.cpp" line="210"/>
 | 
			
		||||
        <source> [DLC]</source>
 | 
			
		||||
        <translation> [DLC]</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ClientManager</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="64"/>
 | 
			
		||||
        <source>Added %1 items to the database</source>
 | 
			
		||||
        <translation>%1個の項目をデータベースに追加しました</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="66"/>
 | 
			
		||||
        <source>Database indexing aborted by user</source>
 | 
			
		||||
        <translation>データベース構築がユーザーにより中止されました</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="80"/>
 | 
			
		||||
        <source>Cannot initialize VitaMTP library</source>
 | 
			
		||||
        <translation>VitaMTPライブラリを初期化できません</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="101"/>
 | 
			
		||||
        <source>This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="147"/>
 | 
			
		||||
        <source>You must enable at least USB or Wireless monitoring</source>
 | 
			
		||||
        <translation>少なくともUSBと無線のどちらかの監視を有効にする必要があります</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/clientmanager.cpp" line="158"/>
 | 
			
		||||
        <source>No PS Vita system has been registered</source>
 | 
			
		||||
        <translation>PS Vitaが登録されていません</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>CmaClient</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/cmaclient.cpp" line="151"/>
 | 
			
		||||
        <location filename="../../src/cmaclient.cpp" line="154"/>
 | 
			
		||||
        <source>Connected to %1 (PS Vita)</source>
 | 
			
		||||
        <translation>%1 (PS Vita) に接続されました</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ConfigWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="14"/>
 | 
			
		||||
        <source>QCMA Settings</source>
 | 
			
		||||
        <translation>QCMA設定</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="26"/>
 | 
			
		||||
        <source>Folders</source>
 | 
			
		||||
        <translation>フォルダ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="39"/>
 | 
			
		||||
        <source>Specify the folders that the PS Vita will access for each content type.</source>
 | 
			
		||||
        <translation>PS Vitaがアクセスするフォルダーをコンテンツの種類ごとに指定してください。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="51"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="63"/>
 | 
			
		||||
        <source>This is the location your Screenshots and Pictures are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>スクリーンショットや画像を保存/インポートする場所です。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="54"/>
 | 
			
		||||
        <source>Photo Folder</source>
 | 
			
		||||
        <translation>フォト</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="73"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="108"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="143"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="178"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="213"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="238"/>
 | 
			
		||||
        <source>Browse...</source>
 | 
			
		||||
        <translation>参照...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="86"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="98"/>
 | 
			
		||||
        <source>This is the location your Videos are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>ビデオを保存/インポートする場所です。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="89"/>
 | 
			
		||||
        <source>Video Folder</source>
 | 
			
		||||
        <translation>ビデオ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="121"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="133"/>
 | 
			
		||||
        <source>This is the location your Music is Saved to/Imported from.</source>
 | 
			
		||||
        <translation>ミュージックを保存/インポートする場所です。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="124"/>
 | 
			
		||||
        <source>Music Folder</source>
 | 
			
		||||
        <translation>ミュージック</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="156"/>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="168"/>
 | 
			
		||||
        <source>This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from.</source>
 | 
			
		||||
        <translation>ゲームやアプリ、セーブデータ、システムバックアップを保存/インポートする場所です。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="159"/>
 | 
			
		||||
        <source>Applications / Backups</source>
 | 
			
		||||
        <translation>アプリケーション/バックアップファイル</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="191"/>
 | 
			
		||||
        <source>This is the location your Software Updates and Browser Data is Saved to/Imported from.</source>
 | 
			
		||||
        <translation>ソフトウェアアップデートとブラウザデータをを保存/インポートする場所です。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="194"/>
 | 
			
		||||
        <source>Updates / Web content</source>
 | 
			
		||||
        <translation>アップデート/Webコンテンツ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="203"/>
 | 
			
		||||
        <source>This is the location your PS Vita system will read all the content that it tries to download.</source>
 | 
			
		||||
        <translation>この場所の全てのコンテンツをPS Vitaシステムが読み込み、ダウンロードを試みます。</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="226"/>
 | 
			
		||||
        <source>Packages</source>
 | 
			
		||||
        <translation>パッケージ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="265"/>
 | 
			
		||||
        <source>Other</source>
 | 
			
		||||
        <translation>その他</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="273"/>
 | 
			
		||||
        <source><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">詳細設定</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="280"/>
 | 
			
		||||
        <source>Offline Mode</source>
 | 
			
		||||
        <translation>オフラインモード</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="290"/>
 | 
			
		||||
        <source>Skip metadata extraction</source>
 | 
			
		||||
        <translation>メタデータの展開をスキップする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="314"/>
 | 
			
		||||
        <source>Update database automatically when files on the PC are changed</source>
 | 
			
		||||
        <translation>PCのファイルが変更された際にデータベースを自動的に更新する</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="342"/>
 | 
			
		||||
        <source>SQLite</source>
 | 
			
		||||
        <translation>SQLite</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="352"/>
 | 
			
		||||
        <source>Skip photo scanning</source>
 | 
			
		||||
        <translation>フォトのスキャンをスキップする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="359"/>
 | 
			
		||||
        <source>Skip video scanning</source>
 | 
			
		||||
        <translation>ビデオのスキャンをスキップする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="366"/>
 | 
			
		||||
        <source>Skip music scanning</source>
 | 
			
		||||
        <translation>ミュージックのスキャンをスキップする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="381"/>
 | 
			
		||||
        <source>CMA protocol version</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="461"/>
 | 
			
		||||
        <source>CMA protocol selection</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="469"/>
 | 
			
		||||
        <source>Latest</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="474"/>
 | 
			
		||||
        <source>Manual</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="479"/>
 | 
			
		||||
        <source>Custom</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="487"/>
 | 
			
		||||
        <source>CMA custom version</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="297"/>
 | 
			
		||||
        <source>Disable USB monitoring</source>
 | 
			
		||||
        <translation>USBの監視を無効にする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="304"/>
 | 
			
		||||
        <source>Disable Wi-Fi monitoring</source>
 | 
			
		||||
        <translation>Wi-Fiの監視を無効にする</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="326"/>
 | 
			
		||||
        <source>Database backend</source>
 | 
			
		||||
        <translation>データベース保存</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.ui" line="337"/>
 | 
			
		||||
        <source>In Memory</source>
 | 
			
		||||
        <translation>メモリ内</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="163"/>
 | 
			
		||||
        <source>Select the folder to be used as a photo source</source>
 | 
			
		||||
        <translation>フォトの参照先として使用されるフォルダを選択してください</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="168"/>
 | 
			
		||||
        <source>Select the folder to be used as a music source</source>
 | 
			
		||||
        <translation>ミュージックの参照先として使用されるフォルダを選択してください</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="173"/>
 | 
			
		||||
        <source>Select the folder to be used as a video source</source>
 | 
			
		||||
        <translation>ビデオの参照先として使用されるフォルダを選択してください</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="178"/>
 | 
			
		||||
        <source>Select the folder to be used to save PS Vita games and backups</source>
 | 
			
		||||
        <translation>PS Vitaのゲームとバックアップの保存に使用されるフォルダを選択してください</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="183"/>
 | 
			
		||||
        <source>Select the folder to be used to fetch software updates</source>
 | 
			
		||||
        <translation>ソフトウェアアップデートの取得に使用されるフォルダを選択してください</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/configwidget.cpp" line="188"/>
 | 
			
		||||
        <source>Select the folder to be used to software packages</source>
 | 
			
		||||
        <translation>ソフトウェアパッケージに使うフォルダを選択してください</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ConfirmDialog</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/confirmdialog.ui" line="14"/>
 | 
			
		||||
        <source>Confirmation Message</source>
 | 
			
		||||
        <translation>確認メッセージ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/confirmdialog.ui" line="63"/>
 | 
			
		||||
        <source><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>
 | 
			
		||||
</source>
 | 
			
		||||
        <translation><html><head/><body><p><span style=" font-size:10pt;">次のゲームのバックアップを削除してもよろしいですか?</span></p><p><span style=" font-size:12pt; font-weight:600;">ゲーム名</span></p></body></html>
 | 
			
		||||
</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>FilterLineEdit</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/filterlineedit.cpp" line="50"/>
 | 
			
		||||
        <location filename="../../src/gui/filterlineedit.cpp" line="71"/>
 | 
			
		||||
        <source>Filter</source>
 | 
			
		||||
        <translation>フィルタ</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HTTPDownloader</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/httpdownloader.cpp" line="129"/>
 | 
			
		||||
        <source>Network error: %1</source>
 | 
			
		||||
        <translation>ネットワークエラー: %1</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>HeadlessManager</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/cli/headlessmanager.cpp" line="97"/>
 | 
			
		||||
        <source>This user doesn't belong to the vitamtp group, there could be a problem while reading the USB bus.</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>KDENotifierTray</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="34"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>設定</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="35"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>データベースを更新する</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="36"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>バックアップマネージャー</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="37"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>QCMAについて</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="38"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>Qtについて</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="39"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>終了</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="69"/>
 | 
			
		||||
        <source>Qcma status</source>
 | 
			
		||||
        <translation>QCMAステータス</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/kdenotifiertray.cpp" line="71"/>
 | 
			
		||||
        <source>Disconnected</source>
 | 
			
		||||
        <translation>切断されました</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>MainWidget</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="79"/>
 | 
			
		||||
        <source>Shutting down...</source>
 | 
			
		||||
        <translation>終了しています...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="81"/>
 | 
			
		||||
        <source>Stopping QCMA (disconnect your PS Vita)</source>
 | 
			
		||||
        <translation>QCMAを停止しています (PS Vitaとの接続を切断してください)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="94"/>
 | 
			
		||||
        <source>Disconnected</source>
 | 
			
		||||
        <translation>切断されました</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="95"/>
 | 
			
		||||
        <source>The device has been disconnected</source>
 | 
			
		||||
        <translation>デバイスが切断されました</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="159"/>
 | 
			
		||||
        <source>About Qcma</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="161"/>
 | 
			
		||||
        <source>Copyright (C) 2015  Codestation</source>
 | 
			
		||||
        <translation type="unfinished">Copyright (C) 2014  Codestation {2015 ?}</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="163"/>
 | 
			
		||||
        <source>Copyright (C) 2015  Codestation
 | 
			
		||||
 | 
			
		||||
build hash: %1
 | 
			
		||||
build branch: %2</source>
 | 
			
		||||
        <translation type="unfinished">Copyright (C) 2014  Codestation
 | 
			
		||||
 | 
			
		||||
ビルドハッシュ: %1
 | 
			
		||||
ビルドブランチ: %2 {2015 ?} {1
 | 
			
		||||
?}</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/mainwidget.cpp" line="266"/>
 | 
			
		||||
        <source>Information</source>
 | 
			
		||||
        <translation>情報</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>PinForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="17"/>
 | 
			
		||||
        <source>Device pairing</source>
 | 
			
		||||
        <translation>端末のペアリング</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="25"/>
 | 
			
		||||
        <source>An unregistered PS Vita system is connecting with QCMA via Wi-Fi</source>
 | 
			
		||||
        <translation>登録されていないPS VitaがWi-Fi経由でQCMAで接続しています</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="35"/>
 | 
			
		||||
        <source>Device: PS Vita</source>
 | 
			
		||||
        <translation>端末: PS Vita</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="45"/>
 | 
			
		||||
        <source>Input the following number in the PS Vita system to register it with QCMA</source>
 | 
			
		||||
        <translation>QCMAでPS Vitaを登録するために次の番号をPS Vitaで入力してください</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="55"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html></source>
 | 
			
		||||
        <translation></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="65"/>
 | 
			
		||||
        <source>Time remaining: 300 seconds</source>
 | 
			
		||||
        <translation>残り時間: 300秒</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.ui" line="90"/>
 | 
			
		||||
        <source>Cancel</source>
 | 
			
		||||
        <translation>キャンセル</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.cpp" line="45"/>
 | 
			
		||||
        <source>Device: %1 (PS Vita)</source>
 | 
			
		||||
        <translation>端末: %1 (PS Vita)</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/pinform.cpp" line="65"/>
 | 
			
		||||
        <source>Time remaining: %1 seconds</source>
 | 
			
		||||
        <translation>残り時間: %1秒</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>ProgressForm</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="17"/>
 | 
			
		||||
        <source>Refreshing database...</source>
 | 
			
		||||
        <translation>データベースを更新しています...</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="25"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Reading directory:</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Leyendo directorio:</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="32"/>
 | 
			
		||||
        <source>directory name</source>
 | 
			
		||||
        <translation>ディレクトリ名</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="39"/>
 | 
			
		||||
        <source><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Processing file:</span></p></body></html></source>
 | 
			
		||||
        <translation><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Procesando archivo:</span></p></body></html></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="46"/>
 | 
			
		||||
        <source>file name</source>
 | 
			
		||||
        <translation>ファイル名</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.ui" line="68"/>
 | 
			
		||||
        <source>Cancel</source>
 | 
			
		||||
        <translation>キャンセル</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.cpp" line="45"/>
 | 
			
		||||
        <source>Database indexing in progress</source>
 | 
			
		||||
        <translation>データベース構築が進行中です</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/forms/progressform.cpp" line="46"/>
 | 
			
		||||
        <source>Are you sure to cancel the database indexing?</source>
 | 
			
		||||
        <translation>データベース構築をキャンセルしてもよろしいですか?</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>QObject</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/gui/main.cpp" line="78"/>
 | 
			
		||||
        <source>An instance of Qcma is already running</source>
 | 
			
		||||
        <translation type="unfinished"></translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>QTrayIcon</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="51"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>設定</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="52"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>データベースを更新する</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="53"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>バックアップマネージャー</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="54"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>QCMAについて</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="55"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>Qtについて</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/qtrayicon.cpp" line="56"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>終了</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
<context>
 | 
			
		||||
    <name>UnityIndicator</name>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="105"/>
 | 
			
		||||
        <source>Settings</source>
 | 
			
		||||
        <translation>設定</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="106"/>
 | 
			
		||||
        <source>Refresh database</source>
 | 
			
		||||
        <translation>データベースを更新する</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="107"/>
 | 
			
		||||
        <source>Backup Manager</source>
 | 
			
		||||
        <translation>バックアップマネージャー</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="109"/>
 | 
			
		||||
        <source>About QCMA</source>
 | 
			
		||||
        <translation>QCMAについて</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="110"/>
 | 
			
		||||
        <source>About Qt</source>
 | 
			
		||||
        <translation>Qtについて</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
    <message>
 | 
			
		||||
        <location filename="../../src/indicator/unityindicator.cpp" line="112"/>
 | 
			
		||||
        <source>Quit</source>
 | 
			
		||||
        <translation>終了</translation>
 | 
			
		||||
    </message>
 | 
			
		||||
</context>
 | 
			
		||||
</TS>
 | 
			
		||||
@@ -1,84 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<update_data_list>
 | 
			
		||||
<region id="au">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="eu">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="jp">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="kr">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="mx">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="ru">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="tw">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="uk">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
<region id="us">
 | 
			
		||||
    <np level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <np_d level0_system_version="00.000.000" level1_system_version="00.000.000" level2_system_version="00.000.000" map="00.000.000" />
 | 
			
		||||
    <version system_version="00.000.000" label="0.00">
 | 
			
		||||
      <update_data update_type="full">
 | 
			
		||||
        <image size="0">http://www.example.com/PSP2UPDAT.PUP</image>
 | 
			
		||||
      </update_data>
 | 
			
		||||
    </version>
 | 
			
		||||
</region>
 | 
			
		||||
</update_data_list>
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
#include "avdecoder.h"
 | 
			
		||||
#include "database.h"
 | 
			
		||||
 | 
			
		||||
#include <QBuffer>
 | 
			
		||||
#include <QFile>
 | 
			
		||||
#include <QImage>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef AVDECODER_H
 | 
			
		||||
#define AVDECODER_H
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <libavcodec/avcodec.h>
 | 
			
		||||
#include <libavformat/avformat.h>
 | 
			
		||||
#include <libswscale/swscale.h>
 | 
			
		||||
#include <libavutil/mathematics.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "capability.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QHostInfo>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CAPABILITY_H
 | 
			
		||||
#define CAPABILITY_H
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cmaclient.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
#include "sqlitedb.h"
 | 
			
		||||
#include "qlistdb.h"
 | 
			
		||||
#include "headlessmanager.h"
 | 
			
		||||
 | 
			
		||||
#include <QCoreApplication>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QTextStream>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef HEADLESSMANAGER_H
 | 
			
		||||
#define HEADLESSMANAGER_H
 | 
			
		||||
 | 
			
		||||
#include "database.h"
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QSocketNotifier>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef Q_OS_WIN32
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QLibraryInfo>
 | 
			
		||||
#include <QLocale>
 | 
			
		||||
#include <QStringList>
 | 
			
		||||
#include <QTextCodec>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QTranslator>
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
#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();
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "singlecoreapplication.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SINGLECOREAPPLICATION_H
 | 
			
		||||
#define SINGLECOREAPPLICATION_H
 | 
			
		||||
 | 
			
		||||
#include <QCoreApplication>
 | 
			
		||||
#include <QLocalSocket>
 | 
			
		||||
#include <QLocalServer>
 | 
			
		||||
#include <QSharedMemory>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cmabroadcast.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QHostAddress>
 | 
			
		||||
#include <QHostInfo>
 | 
			
		||||
#include <QMutexLocker>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QUuid>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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');
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CMABROADCAST_H
 | 
			
		||||
#define CMABROADCAST_H
 | 
			
		||||
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QUdpSocket>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cmaclient.h"
 | 
			
		||||
#include "capability.h"
 | 
			
		||||
#include "avdecoder.h"
 | 
			
		||||
#include "cmaevent.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QImage>
 | 
			
		||||
#include <QTextStream>
 | 
			
		||||
#include <QTime>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QUrl>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CMACLIENT_H
 | 
			
		||||
#define CMACLIENT_H
 | 
			
		||||
 | 
			
		||||
#include "qlistdb.h"
 | 
			
		||||
#include "cmaevent.h"
 | 
			
		||||
#include "cmabroadcast.h"
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QSemaphore>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QWaitCondition>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										1009
									
								
								src/cmaevent.cpp
									
									
									
									
									
								
							
							
						
						@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CMAEVENT_H
 | 
			
		||||
#define CMAEVENT_H
 | 
			
		||||
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "httpdownloader.h"
 | 
			
		||||
 | 
			
		||||
#include <QFile>
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QSemaphore>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cmaobject.h"
 | 
			
		||||
#include "sforeader.h"
 | 
			
		||||
#include "avdecoder.h"
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CMAOBJECT_H
 | 
			
		||||
#define CMAOBJECT_H
 | 
			
		||||
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cmarootobject.h"
 | 
			
		||||
 | 
			
		||||
#include <QDir>
 | 
			
		||||
 | 
			
		||||
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<DataType>(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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CMAROOTOBJECT_H
 | 
			
		||||
#define CMAROOTOBJECT_H
 | 
			
		||||
 | 
			
		||||
#include "cmaobject.h"
 | 
			
		||||
 | 
			
		||||
#include <QList>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										305
									
								
								src/cmautils.cpp
									
									
									
									
									
								
							
							
						
						@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
#include "avdecoder.h"
 | 
			
		||||
 | 
			
		||||
#include <QBuffer>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QImage>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
#ifdef Q_OS_WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#elif defined Q_OS_ANDROID
 | 
			
		||||
#include <sys/vfs.h>
 | 
			
		||||
#define statvfs statfs
 | 
			
		||||
#else
 | 
			
		||||
#include <sys/statvfs.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef Q_OS_LINUX
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#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<char> 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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UTILS_H
 | 
			
		||||
#define UTILS_H
 | 
			
		||||
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
							
								
								
									
										152
									
								
								src/database.cpp
									
									
									
									
									
								
							
							
						
						@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "avdecoder.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QImage>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QTextStream>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								src/database.h
									
									
									
									
									
								
							
							
						
						@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef DATABASE_H
 | 
			
		||||
#define DATABASE_H
 | 
			
		||||
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    const char *file_ext;
 | 
			
		||||
    int file_format;
 | 
			
		||||
    int file_codec;
 | 
			
		||||
} file_type;
 | 
			
		||||
 | 
			
		||||
#define OHFI_BASE_VALUE 256
 | 
			
		||||
 | 
			
		||||
#define FILE_FORMAT_MP4 1
 | 
			
		||||
#define FILE_FORMAT_WAV 2
 | 
			
		||||
#define FILE_FORMAT_MP3 3
 | 
			
		||||
#define FILE_FORMAT_JPG 4
 | 
			
		||||
#define FILE_FORMAT_PNG 5
 | 
			
		||||
#define FILE_FORMAT_GIF 6
 | 
			
		||||
#define FILE_FORMAT_BMP 7
 | 
			
		||||
#define FILE_FORMAT_TIF 8
 | 
			
		||||
 | 
			
		||||
#define CODEC_TYPE_MPEG4 2
 | 
			
		||||
#define CODEC_TYPE_AVC 3
 | 
			
		||||
#define CODEC_TYPE_MP3 12
 | 
			
		||||
#define CODEC_TYPE_AAC 13
 | 
			
		||||
#define CODEC_TYPE_PCM 15
 | 
			
		||||
#define CODEC_TYPE_JPG 17
 | 
			
		||||
#define CODEC_TYPE_PNG 18
 | 
			
		||||
#define CODEC_TYPE_TIF 19
 | 
			
		||||
#define CODEC_TYPE_BMP 20
 | 
			
		||||
#define CODEC_TYPE_GIF 21
 | 
			
		||||
 | 
			
		||||
extern const file_type audio_list[3];
 | 
			
		||||
extern const file_type photo_list[7];
 | 
			
		||||
extern const file_type video_list[1];
 | 
			
		||||
 | 
			
		||||
class Database : public QObject
 | 
			
		||||
{
 | 
			
		||||
    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
 | 
			
		||||
							
								
								
									
										1032
									
								
								src/dds.cpp
									
									
									
									
									
								
							
							
						
						
							
								
								
									
										30
									
								
								src/dds.h
									
									
									
									
									
								
							
							
						
						@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef KIMG_DDS_H
 | 
			
		||||
#define KIMG_DDS_H
 | 
			
		||||
 | 
			
		||||
#include <QImage>
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
bool loadDDS(const QString &filename, QImage *image);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "backupitem.h"
 | 
			
		||||
#include "ui_backupitem.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
#include "dds.h"
 | 
			
		||||
 | 
			
		||||
#include <QDesktopServices>
 | 
			
		||||
#include <QUrl>
 | 
			
		||||
 | 
			
		||||
const QString BackupItem::gameTemplate = "<html><head/><body>"
 | 
			
		||||
        "<p><span style=\" font-size:13pt; font-weight:600;\">%1</span></p>"
 | 
			
		||||
        "</body></html>";
 | 
			
		||||
 | 
			
		||||
const QString BackupItem::sizeTemplate = "<html><head/><body>"
 | 
			
		||||
        "<p><span style=\" font-size:10pt;\">%1</span></p>"
 | 
			
		||||
        "</body></html>";
 | 
			
		||||
 | 
			
		||||
const QString BackupItem::infoTemplate = "<html><head/><body>"
 | 
			
		||||
        "<p><span style=\" font-size:10pt;\"> %1</span></p>"
 | 
			
		||||
        "</body></html>";
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BACKUPITEM_H
 | 
			
		||||
#define BACKUPITEM_H
 | 
			
		||||
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1,154 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>BackupItem</class>
 | 
			
		||||
 <widget class="QWidget" name="BackupItem">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>638</width>
 | 
			
		||||
    <height>75</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="sizePolicy">
 | 
			
		||||
   <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
 | 
			
		||||
    <horstretch>0</horstretch>
 | 
			
		||||
    <verstretch>0</verstretch>
 | 
			
		||||
   </sizepolicy>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string/>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QGridLayout" name="gridLayout">
 | 
			
		||||
   <item row="0" column="0">
 | 
			
		||||
    <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="itemPicture">
 | 
			
		||||
       <property name="minimumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>48</width>
 | 
			
		||||
         <height>48</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="maximumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>0</width>
 | 
			
		||||
         <height>48</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string notr="true"/>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="scaledContents">
 | 
			
		||||
        <bool>true</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="alignment">
 | 
			
		||||
        <set>Qt::AlignCenter</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <layout class="QVBoxLayout" name="verticalLayout_2">
 | 
			
		||||
       <property name="rightMargin">
 | 
			
		||||
        <number>5</number>
 | 
			
		||||
       </property>
 | 
			
		||||
       <item>
 | 
			
		||||
        <widget class="QLabel" name="gameLabel">
 | 
			
		||||
         <property name="text">
 | 
			
		||||
          <string notr="true"><p><span style=" font-size:12pt; font-weight:600;">Game Name</span></p></string>
 | 
			
		||||
         </property>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <layout class="QHBoxLayout" name="horizontalLayout_2">
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QLabel" name="sizeLabel">
 | 
			
		||||
           <property name="sizePolicy">
 | 
			
		||||
            <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
 | 
			
		||||
             <horstretch>0</horstretch>
 | 
			
		||||
             <verstretch>0</verstretch>
 | 
			
		||||
            </sizepolicy>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="minimumSize">
 | 
			
		||||
            <size>
 | 
			
		||||
             <width>90</width>
 | 
			
		||||
             <height>0</height>
 | 
			
		||||
            </size>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string notr="true"><p><span style=" font-size:10pt;">0.00 GiB</span></p></string>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QLabel" name="infoLabel">
 | 
			
		||||
           <property name="sizePolicy">
 | 
			
		||||
            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
 | 
			
		||||
             <horstretch>0</horstretch>
 | 
			
		||||
             <verstretch>0</verstretch>
 | 
			
		||||
            </sizepolicy>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string notr="true"><html><head/><body><p><span style=" font-size:9pt;">[APP] [SAVE] [UPDATE] [DLC]</span></p></body></html></string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="alignment">
 | 
			
		||||
            <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </item>
 | 
			
		||||
      </layout>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <spacer name="horizontalSpacer">
 | 
			
		||||
       <property name="orientation">
 | 
			
		||||
        <enum>Qt::Horizontal</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sizeHint" stdset="0">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>40</width>
 | 
			
		||||
         <height>20</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
      </spacer>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QPushButton" name="deleteButton">
 | 
			
		||||
       <property name="sizePolicy">
 | 
			
		||||
        <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
 | 
			
		||||
         <horstretch>0</horstretch>
 | 
			
		||||
         <verstretch>0</verstretch>
 | 
			
		||||
        </sizepolicy>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="minimumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>0</width>
 | 
			
		||||
         <height>32</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Delete entry</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QPushButton" name="openButton">
 | 
			
		||||
       <property name="minimumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>0</width>
 | 
			
		||||
         <height>32</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Open folder</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "backupmanagerform.h"
 | 
			
		||||
#include "ui_backupmanagerform.h"
 | 
			
		||||
#include "cmaobject.h"
 | 
			
		||||
#include "sforeader.h"
 | 
			
		||||
#include "confirmdialog.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
#include "gui/filterlineedit.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDialogButtonBox>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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<BackupItem *>(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<BackupItem *> 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<BackupItem *>::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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BACKUPMANAGERFORM_H
 | 
			
		||||
#define BACKUPMANAGERFORM_H
 | 
			
		||||
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "backupitem.h"
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1,139 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>BackupManagerForm</class>
 | 
			
		||||
 <widget class="QWidget" name="BackupManagerForm">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>857</width>
 | 
			
		||||
    <height>478</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Backup Manager</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QGridLayout" name="gridLayout">
 | 
			
		||||
   <item row="0" column="0">
 | 
			
		||||
    <layout class="QHBoxLayout" name="horizontalLayout_3">
 | 
			
		||||
     <item>
 | 
			
		||||
      <layout class="QFormLayout" name="formLayout_3">
 | 
			
		||||
       <item row="0" column="0">
 | 
			
		||||
        <widget class="QLabel" name="label_3">
 | 
			
		||||
         <property name="text">
 | 
			
		||||
          <string>Online ID / Username</string>
 | 
			
		||||
         </property>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item row="0" column="1">
 | 
			
		||||
        <widget class="QComboBox" name="accountBox"/>
 | 
			
		||||
       </item>
 | 
			
		||||
      </layout>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <layout class="QFormLayout" name="formLayout_4">
 | 
			
		||||
       <property name="fieldGrowthPolicy">
 | 
			
		||||
        <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <item row="0" column="0">
 | 
			
		||||
        <widget class="QLabel" name="label_4">
 | 
			
		||||
         <property name="text">
 | 
			
		||||
          <string>Backup Type</string>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="margin">
 | 
			
		||||
          <number>2</number>
 | 
			
		||||
         </property>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item row="0" column="1">
 | 
			
		||||
        <widget class="QComboBox" name="backupComboBox">
 | 
			
		||||
         <item>
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>PS Vita Games</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>PSP Games</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>PSM Games</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>PSOne Games</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>PSP Savedatas</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <property name="text">
 | 
			
		||||
           <string>Backups</string>
 | 
			
		||||
          </property>
 | 
			
		||||
         </item>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </item>
 | 
			
		||||
      </layout>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item row="1" column="0">
 | 
			
		||||
    <widget class="QTableWidget" name="tableWidget">
 | 
			
		||||
     <property name="columnCount">
 | 
			
		||||
      <number>1</number>
 | 
			
		||||
     </property>
 | 
			
		||||
     <column/>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item row="2" column="0">
 | 
			
		||||
    <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="usageLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Backup disk usage</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <spacer name="horizontalSpacer">
 | 
			
		||||
       <property name="orientation">
 | 
			
		||||
        <enum>Qt::Horizontal</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sizeHint" stdset="0">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>40</width>
 | 
			
		||||
         <height>20</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
      </spacer>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="FilterLineEdit" name="filterLineEdit">
 | 
			
		||||
       <property name="styleSheet">
 | 
			
		||||
        <string notr="true">FilterLineEdit { color:gray; font-style:italic; }</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Filter</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <customwidgets>
 | 
			
		||||
  <customwidget>
 | 
			
		||||
   <class>FilterLineEdit</class>
 | 
			
		||||
   <extends>QLineEdit</extends>
 | 
			
		||||
   <header>gui/filterlineedit.h</header>
 | 
			
		||||
  </customwidget>
 | 
			
		||||
 </customwidgets>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "configwidget.h"
 | 
			
		||||
#include "ui_configwidget.h"
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <QFileDialog>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
 | 
			
		||||
#include <QStandardPaths>
 | 
			
		||||
#else
 | 
			
		||||
#include <QDesktopServices>
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIGWIDGET_H
 | 
			
		||||
#define CONFIGWIDGET_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
#include <QLineEdit>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QSignalMapper>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1,525 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>ConfigWidget</class>
 | 
			
		||||
 <widget class="QWidget" name="ConfigWidget">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>519</width>
 | 
			
		||||
    <height>525</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>QCMA Settings</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QGridLayout" name="gridLayout">
 | 
			
		||||
   <item row="0" column="0">
 | 
			
		||||
    <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QTabWidget" name="tabWidget">
 | 
			
		||||
       <property name="currentIndex">
 | 
			
		||||
        <number>0</number>
 | 
			
		||||
       </property>
 | 
			
		||||
       <widget class="QWidget" name="tab">
 | 
			
		||||
        <attribute name="title">
 | 
			
		||||
         <string>Folders</string>
 | 
			
		||||
        </attribute>
 | 
			
		||||
        <layout class="QGridLayout" name="gridLayout_2">
 | 
			
		||||
         <item row="1" column="0">
 | 
			
		||||
          <layout class="QVBoxLayout" name="verticalLayout_2">
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QLabel" name="label">
 | 
			
		||||
             <property name="font">
 | 
			
		||||
              <font>
 | 
			
		||||
               <pointsize>10</pointsize>
 | 
			
		||||
              </font>
 | 
			
		||||
             </property>
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Specify the folders that the PS Vita will access for each content type.</string>
 | 
			
		||||
             </property>
 | 
			
		||||
             <property name="wordWrap">
 | 
			
		||||
              <bool>true</bool>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QVBoxLayout" name="verticalLayout_3">
 | 
			
		||||
             <item>
 | 
			
		||||
              <widget class="QLabel" name="label_2">
 | 
			
		||||
               <property name="whatsThis">
 | 
			
		||||
                <string>This is the location your Screenshots and Pictures are Saved to/Imported from.</string>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>Photo Folder</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item>
 | 
			
		||||
              <layout class="QHBoxLayout" name="horizontalLayout_7">
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QLineEdit" name="photoPath">
 | 
			
		||||
                 <property name="toolTip">
 | 
			
		||||
                  <string>This is the location your Screenshots and Pictures are Saved to/Imported from.</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="readOnly">
 | 
			
		||||
                  <bool>true</bool>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QPushButton" name="photoBtn">
 | 
			
		||||
                 <property name="text">
 | 
			
		||||
                  <string>Browse...</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
              </layout>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QVBoxLayout" name="verticalLayout_4">
 | 
			
		||||
             <item>
 | 
			
		||||
              <widget class="QLabel" name="label_3">
 | 
			
		||||
               <property name="whatsThis">
 | 
			
		||||
                <string>This is the location your Videos are Saved to/Imported from.</string>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>Video Folder</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item>
 | 
			
		||||
              <layout class="QHBoxLayout" name="horizontalLayout_8">
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QLineEdit" name="videoPath">
 | 
			
		||||
                 <property name="toolTip">
 | 
			
		||||
                  <string>This is the location your Videos are Saved to/Imported from.</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="readOnly">
 | 
			
		||||
                  <bool>true</bool>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QPushButton" name="videoBtn">
 | 
			
		||||
                 <property name="text">
 | 
			
		||||
                  <string>Browse...</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
              </layout>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QVBoxLayout" name="verticalLayout_5">
 | 
			
		||||
             <item>
 | 
			
		||||
              <widget class="QLabel" name="label_4">
 | 
			
		||||
               <property name="whatsThis">
 | 
			
		||||
                <string>This is the location your Music is Saved to/Imported from.</string>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>Music Folder</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item>
 | 
			
		||||
              <layout class="QHBoxLayout" name="horizontalLayout_9">
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QLineEdit" name="musicPath">
 | 
			
		||||
                 <property name="toolTip">
 | 
			
		||||
                  <string>This is the location your Music is Saved to/Imported from.</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="readOnly">
 | 
			
		||||
                  <bool>true</bool>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QPushButton" name="musicBtn">
 | 
			
		||||
                 <property name="text">
 | 
			
		||||
                  <string>Browse...</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
              </layout>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QVBoxLayout" name="verticalLayout_7">
 | 
			
		||||
             <item>
 | 
			
		||||
              <widget class="QLabel" name="label_6">
 | 
			
		||||
               <property name="whatsThis">
 | 
			
		||||
                <string>This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from.</string>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>Applications / Backups</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item>
 | 
			
		||||
              <layout class="QHBoxLayout" name="horizontalLayout_2">
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QLineEdit" name="appPath">
 | 
			
		||||
                 <property name="toolTip">
 | 
			
		||||
                  <string>This is the location your Games, Apps, Savegames, and System Backups are Saved to/Imported from.</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="readOnly">
 | 
			
		||||
                  <bool>true</bool>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QPushButton" name="appBtn">
 | 
			
		||||
                 <property name="text">
 | 
			
		||||
                  <string>Browse...</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
              </layout>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QVBoxLayout" name="verticalLayout_6">
 | 
			
		||||
             <item>
 | 
			
		||||
              <widget class="QLabel" name="label_5">
 | 
			
		||||
               <property name="whatsThis">
 | 
			
		||||
                <string>This is the location your Software Updates and Browser Data is Saved to/Imported from.</string>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>Updates / Web content</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item>
 | 
			
		||||
              <layout class="QHBoxLayout" name="horizontalLayout_10">
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QLineEdit" name="urlPath">
 | 
			
		||||
                 <property name="toolTip">
 | 
			
		||||
                  <string>This is the location your PS Vita system will read all the content that it tries to download.</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="readOnly">
 | 
			
		||||
                  <bool>true</bool>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QPushButton" name="urlBtn">
 | 
			
		||||
                 <property name="text">
 | 
			
		||||
                  <string>Browse...</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
              </layout>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QVBoxLayout" name="verticalLayout_9">
 | 
			
		||||
             <item>
 | 
			
		||||
              <widget class="QLabel" name="label_9">
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>Packages</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item>
 | 
			
		||||
              <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QLineEdit" name="pkgPath"/>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <widget class="QPushButton" name="pkgBtn">
 | 
			
		||||
                 <property name="text">
 | 
			
		||||
                  <string>Browse...</string>
 | 
			
		||||
                 </property>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
              </layout>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item>
 | 
			
		||||
              <spacer name="verticalSpacer_2">
 | 
			
		||||
               <property name="orientation">
 | 
			
		||||
                <enum>Qt::Vertical</enum>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="sizeHint" stdset="0">
 | 
			
		||||
                <size>
 | 
			
		||||
                 <width>20</width>
 | 
			
		||||
                 <height>40</height>
 | 
			
		||||
                </size>
 | 
			
		||||
               </property>
 | 
			
		||||
              </spacer>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
          </layout>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </widget>
 | 
			
		||||
       <widget class="QWidget" name="tab_2">
 | 
			
		||||
        <attribute name="title">
 | 
			
		||||
         <string>Other</string>
 | 
			
		||||
        </attribute>
 | 
			
		||||
        <layout class="QGridLayout" name="gridLayout_3">
 | 
			
		||||
         <item row="2" column="0">
 | 
			
		||||
          <layout class="QVBoxLayout" name="verticalLayout_8">
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QLabel" name="label_7">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string><html><head/><body><p align="center"><span style=" font-size:14pt; font-weight:600;">Advanced settings</span></p></body></html></string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="offlineCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Offline Mode</string>
 | 
			
		||||
             </property>
 | 
			
		||||
             <property name="checked">
 | 
			
		||||
              <bool>true</bool>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="metadataCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Skip metadata extraction</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="usbCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Disable USB monitoring</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="wifiCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Disable Wi-Fi monitoring</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="checkBox_3">
 | 
			
		||||
             <property name="enabled">
 | 
			
		||||
              <bool>false</bool>
 | 
			
		||||
             </property>
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Update database automatically when files on the PC are changed</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QFormLayout" name="formLayout">
 | 
			
		||||
             <property name="fieldGrowthPolicy">
 | 
			
		||||
              <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
 | 
			
		||||
             </property>
 | 
			
		||||
             <item row="0" column="0">
 | 
			
		||||
              <widget class="QLabel" name="label_8">
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>Database backend</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="0" column="1">
 | 
			
		||||
              <widget class="QComboBox" name="databaseSelect">
 | 
			
		||||
               <property name="enabled">
 | 
			
		||||
                <bool>false</bool>
 | 
			
		||||
               </property>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string>In Memory</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string>SQLite</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="photoSkipCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Skip photo scanning</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="videoSkipCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Skip video scanning</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <widget class="QCheckBox" name="musicSkipCheck">
 | 
			
		||||
             <property name="text">
 | 
			
		||||
              <string>Skip music scanning</string>
 | 
			
		||||
             </property>
 | 
			
		||||
            </widget>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QHBoxLayout" name="horizontalLayout_4"/>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <layout class="QFormLayout" name="formLayout_2">
 | 
			
		||||
             <property name="fieldGrowthPolicy">
 | 
			
		||||
              <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
 | 
			
		||||
             </property>
 | 
			
		||||
             <item row="1" column="0">
 | 
			
		||||
              <widget class="QLabel" name="label_10">
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>CMA protocol version</string>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="alignment">
 | 
			
		||||
                <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="1" column="1">
 | 
			
		||||
              <widget class="QComboBox" name="protocolBox">
 | 
			
		||||
               <property name="minimumSize">
 | 
			
		||||
                <size>
 | 
			
		||||
                 <width>200</width>
 | 
			
		||||
                 <height>0</height>
 | 
			
		||||
                </size>
 | 
			
		||||
               </property>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 3.30 - 1900010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 3.10 - 1800010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 3.00 - 1700010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 2.60 - 1600010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 2.10 - 1500010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 2.00 - 1400010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 1.80 - 1300010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 1.60 - 1200010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 1.50 - 1100010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string notr="true">FW 1.00 - 1000010</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="2" column="1">
 | 
			
		||||
              <widget class="QLineEdit" name="protocolEdit">
 | 
			
		||||
               <property name="inputMask">
 | 
			
		||||
                <string notr="true">9999999</string>
 | 
			
		||||
               </property>
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string notr="true"/>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="0" column="0">
 | 
			
		||||
              <widget class="QLabel" name="label_11">
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>CMA protocol selection</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="0" column="1">
 | 
			
		||||
              <widget class="QComboBox" name="protocolModeBox">
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string>Latest</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string>Manual</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
               <item>
 | 
			
		||||
                <property name="text">
 | 
			
		||||
                 <string>Custom</string>
 | 
			
		||||
                </property>
 | 
			
		||||
               </item>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
             <item row="2" column="0">
 | 
			
		||||
              <widget class="QLabel" name="label_12">
 | 
			
		||||
               <property name="text">
 | 
			
		||||
                <string>CMA custom version</string>
 | 
			
		||||
               </property>
 | 
			
		||||
              </widget>
 | 
			
		||||
             </item>
 | 
			
		||||
            </layout>
 | 
			
		||||
           </item>
 | 
			
		||||
           <item>
 | 
			
		||||
            <spacer name="verticalSpacer">
 | 
			
		||||
             <property name="orientation">
 | 
			
		||||
              <enum>Qt::Vertical</enum>
 | 
			
		||||
             </property>
 | 
			
		||||
             <property name="sizeHint" stdset="0">
 | 
			
		||||
              <size>
 | 
			
		||||
               <width>20</width>
 | 
			
		||||
               <height>40</height>
 | 
			
		||||
              </size>
 | 
			
		||||
             </property>
 | 
			
		||||
            </spacer>
 | 
			
		||||
           </item>
 | 
			
		||||
          </layout>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QDialogButtonBox" name="buttonBox">
 | 
			
		||||
       <property name="standardButtons">
 | 
			
		||||
        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "confirmdialog.h"
 | 
			
		||||
#include "ui_confirmdialog.h"
 | 
			
		||||
 | 
			
		||||
const QString ConfirmDialog::messageTemplate = "<html><head/><body>"
 | 
			
		||||
        "<p><span style=\"font-size:10pt;\">%1</span></p>"
 | 
			
		||||
        "<p><span style=\"font-size:12pt; font-weight:600;\">%2</span></p>"
 | 
			
		||||
        "</body></html>";
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIRMDIALOG_H
 | 
			
		||||
#define CONFIRMDIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1,120 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>ConfirmDialog</class>
 | 
			
		||||
 <widget class="QDialog" name="ConfirmDialog">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>519</width>
 | 
			
		||||
    <height>106</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Confirmation Message</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="modal">
 | 
			
		||||
   <bool>true</bool>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QGridLayout" name="gridLayout">
 | 
			
		||||
   <item row="0" column="0">
 | 
			
		||||
    <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="itemPicture">
 | 
			
		||||
       <property name="minimumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>48</width>
 | 
			
		||||
         <height>48</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="maximumSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>0</width>
 | 
			
		||||
         <height>48</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string/>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="scaledContents">
 | 
			
		||||
        <bool>true</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <spacer name="horizontalSpacer">
 | 
			
		||||
       <property name="orientation">
 | 
			
		||||
        <enum>Qt::Horizontal</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sizeType">
 | 
			
		||||
        <enum>QSizePolicy::Fixed</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sizeHint" stdset="0">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>10</width>
 | 
			
		||||
         <height>0</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
      </spacer>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="confirmText">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string><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>
 | 
			
		||||
</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="margin">
 | 
			
		||||
        <number>0</number>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item row="1" column="0">
 | 
			
		||||
    <widget class="QDialogButtonBox" name="buttonBox">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Horizontal</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="standardButtons">
 | 
			
		||||
      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>accepted()</signal>
 | 
			
		||||
   <receiver>ConfirmDialog</receiver>
 | 
			
		||||
   <slot>accept()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>248</x>
 | 
			
		||||
     <y>254</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>157</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>rejected()</signal>
 | 
			
		||||
   <receiver>ConfirmDialog</receiver>
 | 
			
		||||
   <slot>reject()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>316</x>
 | 
			
		||||
     <y>260</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>286</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
 </connections>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "pinform.h"
 | 
			
		||||
#include "ui_pinform.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDesktopWidget>
 | 
			
		||||
 | 
			
		||||
const QString PinForm::pinFormat =
 | 
			
		||||
    "<html><head/><body>"
 | 
			
		||||
    "<p><span style=\"font-size:24pt; font-weight:600;\">%1</span></p>"
 | 
			
		||||
    "</body></html>";
 | 
			
		||||
 | 
			
		||||
PinForm::PinForm(QWidget *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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef PINFORM_H
 | 
			
		||||
#define PINFORM_H
 | 
			
		||||
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1,115 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>PinForm</class>
 | 
			
		||||
 <widget class="QWidget" name="PinForm">
 | 
			
		||||
  <property name="windowModality">
 | 
			
		||||
   <enum>Qt::ApplicationModal</enum>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>526</width>
 | 
			
		||||
    <height>216</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Device pairing</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QGridLayout" name="gridLayout">
 | 
			
		||||
   <item row="0" column="0">
 | 
			
		||||
    <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="label_2">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>An unregistered PS Vita system is connecting with QCMA via Wi-Fi</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="alignment">
 | 
			
		||||
        <set>Qt::AlignCenter</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="deviceLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Device: PS Vita</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="alignment">
 | 
			
		||||
        <set>Qt::AlignCenter</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="label_3">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Input the following number in the PS Vita system to register it with QCMA</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="alignment">
 | 
			
		||||
        <set>Qt::AlignCenter</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="pinLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string><html><head/><body><p><span style=" font-size:24pt; font-weight:600;">12345678</span></p></body></html></string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="alignment">
 | 
			
		||||
        <set>Qt::AlignCenter</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="timeLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Time remaining: 300 seconds</string>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="alignment">
 | 
			
		||||
        <set>Qt::AlignCenter</set>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
       <item>
 | 
			
		||||
        <spacer name="horizontalSpacer_2">
 | 
			
		||||
         <property name="orientation">
 | 
			
		||||
          <enum>Qt::Horizontal</enum>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="sizeHint" stdset="0">
 | 
			
		||||
          <size>
 | 
			
		||||
           <width>40</width>
 | 
			
		||||
           <height>20</height>
 | 
			
		||||
          </size>
 | 
			
		||||
         </property>
 | 
			
		||||
        </spacer>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <widget class="QPushButton" name="cancelButton">
 | 
			
		||||
         <property name="text">
 | 
			
		||||
          <string>Cancel</string>
 | 
			
		||||
         </property>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <spacer name="horizontalSpacer">
 | 
			
		||||
         <property name="orientation">
 | 
			
		||||
          <enum>Qt::Horizontal</enum>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="sizeHint" stdset="0">
 | 
			
		||||
          <size>
 | 
			
		||||
           <width>40</width>
 | 
			
		||||
           <height>20</height>
 | 
			
		||||
          </size>
 | 
			
		||||
         </property>
 | 
			
		||||
        </spacer>
 | 
			
		||||
       </item>
 | 
			
		||||
      </layout>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "progressform.h"
 | 
			
		||||
#include "ui_progressform.h"
 | 
			
		||||
 | 
			
		||||
#include <QDesktopWidget>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef PROGRESSFORM_H
 | 
			
		||||
#define PROGRESSFORM_H
 | 
			
		||||
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -1,80 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>ProgressForm</class>
 | 
			
		||||
 <widget class="QWidget" name="ProgressForm">
 | 
			
		||||
  <property name="windowModality">
 | 
			
		||||
   <enum>Qt::ApplicationModal</enum>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>602</width>
 | 
			
		||||
    <height>138</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Refreshing database...</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QGridLayout" name="gridLayout">
 | 
			
		||||
   <item row="1" column="0">
 | 
			
		||||
    <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="label">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Reading directory:</span></p></body></html></string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="directoryLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>directory name</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="label_3">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string><html><head/><body><p><span style=" font-size:11pt; font-weight:600;">Processing file:</span></p></body></html></string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QLabel" name="fileLabel">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>file name</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
       <item>
 | 
			
		||||
        <spacer name="horizontalSpacer">
 | 
			
		||||
         <property name="orientation">
 | 
			
		||||
          <enum>Qt::Horizontal</enum>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="sizeHint" stdset="0">
 | 
			
		||||
          <size>
 | 
			
		||||
           <width>40</width>
 | 
			
		||||
           <height>20</height>
 | 
			
		||||
          </size>
 | 
			
		||||
         </property>
 | 
			
		||||
        </spacer>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <widget class="QPushButton" name="cancelButton">
 | 
			
		||||
         <property name="text">
 | 
			
		||||
          <string>Cancel</string>
 | 
			
		||||
         </property>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </item>
 | 
			
		||||
      </layout>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clientmanager.h"
 | 
			
		||||
#include "cmaclient.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
#include "forms/progressform.h"
 | 
			
		||||
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
#ifdef Q_OS_UNIX
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CLIENTMANAGER_H
 | 
			
		||||
#define CLIENTMANAGER_H
 | 
			
		||||
 | 
			
		||||
#include "database.h"
 | 
			
		||||
#include "forms/pinform.h"
 | 
			
		||||
#include "forms/progressform.h"
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
#ifdef Q_OS_UNIX
 | 
			
		||||
#include <QSocketNotifier>
 | 
			
		||||
#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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "filterlineedit.h"
 | 
			
		||||
 | 
			
		||||
#include <QIcon>
 | 
			
		||||
#include <QStyle>
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef FILTERLINEEDIT_H
 | 
			
		||||
#define FILTERLINEEDIT_H
 | 
			
		||||
 | 
			
		||||
#include <QLineEdit>
 | 
			
		||||
#include <QToolButton>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										152
									
								
								src/gui/main.cpp
									
									
									
									
									
								
							
							
						
						@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef Q_OS_WIN32
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QLibraryInfo>
 | 
			
		||||
#include <QLocale>
 | 
			
		||||
#include <QTextCodec>
 | 
			
		||||
#include <QTextStream>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
#include <QTranslator>
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#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();
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "mainwidget.h"
 | 
			
		||||
#include "cmaclient.h"
 | 
			
		||||
#include "cmautils.h"
 | 
			
		||||
 | 
			
		||||
#include "qlistdb.h"
 | 
			
		||||
#include "sqlitedb.h"
 | 
			
		||||
 | 
			
		||||
#include "indicator/qtrayicon.h"
 | 
			
		||||
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <QGridLayout>
 | 
			
		||||
#include <QLibrary>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QSettings>
 | 
			
		||||
#include <QSpacerItem>
 | 
			
		||||
 | 
			
		||||
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<TrayFunctionPointer>(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<TrayFunctionPointer>(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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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 <QAction>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
#include <QSystemTrayIcon>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "singleapplication.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SINGLEAPPLICATION_H
 | 
			
		||||
#define SINGLEAPPLICATION_H
 | 
			
		||||
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include <QLocalSocket>
 | 
			
		||||
#include <QLocalServer>
 | 
			
		||||
#include <QSharedMemory>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "httpdownloader.h"
 | 
			
		||||
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
#include <vitamtp.h>
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef HTTPDOWNLOADER_H
 | 
			
		||||
#define HTTPDOWNLOADER_H
 | 
			
		||||
 | 
			
		||||
#include <QByteArray>
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QWaitCondition>
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "kdenotifier.h"
 | 
			
		||||
 | 
			
		||||
KDENotifier::KDENotifier(const QString ¬ifier_id, QObject *obj_parent) :
 | 
			
		||||
    KStatusNotifierItem(notifier_id, obj_parent)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef KDENOTIFIER_H
 | 
			
		||||
#define KDENOTIFIER_H
 | 
			
		||||
 | 
			
		||||
#include <kstatusnotifieritem.h>
 | 
			
		||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
 | 
			
		||||
#include <kmenu.h>
 | 
			
		||||
#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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "kdenotifiertray.h"
 | 
			
		||||
#ifndef ENABLE_KNOTIFICATIONS
 | 
			
		||||
#include <kmenu.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <QMenu>
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qtrayicon.h"
 | 
			
		||||
 | 
			
		||||
#include <QIcon>
 | 
			
		||||
#include <QMenu>
 | 
			
		||||
#include <QSystemTrayIcon>
 | 
			
		||||
 | 
			
		||||
#ifdef Q_OS_LINUX
 | 
			
		||||
#undef signals
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include <libnotify/notify.h>
 | 
			
		||||
}
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
@@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef TRAYINDICATOR_H
 | 
			
		||||
#define TRAYINDICATOR_H
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||