Added rest of file modifications. (oops)

This commit is contained in:
codestation
2015-03-21 14:53:43 -04:30
parent 9f790dc788
commit 79067535c0
112 changed files with 228 additions and 14060 deletions

View File

@@ -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>

View File

@@ -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) LIBS += $$system(pkg-config --static --libs libvitamtp libavformat libavcodec libavutil libswscale)
SOURCES += \ SOURCES += \
main_android.cpp main_android.cpp \
qtandroidservice.cpp
# headlessmanager.cpp # headlessmanager.cpp
#HEADERS += \ #HEADERS += \
# headlessmanager.h # headlessmanager.h
DISTFILES += \ 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/gradle/wrapper/gradle-wrapper.jar \
android-src/AndroidManifest.xml \ android-src/AndroidManifest.xml \
android-src/gradlew.bat \ android-src/gradlew.bat \

View File

@@ -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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -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();
}
}

View File

@@ -15,10 +15,6 @@ HEADERS += \
singlecoreapplication.h \ singlecoreapplication.h \
headlessmanager.h headlessmanager.h
# find packages using pkg-config
QT_CONFIG -= no-pkg-config
CONFIG += link_pkgconfig
PKGCONFIG = libvitamtp libavformat libavcodec libavutil libswscale PKGCONFIG = libvitamtp libavformat libavcodec libavutil libswscale
# Linux-only config # Linux-only config

View File

@@ -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 \ CXXFLAGS_WARNINGS = -Wall -Wextra -Wdisabled-optimization -Wformat=2 -Winit-self \
-Wmissing-include-dirs -Woverloaded-virtual -Wundef -Wno-unused \ -Wmissing-include-dirs -Woverloaded-virtual -Wundef -Wno-unused \
-Wno-missing-field-initializers -Wno-format-nonliteral -Wno-missing-field-initializers -Wno-format-nonliteral
@@ -5,12 +16,6 @@ CXXFLAGS_WARNINGS = -Wall -Wextra -Wdisabled-optimization -Wformat=2 -Winit-self
# custom CXXFLAGS # custom CXXFLAGS
QMAKE_CXXFLAGS += -Wno-write-strings -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS $$CXXFLAGS_WARNINGS 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 #Linux-only config
unix:!macx { unix:!macx {
# largefile support # largefile support

View File

@@ -1 +1 @@
man/qcma_cli.1 cli/qcma_cli.1

4
debian/qcma.install vendored
View File

@@ -1,4 +1,4 @@
usr/bin/qcma usr/bin/qcma
resources/qcma.desktop usr/share/applications/qcma gui/resources/qcma.desktop usr/share/applications/qcma
resources/images/qcma.png usr/share/icons/hicolor/64x64/apps gui/resources/images/qcma.png usr/share/icons/hicolor/64x64/apps

View File

@@ -1 +1 @@
man/qcma.1 gui/qcma.1

View File

@@ -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

View File

@@ -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

View File

@@ -5,26 +5,29 @@
#------------------------------------------------- #-------------------------------------------------
TEMPLATE = subdirs 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 { 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 # The appindicator and kde extensions are linux only too
ENABLE_APPINDICATOR { ENABLE_APPINDICATOR {
SUBDIRS += qcma_appindicator.pro SUBDIRS += appindicator
appindicator.depends = gui
} }
ENABLE_KDENOTIFIER { ENABLE_KDENOTIFIER {
SUBDIRS += qcma_kdenotifier.pro SUBDIRS += kdenotifier
kdenotifier.depends = gui
} }
} }
TRANSLATIONS += \ android {
resources/translations/qcma_es.ts \ SUBDIRS += android
resources/translations/qcma_fr.ts \ android.depends = common
resources/translations/qcma_ja.ts } else {
SUBDIRS += gui
gui.depends = common
}

View File

@@ -1 +0,0 @@
IDI_ICON1 ICON DISCARDABLE "resources/images/qcma.ico"

View File

@@ -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

View File

@@ -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
}

View File

@@ -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\\\"
}
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 994 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 994 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 B

View File

@@ -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;

View File

@@ -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&apos;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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Advanced settings&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Ajustes Avanzados&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Are you sure to delete the backup of the following game?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Game Name&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;
</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&apos;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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:24pt; font-weight:600;&quot;&gt;12345678&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation></translation>
</message>
<message>
<location filename="../../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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Reading directory:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Leyendo directorio:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Processing file:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Procesando archivo:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../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>

View File

@@ -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&apos;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&apos;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 é 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&apos;utilisateur</translation>
</message>
<message>
<location filename="../../src/gui/clientmanager.cpp" line="80"/>
<source>Cannot initialize VitaMTP library</source>
<translation>Impossible d&apos;initaliser la librairie VitaMTP</translation>
</message>
<message>
<location filename="../../src/gui/clientmanager.cpp" line="101"/>
<source>This user doesn&apos;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&apos;é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 &amp; 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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Advanced settings&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Options Avancées&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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&apos;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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Are you sure to delete the backup of the following game?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Game Name&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;
</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&apos;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&apos;appareil a é 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&apos;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&apos;identification dans le systême PS Vita pour l&apos;enregistrer avec QCMA</translation>
</message>
<message>
<location filename="../../src/forms/pinform.ui" line="55"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:24pt; font-weight:600;&quot;&gt;12345678&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation></translation>
</message>
<message>
<location filename="../../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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Reading directory:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Lecture du répertoire:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Processing file:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Traitement du fichier:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>

View File

@@ -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&apos;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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Advanced settings&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Are you sure to delete the backup of the following game?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Game Name&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;
</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;
</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&apos;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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:24pt; font-weight:600;&quot;&gt;12345678&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation></translation>
</message>
<message>
<location filename="../../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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Reading directory:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Leyendo directorio:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/forms/progressform.ui" line="32"/>
<source>directory name</source>
<translation></translation>
</message>
<message>
<location filename="../../src/forms/progressform.ui" line="39"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Processing file:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Procesando archivo:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../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>

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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');
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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;\">&nbsp;%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;
}

View File

@@ -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

View File

@@ -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">&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Game Name&lt;/span&gt;&lt;/p&gt;</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">&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;0.00 GiB&lt;/span&gt;&lt;/p&gt;</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">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:9pt;&quot;&gt;[APP] [SAVE] [UPDATE] [DLC]&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>

View File

@@ -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);
}
}
}
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Advanced settings&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Are you sure to delete the backup of the following game?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Game Name&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;
</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>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:24pt; font-weight:600;&quot;&gt;12345678&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="timeLabel">
<property name="text">
<string>Time remaining: 300 seconds</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Reading directory:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="directoryLabel">
<property name="text">
<string>directory name</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:11pt; font-weight:600;&quot;&gt;Processing file:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="fileLabel">
<property name="text">
<string>file name</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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 &notifier_id, QObject *obj_parent) :
KStatusNotifierItem(notifier_id, obj_parent)
{
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More