mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-25 17:21:27 -05:00
Merge pull request #550 from G10h4ck/android
Android - Still need to remove all refs to Qt.
This commit is contained in:
commit
befeb44f07
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,3 @@
|
||||
/RetroShare.pro.user
|
||||
*.o
|
||||
*.sw?
|
||||
*.so
|
||||
@ -10,3 +9,6 @@ Makefile*
|
||||
*.sw?
|
||||
*~
|
||||
Thumbs.db
|
||||
*.pro.user
|
||||
.kdev4
|
||||
*.kdev4
|
||||
|
@ -47,12 +47,12 @@ addons:
|
||||
project:
|
||||
name: "RetroShare/RetroShare"
|
||||
description: "RetroShare Build submitted via Travis CI"
|
||||
build_command_prepend: "qmake CONFIG+=NO_SQLCIPHER; make clean"
|
||||
build_command_prepend: "qmake CONFIG+=no_sqlcipher; make clean"
|
||||
build_command: "make -j 4"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
before_script:
|
||||
- qmake QMAKE_CC=$CC QMAKE_CXX=$CXX CONFIG+=NO_SQLCIPHER CONFIG+=tests
|
||||
- qmake QMAKE_CC=$CC QMAKE_CXX=$CXX CONFIG+=no_sqlcipher CONFIG+=tests
|
||||
|
||||
script:
|
||||
- if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make && tests/unittests/unittests >/dev/null 2>&1 ; fi
|
||||
|
86
README-Android.asciidoc
Normal file
86
README-Android.asciidoc
Normal file
@ -0,0 +1,86 @@
|
||||
Compile Retroshare for Android
|
||||
==============================
|
||||
|
||||
== Introduction
|
||||
|
||||
Compiling an application for Android is not as easy as one would imagine, expecially one like RetroShare that has a big codebase and is not well documented. This document is aimed to empower the reader so she can hopefully succed or at least have a significant help in compiling her own RetroShare APK package installable on Android.
|
||||
|
||||
== Preparing The Environement
|
||||
|
||||
First of all setup your Qt for Android development environement following the guide on the link:http://doc.qt.io/qt-5/androidgs.html[Qt for android web site].
|
||||
At this point you should have Android SDK, Android NDK, and Qt for Android working fine, and you should be capable of executing on an Android emulator or on your Android phone Qt for Android examples.
|
||||
|
||||
But RetroShare is not as simple to compile as those examples. In particular, the Android NDK precompiled toolchain is limited and doesn't support the full C++ specification, and it is missing some part that is needed to build RetroShare. The good news is that Android NDK ships all the necessary to build a custom toolchain that is suitable to build RetroShare. In order to build the toolchain with needed library RetroShare provides the +android-prepare-toolchain.sh+ script; before you execute it you should define some variables the script cannot determine in an easy and reliable manner by itself in your terminal.
|
||||
|
||||
[source,bash]
|
||||
-------------------------------------------------------------------------------
|
||||
## The path where Android NDK is installed in your system
|
||||
export ANDROID_NDK_PATH="/opt/android-ndk/"
|
||||
|
||||
## The path where your fresh compiled toolchain will be installed, make sure
|
||||
## the parent exists
|
||||
export NDK_TOOLCHAIN_PATH="/home/$(whoami)/Development/android-toolchains/retroshare-android/"
|
||||
|
||||
## The CPU architecture of the Android device you want to target
|
||||
export ANDROID_NDK_ARCH="arm"
|
||||
|
||||
## The Android API level the Android device you want to target
|
||||
export ANDROID_PLATFORM_VER="19"
|
||||
|
||||
## The number of core that yout host CPU have (just to speed up compilation) set it to 1 if unsure
|
||||
export HOST_NUM_CPU=1
|
||||
|
||||
./android-prepare-toolchain.sh
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Now is time for the bad news: as of today Qt assumes you use the NDK precompiled toolchain and doesn't have an option to use the custom toolchain you just generated, so you need to tweak Qt internals a little to make usage of the custom toolchain. First of all you need to determine your Qt for Android installation path -in my case it is +/opt/Qt5.7.0/+ - then find the +mkspecs+ directory -in my case it is +/opt/Qt5.7.0/5.7/android_armv7/mkspecs+ - and then modify qmake configuration for the android target according to your toolchain, in my case I have done it with the following commands (in the same shell I used before, to take advantage of the already set variables):
|
||||
|
||||
WARNING: This may need a slight modification if you have a different Qt version.
|
||||
|
||||
[source,bash]
|
||||
-------------------------------------------------------------------------------
|
||||
export QT_PATH="/opt/Qt5.7.0/"
|
||||
export QT_MAJOR_VERSION="5.7"
|
||||
|
||||
cd ${QT_PATH}/${QT_MAJOR_VERSION}/android_armv7/mkspecs
|
||||
sudo --preserve-env -s
|
||||
cp -r android-g++ android-g++-backup
|
||||
cd android-g++
|
||||
sed -i "s|^NDK_TOOLCHAIN_PATH =.*|NDK_TOOLCHAIN_PATH = ${NDK_TOOLCHAIN_PATH}|" qmake.conf
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== Preparing Qt Creator
|
||||
|
||||
Now that your environement is set up you should configure Qt Creator for Android following the link:http://doc.qt.io/qtcreator/creator-developing-android.html[official guide]. At the end of this step your Qt Creator should recognize the Android compiler and the Qt for Android kit. As we use a custom toolchain one more step is needed.
|
||||
|
||||
From the top menu click
|
||||
_Tools -> Options... -> Build & Run -> Compilers -> Android GCC (arm-4.9) -> Clone_
|
||||
|
||||
Now a new compiler (usually named +Clone of Android GCC (arm-4.9)+) should have appeared on your compilers list. Select that compiler and press the Browse button to look for your custom toolchain compiler. You should find it at +$NDK_TOOLCHAIN_PATH/bin/arm-linux-androideabi-gcc+. Select it, then press Apply.
|
||||
|
||||
Now go to the Kits tab, select +Android for armeabi-v7a (GCC 4.9, Qt 5.7.0)+ and press the Clone button. A new kit is created (usually named +Clone of Android for armeabi-v7a (GCC 4.9, Qt 5.7.0)+). Now select the new kit and change the compiler to the one you have just created.
|
||||
|
||||
Your Kit is now ready to use. Now you can open RetroShare as a Qt Creator project and in the Projects left menu add the newly created kit if not already present, so you can select it on the build type selection button down on the left.
|
||||
|
||||
Some of RetroShare modules like +retroshare-gui+, +WebUI+ and +sqlcipher+ are not supported yet on Android so to be able to compile RetroShare without errors you will have to go to +
|
||||
|
||||
_Qt Creator left pane -> Projects -> Build and Run -> Android SOMESTUFF kit -> Build Steps -> qmake -> Additional arguments_
|
||||
|
||||
and add the following configurations
|
||||
|
||||
[source,makefile]
|
||||
-------------------------------------------------------------------------------
|
||||
CONFIG+=no_retroshare_gui CONFIG+=no_retroshare_nogui CONFIG+=no_retroshare_plugins CONFIG+=retroshare_android_service CONFIG+=libresapilocalserver CONFIG+=no_libresapihttpserver CONFIG+=no_sqlcipher CONFIG+=retroshare_qml_app
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
WARNING: SQLCipher is not supported yet on RetroShare for Android. This poses a major security concern, we are working to fix this ASAP.
|
||||
|
||||
WARNING: Some versions of QtCreator try to find the Android SDK in +/opt/android/sdk+. A workaround to this is to make a symbolic link there pointing to your SDK installation path, like +mkdir -p /opt/android/sdk && ln -s /home/user/android-sdk-linux /opt/android/sdk+
|
||||
|
||||
== Furter Readings
|
||||
|
||||
- link:http://doc.qt.io/qt-5/android-support.html[]
|
||||
- link:https://developer.android.com/ndk/guides/libs.html[]
|
||||
- link:retroshare://forum?name=Compiling%20nogui%20for%20android&id=8fd22bd8f99754461e7ba1ca8a727995&msgid=4e0f92330600bba9cf978f384f4b7b2f2ca64eff[]
|
||||
- link:retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136[]
|
@ -3,36 +3,54 @@
|
||||
TEMPLATE = subdirs
|
||||
#CONFIG += tests
|
||||
|
||||
SUBDIRS += \
|
||||
openpgpsdk \
|
||||
libbitdht \
|
||||
libretroshare \
|
||||
libresapi \
|
||||
retroshare_gui \
|
||||
retroshare_nogui \
|
||||
plugins
|
||||
|
||||
SUBDIRS += openpgpsdk
|
||||
openpgpsdk.file = openpgpsdk/src/openpgpsdk.pro
|
||||
|
||||
SUBDIRS += libbitdht
|
||||
libbitdht.file = libbitdht/src/libbitdht.pro
|
||||
|
||||
SUBDIRS += libretroshare
|
||||
libretroshare.file = libretroshare/src/libretroshare.pro
|
||||
libretroshare.depends = openpgpsdk libbitdht
|
||||
|
||||
SUBDIRS += libresapi
|
||||
libresapi.file = libresapi/src/libresapi.pro
|
||||
libresapi.depends = libretroshare
|
||||
|
||||
retroshare_gui.file = retroshare-gui/src/retroshare-gui.pro
|
||||
retroshare_gui.depends = libretroshare libresapi
|
||||
retroshare_gui.target = retroshare-gui
|
||||
retroshare_gui {
|
||||
SUBDIRS += retroshare_gui
|
||||
retroshare_gui.file = retroshare-gui/src/retroshare-gui.pro
|
||||
retroshare_gui.depends = libretroshare libresapi
|
||||
retroshare_gui.target = retroshare_gui
|
||||
}
|
||||
|
||||
retroshare_nogui.file = retroshare-nogui/src/retroshare-nogui.pro
|
||||
retroshare_nogui.depends = libretroshare libresapi
|
||||
retroshare_nogui.target = retroshare-nogui
|
||||
retroshare_nogui {
|
||||
SUBDIRS += retroshare_nogui
|
||||
retroshare_nogui.file = retroshare-nogui/src/retroshare-nogui.pro
|
||||
retroshare_nogui.depends = libretroshare libresapi
|
||||
retroshare_nogui.target = retroshare_nogui
|
||||
}
|
||||
|
||||
plugins.file = plugins/plugins.pro
|
||||
plugins.depends = retroshare_gui
|
||||
plugins.target = plugins
|
||||
retroshare_android_service {
|
||||
SUBDIRS += retroshare_android_service
|
||||
retroshare_android_service.file = retroshare-android-service/src/retroshare-android-service.pro
|
||||
retroshare_android_service.depends = libretroshare libresapi
|
||||
retroshare_android_service.target = retroshare_android_service
|
||||
}
|
||||
|
||||
retroshare_qml_app {
|
||||
SUBDIRS += retroshare_qml_app
|
||||
retroshare_qml_app.file = retroshare-qml-app/src/retroshare-qml-app.pro
|
||||
retroshare_qml_app.depends = libretroshare retroshare_android_service
|
||||
retroshare_qml_app.target = retroshare_qml_app
|
||||
}
|
||||
|
||||
retroshare_plugins {
|
||||
SUBDIRS += plugins
|
||||
plugins.file = plugins/plugins.pro
|
||||
plugins.depends = retroshare_gui
|
||||
plugins.target = plugins
|
||||
}
|
||||
|
||||
wikipoos {
|
||||
SUBDIRS += pegmarkdown
|
||||
|
152
android-prepare-toolchain.sh
Executable file
152
android-prepare-toolchain.sh
Executable file
@ -0,0 +1,152 @@
|
||||
#!/bin/bash
|
||||
|
||||
## You are supposed to provide the following variables according to your system setup
|
||||
[ -z ${ANDROID_NDK_PATH+x} ] && export ANDROID_NDK_PATH="/opt/android-ndk/"
|
||||
[ -z ${ANDROID_NDK_ARCH+x} ] && export ANDROID_NDK_ARCH="arm"
|
||||
[ -z ${ANDROID_NDK_ABI_VER+x} ] && export ANDROID_NDK_ABI_VER="4.9"
|
||||
[ -z ${ANDROID_PLATFORM_VER+x} ] && export ANDROID_PLATFORM_VER="18"
|
||||
[ -z ${NDK_TOOLCHAIN_PATH+x} ] && export NDK_TOOLCHAIN_PATH="/home/$(whoami)/Development/android-toolchains/retroshare-android-${ANDROID_PLATFORM_VER}-${ANDROID_NDK_ARCH}-abi${ANDROID_NDK_ABI_VER}/"
|
||||
[ -z ${HOST_NUM_CPU+x} ] && export HOST_NUM_CPU=4
|
||||
|
||||
runDir="$(pwd)"
|
||||
|
||||
## You should not edit the following variables
|
||||
if [ "${ANDROID_NDK_ARCH}" == "x86" ]; then
|
||||
cArch="i686"
|
||||
eABI=""
|
||||
else
|
||||
cArch="${ANDROID_NDK_ARCH}"
|
||||
eABI="eabi"
|
||||
fi
|
||||
export SYSROOT="${NDK_TOOLCHAIN_PATH}/sysroot"
|
||||
export PREFIX="${SYSROOT}"
|
||||
export CC="${NDK_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-gcc"
|
||||
export CXX="${NDK_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-g++"
|
||||
export AR="${NDK_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ar"
|
||||
export RANLIB="${NDK_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ranlib"
|
||||
export ANDROID_DEV="${ANDROID_NDK_PATH}/platforms/android-${ANDROID_PLATFORM_VER}/arch-${ANDROID_NDK_ARCH}/usr"
|
||||
|
||||
|
||||
## More information available at https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html
|
||||
build_toolchain()
|
||||
{
|
||||
rm -rf ${NDK_TOOLCHAIN_PATH}
|
||||
[ "${ANDROID_NDK_ARCH}" == "x86" ] && toolchainName="${ANDROID_NDK_ARCH}-${ANDROID_NDK_ABI_VER}" || toolchainName="${ANDROID_NDK_ARCH}-linux-androideabi-${ANDROID_NDK_ABI_VER}"
|
||||
${ANDROID_NDK_PATH}/build/tools/make-standalone-toolchain.sh --ndk-dir=${ANDROID_NDK_PATH} --arch=${ANDROID_NDK_ARCH} --install-dir=${NDK_TOOLCHAIN_PATH} --platform=android-${ANDROID_PLATFORM_VER} --toolchain=${toolchainName} --verbose
|
||||
}
|
||||
|
||||
## More information available at retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136
|
||||
build_bzlib()
|
||||
{
|
||||
B_dir="bzip2-1.0.6"
|
||||
rm -rf $B_dir
|
||||
[ -f $B_dir.tar.gz ] || wget http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz
|
||||
tar -xf $B_dir.tar.gz
|
||||
cd $B_dir
|
||||
sed -i "/^CC=.*/d" Makefile
|
||||
sed -i "/^AR=.*/d" Makefile
|
||||
sed -i "/^RANLIB=.*/d" Makefile
|
||||
sed -i "/^LDFLAGS=.*/d" Makefile
|
||||
sed -i "s/^all: libbz2.a bzip2 bzip2recover test/all: libbz2.a bzip2 bzip2recover/" Makefile
|
||||
make -j${HOST_NUM_CPU}
|
||||
make install PREFIX=${SYSROOT}/usr
|
||||
# sed -i "/^CC=.*/d" Makefile-libbz2_so
|
||||
# make -f Makefile-libbz2_so -j${HOST_NUM_CPU}
|
||||
# cp libbz2.so.1.0.6 ${SYSROOT}/usr/lib/libbz2.so
|
||||
cd ..
|
||||
}
|
||||
|
||||
## More information available at http://doc.qt.io/qt-5/opensslsupport.html
|
||||
build_openssl()
|
||||
{
|
||||
B_dir="openssl-1.0.2h"
|
||||
rm -rf $B_dir
|
||||
[ -f $B_dir.tar.gz ] || wget https://www.openssl.org/source/$B_dir.tar.gz
|
||||
tar -xf $B_dir.tar.gz
|
||||
cd $B_dir
|
||||
if [ "${ANDROID_NDK_ARCH}" == "arm" ]; then
|
||||
oArch="armv7"
|
||||
else
|
||||
oArch="${ANDROID_NDK_ARCH}"
|
||||
fi
|
||||
# ANDROID_NDK_ROOT="${ANDROID_NDK_PATH}" ./Configure android-${oArch} shared --prefix="${SYSROOT}/usr" --openssldir="${SYSROOT}/etc/ssl"
|
||||
## We link openssl statically to avoid android silently sneaking in his own
|
||||
## version of libssl.so (we noticed this because it had some missing symbol
|
||||
## that made RS crash), the crash in some android version is only one of the
|
||||
## possible problems the fact that android insert his own binary libssl.so pose
|
||||
## non neglegible security concerns.
|
||||
ANDROID_NDK_ROOT="${ANDROID_NDK_PATH}" ./Configure android-${oArch} --prefix="${SYSROOT}/usr" --openssldir="${SYSROOT}/etc/ssl"
|
||||
sed -i 's/LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \\/LIBNAME=$$i \\/g' Makefile
|
||||
sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile
|
||||
make -j${HOST_NUM_CPU}
|
||||
make install
|
||||
# cp *.so "${SYSROOT}/usr/lib"
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_sqlite()
|
||||
{
|
||||
B_dir="sqlite-autoconf-3130000"
|
||||
[ -f $B_dir.tar.gz ] || wget https://www.sqlite.org/2016/$B_dir.tar.gz
|
||||
tar -xf $B_dir.tar.gz
|
||||
cd $B_dir
|
||||
./configure --prefix="${SYSROOT}/usr" --host=${ANDROID_NDK_ARCH}-linux
|
||||
make -j${HOST_NUM_CPU}
|
||||
make install
|
||||
rm -f ${SYSROOT}/usr/lib/libsqlite3.so*
|
||||
${CC} -shared -o libsqlite3.so -fPIC sqlite3.o -ldl
|
||||
cp libsqlite3.so "${SYSROOT}/usr/lib"
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_sqlcipher()
|
||||
{
|
||||
echo "sqlcipher not supported yet on android"
|
||||
return 0
|
||||
|
||||
cd sqlcipher
|
||||
./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="${SYSROOT}/usr/lib/libcrypto.a"
|
||||
make -j${HOST_NUM_CPU}
|
||||
make install
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_libupnp()
|
||||
{
|
||||
B_dir="libupnp-1.6.20"
|
||||
rm -rf $B_dir
|
||||
[ -f $B_dir.tar.bz2 ] || wget https://sourceforge.net/projects/pupnp/files/pupnp/libUPnP%201.6.20/$B_dir.tar.bz2
|
||||
tar -xf $B_dir.tar.bz2
|
||||
cd $B_dir
|
||||
## liupnp must be configured as static library because if not the linker will
|
||||
## look for libthreadutils.so.6 at runtime that cannot be packaged on android
|
||||
## as it supports only libname.so format for libraries, thus resulting in a
|
||||
## crash at startup.
|
||||
./configure --enable-static --disable-shared --disable-samples --prefix="${SYSROOT}/usr" --host=${ANDROID_NDK_ARCH}-linux
|
||||
make -j${HOST_NUM_CPU}
|
||||
make install
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_libmicrohttpd()
|
||||
{
|
||||
echo "libmicrohttpd not supported yet on android"
|
||||
return 0
|
||||
|
||||
B_dir="libmicrohttpd-0.9.50"
|
||||
rm -rf $B_dir
|
||||
[ -f $B_dir.tar.gz ] || wget ftp://ftp.gnu.org/gnu/libmicrohttpd/$B_dir.tar.gz
|
||||
tar -xf $B_dir.tar.gz
|
||||
cd $B_dir
|
||||
./configure --prefix="${SYSROOT}/usr" --host=${ANDROID_NDK_ARCH}-linux
|
||||
#make -e ?
|
||||
make -j${HOST_NUM_CPU}
|
||||
make install
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_toolchain
|
||||
build_bzlib
|
||||
build_openssl
|
||||
build_sqlite
|
||||
build_libupnp
|
@ -21,9 +21,9 @@
|
||||
|
||||
namespace resource_api{
|
||||
|
||||
ApiServerLocal::ApiServerLocal(ApiServer* server, QObject *parent) :
|
||||
ApiServerLocal::ApiServerLocal(ApiServer* server, const QString &listenPath, QObject *parent) :
|
||||
QObject(parent), serverThread(this),
|
||||
localListener(server) // Must have no parent to be movable to other thread
|
||||
localListener(server, listenPath) // Must have no parent to be movable to other thread
|
||||
{
|
||||
localListener.moveToThread(&serverThread);
|
||||
serverThread.start();
|
||||
@ -31,15 +31,17 @@ ApiServerLocal::ApiServerLocal(ApiServer* server, QObject *parent) :
|
||||
|
||||
ApiServerLocal::~ApiServerLocal() { serverThread.quit(); }
|
||||
|
||||
ApiLocalListener::ApiLocalListener(ApiServer *server, QObject *parent) :
|
||||
ApiLocalListener::ApiLocalListener(ApiServer *server,
|
||||
const QString &listenPath,
|
||||
QObject *parent) :
|
||||
QObject(parent), mApiServer(server), mLocalServer(this)
|
||||
{
|
||||
mLocalServer.removeServer(serverName());
|
||||
mLocalServer.removeServer(listenPath);
|
||||
#if QT_VERSION >= 0x050000
|
||||
mLocalServer.setSocketOptions(QLocalServer::UserAccessOption);
|
||||
#endif
|
||||
connect(&mLocalServer, SIGNAL(newConnection()), this, SLOT(handleConnection()));
|
||||
mLocalServer.listen(serverName());
|
||||
mLocalServer.listen(listenPath);
|
||||
}
|
||||
|
||||
void ApiLocalListener::handleConnection()
|
||||
@ -71,16 +73,27 @@ void ApiLocalConnectionHandler::handlePendingRequests()
|
||||
{
|
||||
if(mLocalSocket->canReadLine())
|
||||
{
|
||||
readPath:
|
||||
reqPath = mLocalSocket->readLine().constData();
|
||||
mState = WAITING_DATA;
|
||||
readPath:
|
||||
QString rString(mLocalSocket->readLine());
|
||||
rString = rString.simplified();
|
||||
if (!rString.isEmpty())
|
||||
{
|
||||
if(rString.startsWith("PUT", Qt::CaseInsensitive)) reqMeth = resource_api::Request::PUT;
|
||||
else if (rString.startsWith("DELETE", Qt::CaseInsensitive)) reqMeth = resource_api::Request::DELETE_AA;
|
||||
else reqMeth = resource_api::Request::GET;
|
||||
if(rString.contains(' ')) rString = rString.split(' ')[1];
|
||||
|
||||
/* Because QLocalSocket is SOCK_STREAM some clients implementations
|
||||
* like the one based on QLocalSocket feel free to send the whole
|
||||
* request (PATH + DATA) in a single write(), causing readyRead()
|
||||
* signal being emitted only once, in that case we should continue
|
||||
* processing without waiting for readyRead() being fired again, so
|
||||
* we don't break here as there may be more lines to read */
|
||||
reqPath = rString.toStdString();
|
||||
mState = WAITING_DATA;
|
||||
|
||||
/* Because QLocalSocket is SOCK_STREAM some clients implementations
|
||||
* like the one based on QLocalSocket feel free to send the whole
|
||||
* request (PATH + DATA) in a single write(), causing readyRead()
|
||||
* signal being emitted only once, in that case we should continue
|
||||
* processing without waiting for readyRead() being fired again, so
|
||||
* we don't break here as there may be more lines to read */
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
case WAITING_DATA:
|
||||
@ -90,6 +103,7 @@ void ApiLocalConnectionHandler::handlePendingRequests()
|
||||
resource_api::JsonStream reqJson;
|
||||
reqJson.setJsonString(std::string(mLocalSocket->readLine().constData()));
|
||||
resource_api::Request req(reqJson);
|
||||
req.mMethod = reqMeth;
|
||||
req.setPath(reqPath);
|
||||
std::string resultString = mApiServer->handleRequest(req);
|
||||
mLocalSocket->write(resultString.c_str(), resultString.length());
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <retroshare/rsinit.h>
|
||||
#include <string>
|
||||
|
||||
#include "ApiTypes.h"
|
||||
#include "ApiServer.h"
|
||||
|
||||
namespace resource_api
|
||||
@ -34,16 +35,9 @@ class ApiLocalListener : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApiLocalListener(ApiServer* server, QObject *parent=0);
|
||||
ApiLocalListener(ApiServer* server, const QString &listenPath, QObject *parent=0);
|
||||
~ApiLocalListener() { mLocalServer.close(); }
|
||||
|
||||
const static QString& serverName()
|
||||
{
|
||||
const static QString sockPath(RsAccounts::AccountDirectory()
|
||||
.append("/libresapi.sock").c_str());
|
||||
return sockPath;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void handleConnection();
|
||||
|
||||
@ -57,9 +51,23 @@ class ApiServerLocal : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ApiServerLocal(ApiServer* server, QObject *parent=0);
|
||||
ApiServerLocal(ApiServer* server, const QString& listenPath, QObject *parent=0);
|
||||
~ApiServerLocal();
|
||||
|
||||
const static QString& loginServerPath()
|
||||
{
|
||||
const static QString sockPath(RsAccounts::ConfigDirectory()
|
||||
.append("/libresapi.sock").c_str());
|
||||
return sockPath;
|
||||
}
|
||||
|
||||
const static QString& serverPath()
|
||||
{
|
||||
const static QString sockPath(RsAccounts::AccountDirectory()
|
||||
.append("/libresapi.sock").c_str());
|
||||
return sockPath;
|
||||
}
|
||||
|
||||
private:
|
||||
QThread serverThread;
|
||||
ApiLocalListener localListener;
|
||||
@ -82,6 +90,7 @@ private:
|
||||
QLocalSocket* mLocalSocket;
|
||||
State mState;
|
||||
std::string reqPath;
|
||||
resource_api::Request::Method reqMeth;
|
||||
};
|
||||
|
||||
} // namespace resource_api
|
||||
|
@ -211,30 +211,7 @@ public:
|
||||
req.mMethod = resource_api::Request::DELETE_AA;
|
||||
}
|
||||
|
||||
std::stack<std::string> stack;
|
||||
std::string str;
|
||||
for(std::string::reverse_iterator sit = path2.rbegin(); sit != path2.rend(); sit++)
|
||||
{
|
||||
if((*sit) != '/')
|
||||
{
|
||||
// add to front because we are traveling in reverse order
|
||||
str = *sit + str;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(str != "")
|
||||
{
|
||||
stack.push(str);
|
||||
str.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(str != "")
|
||||
{
|
||||
stack.push(str);
|
||||
}
|
||||
req.mPath = stack;
|
||||
req.mFullPath = path2;
|
||||
req.setPath(path2);
|
||||
|
||||
std::string result = mApiServer->handleRequest(req);
|
||||
|
||||
|
@ -193,29 +193,21 @@ public:
|
||||
// then each handler should pop the top element
|
||||
std::stack<std::string> mPath;
|
||||
std::string mFullPath;
|
||||
bool setPath(std::string reqPath)
|
||||
bool setPath(const std::string &reqPath)
|
||||
{
|
||||
std::string str;
|
||||
for(std::string::reverse_iterator sit = reqPath.rbegin(); sit != reqPath.rend(); sit++)
|
||||
std::string::const_reverse_iterator sit;
|
||||
for( sit = reqPath.rbegin(); sit != reqPath.rend(); ++sit )
|
||||
{
|
||||
if((*sit) != '/')
|
||||
// add to front because we are traveling in reverse order
|
||||
if((*sit) != '/') str = *sit + str;
|
||||
else if(!str.empty())
|
||||
{
|
||||
// add to front because we are traveling in reverse order
|
||||
str = *sit + str;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(str != "")
|
||||
{
|
||||
mPath.push(str);
|
||||
str.clear();
|
||||
}
|
||||
mPath.push(str);
|
||||
str.clear();
|
||||
}
|
||||
}
|
||||
if(str != "")
|
||||
{
|
||||
mPath.push(str);
|
||||
}
|
||||
if(!str.empty()) mPath.push(str);
|
||||
mFullPath = reqPath;
|
||||
|
||||
return true;
|
||||
@ -231,8 +223,7 @@ public:
|
||||
// contains data for new resources
|
||||
StreamBase& mStream;
|
||||
|
||||
// use the is*() methods to query the method type
|
||||
//private:
|
||||
// use the is*() methods to query the method type:
|
||||
enum Method { GET, PUT, DELETE_AA, EXEC};// something is wrong with DELETE, it won't compile with it
|
||||
Method mMethod;
|
||||
};
|
||||
|
@ -59,7 +59,7 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string
|
||||
{
|
||||
cancelled = false ;
|
||||
{
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
|
||||
if(mFixedPassword != "")
|
||||
{
|
||||
password = mFixedPassword;
|
||||
@ -78,7 +78,7 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string
|
||||
{
|
||||
usleep(5*1000);
|
||||
|
||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||
RS_STACK_MUTEX(mDataMtx); // ********** LOCKED **********
|
||||
wait = mWantPassword;
|
||||
if(!wait && mPassword != "")
|
||||
{
|
||||
|
@ -243,7 +243,10 @@ bool GxsSecurity::checkPublicKey(const RsTlvPublicRSAKey &key)
|
||||
bool GxsSecurity::generateKeyPair(RsTlvPublicRSAKey& public_key,RsTlvPrivateRSAKey& private_key)
|
||||
{
|
||||
// admin keys
|
||||
RSA *rsa = RSA_generate_key(2048, 65537, NULL, NULL);
|
||||
BIGNUM *ebn = BN_new();
|
||||
BN_set_word(ebn, 65537);
|
||||
RSA *rsa = RSA_new();
|
||||
RSA_generate_key_ex(rsa, 2048, ebn, NULL);
|
||||
RSA *rsa_pub = RSAPublicKey_dup(rsa);
|
||||
|
||||
public_key.keyFlags = RSTLV_KEY_TYPE_PUBLIC_ONLY ;
|
||||
|
@ -156,8 +156,7 @@ linux-* {
|
||||
QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64
|
||||
QMAKE_CC = $${QMAKE_CXX}
|
||||
|
||||
contains(CONFIG, NO_SQLCIPHER) {
|
||||
DEFINES *= NO_SQLCIPHER
|
||||
no_sqlcipher {
|
||||
PKGCONFIG *= sqlite3
|
||||
} else {
|
||||
SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes)
|
||||
@ -168,7 +167,7 @@ linux-* {
|
||||
DEPENDPATH += ../../../lib/
|
||||
INCLUDEPATH += ../../../lib/
|
||||
} else {
|
||||
error("libsqlcipher is not installed and libsqlcipher.a not found. SQLCIPHER is necessary for encrypted database, to build with unencrypted database, run: qmake CONFIG+=NO_SQLCIPHER")
|
||||
error("libsqlcipher is not installed and libsqlcipher.a not found. SQLCIPHER is necessary for encrypted database, to build with unencrypted database, run: qmake CONFIG+=no_sqlcipher")
|
||||
}
|
||||
} else {
|
||||
# Workaround for broken sqlcipher packages, e.g. Ubuntu 14.04
|
||||
@ -182,7 +181,7 @@ linux-* {
|
||||
|
||||
# linux/bsd can use either - libupnp is more complete and packaged.
|
||||
#CONFIG += upnp_miniupnpc
|
||||
CONFIG += upnp_libupnp
|
||||
CONFIG += upnp_libupnp
|
||||
|
||||
# Check if the systems libupnp has been Debian-patched
|
||||
system(grep -E 'char[[:space:]]+PublisherUrl' /usr/include/upnp/upnp.h >/dev/null 2>&1) {
|
||||
@ -332,7 +331,7 @@ freebsd-* {
|
||||
|
||||
# linux/bsd can use either - libupnp is more complete and packaged.
|
||||
#CONFIG += upnp_miniupnpc
|
||||
CONFIG += upnp_libupnp
|
||||
CONFIG += upnp_libupnp
|
||||
}
|
||||
|
||||
################################# OpenBSD ##########################################
|
||||
@ -891,3 +890,25 @@ test_bitdht {
|
||||
# ENABLED UDP NOW.
|
||||
}
|
||||
|
||||
################################# Android #####################################
|
||||
|
||||
android-g++ {
|
||||
## ifaddrs is missing on Android add them don't use the one from
|
||||
## https://github.com/morristech/android-ifaddrs
|
||||
## because they crash, use QNetworkInterface from Qt instead
|
||||
CONFIG *= qt
|
||||
QT *= network
|
||||
|
||||
## Add this here and not in retroshare.pri because static library are very
|
||||
## sensible to order in command line, has to be in the end of file for the
|
||||
## same reason
|
||||
LIBS += -L$$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/ -lssl
|
||||
INCLUDEPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
DEPENDPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
PRE_TARGETDEPS += $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libssl.a
|
||||
|
||||
LIBS += -L$$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/ -lcrypto
|
||||
INCLUDEPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
DEPENDPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
PRE_TARGETDEPS += $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libcrypto.a
|
||||
}
|
||||
|
@ -24,9 +24,9 @@
|
||||
*/
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
#include "util/rswin.h"
|
||||
#include "util/rsmemory.h"
|
||||
#include <ws2tcpip.h>
|
||||
# include "util/rswin.h"
|
||||
# include "util/rsmemory.h"
|
||||
# include <ws2tcpip.h>
|
||||
#endif // WINDOWS_SYS
|
||||
|
||||
#include "pqi/pqinetwork.h"
|
||||
@ -271,12 +271,17 @@ int inet_aton(const char *name, struct in_addr *addr)
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef WINDOWS_SYS
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
#else // WINDOWS_SYS
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
# include <winsock2.h>
|
||||
# include <iphlpapi.h>
|
||||
# pragma comment(lib, "IPHLPAPI.lib")
|
||||
#elif defined(__ANDROID__)
|
||||
# include <string>
|
||||
# include <QString>
|
||||
# include <QHostAddress>
|
||||
# include <QNetworkInterface>
|
||||
#else // not __ANDROID__ nor WINDOWS => Linux and other unixes
|
||||
# include <ifaddrs.h>
|
||||
# include <net/if.h>
|
||||
#endif // WINDOWS_SYS
|
||||
|
||||
bool getLocalAddresses(std::list<sockaddr_storage> & addrs)
|
||||
@ -317,7 +322,15 @@ bool getLocalAddresses(std::list<sockaddr_storage> & addrs)
|
||||
}
|
||||
}
|
||||
free(adapter_addresses);
|
||||
#else // WINDOWS_SYS
|
||||
#elif defined(__ANDROID__)
|
||||
foreach(QHostAddress qAddr, QNetworkInterface::allAddresses())
|
||||
{
|
||||
sockaddr_storage tmpAddr;
|
||||
sockaddr_storage_clear(tmpAddr);
|
||||
if(sockaddr_storage_ipv4_aton(tmpAddr, qAddr.toString().toStdString().c_str()))
|
||||
addrs.push_back(tmpAddr);
|
||||
}
|
||||
#else // not WINDOWS_SYS not ANDROID => Linux and other unixes
|
||||
struct ifaddrs *ifsaddrs, *ifa;
|
||||
if(getifaddrs(&ifsaddrs) != 0)
|
||||
{
|
||||
|
@ -105,11 +105,15 @@ X509_REQ *GenerateX509Req(
|
||||
fprintf(stderr,"GenerateX509Req: reverting to %d\n", nbits);
|
||||
}
|
||||
|
||||
rsa = RSA_generate_key(nbits, e, NULL, NULL);
|
||||
|
||||
rsa = RSA_new();
|
||||
if ((rsa == NULL) || !EVP_PKEY_assign_RSA(pkey, rsa))
|
||||
throw std::runtime_error("Couldn't generate RSA Key");
|
||||
|
||||
BIGNUM *ebn = BN_new();
|
||||
BN_set_word(ebn, e);
|
||||
RSA_generate_key_ex(rsa, nbits, ebn, NULL);
|
||||
|
||||
// open the file.
|
||||
FILE *out;
|
||||
if (NULL == (out = RsDirUtil::rs_fopen(pkey_file.c_str(), "w")))
|
||||
|
@ -129,15 +129,21 @@ class RsInit
|
||||
|
||||
namespace RsAccounts
|
||||
{
|
||||
// Directories.
|
||||
std::string ConfigDirectory(); // aka Base Directory. (normally ~/.retroshare)
|
||||
/**
|
||||
* @brief ConfigDirectory (normally ~/.retroshare) you can call this method
|
||||
* even before initialisation (you can't with some other methods)
|
||||
* @see RsAccountsDetail::PathBaseDirectory()
|
||||
*/
|
||||
std::string ConfigDirectory();
|
||||
|
||||
/**
|
||||
* @brief DataDirectory
|
||||
* you can call this method even before initialisation (you can't with the other methods)
|
||||
* you can call this method even before initialisation (you can't with some other methods)
|
||||
* @param check if set to true and directory does not exist, return empty string
|
||||
* @return path where global platform independent files are stored, like bdboot.txt or webinterface files
|
||||
*/
|
||||
std::string DataDirectory(bool check = true);
|
||||
|
||||
std::string PGPDirectory();
|
||||
std::string AccountDirectory();
|
||||
|
||||
|
@ -26,11 +26,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include "retroshare/rspeers.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
class p3PeerMgr;
|
||||
class p3NetMgr;
|
||||
struct sockaddr_storage;
|
||||
|
||||
|
||||
class p3Peers: public RsPeers
|
||||
|
@ -65,14 +65,8 @@ AccountDetails::AccountDetails()
|
||||
return;
|
||||
}
|
||||
|
||||
RsAccountsDetail::RsAccountsDetail()
|
||||
:mAccountsLocked(false), mPreferredId(""), mBaseDirectory("")
|
||||
{
|
||||
mAccounts.clear();
|
||||
mUnsupportedKeys.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
RsAccountsDetail::RsAccountsDetail() : mAccountsLocked(false), mPreferredId("")
|
||||
{}
|
||||
|
||||
bool RsAccountsDetail::loadAccounts()
|
||||
{
|
||||
@ -214,6 +208,7 @@ std::string RsAccountsDetail::PathPGPDirectory()
|
||||
|
||||
std::string RsAccountsDetail::PathBaseDirectory()
|
||||
{
|
||||
if(mBaseDirectory.empty()) defaultBaseDirectory();
|
||||
return mBaseDirectory;
|
||||
}
|
||||
|
||||
@ -326,8 +321,6 @@ bool RsAccountsDetail::setupBaseDirectory(std::string alt_basedir)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool RsAccountsDetail::defaultBaseDirectory()
|
||||
{
|
||||
std::string basedir;
|
||||
@ -339,8 +332,8 @@ bool RsAccountsDetail::defaultBaseDirectory()
|
||||
char *h = getenv("HOME");
|
||||
if (h == NULL)
|
||||
{
|
||||
std::cerr << "defaultBaseDirectory() Error: ";
|
||||
std::cerr << "cannot determine $HOME dir" <<std::endl;
|
||||
std::cerr << "defaultBaseDirectory() Error: cannot determine $HOME dir"
|
||||
<< std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
@ -1253,7 +1246,7 @@ bool RsInit::LoadPassword(const std::string& id, const std::string& inPwd)
|
||||
********************************************************************************/
|
||||
|
||||
// Directories.
|
||||
std::string RsAccounts::ConfigDirectory() { return rsAccounts->PathBaseDirectory(); }
|
||||
std::string RsAccounts::ConfigDirectory() { return RsAccountsDetail::PathBaseDirectory(); }
|
||||
std::string RsAccounts::DataDirectory(bool check) { return RsAccountsDetail::PathDataDirectory(check); }
|
||||
std::string RsAccounts::PGPDirectory() { return rsAccounts->PathPGPDirectory(); }
|
||||
std::string RsAccounts::AccountDirectory() { return rsAccounts->PathAccountDirectory(); }
|
||||
@ -1332,3 +1325,4 @@ bool RsAccounts::GenerateSSLCertificate(const RsPgpId& pgp_id, const std::str
|
||||
* END OF: PUBLIC INTERFACE FUNCTIONS
|
||||
********************************************************************************/
|
||||
|
||||
std::string RsAccountsDetail::mBaseDirectory;
|
||||
|
@ -80,7 +80,13 @@ class RsAccountsDetail
|
||||
* @return path where global platform independent files are stored, like bdboot.txt or webinterface files
|
||||
*/
|
||||
static std::string PathDataDirectory(bool check = true);
|
||||
std::string PathBaseDirectory();
|
||||
|
||||
/**
|
||||
* @brief PathBaseDirectory
|
||||
* @return path where user data is stored ( on Linux and similar
|
||||
* systems it is usually something like /home/USERNAME/.retroshare ).
|
||||
*/
|
||||
static std::string PathBaseDirectory();
|
||||
|
||||
// PGP Path is only dependent on BaseDirectory.
|
||||
std::string PathPGPDirectory();
|
||||
@ -134,7 +140,7 @@ class RsAccountsDetail
|
||||
private:
|
||||
bool checkPreferredId();
|
||||
|
||||
bool defaultBaseDirectory();
|
||||
static bool defaultBaseDirectory();
|
||||
|
||||
bool getAvailableAccounts(std::map<RsPeerId, AccountDetails> &accounts,
|
||||
int& failing_accounts,
|
||||
@ -148,7 +154,7 @@ class RsAccountsDetail
|
||||
|
||||
std::map<RsPeerId, AccountDetails> mAccounts;
|
||||
RsPeerId mPreferredId;
|
||||
std::string mBaseDirectory;
|
||||
static std::string mBaseDirectory;
|
||||
|
||||
std::map<std::string,std::vector<std::string> > mUnsupportedKeys ;
|
||||
};
|
||||
|
@ -508,7 +508,7 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
|
||||
AuthSSL::AuthSSLInit();
|
||||
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
|
||||
|
||||
rsAccounts = new RsAccountsDetail() ;
|
||||
rsAccounts = new RsAccountsDetail();
|
||||
|
||||
// first check config directories, and set bootstrap values.
|
||||
if(!rsAccounts->setupBaseDirectory(opt_base_dir))
|
||||
|
@ -198,60 +198,9 @@ bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd
|
||||
return (status == 0);
|
||||
|
||||
/******************** OSX KeyChain stuff *****************************/
|
||||
#else /* UNIX, but not HAS_GNOME_KEYRING or APPLE */
|
||||
|
||||
FILE* helpFile = RsDirUtil::rs_fopen(getAutologinFileName(ssl_id).c_str(), "r");
|
||||
|
||||
if(helpFile == NULL){
|
||||
std::cerr << "\nFailed to open help file\n" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* decrypt help */
|
||||
|
||||
int c ;
|
||||
std::string passwd ;
|
||||
while( (c = getc(helpFile)) != EOF )
|
||||
passwd += (char)c ;
|
||||
|
||||
const int DAT_LEN = passwd.length();
|
||||
const int KEY_DAT_LEN = RsInitConfig::load_cert.length();
|
||||
unsigned char* key_data = (unsigned char*)RsInitConfig::load_cert.c_str();
|
||||
unsigned char* indata = new unsigned char[DAT_LEN];
|
||||
unsigned char* outdata = new unsigned char[DAT_LEN];
|
||||
|
||||
for(int i=0;i<DAT_LEN;++i)
|
||||
indata[i] = passwd[i] ;
|
||||
|
||||
// if(fscanf(helpFile, "%s", indata) != 1)
|
||||
// {
|
||||
// std::cerr << "Can't read RSA key in help file " << helpFileName << ". Sorry." << std::endl ;
|
||||
// return false ;
|
||||
// }
|
||||
|
||||
RC4_KEY* key = new RC4_KEY;
|
||||
RC4_set_key(key, KEY_DAT_LEN, key_data);
|
||||
|
||||
RC4(key, DAT_LEN, indata, outdata);
|
||||
|
||||
ssl_passwd.clear();
|
||||
ssl_passwd.insert(0, (char*)outdata, DAT_LEN);
|
||||
|
||||
|
||||
fclose(helpFile);
|
||||
|
||||
|
||||
delete[] indata;
|
||||
delete[] outdata;
|
||||
|
||||
if(key != NULL)
|
||||
delete key;
|
||||
|
||||
return true;
|
||||
#endif // APPLE
|
||||
#endif // HAS_GNOME_KEYRING
|
||||
/******* WINDOWS BELOW *****/
|
||||
#else
|
||||
#endif // HAS_GNOME_KEYRING
|
||||
#else /******* WINDOWS BELOW *****/
|
||||
|
||||
/* try to load from file */
|
||||
std::string entropy = getSSLPasswdFileName(ssl_id);
|
||||
@ -419,6 +368,7 @@ bool RsLoginHandler::enableAutoLogin(const RsPeerId& ssl_id,const std::string& s
|
||||
|
||||
/***************** OSX KEYCHAIN ****************/
|
||||
#else
|
||||
#ifdef TODO_CODE_ROTTEN
|
||||
|
||||
/* WARNING: Autologin is inherently unsafe */
|
||||
FILE* helpFile = RsDirUtil::rs_fopen(getAutologinFileName.c_str(), "w");
|
||||
@ -450,6 +400,7 @@ bool RsLoginHandler::enableAutoLogin(const RsPeerId& ssl_id,const std::string& s
|
||||
|
||||
|
||||
return true;
|
||||
#endif // TODO_CODE_ROTTEN
|
||||
#endif // __APPLE__
|
||||
#endif // HAS_GNOME_KEYRING.
|
||||
#else /* windows */
|
||||
|
@ -32,10 +32,19 @@
|
||||
#include "rsserver/rsaccounts.h"
|
||||
#include "rsdiscspace.h"
|
||||
#include <util/rsthreads.h>
|
||||
#ifndef WIN32
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
# include <android/api-level.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# include <wtypes.h>
|
||||
#elif defined(__ANDROID__) && (__ANDROID_API__ < 21)
|
||||
# include <sys/vfs.h>
|
||||
# define statvfs64 statfs
|
||||
# warning statvfs64 is not supported with android platform < 21 falling back to statfs that is untested (may misbehave)
|
||||
#else
|
||||
#include <wtypes.h>
|
||||
# include <sys/statvfs.h>
|
||||
#endif
|
||||
|
||||
#define DELAY_BETWEEN_CHECKS 2
|
||||
|
@ -119,3 +119,21 @@ SOURCES += openpgpsdk/accumulate.c \
|
||||
win32{
|
||||
SOURCES += openpgpsdk/opsstring.c
|
||||
}
|
||||
|
||||
################################# Android #####################################
|
||||
|
||||
android-g++ {
|
||||
|
||||
## Add this here and not in retroshare.pri because static library are very
|
||||
## sensible to order in command line
|
||||
LIBS += -L$$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/ -lssl
|
||||
INCLUDEPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
DEPENDPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
PRE_TARGETDEPS += $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libssl.a
|
||||
|
||||
LIBS += -L$$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/ -lcrypto
|
||||
INCLUDEPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
DEPENDPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
PRE_TARGETDEPS += $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libcrypto.a
|
||||
|
||||
}
|
||||
|
@ -460,7 +460,12 @@ callback_cmd_get_secret_key(const ops_parser_content_t *content_,ops_parse_cb_in
|
||||
|
||||
char *ops_get_passphrase(void)
|
||||
{
|
||||
#ifndef __ANDROID__
|
||||
return ops_malloc_passphrase(getpass("Passphrase: "));
|
||||
#else // __ANDROID__
|
||||
return ops_malloc_passphrase("getpass not supported on android");
|
||||
#warning "getpass not supported on android"
|
||||
#endif // __ANDROID__
|
||||
}
|
||||
|
||||
char *ops_malloc_passphrase(char *pp)
|
||||
|
@ -0,0 +1,24 @@
|
||||
!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
|
||||
|
||||
TARGET = retroshare-android-service
|
||||
|
||||
QT += core network
|
||||
QT -= gui
|
||||
|
||||
CONFIG += c++11
|
||||
CONFIG += dll
|
||||
|
||||
android-g++:TEMPLATE = lib
|
||||
!android-g++:TEMPLATE = app
|
||||
|
||||
SOURCES += service.cpp
|
||||
|
||||
DEPENDPATH *= ../../libresapi/src
|
||||
INCLUDEPATH *= ../../libresapi/src
|
||||
PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a
|
||||
LIBS *= ../../libresapi/src/lib/libresapi.a
|
||||
|
||||
DEPENDPATH *= ../../libretroshare/src
|
||||
INCLUDEPATH *= ../../libretroshare/src
|
||||
PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a
|
||||
LIBS *= ../../libretroshare/src/lib/libretroshare.a
|
57
retroshare-android-service/src/service.cpp
Normal file
57
retroshare-android-service/src/service.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* RetroShare Android Service
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
# include <QtAndroidExtras>
|
||||
#endif
|
||||
|
||||
#include "retroshare/rsinit.h"
|
||||
#include "api/ApiServer.h"
|
||||
#include "api/ApiServerLocal.h"
|
||||
#include "api/RsControlModule.h"
|
||||
|
||||
using namespace resource_api;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
ApiServer api;
|
||||
RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true);
|
||||
api.addResourceHandler("control", dynamic_cast<resource_api::ResourceRouter*>(&ctrl_mod), &resource_api::RsControlModule::handleRequest);
|
||||
|
||||
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory());
|
||||
sockPath.append("/libresapi.sock");
|
||||
qDebug() << "Listening on:" << sockPath;
|
||||
ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
qDebug() << "Is service.cpp running as a service?" << QtAndroid::androidService().isValid();
|
||||
qDebug() << "Is service.cpp running as an activity?" << QtAndroid::androidActivity().isValid();
|
||||
#endif
|
||||
|
||||
while (!ctrl_mod.processShouldExit())
|
||||
{
|
||||
a.processEvents();
|
||||
usleep(20000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -26,11 +26,11 @@
|
||||
#include "ui_ServerPage.h"
|
||||
#include "RsAutoUpdatePage.h"
|
||||
#include <inttypes.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
class QNetworkReply;
|
||||
class QNetworkAccessManager;
|
||||
class BanListPeer;
|
||||
struct sockaddr_storage;
|
||||
|
||||
class ServerPage: public ConfigPage
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ QString WebuiPage::helpText() const
|
||||
|
||||
// TODO: LIBRESAPI_LOCAL_SERVER Move in appropriate place
|
||||
#ifdef LIBRESAPI_LOCAL_SERVER
|
||||
apiServerLocal = new resource_api::ApiServerLocal(apiServer);
|
||||
apiServerLocal = new resource_api::ApiServerLocal(apiServer, resource_api::ApiServerLocal::serverPath());
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <QString>
|
||||
#include <inttypes.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
class RsNetUtil
|
||||
{
|
||||
|
5
retroshare-qml-app/src/android/.gitignore
vendored
Normal file
5
retroshare-qml-app/src/android/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.build
|
||||
.gradle
|
||||
.idea
|
||||
captures
|
||||
local.properties
|
136
retroshare-qml-app/src/android/AndroidManifest.xml
Normal file
136
retroshare-qml-app/src/android/AndroidManifest.xml
Normal file
@ -0,0 +1,136 @@
|
||||
<?xml version="1.0"?>
|
||||
<manifest package="org.retroshare.android.qml_app" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
|
||||
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="RetroShare">
|
||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name=".RetroShareQmlActivity" android:label="RetroShare QML" android:screenOrientation="unspecified" android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
|
||||
<!-- Application to launch -->
|
||||
<meta-data android:name="android.app.lib_name" android:value="retroshare-qml-app"/>
|
||||
<!-- Application to launch -->
|
||||
|
||||
<!-- Application arguments -->
|
||||
<!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
|
||||
<!-- Application arguments -->
|
||||
|
||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||
<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:name="android.app.bundle_local_qt_libs" android:value="-- %%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:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
|
||||
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
|
||||
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_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_drawable" android:resource="@drawable/logo"/ -->
|
||||
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
|
||||
<!-- Splash screen -->
|
||||
|
||||
<!-- Background running -->
|
||||
<!-- Warning: changing this value to true may cause unexpected crashes if the
|
||||
application still try to draw after
|
||||
"applicationStateChanged(Qt::ApplicationSuspended)"
|
||||
signal is sent! -->
|
||||
<meta-data android:name="android.app.background_running" android:value="false"/>
|
||||
<!-- Background running -->
|
||||
|
||||
<!-- auto screen scale factor -->
|
||||
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
|
||||
<!-- auto screen scale factor -->
|
||||
|
||||
<!-- extract android style -->
|
||||
<!-- available android:values :
|
||||
* full - useful QWidget & Quick Controls 1 apps
|
||||
* minimal - useful for Quick Controls 2 apps, it is much faster than "full"
|
||||
* none - useful for apps that don't use any of the above Qt modules
|
||||
-->
|
||||
<meta-data android:name="android.app.extract_android_style" android:value="full"/>
|
||||
<!-- extract android style -->
|
||||
</activity>
|
||||
|
||||
<receiver android:name=".BootCompletedReceiver" android:enabled="true" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".AppUpdatedReceiver" android:enabled="true" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
|
||||
<service android:process=":rs" android:name=".RetroShareAndroidService" android:label="RetroShare Service" android:exported="true"> <!-- Added to be able to run the service from adb shell -->
|
||||
<!-- android:process=":qt" is needed to force the service to run on a separate process than the Activity -->
|
||||
|
||||
|
||||
<!-- Application arguments -->
|
||||
<!-- meta-data android:name="android.app.arguments" android:value="-service"/ -->
|
||||
<!-- Application arguments -->
|
||||
|
||||
<!-- If you are using the same application (.so file) for activity and also for service, then you
|
||||
need to use *android.app.arguments* to pass some arguments to your service in order to know which
|
||||
one is which.
|
||||
-->
|
||||
|
||||
<!-- Application to launch -->
|
||||
<meta-data android:name="android.app.lib_name" android:value="retroshare-android-service"/>
|
||||
<!-- Application to launch -->
|
||||
|
||||
<!-- Ministro -->
|
||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||
<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:name="android.app.bundle_local_qt_libs" android:value="-- %%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:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
|
||||
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
|
||||
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
|
||||
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_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 -->
|
||||
|
||||
|
||||
<!-- Background running -->
|
||||
<meta-data android:name="android.app.background_running" android:value="true"/>
|
||||
<!-- Background running -->
|
||||
</service>
|
||||
</application>
|
||||
|
||||
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="18"/>
|
||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
|
||||
Remove the comment if you do not require these default permissions. -->
|
||||
<!-- %%INSERT_PERMISSIONS -->
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
|
||||
Remove the comment if you do not require these default features. -->
|
||||
<!-- %%INSERT_FEATURES -->
|
||||
|
||||
<!-- Added by G10h4ck: Needed permission for autostart at boot -->
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
</manifest>
|
96
retroshare-qml-app/src/android/android.iml
Normal file
96
retroshare-qml-app/src/android/android.iml
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="android" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<afterSyncTasks>
|
||||
<task>generateDebugSources</task>
|
||||
</afterSyncTasks>
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/../../../../qt5/qtbase/src/android/java/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/../../../../qt5/qtbase/src/android/java/res;file://$MODULE_DIR$/res" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/.build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/.build/intermediates/classes/test/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/../../../../qt5/qtbase/src/android/java/res">
|
||||
<sourceFolder url="file://$MODULE_DIR$/../../../../qt5/qtbase/src/android/java/res" type="java-resource" />
|
||||
</content>
|
||||
<content url="file://$MODULE_DIR$/../../../../qt5/qtbase/src/android/java/src">
|
||||
<sourceFolder url="file://$MODULE_DIR$/../../../../qt5/qtbase/src/android/java/src" isTestSource="false" />
|
||||
</content>
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/res/generated/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/.build/generated/res/generated/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/mockable-android-18.jar" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/resources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.build/outputs" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 18 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" scope="TEST" name="mockable-android-18" level="project" />
|
||||
</component>
|
||||
</module>
|
57
retroshare-qml-app/src/android/build.gradle
Normal file
57
retroshare-qml-app/src/android/build.gradle
Normal file
@ -0,0 +1,57 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.1.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
||||
android {
|
||||
/*******************************************************
|
||||
* The following variables:
|
||||
* - androidBuildToolsVersion,
|
||||
* - androidCompileSdkVersion
|
||||
* - qt5AndroidDir - holds the path to qt android files
|
||||
* needed to build any Qt application
|
||||
* on Android.
|
||||
*
|
||||
* are defined in gradle.properties file. This file is
|
||||
* updated by QtCreator and androiddeployqt tools.
|
||||
* Changing them manually might break the compilation!
|
||||
*******************************************************/
|
||||
|
||||
compileSdkVersion androidCompileSdkVersion.toInteger()
|
||||
|
||||
buildToolsVersion androidBuildToolsVersion
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
|
||||
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
|
||||
res.srcDirs = [qt5AndroidDir + '/res', 'res']
|
||||
resources.srcDirs = ['src']
|
||||
renderscript.srcDirs = ['src']
|
||||
assets.srcDirs = ['assets']
|
||||
jniLibs.srcDirs = ['libs']
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
Activity Resolver Table:
|
||||
Non-Data Actions:
|
||||
android.intent.action.MAIN:
|
||||
42420338 org.retroshare.android.qml_app/.RetroShareQmlActivity filter 42424830
|
||||
|
||||
Receiver Resolver Table:
|
||||
Non-Data Actions:
|
||||
android.intent.action.BOOT_COMPLETED:
|
||||
4245c230 org.retroshare.android.qml_app/.BootCompletedReceiver filter 4245c360
|
||||
|
||||
Packages:
|
||||
Package [org.retroshare.android.qml_app] (4289b2f8):
|
||||
userId=10168 gids=[3003, 1015, 1028]
|
||||
pkg=Package{42244e18 org.retroshare.android.qml_app}
|
||||
codePath=/data/app/org.retroshare.android.qml_app-2.apk
|
||||
resourcePath=/data/app/org.retroshare.android.qml_app-2.apk
|
||||
nativeLibraryPath=/data/app-lib/org.retroshare.android.qml_app-2
|
||||
versionCode=1 targetSdk=18
|
||||
versionName=1.0
|
||||
applicationInfo=ApplicationInfo{4232af50 org.retroshare.android.qml_app}
|
||||
flags=[ DEBUGGABLE HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
|
||||
dataDir=/data/data/org.retroshare.android.qml_app
|
||||
supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
|
||||
timeStamp=2016-08-22 16:53:12
|
||||
firstInstallTime=2016-08-22 16:47:19
|
||||
lastUpdateTime=2016-08-22 16:53:30
|
||||
signatures=PackageSignatures{4233b1e0 [4265b018]}
|
||||
permissionsFixed=true haveGids=true installStatus=1
|
||||
pkgFlags=[ DEBUGGABLE HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
|
||||
User 0: installed=true stopped=false notLaunched=false enabled=0
|
||||
grantedPermissions:
|
||||
android.permission.READ_EXTERNAL_STORAGE
|
||||
android.permission.RECEIVE_BOOT_COMPLETED
|
||||
android.permission.ACCESS_NETWORK_STATE
|
||||
android.permission.WRITE_EXTERNAL_STORAGE
|
||||
android.permission.INTERNET
|
9
retroshare-qml-app/src/android/gradle.properties
Normal file
9
retroshare-qml-app/src/android/gradle.properties
Normal file
@ -0,0 +1,9 @@
|
||||
## This file is automatically generated by QtCreator.
|
||||
#
|
||||
# This file must *NOT* be checked into Version Control Systems,
|
||||
# as it contains information specific to your local configuration.
|
||||
|
||||
androidBuildToolsVersion=24.0.1
|
||||
androidCompileSdkVersion=18
|
||||
buildDir=.build
|
||||
qt5AndroidDir=/opt/Qt5.7.0/5.7/android_armv7/src/android/java
|
BIN
retroshare-qml-app/src/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
retroshare-qml-app/src/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
retroshare-qml-app/src/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
retroshare-qml-app/src/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
|
164
retroshare-qml-app/src/android/gradlew
vendored
Executable file
164
retroshare-qml-app/src/android/gradlew
vendored
Executable file
@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
retroshare-qml-app/src/android/gradlew.bat
vendored
Normal file
90
retroshare-qml-app/src/android/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
25
retroshare-qml-app/src/android/res/values/libs.xml
Normal file
25
retroshare-qml-app/src/android/res/values/libs.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<resources>
|
||||
<array name="qt_sources">
|
||||
<item>https://download.qt.io/ministro/android/qt5/qt-5.7</item>
|
||||
</array>
|
||||
|
||||
<!-- The following is handled automatically by the deployment tool. It should
|
||||
not be edited manually. -->
|
||||
|
||||
<array name="bundled_libs">
|
||||
<!-- %%INSERT_EXTRA_LIBS%% -->
|
||||
</array>
|
||||
|
||||
<array name="qt_libs">
|
||||
<!-- %%INSERT_QT_LIBS%% -->
|
||||
</array>
|
||||
|
||||
<array name="bundled_in_lib">
|
||||
<!-- %%INSERT_BUNDLED_IN_LIB%% -->
|
||||
</array>
|
||||
<array name="bundled_in_assets">
|
||||
<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
|
||||
</array>
|
||||
|
||||
</resources>
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* RetroShare Android Service
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.retroshare.android.qml_app;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
public class AppUpdatedReceiver extends BroadcastReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Log.i("AppUpdatedReceiver", "onReceive() Restarting RetroShare Android Service After Update");
|
||||
Intent myIntent = new Intent(context, RetroShareAndroidService.class);
|
||||
context.stopService(myIntent);
|
||||
context.startService(myIntent);
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* RetroShare Android Service
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.retroshare.android.qml_app;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class BootCompletedReceiver extends BroadcastReceiver
|
||||
{
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
Intent myIntent = new Intent(context, RetroShareAndroidService.class);
|
||||
context.startService(myIntent);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* RetroShare Android Service
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.retroshare.android.qml_app;
|
||||
|
||||
import org.qtproject.qt5.android.bindings.QtService;
|
||||
|
||||
public class RetroShareAndroidService extends QtService {}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.retroshare.android.qml_app;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import org.qtproject.qt5.android.bindings.QtActivity;
|
||||
|
||||
public class RetroShareQmlActivity extends QtActivity
|
||||
{
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
if (!isMyServiceRunning(RetroShareAndroidService.class))
|
||||
{
|
||||
Log.i("RetroShareQmlActivity", "onCreate(): RetroShareAndroidService is not running, let's start it by Intent");
|
||||
Intent rsIntent = new Intent(this, RetroShareAndroidService.class);
|
||||
startService(rsIntent);
|
||||
}
|
||||
else Log.v("RetroShareQmlActivity", "onCreate(): RetroShareAndroidService already running");
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
private boolean isMyServiceRunning(Class<?> serviceClass)
|
||||
{
|
||||
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
|
||||
if (serviceClass.getName().equals(service.service.getClassName()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
15
retroshare-qml-app/src/debugutils.h
Normal file
15
retroshare-qml-app/src/debugutils.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef DEBUGUTILS_H
|
||||
#define DEBUGUTILS_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
//To switch between debugging and normal mode, un-/comment next line
|
||||
#define DEBUGGING
|
||||
#ifdef DEBUGGING
|
||||
#define myDebug(line) qDebug() << "| FILE:" << __FILE__ << " | LINE_NUMBER:"\
|
||||
<< __LINE__ << " | FUNCTION:" << __FUNCTION__ << " | CONTENT:" << line
|
||||
#else
|
||||
#define myDebug(line)
|
||||
#endif
|
||||
|
||||
#endif // DEBUGUTILS_H
|
13
retroshare-qml-app/src/deployment.pri
Normal file
13
retroshare-qml-app/src/deployment.pri
Normal file
@ -0,0 +1,13 @@
|
||||
unix:!android {
|
||||
isEmpty(target.path) {
|
||||
qnx {
|
||||
target.path = /tmp/$${TARGET}/bin
|
||||
} else {
|
||||
target.path = /opt/$${TARGET}/bin
|
||||
}
|
||||
export(target.path)
|
||||
}
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
export(INSTALLS)
|
84
retroshare-qml-app/src/libresapilocalclient.cpp
Normal file
84
retroshare-qml-app/src/libresapilocalclient.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
* Copyright (C) 2016 Manu Pineda <manu@cooperativa.cat>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "libresapilocalclient.h"
|
||||
#include "debugutils.h"
|
||||
#include <QChar>
|
||||
|
||||
|
||||
void LibresapiLocalClient::openConnection(QString socketPath)
|
||||
{
|
||||
connect(& mLocalSocket, SIGNAL(error(QLocalSocket::LocalSocketError)),
|
||||
this, SLOT(socketError(QLocalSocket::LocalSocketError)));
|
||||
connect(& mLocalSocket, SIGNAL(readyRead()),
|
||||
this, SLOT(read()));
|
||||
mLocalSocket.connectToServer(socketPath);
|
||||
}
|
||||
|
||||
int LibresapiLocalClient::request(const QString & path, const QString & jsonData)
|
||||
{
|
||||
qDebug() << "LibresapiLocalClient::request()" << path << jsonData;
|
||||
QByteArray data;
|
||||
data.append(path); data.append('\n');
|
||||
data.append(jsonData); data.append('\n');
|
||||
mLocalSocket.write(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LibresapiLocalClient::socketError(QLocalSocket::LocalSocketError)
|
||||
{
|
||||
myDebug("error!!!!\n" + mLocalSocket.errorString());
|
||||
}
|
||||
|
||||
void LibresapiLocalClient::read()
|
||||
{
|
||||
receivedBytes = mLocalSocket.readLine();
|
||||
|
||||
qDebug() << receivedBytes;
|
||||
|
||||
if(parseResponse()) // pensar en fer un buffer per parsejar, per evitar errors.
|
||||
emit goodResponseReceived(QString(receivedBytes));
|
||||
else
|
||||
{
|
||||
QString errMess = "The message was not understood!\n"
|
||||
"It should be a JSON formatted text file\n"
|
||||
"Its contents were:\n" + receivedBytes;
|
||||
myDebug(errMess.replace(QChar('\n'), QChar::LineSeparator));
|
||||
}
|
||||
}
|
||||
|
||||
bool LibresapiLocalClient::parseResponse()
|
||||
{
|
||||
QJsonParseError error;
|
||||
json = QJsonDocument::fromJson(receivedBytes, &error);
|
||||
myDebug(QString(json.toJson()).replace(QChar('\n'), QChar::LineSeparator));
|
||||
|
||||
if(error.error == QJsonParseError::NoError){
|
||||
return true;
|
||||
}
|
||||
myDebug(error.errorString());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonDocument & LibresapiLocalClient::getJson()
|
||||
{
|
||||
return json;
|
||||
}
|
56
retroshare-qml-app/src/libresapilocalclient.h
Normal file
56
retroshare-qml-app/src/libresapilocalclient.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* libresapi local socket client
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
* Copyright (C) 2016 Manu Pineda <manu@cooperativa.cat>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBRESAPILOCALCLIENT_H
|
||||
#define LIBRESAPILOCALCLIENT_H
|
||||
|
||||
#include <QLocalSocket>
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
#include <QVector>
|
||||
|
||||
class LibresapiLocalClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LibresapiLocalClient() : mLocalSocket(this) {}
|
||||
|
||||
// potser abstreure el següent amb QUrl urlPath (path) i amb QJson jsonData.
|
||||
Q_INVOKABLE int request(const QString & path, const QString & jsonData);
|
||||
const QJsonDocument & getJson();
|
||||
Q_INVOKABLE void openConnection(QString socketPath);
|
||||
|
||||
private:
|
||||
QLocalSocket mLocalSocket;
|
||||
QByteArray receivedBytes;
|
||||
QJsonDocument json;
|
||||
//QVector<QJsonDocument> responses;
|
||||
|
||||
bool parseResponse(); //std::string msg);
|
||||
|
||||
private slots:
|
||||
void socketError(QLocalSocket::LocalSocketError error);
|
||||
void read();
|
||||
|
||||
signals:
|
||||
void goodResponseReceived(const QString & msg);//, int requestId);
|
||||
};
|
||||
|
||||
#endif // LIBRESAPILOCALCLIENT_H
|
61
retroshare-qml-app/src/main.cpp
Normal file
61
retroshare-qml-app/src/main.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlComponent>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
# include <QtAndroidExtras>
|
||||
#endif
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "libresapilocalclient.h"
|
||||
#include "retroshare/rsinit.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
qmlRegisterType<LibresapiLocalClient>(
|
||||
"org.retroshare.qml_components.LibresapiLocalClient", 1, 0,
|
||||
"LibresapiLocalClient");
|
||||
|
||||
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory());
|
||||
sockPath.append("/libresapi.sock");
|
||||
|
||||
engine.rootContext()->setContextProperty("apiSocketPath", sockPath);
|
||||
engine.load(QUrl(QLatin1String("qrc:/qml/main.qml")));
|
||||
|
||||
QFileInfo fileInfo(sockPath);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
qDebug() << "Is main.cpp running as a service?" << QtAndroid::androidService().isValid();
|
||||
qDebug() << "Is main.cpp running as an activity?" << QtAndroid::androidActivity().isValid();
|
||||
#endif
|
||||
|
||||
qDebug() << "QML APP:" << sockPath << fileInfo.exists() << fileInfo.lastModified().toString();
|
||||
|
||||
return app.exec();
|
||||
}
|
26
retroshare-qml-app/src/qml.qrc
Normal file
26
retroshare-qml-app/src/qml.qrc
Normal file
@ -0,0 +1,26 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qml/main.qml</file>
|
||||
<file>qml/icons/star-2-128.png</file>
|
||||
<file>qml/icons/settings-4-128.png</file>
|
||||
<file>qml/icons/email-128.png</file>
|
||||
<file>qml/icons/contacts-128.png</file>
|
||||
<file>qml/PostedMsgDelegate.qml</file>
|
||||
<file>qml/GxsService.qml</file>
|
||||
<file>qml/GxsIdDelegate.qml</file>
|
||||
<file>qml/GxsGroupDelegate.qml</file>
|
||||
<file>qml/ForumMsgDelegate.qml</file>
|
||||
<file>qml/ContactBox.qml</file>
|
||||
<file>qml/ChannelMsgDelegate.qml</file>
|
||||
<file>qml/ChannelGroupDelegate.qml</file>
|
||||
<file>qml/ApplicationBar.qml</file>
|
||||
<file>qml/AppButton.qml</file>
|
||||
<file>qml/Locations.qml</file>
|
||||
<file>qml/jsonpath.js</file>
|
||||
<file>qml/JSONListModel.qml</file>
|
||||
<file>qml/Contacts.qml</file>
|
||||
<file>qml/AddTrustedNode.qml</file>
|
||||
<file>qml/RsLoginPassView.qml</file>
|
||||
<file>qml/TrustedNodesView.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
78
retroshare-qml-app/src/qml/AddTrustedNode.qml
Normal file
78
retroshare-qml-app/src/qml/AddTrustedNode.qml
Normal file
@ -0,0 +1,78 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
|
||||
Item
|
||||
{
|
||||
function refreshData() { rsApi.request("/peers/self/certificate/", "") }
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
rsApi.openConnection(apiSocketPath)
|
||||
refreshData()
|
||||
}
|
||||
onFocusChanged: focus && refreshData()
|
||||
|
||||
LibresapiLocalClient
|
||||
{
|
||||
id: rsApi
|
||||
onGoodResponseReceived:
|
||||
{
|
||||
var jsonData = JSON.parse(msg)
|
||||
if(jsonData && jsonData.data && jsonData.data.cert_string)
|
||||
myKeyField.text = jsonData.data.cert_string
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
anchors.fill: parent
|
||||
|
||||
Button
|
||||
{
|
||||
id: bottomButton
|
||||
text: "Add trusted node"
|
||||
onClicked:
|
||||
{
|
||||
console.log("retroshare addtrusted: ", otherKeyField.text)
|
||||
var jsonData =
|
||||
{
|
||||
cert_string: otherKeyField.text,
|
||||
flags:
|
||||
{
|
||||
allow_direct_download: true,
|
||||
allow_push: false,
|
||||
require_whitelist: false,
|
||||
}
|
||||
}
|
||||
console.log("retroshare addtrusted jsonData: ", JSON.stringify(jsonData))
|
||||
//rsApi.request("/peers/examine_cert/", JSON.stringify({ cert_string: otherKeyField.text }))
|
||||
rsApi.request("PUT /peers", JSON.stringify(jsonData))
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
text: "Copy"
|
||||
onClicked:
|
||||
{
|
||||
myKeyField.selectAll()
|
||||
myKeyField.copy()
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
text: "Paste"
|
||||
onClicked:
|
||||
{
|
||||
otherKeyField.selectAll()
|
||||
otherKeyField.paste()
|
||||
}
|
||||
}
|
||||
|
||||
TextField { id: myKeyField }
|
||||
TextField { id: otherKeyField }
|
||||
}
|
||||
}
|
30
retroshare-qml-app/src/qml/AppButton.qml
Normal file
30
retroshare-qml-app/src/qml/AppButton.qml
Normal file
@ -0,0 +1,30 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import "."
|
||||
|
||||
Rectangle {
|
||||
id: appButton
|
||||
property alias icon: appIcon.source
|
||||
|
||||
signal buttonClicked
|
||||
|
||||
width: parent.height
|
||||
height: parent.height
|
||||
color: "#00000000"
|
||||
|
||||
Image {
|
||||
id: appIcon
|
||||
anchors.centerIn: parent
|
||||
width: 25
|
||||
height: 25
|
||||
}
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
appButton.buttonClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
37
retroshare-qml-app/src/qml/ApplicationBar.qml
Normal file
37
retroshare-qml-app/src/qml/ApplicationBar.qml
Normal file
@ -0,0 +1,37 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import "."
|
||||
|
||||
Rectangle {
|
||||
id: status
|
||||
anchors.fill: parent
|
||||
color: "#336699" //"#FF7733"
|
||||
height: 50
|
||||
|
||||
default property alias contents: placeholder.children
|
||||
|
||||
RowLayout {
|
||||
id: placeholder
|
||||
spacing: 0
|
||||
width: 200
|
||||
height: parent.height
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
|
||||
}
|
||||
|
||||
ContactBox {
|
||||
|
||||
width: 200
|
||||
height: parent.height
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
|
||||
icon: "icons/contacts-128.png"
|
||||
name: "Vade Retro"
|
||||
status: "Away"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
33
retroshare-qml-app/src/qml/ChannelGroupDelegate.qml
Normal file
33
retroshare-qml-app/src/qml/ChannelGroupDelegate.qml
Normal file
@ -0,0 +1,33 @@
|
||||
import QtQuick 2.2
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: item
|
||||
width: parent.width
|
||||
height: 50
|
||||
|
||||
Column {
|
||||
Text { text: '<b>' + model.GroupName + '</b>' }
|
||||
Text { text: GroupId }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
item.ListView.view.currentIndex = index
|
||||
channelMsgModel.updateEntries(model.GroupId)
|
||||
console.log("Clicked on Channel GroupId: " + model.GroupId)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: "#AAAAAA"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
|
42
retroshare-qml-app/src/qml/ChannelMsgDelegate.qml
Normal file
42
retroshare-qml-app/src/qml/ChannelMsgDelegate.qml
Normal file
@ -0,0 +1,42 @@
|
||||
import QtQuick 2.2
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: msgDelegate
|
||||
|
||||
width: parent.width
|
||||
height: 150
|
||||
|
||||
Column {
|
||||
Text { text: '<b>MsgId:</b> ' + AuthorId }
|
||||
Text { text: '<b>AuthorId:</b> ' + AuthorId }
|
||||
Row {
|
||||
Text { text: '<b>Name:</b> ' + MsgName }
|
||||
Text { text: ' <b>PublishTs:</b> ' + PublishTs }
|
||||
}
|
||||
Text { text: '<b>Msg:</b> ' + Msg }
|
||||
Row {
|
||||
Text { text: '<b>NumberFiles:</b> ' + NumberFiles }
|
||||
Text { text: ' <b>TotalFileSize:</b> ' + TotalFileSize }
|
||||
}
|
||||
|
||||
Text { text: '<b>FileNames:</b> ' + FileNames }
|
||||
Text { text: '<b>FileSizes:</b> ' + FileSizes }
|
||||
Text { text: '<b>FileHashes:</b> ' + FileHashes }
|
||||
Row {
|
||||
Text { text: '<b>HaveVoted:</b> ' + HaveVoted }
|
||||
Text { text: ' <b>UpVotes:</b> ' + UpVotes }
|
||||
Text { text: ' <b>DownVotes:</b> ' + DownVotes }
|
||||
Text { text: ' <b>Comments:</b> ' + Comments }
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
item.ListView.view.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
retroshare-qml-app/src/qml/ContactBox.qml
Normal file
61
retroshare-qml-app/src/qml/ContactBox.qml
Normal file
@ -0,0 +1,61 @@
|
||||
import QtQuick 2.2
|
||||
import "."
|
||||
|
||||
Item {
|
||||
|
||||
property alias icon: contactIcon.source
|
||||
property alias name: contactName.text
|
||||
property alias status: contactStatus.text
|
||||
|
||||
Rectangle {
|
||||
|
||||
anchors.fill: parent
|
||||
color: "#00000000"
|
||||
|
||||
Image {
|
||||
id: contactIcon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
width: 40
|
||||
height: 40
|
||||
source: "icons/contacts-128.png"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: contactIcon.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: contactIcon.right
|
||||
color: parent.color
|
||||
|
||||
Text {
|
||||
id: contactName
|
||||
text: "Username"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
anchors.bottom: contactStatus.top
|
||||
anchors.bottomMargin: 2
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pointSize: 14
|
||||
font.bold: false
|
||||
color: "#FFFFFF"
|
||||
}
|
||||
|
||||
Text {
|
||||
id: contactStatus
|
||||
text: "Hello world!"
|
||||
anchors.left: parent.right
|
||||
anchors.leftMargin: 10
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 1
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pointSize: 10
|
||||
font.bold: false
|
||||
color: "#FFFFFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
52
retroshare-qml-app/src/qml/Contacts.qml
Normal file
52
retroshare-qml-app/src/qml/Contacts.qml
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
|
||||
Item
|
||||
{
|
||||
function refreshData() { rsApi.request("/identity/*/", "") }
|
||||
|
||||
onFocusChanged: focus && refreshData()
|
||||
|
||||
LibresapiLocalClient
|
||||
{
|
||||
id: rsApi
|
||||
onGoodResponseReceived: locationsModel.json = msg
|
||||
Component.onCompleted: { openConnection(apiSocketPath) }
|
||||
}
|
||||
|
||||
JSONListModel
|
||||
{
|
||||
id: locationsModel
|
||||
query: "$.data[*]"
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
id: locationsListView
|
||||
width: parent.width
|
||||
height: 300
|
||||
model: locationsModel.model
|
||||
delegate: Text { text: model.name }
|
||||
}
|
||||
|
||||
Text { text: "Contacts View"; anchors.bottom: parent.bottom }
|
||||
}
|
41
retroshare-qml-app/src/qml/ForumMsgDelegate.qml
Normal file
41
retroshare-qml-app/src/qml/ForumMsgDelegate.qml
Normal file
@ -0,0 +1,41 @@
|
||||
import QtQuick 2.2
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: msgDelegate
|
||||
|
||||
width: parent.width
|
||||
height: col.height
|
||||
|
||||
Column {
|
||||
id: col
|
||||
Text { text: '<b>MsgId:</b> ' + AuthorId }
|
||||
Text { text: '<b>AuthorId:</b> ' + AuthorId }
|
||||
Row {
|
||||
Text { text: '<b>Name:</b> ' + MsgName }
|
||||
Text { text: ' <b>PublishTs:</b> ' + PublishTs }
|
||||
}
|
||||
Text {
|
||||
wrapMode: Text.Wrap
|
||||
text: '<b>Msg:</b> ' + Msg
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
item.ListView.view.currentIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 2
|
||||
color: "#AAAAAA"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.bottom
|
||||
}
|
||||
|
||||
}
|
||||
|
26
retroshare-qml-app/src/qml/GxsGroupDelegate.qml
Normal file
26
retroshare-qml-app/src/qml/GxsGroupDelegate.qml
Normal file
@ -0,0 +1,26 @@
|
||||
import QtQuick 2.2
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: item
|
||||
property var msgModel: {}
|
||||
|
||||
width: parent.width
|
||||
height: 50
|
||||
|
||||
Column {
|
||||
Text { text: '<b>Name:</b> ' + model.GroupName }
|
||||
Text { text: '<b>Number:</b> ' + GroupId }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
item.ListView.view.currentIndex = index
|
||||
item.msgModel.updateEntries(model.GroupId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
33
retroshare-qml-app/src/qml/GxsIdDelegate.qml
Normal file
33
retroshare-qml-app/src/qml/GxsIdDelegate.qml
Normal file
@ -0,0 +1,33 @@
|
||||
import QtQuick 2.2
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: item
|
||||
width: parent.width
|
||||
height: 50
|
||||
|
||||
Column {
|
||||
Text { text: '<b>' + model.GroupName + '</b>' }
|
||||
Text { text: GroupId }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
item.ListView.view.currentIndex = index
|
||||
//channelMsgModel.updateEntries(model.GroupId)
|
||||
//console.log("Clicked on Channel GroupId: " + model.GroupId)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: "#AAAAAA"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
|
119
retroshare-qml-app/src/qml/GxsService.qml
Normal file
119
retroshare-qml-app/src/qml/GxsService.qml
Normal file
@ -0,0 +1,119 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls 1.1
|
||||
import "."
|
||||
|
||||
|
||||
Item {
|
||||
id: gxsService
|
||||
|
||||
property alias icon: sideIcon.source
|
||||
property alias title: sideTitle.text
|
||||
|
||||
property alias groupDelegate: sideList.delegate
|
||||
property alias groupModel: sideList.model
|
||||
|
||||
property alias msgDelegate: mainList.delegate
|
||||
property alias msgModel: mainList.model
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
id: sideBar
|
||||
width: 200
|
||||
Layout.fillHeight: true
|
||||
|
||||
Rectangle {
|
||||
id: sideHeader
|
||||
width: parent.width
|
||||
height: 30
|
||||
|
||||
Text {
|
||||
id: sideTitle
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
width: 20
|
||||
height: 20
|
||||
text: "Service"
|
||||
color: "#333333"
|
||||
}
|
||||
|
||||
Image {
|
||||
id: sideIcon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10
|
||||
width: 20
|
||||
height: 20
|
||||
source: "icons/contacts-128.png"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: sideListBox
|
||||
width: parent.width
|
||||
|
||||
anchors.top: sideHeader.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
ListView {
|
||||
id: sideList
|
||||
anchors.fill: parent
|
||||
|
||||
delegate: GxsGroupDelegate {
|
||||
msgModel: mainList.model
|
||||
}
|
||||
|
||||
// section.
|
||||
section.property: "SubscribeStatus"
|
||||
section.criteria: ViewSection.FullString
|
||||
section.delegate: Rectangle {
|
||||
width: sideListBox.width
|
||||
height: childrenRect.height
|
||||
color: "blue"
|
||||
|
||||
Text {
|
||||
text: section
|
||||
font.bold: true
|
||||
font.pixelSize: 20
|
||||
}
|
||||
}
|
||||
|
||||
clip: true
|
||||
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
|
||||
focus: true
|
||||
|
||||
onCurrentItemChanged: {
|
||||
console.log("SideBar Item Changed on " + gxsService.title)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
ListView {
|
||||
id: mainList
|
||||
anchors.fill: parent
|
||||
|
||||
clip: true
|
||||
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
|
||||
focus: true
|
||||
onCurrentItemChanged: {
|
||||
console.log("item changed")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
51
retroshare-qml-app/src/qml/JSONListModel.qml
Normal file
51
retroshare-qml-app/src/qml/JSONListModel.qml
Normal file
@ -0,0 +1,51 @@
|
||||
/* JSONListModel - a QML ListModel with JSON and JSONPath support
|
||||
*
|
||||
* Copyright (c) 2012 Romain Pokrzywka (KDAB) (romain@kdab.com)
|
||||
* Licensed under the MIT licence (http://opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import "jsonpath.js" as JSONPath
|
||||
|
||||
Item {
|
||||
property string source: ""
|
||||
property string json: ""
|
||||
property string query: ""
|
||||
|
||||
property ListModel model : ListModel { id: jsonModel }
|
||||
property alias count: jsonModel.count
|
||||
|
||||
onSourceChanged: {
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("GET", source);
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == XMLHttpRequest.DONE)
|
||||
json = xhr.responseText;
|
||||
}
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
onJsonChanged: updateJSONModel()
|
||||
onQueryChanged: updateJSONModel()
|
||||
|
||||
function updateJSONModel() {
|
||||
jsonModel.clear();
|
||||
|
||||
if ( json === "" )
|
||||
return;
|
||||
|
||||
var objectArray = parseJSONString(json, query);
|
||||
for ( var key in objectArray ) {
|
||||
var jo = objectArray[key];
|
||||
jsonModel.append( jo );
|
||||
}
|
||||
}
|
||||
|
||||
function parseJSONString(jsonString, jsonPathQuery) {
|
||||
var objectArray = JSON.parse(jsonString);
|
||||
if ( jsonPathQuery !== "" )
|
||||
objectArray = JSONPath.jsonPath(objectArray, jsonPathQuery);
|
||||
|
||||
return objectArray;
|
||||
}
|
||||
}
|
192
retroshare-qml-app/src/qml/Locations.qml
Normal file
192
retroshare-qml-app/src/qml/Locations.qml
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
|
||||
Item
|
||||
{
|
||||
id: locationView
|
||||
state: "selectLocation"
|
||||
property var qParent
|
||||
property bool attemptLogin: false
|
||||
property string password
|
||||
property string sslid
|
||||
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "selectLocation"
|
||||
PropertyChanges { target: locationsListView; visible: true }
|
||||
PropertyChanges { target: bottomButton; visible: true }
|
||||
PropertyChanges { target: loginView; visible: false }
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "createLocation"
|
||||
PropertyChanges { target: locationsListView; visible: false }
|
||||
PropertyChanges { target: bottomButton; visible: false }
|
||||
PropertyChanges
|
||||
{
|
||||
target: loginView
|
||||
visible: true
|
||||
buttonText: "Save"
|
||||
onSubmit:
|
||||
{
|
||||
var jsonData = { pgp_name: login, ssl_name: login, pgp_password: password }
|
||||
rsApi.request("/control/create_location/", JSON.stringify(jsonData))
|
||||
locationView.state = "selectLocation"
|
||||
}
|
||||
}
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "login"
|
||||
PropertyChanges { target: locationsListView; visible: false }
|
||||
PropertyChanges { target: bottomButton; visible: false }
|
||||
PropertyChanges
|
||||
{
|
||||
target: loginView
|
||||
visible: true
|
||||
onSubmit:
|
||||
{
|
||||
locationView.password = password
|
||||
console.log("locationView.sslid: ", locationView.sslid)
|
||||
rsApi.request("/control/login/", JSON.stringify({id: locationView.sslid}))
|
||||
locationView.attemptLogin = true
|
||||
busyIndicator.running = true
|
||||
attemptTimer.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
function requestLocationsList() { rsApi.request("/control/locations/", "") }
|
||||
|
||||
onFocusChanged: focus && requestLocationsList()
|
||||
|
||||
LibresapiLocalClient
|
||||
{
|
||||
id: rsApi
|
||||
Component.onCompleted:
|
||||
{
|
||||
openConnection(apiSocketPath)
|
||||
locationView.requestLocationsList()
|
||||
}
|
||||
onGoodResponseReceived:
|
||||
{
|
||||
var jsonData = JSON.parse(msg)
|
||||
|
||||
|
||||
if(jsonData)
|
||||
{
|
||||
if(jsonData.data)
|
||||
{
|
||||
if(jsonData.data[0] && jsonData.data[0].pgp_id)
|
||||
{
|
||||
// if location list update
|
||||
locationsModel.json = msg
|
||||
busyIndicator.running = false
|
||||
}
|
||||
if (jsonData.data.key_name)
|
||||
{
|
||||
if(jsonData.data.want_password)
|
||||
{
|
||||
// if Server requested password
|
||||
var jsonPass = { password: locationView.password }
|
||||
rsApi.request("/control/password/", JSON.stringify(jsonPass))
|
||||
locationView.attemptLogin = false
|
||||
console.debug("RS core asked for password")
|
||||
}
|
||||
else
|
||||
{
|
||||
// if Already logged in
|
||||
bottomButton.enabled = false
|
||||
bottomButton.text = "Already logged in"
|
||||
locationView.attemptLogin = false
|
||||
busyIndicator.running = false
|
||||
locationView.state = "selectLocation"
|
||||
locationsListView.enabled = false
|
||||
console.debug("Already logged in")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusyIndicator { id: busyIndicator; anchors.centerIn: parent }
|
||||
|
||||
JSONListModel
|
||||
{
|
||||
id: locationsModel
|
||||
query: "$.data[*]"
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
id: locationsListView
|
||||
width: parent.width
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: bottomButton.top
|
||||
model: locationsModel.model
|
||||
delegate: Button
|
||||
{
|
||||
text: model.name
|
||||
onClicked:
|
||||
{
|
||||
loginView.login = text
|
||||
locationView.sslid = model.id
|
||||
locationView.state = "login"
|
||||
}
|
||||
}
|
||||
visible: false
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: bottomButton
|
||||
text: "Create new location"
|
||||
anchors.bottom: parent.bottom
|
||||
onClicked: locationView.state = "createLocation"
|
||||
}
|
||||
|
||||
RsLoginPassView
|
||||
{
|
||||
id: loginView
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Timer
|
||||
{
|
||||
id: attemptTimer
|
||||
interval: 500
|
||||
repeat: true
|
||||
onTriggered:
|
||||
{
|
||||
if(locationView.focus)
|
||||
locationView.requestLocationsList()
|
||||
|
||||
if (locationView.attemptLogin)
|
||||
rsApi.request("/control/password/", "")
|
||||
}
|
||||
}
|
||||
}
|
40
retroshare-qml-app/src/qml/PostedMsgDelegate.qml
Normal file
40
retroshare-qml-app/src/qml/PostedMsgDelegate.qml
Normal file
@ -0,0 +1,40 @@
|
||||
import QtQuick 2.2
|
||||
import "."
|
||||
|
||||
Item {
|
||||
id: msgDelegate
|
||||
|
||||
width: parent.width
|
||||
height: 150
|
||||
|
||||
Column {
|
||||
Text { text: '<b>MsgId:</b> ' + AuthorId }
|
||||
Text { text: '<b>AuthorId:</b> ' + AuthorId }
|
||||
Row {
|
||||
Text { text: '<b>Name:</b> ' + MsgName }
|
||||
Text { text: ' <b>PublishTs:</b> ' + PublishTs }
|
||||
}
|
||||
Text { text: '<b>Link:</b> ' + Link }
|
||||
Text { text: '<b>Notes:</b> ' + Notes }
|
||||
Row {
|
||||
Text { text: '<b>Hot:</b> ' + HotScore }
|
||||
Text { text: ' <b>Top:</b> ' + HotScore }
|
||||
Text { text: ' <b>New:</b> ' + HotScore }
|
||||
}
|
||||
Row {
|
||||
Text { text: '<b>HaveVoted:</b> ' + HaveVoted }
|
||||
Text { text: ' <b>UpVotes:</b> ' + UpVotes }
|
||||
Text { text: ' <b>DownVotes:</b> ' + DownVotes }
|
||||
Text { text: ' <b>Comments:</b> ' + Comments }
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
item.ListView.view.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
52
retroshare-qml-app/src/qml/RsLoginPassView.qml
Normal file
52
retroshare-qml-app/src/qml/RsLoginPassView.qml
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQml 2.2
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
|
||||
Item
|
||||
{
|
||||
id: loginView
|
||||
property string buttonText: "Login"
|
||||
property string login
|
||||
property string password
|
||||
signal submit(string login, string password)
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
id: inputView
|
||||
width: parent.width
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: bottomButton.top
|
||||
|
||||
Row { Text {text: "Name:" } TextField { id: nameField; text: loginView.login } }
|
||||
Row { Text {text: "Password:" } TextField { id: passwordField; text: loginView.password } }
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: bottomButton
|
||||
text: loginView.buttonText
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
onClicked: loginView.submit(nameField.text, passwordField.text)
|
||||
}
|
||||
}
|
63
retroshare-qml-app/src/qml/TrustedNodesView.qml
Normal file
63
retroshare-qml-app/src/qml/TrustedNodesView.qml
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
import "jsonpath.js" as JSONPath
|
||||
|
||||
Item
|
||||
{
|
||||
function refreshData() { rsApi.request("/peers/*", "") }
|
||||
|
||||
onFocusChanged: focus && refreshData()
|
||||
|
||||
LibresapiLocalClient
|
||||
{
|
||||
id: rsApi
|
||||
onGoodResponseReceived: jsonModel.json = msg
|
||||
Component.onCompleted: { openConnection(apiSocketPath) }
|
||||
}
|
||||
|
||||
JSONListModel
|
||||
{
|
||||
id: jsonModel
|
||||
query: "$.data[*]"
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
width: parent.width
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: bottomButton.top
|
||||
model: jsonModel.model
|
||||
delegate: Text
|
||||
{
|
||||
text: model.name
|
||||
onTextChanged: color = JSONPath.jsonPath(JSON.parse(jsonModel.json), "$.data[?(@.pgp_id=='"+model.pgp_id+"')].locations[*].is_online").reduce(function(cur,acc){return cur || acc}, false) ? "lime" : "darkslategray"
|
||||
}
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: bottomButton
|
||||
text: "Add Trusted Node"
|
||||
anchors.bottom: parent.bottom
|
||||
onClicked: swipeView.currentIndex = 3
|
||||
}
|
||||
}
|
BIN
retroshare-qml-app/src/qml/icons/contacts-128.png
Executable file
BIN
retroshare-qml-app/src/qml/icons/contacts-128.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
retroshare-qml-app/src/qml/icons/email-128.png
Executable file
BIN
retroshare-qml-app/src/qml/icons/email-128.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
retroshare-qml-app/src/qml/icons/settings-4-128.png
Executable file
BIN
retroshare-qml-app/src/qml/icons/settings-4-128.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
BIN
retroshare-qml-app/src/qml/icons/star-2-128.png
Executable file
BIN
retroshare-qml-app/src/qml/icons/star-2-128.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
88
retroshare-qml-app/src/qml/jsonpath.js
Normal file
88
retroshare-qml-app/src/qml/jsonpath.js
Normal file
@ -0,0 +1,88 @@
|
||||
/* JSONPath 0.8.5 - XPath for JSON
|
||||
*
|
||||
* Copyright (c) 2007 Stefan Goessner (goessner.net)
|
||||
* Licensed under the MIT (MIT-LICENSE.txt) licence.
|
||||
*
|
||||
*/
|
||||
function jsonPath(obj, expr, arg) {
|
||||
var P = {
|
||||
resultType: arg && arg.resultType || "VALUE",
|
||||
result: [],
|
||||
normalize: function(expr) {
|
||||
var subx = [];
|
||||
return expr.replace(/[\['](\??\(.*?\))[\]']|\['(.*?)'\]/g, function($0,$1,$2){return "[#"+(subx.push($1||$2)-1)+"]";}) /* http://code.google.com/p/jsonpath/issues/detail?id=4 */
|
||||
.replace(/'?\.'?|\['?/g, ";")
|
||||
.replace(/;;;|;;/g, ";..;")
|
||||
.replace(/;$|'?\]|'$/g, "")
|
||||
.replace(/#([0-9]+)/g, function($0,$1){return subx[$1];});
|
||||
},
|
||||
asPath: function(path) {
|
||||
var x = path.split(";"), p = "$";
|
||||
for (var i=1,n=x.length; i<n; i++)
|
||||
p += /^[0-9*]+$/.test(x[i]) ? ("["+x[i]+"]") : ("['"+x[i]+"']");
|
||||
return p;
|
||||
},
|
||||
store: function(p, v) {
|
||||
if (p) P.result[P.result.length] = P.resultType == "PATH" ? P.asPath(p) : v;
|
||||
return !!p;
|
||||
},
|
||||
trace: function(expr, val, path) {
|
||||
if (expr !== "") {
|
||||
var x = expr.split(";"), loc = x.shift();
|
||||
x = x.join(";");
|
||||
if (val && val.hasOwnProperty(loc))
|
||||
P.trace(x, val[loc], path + ";" + loc);
|
||||
else if (loc === "*")
|
||||
P.walk(loc, x, val, path, function(m,l,x,v,p) { P.trace(m+";"+x,v,p); });
|
||||
else if (loc === "..") {
|
||||
P.trace(x, val, path);
|
||||
P.walk(loc, x, val, path, function(m,l,x,v,p) { typeof v[m] === "object" && P.trace("..;"+x,v[m],p+";"+m); });
|
||||
}
|
||||
else if (/^\(.*?\)$/.test(loc)) // [(expr)]
|
||||
P.trace(P.eval(loc, val, path.substr(path.lastIndexOf(";")+1))+";"+x, val, path);
|
||||
else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)]
|
||||
P.walk(loc, x, val, path, function(m,l,x,v,p) { if (P.eval(l.replace(/^\?\((.*?)\)$/,"$1"), v instanceof Array ? v[m] : v, m)) P.trace(m+";"+x,v,p); }); // issue 5 resolved
|
||||
else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step] phyton slice syntax
|
||||
P.slice(loc, x, val, path);
|
||||
else if (/,/.test(loc)) { // [name1,name2,...]
|
||||
for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++)
|
||||
P.trace(s[i]+";"+x, val, path);
|
||||
}
|
||||
}
|
||||
else
|
||||
P.store(path, val);
|
||||
},
|
||||
walk: function(loc, expr, val, path, f) {
|
||||
if (val instanceof Array) {
|
||||
for (var i=0,n=val.length; i<n; i++)
|
||||
if (i in val)
|
||||
f(i,loc,expr,val,path);
|
||||
}
|
||||
else if (typeof val === "object") {
|
||||
for (var m in val)
|
||||
if (val.hasOwnProperty(m))
|
||||
f(m,loc,expr,val,path);
|
||||
}
|
||||
},
|
||||
slice: function(loc, expr, val, path) {
|
||||
if (val instanceof Array) {
|
||||
var len=val.length, start=0, end=len, step=1;
|
||||
loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g, function($0,$1,$2,$3){start=parseInt($1||start);end=parseInt($2||end);step=parseInt($3||step);});
|
||||
start = (start < 0) ? Math.max(0,start+len) : Math.min(len,start);
|
||||
end = (end < 0) ? Math.max(0,end+len) : Math.min(len,end);
|
||||
for (var i=start; i<end; i+=step)
|
||||
P.trace(i+";"+expr, val, path);
|
||||
}
|
||||
},
|
||||
eval: function(x, _v, _vname) {
|
||||
try { return $ && _v && eval(x.replace(/(^|[^\\])@/g, "$1_v").replace(/\\@/g, "@")); } // issue 7 : resolved ..
|
||||
catch(e) { throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/(^|[^\\])@/g, "$1_v").replace(/\\@/g, "@")); } // issue 7 : resolved ..
|
||||
}
|
||||
};
|
||||
|
||||
var $ = obj;
|
||||
if (expr && obj && (P.resultType == "VALUE" || P.resultType == "PATH")) {
|
||||
P.trace(P.normalize(expr).replace(/^\$;?/,""), obj, "$"); // issue 6 resolved
|
||||
return P.result.length ? P.result : false;
|
||||
}
|
||||
}
|
246
retroshare-qml-app/src/qml/main.qml
Normal file
246
retroshare-qml-app/src/qml/main.qml
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* RetroShare Android QML App
|
||||
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
|
||||
ApplicationWindow
|
||||
{
|
||||
id: mainWindow
|
||||
visible: true
|
||||
title: qsTr("RSChat")
|
||||
width: 400
|
||||
height: 400
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: mainView
|
||||
anchors.fill: parent
|
||||
states:
|
||||
[
|
||||
State
|
||||
{
|
||||
name: "waiting_account_select"
|
||||
PropertyChanges { target: swipeView; currentIndex: 0 }
|
||||
PropertyChanges { target: locationsTab; enabled: true }
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "running_ok"
|
||||
PropertyChanges { target: swipeView; currentIndex: 1 }
|
||||
PropertyChanges { target: locationsTab; enabled: false }
|
||||
},
|
||||
State
|
||||
{
|
||||
name: "running_ok_no_full_control"
|
||||
PropertyChanges { target: swipeView; currentIndex: 1 }
|
||||
PropertyChanges { target: locationsTab; enabled: false }
|
||||
}
|
||||
]
|
||||
|
||||
LibresapiLocalClient
|
||||
{
|
||||
onGoodResponseReceived:
|
||||
{
|
||||
var jsonReponse = JSON.parse(msg)
|
||||
mainView.state = jsonReponse.data.runstate
|
||||
}
|
||||
Component.onCompleted:
|
||||
{
|
||||
openConnection(apiSocketPath)
|
||||
request("/control/runstate/", "")
|
||||
}
|
||||
}
|
||||
|
||||
TabView
|
||||
{
|
||||
id: swipeView
|
||||
anchors.fill: parent
|
||||
visible: true
|
||||
currentIndex: 0
|
||||
|
||||
Tab
|
||||
{
|
||||
title:"Locations"
|
||||
id: locationsTab
|
||||
Locations { onVisibleChanged: focus = visible }
|
||||
}
|
||||
|
||||
Tab
|
||||
{
|
||||
title: "Trusted Nodes"
|
||||
TrustedNodesView { onVisibleChanged: focus = visible }
|
||||
}
|
||||
|
||||
Tab
|
||||
{
|
||||
title: "Contacts"
|
||||
Contacts { onVisibleChanged: focus = visible }
|
||||
}
|
||||
|
||||
Tab
|
||||
{
|
||||
title: "Add Node"
|
||||
AddTrustedNode { onVisibleChanged: focus = visible }
|
||||
}
|
||||
|
||||
Tab
|
||||
{
|
||||
title: "Blue"
|
||||
Rectangle { color: "blue"; anchors.fill: parent }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
onSceneGraphInitialized: llc.openConnection()
|
||||
|
||||
Rectangle {
|
||||
id: page
|
||||
width: 600; height: 400
|
||||
color: "#336699" // "#FFFFFF"
|
||||
|
||||
Rectangle {
|
||||
id: header
|
||||
width: parent.width
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
height: 50
|
||||
|
||||
ApplicationBar {
|
||||
id: status
|
||||
|
||||
AppButton {
|
||||
icon: "icons/contacts-128.png"
|
||||
onButtonClicked : {
|
||||
tabView.currentIndex = 0
|
||||
}
|
||||
}
|
||||
|
||||
AppButton {
|
||||
icon: "icons/settings-4-128.png"
|
||||
onButtonClicked : {
|
||||
tabView.currentIndex = 1
|
||||
}
|
||||
}
|
||||
|
||||
AppButton {
|
||||
icon: "icons/email-128.png"
|
||||
onButtonClicked : {
|
||||
tabView.currentIndex = 2
|
||||
}
|
||||
}
|
||||
|
||||
AppButton {
|
||||
icon: "icons/star-2-128.png"
|
||||
onButtonClicked : {
|
||||
tabView.currentIndex = 3
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TabView {
|
||||
id: tabView
|
||||
width: parent.width
|
||||
anchors.top: header.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
tabsVisible: false
|
||||
|
||||
Tab {
|
||||
id: gxsIds
|
||||
//onActiveChanged: llc.request("/identity/", "")
|
||||
|
||||
onVisibleChanged: llc.request("/identity/", "")
|
||||
|
||||
GxsService {
|
||||
id: gxss
|
||||
title: "Friends"
|
||||
// Button {
|
||||
// text: "buto"
|
||||
// anchors.left: gxss.right
|
||||
// onClicked: {
|
||||
// // gxss.title = "provaboba"
|
||||
// // gxss.title = llc.request("/identity/", "")
|
||||
// //llc.request("/identity/", "") // canviar per onVisibleChanged de Tab potser
|
||||
// }
|
||||
|
||||
// }
|
||||
Connections {
|
||||
target: llc
|
||||
onGoodResponseReceived: gxss.title = msg //console.log("Image has changed!")
|
||||
}
|
||||
//groupDelegate: GxsIdDelegate {}
|
||||
//groupModel: gxsIdModel
|
||||
}
|
||||
}
|
||||
|
||||
Tab {
|
||||
id: forum
|
||||
|
||||
GxsService {
|
||||
id: gxssforum
|
||||
title: "Forums"
|
||||
onVisibleChanged: llc.request("/control/locations/", "")
|
||||
Connections {
|
||||
target: llc
|
||||
onGoodResponseReceived: gxssforum.title = msg //console.log("Image has changed!")
|
||||
}
|
||||
// This one uses the default GxsGroupDelegate.
|
||||
// groupModel: forumGroupModel
|
||||
|
||||
// msgDelegate: ForumMsgDelegate {}
|
||||
// msgModel: forumMsgModel
|
||||
}
|
||||
}
|
||||
|
||||
Tab {
|
||||
id: channelLinks
|
||||
GxsService {
|
||||
title: "Channels"
|
||||
|
||||
// custom GroupDelegate.
|
||||
// groupDelegate: ChannelGroupDelegate {}
|
||||
// groupModel: channelGroupModel
|
||||
|
||||
// msgDelegate: ChannelMsgDelegate {}
|
||||
// msgModel: channelMsgModel
|
||||
}
|
||||
}
|
||||
|
||||
Tab {
|
||||
id: postedLinks
|
||||
|
||||
GxsService {
|
||||
title: "Posted"
|
||||
|
||||
// This one uses the default GxsGroupDelegate.
|
||||
// groupModel: postedGroupModel
|
||||
|
||||
// msgDelegate: PostedMsgDelegate {}
|
||||
// msgModel: postedMsgModel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
36
retroshare-qml-app/src/retroshare-qml-app.pro
Normal file
36
retroshare-qml-app/src/retroshare-qml-app.pro
Normal file
@ -0,0 +1,36 @@
|
||||
!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
|
||||
|
||||
QT += qml quick
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
SOURCES += main.cpp \
|
||||
libresapilocalclient.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH =
|
||||
|
||||
# Default rules for deployment.
|
||||
include(deployment.pri)
|
||||
|
||||
DISTFILES += \
|
||||
android/AndroidManifest.xml \
|
||||
android/gradle/wrapper/gradle-wrapper.jar \
|
||||
android/gradlew \
|
||||
android/res/values/libs.xml \
|
||||
android/build.gradle \
|
||||
android/gradle/wrapper/gradle-wrapper.properties \
|
||||
android/gradlew.bat
|
||||
|
||||
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
|
||||
|
||||
DEPENDPATH *= ../../libretroshare/src
|
||||
INCLUDEPATH *= ../../libretroshare/src
|
||||
PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a
|
||||
LIBS *= ../../libretroshare/src/lib/libretroshare.a
|
||||
|
||||
HEADERS += \
|
||||
libresapilocalclient.h \
|
||||
debugutils.h
|
@ -1,12 +1,44 @@
|
||||
# To {dis,en}able libresapi via local socket (unix domain socket or windows named pipes)
|
||||
# {,un}comment the following line
|
||||
#CONFIG *= libresapilocalserver
|
||||
# To disable RetroShare-gui append the following
|
||||
# assignation to qmake command line "CONFIG+=no_retroshare_gui"
|
||||
CONFIG *= retroshare_gui
|
||||
no_retroshare_gui:CONFIG -= retroshare_gui
|
||||
|
||||
# To {dis,en}able libresapi via HTTP (libmicrohttpd) {,un}comment the following line
|
||||
# To disable RetroShare-nogui append the following
|
||||
# assignation to qmake command line "CONFIG+=no_retroshare_nogui"
|
||||
CONFIG *= retroshare_nogui
|
||||
no_retroshare_nogui:CONFIG -= retroshare_nogui
|
||||
|
||||
# To disable RetroShare plugins append the following
|
||||
# assignation to qmake command line "CONFIG+=no_retroshare_plugins"
|
||||
CONFIG *= retroshare_plugins
|
||||
no_retroshare_plugins:CONFIG -= retroshare_plugins
|
||||
|
||||
# To enable RetroShare-android-service append the following assignation to
|
||||
# qmake command line "CONFIG+=retroshare_android_service"
|
||||
CONFIG *= no_retroshare_android_service
|
||||
retroshare_android_service:CONFIG -= no_retroshare_android_service
|
||||
|
||||
# To enable libresapi via local socket (unix domain socket or windows named
|
||||
# pipes) append the following assignation to qmake command line
|
||||
#"CONFIG+=libresapilocalserver"
|
||||
CONFIG *= no_libresapilocalserver
|
||||
libresapilocalserver:CONFIG -= no_libresapilocalserver
|
||||
|
||||
# To disable libresapi via HTTP (based on libmicrohttpd) append the following
|
||||
# assignation to qmake command line "CONFIG+=no_libresapihttpserver"
|
||||
CONFIG *= libresapihttpserver
|
||||
no_libresapihttpserver:CONFIG -= libresapihttpserver
|
||||
|
||||
# To disable SQLCipher support append the following assignation to qmake
|
||||
# command line "CONFIG+=no_sqlcipher"
|
||||
CONFIG *= sqlcipher
|
||||
no_sqlcipher:CONFIG -= sqlcipher
|
||||
|
||||
# To disable GXS (General eXchange System) append the following
|
||||
# assignation to qmake command line "CONFIG+=no_rs_gxs"
|
||||
CONFIG *= rs_gxs
|
||||
no_rs_gxs:CONFIG -= rs_gxs
|
||||
|
||||
# Gxs is always enabled now.
|
||||
DEFINES *= RS_ENABLE_GXS
|
||||
|
||||
unix {
|
||||
isEmpty(PREFIX) { PREFIX = "/usr" }
|
||||
@ -18,22 +50,21 @@ unix {
|
||||
}
|
||||
|
||||
android-g++ {
|
||||
DEFINES *= NO_SQLCIPHER
|
||||
CONFIG *= no_libresapihttpserver no_sqlcipher upnp_libupnp
|
||||
CONFIG -= libresapihttpserver sqlcipher upnp_miniupnpc
|
||||
QT *= androidextras
|
||||
DEFINES *= "fopen64=fopen"
|
||||
DEFINES *= "fseeko64=fseeko"
|
||||
DEFINES *= "ftello64=ftello"
|
||||
INCLUDEPATH *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/include/
|
||||
INCLUDEPATH += $$NDK_TOOLCHAIN_PATH/sysroot/usr/include
|
||||
LIBS *= -L$$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/
|
||||
LIBS *= -lssl -lcrypto -lsqlite3 -lupnp -lixml
|
||||
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libcrypto.so
|
||||
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libssl.so
|
||||
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libbz2.so
|
||||
LIBS *= -lbz2 -lupnp -lixml -lthreadutil -lsqlite3
|
||||
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libsqlite3.so
|
||||
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libupnp.so
|
||||
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libixml.so
|
||||
message(NDK_TOOLCHAIN_PATH: $$NDK_TOOLCHAIN_PATH)
|
||||
message(LIBS: $$LIBS)
|
||||
message(ANDROID_EXTRA_LIBS: $$ANDROID_EXTRA_LIBS)
|
||||
# message(LIBS: $$LIBS)
|
||||
# message(ANDROID_EXTRA_LIBS: $$ANDROID_EXTRA_LIBS)
|
||||
# message(ANDROID_PLATFORM: $$ANDROID_PLATFORM)
|
||||
# message(ANDROID_PLATFORM_ROOT_PATH: $$ANDROID_PLATFORM_ROOT_PATH)
|
||||
# message(NDK_TOOLCHAIN_PATH: $$NDK_TOOLCHAIN_PATH)
|
||||
}
|
||||
|
||||
win32 {
|
||||
@ -95,6 +126,8 @@ unfinished {
|
||||
}
|
||||
|
||||
wikipoos:DEFINES *= RS_USE_WIKI
|
||||
|
||||
rs_gxs:DEFINES *= RS_ENABLE_GXS
|
||||
libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER
|
||||
libresapihttpserver::DEFINES *= ENABLE_WEBUI
|
||||
libresapihttpserver:DEFINES *= ENABLE_WEBUI
|
||||
sqlcipher:DEFINES -= NO_SQLCIPHER
|
||||
no_sqlcipher:DEFINES *= NO_SQLCIPHER
|
||||
|
@ -47,7 +47,7 @@ linux-* {
|
||||
|
||||
#LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a
|
||||
|
||||
contains(CONFIG, NO_SQLCIPHER) {
|
||||
no_sqlcipher {
|
||||
DEFINES *= NO_SQLCIPHER
|
||||
PKGCONFIG *= sqlite3
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user