From 50fe3dd7118c41238d6c5bd57bf2df69358d7872 Mon Sep 17 00:00:00 2001 From: manu Date: Sun, 4 Sep 2016 15:01:44 +0200 Subject: [PATCH] QML activity interacts with backend. Test QML activity changed for a simplified version of drbob's rsqml-models. It requests JSON documents from the libresapilocalserver and shows them raw. Updated Android documentation. Moved Android qmake section to the end of libretroshare.pro and openpgpsdk.pro to avoid static linking errors. --- README-Android.asciidoc | 32 ++-- libretroshare/src/libretroshare.pro | 43 ++--- openpgpsdk/src/openpgpsdk.pro | 18 ++ retroshare-qml-app/src/Page1.qml | 10 -- retroshare-qml-app/src/Page1Form.ui.qml | 22 --- .../src/android/AndroidManifest.xml | 15 +- retroshare-qml-app/src/debugutils.h | 15 ++ .../src/libresapilocalclient.cpp | 79 +++++++++ retroshare-qml-app/src/libresapilocalclient.h | 64 +++++++ retroshare-qml-app/src/main.cpp | 29 ++-- retroshare-qml-app/src/main.qml | 37 ---- retroshare-qml-app/src/qml.qrc | 16 ++ retroshare-qml-app/src/qml/AppButton.qml | 30 ++++ retroshare-qml-app/src/qml/ApplicationBar.qml | 37 ++++ .../src/qml/ChannelGroupDelegate.qml | 33 ++++ .../src/qml/ChannelMsgDelegate.qml | 42 +++++ retroshare-qml-app/src/qml/ContactBox.qml | 61 +++++++ .../src/qml/ForumMsgDelegate.qml | 41 +++++ .../src/qml/GxsGroupDelegate.qml | 26 +++ retroshare-qml-app/src/qml/GxsIdDelegate.qml | 33 ++++ retroshare-qml-app/src/qml/GxsService.qml | 119 +++++++++++++ .../src/qml/LibresapiLocalClientComm.qml | 5 + .../src/qml/PostedMsgDelegate.qml | 40 +++++ .../src/qml/icons/contacts-128.png | Bin 0 -> 2399 bytes .../src/qml/icons/email-128.png | Bin 0 -> 2915 bytes .../src/qml/icons/settings-4-128.png | Bin 0 -> 3162 bytes .../src/qml/icons/star-2-128.png | Bin 0 -> 1973 bytes retroshare-qml-app/src/qml/main.qml | 160 ++++++++++++++++++ retroshare-qml-app/src/retroshare-qml-app.pro | 7 +- 29 files changed, 886 insertions(+), 128 deletions(-) delete mode 100644 retroshare-qml-app/src/Page1.qml delete mode 100644 retroshare-qml-app/src/Page1Form.ui.qml create mode 100644 retroshare-qml-app/src/debugutils.h create mode 100644 retroshare-qml-app/src/libresapilocalclient.cpp create mode 100644 retroshare-qml-app/src/libresapilocalclient.h delete mode 100644 retroshare-qml-app/src/main.qml create mode 100644 retroshare-qml-app/src/qml/AppButton.qml create mode 100644 retroshare-qml-app/src/qml/ApplicationBar.qml create mode 100644 retroshare-qml-app/src/qml/ChannelGroupDelegate.qml create mode 100644 retroshare-qml-app/src/qml/ChannelMsgDelegate.qml create mode 100644 retroshare-qml-app/src/qml/ContactBox.qml create mode 100644 retroshare-qml-app/src/qml/ForumMsgDelegate.qml create mode 100644 retroshare-qml-app/src/qml/GxsGroupDelegate.qml create mode 100644 retroshare-qml-app/src/qml/GxsIdDelegate.qml create mode 100644 retroshare-qml-app/src/qml/GxsService.qml create mode 100644 retroshare-qml-app/src/qml/LibresapiLocalClientComm.qml create mode 100644 retroshare-qml-app/src/qml/PostedMsgDelegate.qml create mode 100755 retroshare-qml-app/src/qml/icons/contacts-128.png create mode 100755 retroshare-qml-app/src/qml/icons/email-128.png create mode 100755 retroshare-qml-app/src/qml/icons/settings-4-128.png create mode 100755 retroshare-qml-app/src/qml/icons/star-2-128.png create mode 100644 retroshare-qml-app/src/qml/main.qml diff --git a/README-Android.asciidoc b/README-Android.asciidoc index 5c126b059..b84d4a482 100644 --- a/README-Android.asciidoc +++ b/README-Android.asciidoc @@ -8,16 +8,16 @@ Compiling an application for Android is not as easy as one would imagine, expeci == 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 execute on a Android emulator on on your Android phone Qt for Android examples. +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 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 provide the +android-prepare-toolchain.sh+ script, before you execute it you should define some variable the script cannot determine in an easy and reliable manner by itself in your terminal. +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, take care +## 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/" @@ -25,7 +25,7 @@ export NDK_TOOLCHAIN_PATH="/home/$(whoami)/Development/android-toolchains/retros export ANDROID_NDK_ARCH="arm" ## The Android API level the Android device you want to target -export ANDROID_PLATFORM_VER="23" +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 @@ -33,9 +33,9 @@ export HOST_NUM_CPU=1 ./android-prepare-toolchain.sh ------------------------------------------------------------------------------- -Now is time for the bad news: as of today Qt assume 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 a little Qt internals 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 +/opt/Qt5.7.0/5.7/android_armv7/mkspecs+ and then modify qmake configuration for 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 advantege of the variables I set before. +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 slightly modification if you have a different Qt version. +WARNING: This may need a slight modification if you have a different Qt version. [source,bash] ------------------------------------------------------------------------------- @@ -52,27 +52,31 @@ sed -i "s|^NDK_TOOLCHAIN_PATH =.*|NDK_TOOLCHAIN_PATH = ${NDK_TOOLCHAIN_PATH}|" q == 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 Android compiler and Qt for Android kit, because we use a custom toolchain some step more is needed. +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 +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+ then press Apply. +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 Clone button a new kit is created and it is 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. +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 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. +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 error you will have to go to + +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 +_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 pose a mayor security concern, we are working to fix this ASAP. +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 diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 1b41ec215..5cb1d0781 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -335,27 +335,6 @@ haiku-* { DESTDIR = lib } -################################# Android ##################################### - -android-g++ { -## ifaddrs is missing on Android add them -## taken from https://github.com/morristech/android-ifaddrs - HEADERS *= util/ifaddrs.h - SOURCES *= util/ifaddrs.c - -## 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 -} - ################################### COMMON stuff ################################## # openpgpsdk @@ -892,3 +871,25 @@ test_bitdht { # ENABLED UDP NOW. } + +################################# Android ##################################### + +android-g++ { +## ifaddrs is missing on Android add them +## taken from https://github.com/morristech/android-ifaddrs + HEADERS *= util/ifaddrs.h + SOURCES *= util/ifaddrs.c + +## 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 +} diff --git a/openpgpsdk/src/openpgpsdk.pro b/openpgpsdk/src/openpgpsdk.pro index 2cee7847d..6847c195c 100644 --- a/openpgpsdk/src/openpgpsdk.pro +++ b/openpgpsdk/src/openpgpsdk.pro @@ -115,3 +115,21 @@ SOURCES += openpgpsdk/accumulate.c \ openpgpsdk/writer_stream_encrypt_se_ip.c \ openpgpsdk/opsdir.c \ 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 + +} diff --git a/retroshare-qml-app/src/Page1.qml b/retroshare-qml-app/src/Page1.qml deleted file mode 100644 index d5b808f9b..000000000 --- a/retroshare-qml-app/src/Page1.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.7 - -Page1Form { - button1.onClicked: { - console.log("Button 1 clicked."); - } - button2.onClicked: { - console.log("Button 2 clicked."); - } -} diff --git a/retroshare-qml-app/src/Page1Form.ui.qml b/retroshare-qml-app/src/Page1Form.ui.qml deleted file mode 100644 index 806ad2190..000000000 --- a/retroshare-qml-app/src/Page1Form.ui.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 - -Item { - property alias button1: button1 - property alias button2: button2 - - RowLayout { - anchors.centerIn: parent - - Button { - id: button1 - text: qsTr("Press Me 1") - } - - Button { - id: button2 - text: qsTr("Press Me 2") - } - } -} diff --git a/retroshare-qml-app/src/android/AndroidManifest.xml b/retroshare-qml-app/src/android/AndroidManifest.xml index 54eb4f894..c5552d619 100644 --- a/retroshare-qml-app/src/android/AndroidManifest.xml +++ b/retroshare-qml-app/src/android/AndroidManifest.xml @@ -1,12 +1,7 @@ - + @@ -74,11 +69,7 @@ - + @@ -135,5 +126,5 @@ - + diff --git a/retroshare-qml-app/src/debugutils.h b/retroshare-qml-app/src/debugutils.h new file mode 100644 index 000000000..a9a2f39ff --- /dev/null +++ b/retroshare-qml-app/src/debugutils.h @@ -0,0 +1,15 @@ +#ifndef DEBUGUTILS_H +#define DEBUGUTILS_H + +#include + +//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 diff --git a/retroshare-qml-app/src/libresapilocalclient.cpp b/retroshare-qml-app/src/libresapilocalclient.cpp new file mode 100644 index 000000000..6b7e1d1f1 --- /dev/null +++ b/retroshare-qml-app/src/libresapilocalclient.cpp @@ -0,0 +1,79 @@ +#include "libresapilocalclient.h" +#include "debugutils.h" +#include + +/* Constructor de còpia per proves, no s'ha d'usar. +LibresapiLocalClient::LibresapiLocalClient(const LibresapiLocalClient & l) +{ + //mLocalSocket = l.mLocalSocket; + receivedBytes = l.receivedBytes; + json = l.json; +}*/ + +LibresapiLocalClient::LibresapiLocalClient(const QString & socketPath) : + mLocalSocket(this) +{ + myDebug(this); + mSocketPath = socketPath; + connect(& mLocalSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), + this, SLOT(socketError(QLocalSocket::LocalSocketError))); + connect(& mLocalSocket, SIGNAL(readyRead()), + this, SLOT(read())); + //openConnection(); +} + + +void LibresapiLocalClient::openConnection() +{ + mLocalSocket.connectToServer(mSocketPath); +} + +int LibresapiLocalClient::request(const QString & path, const QString & 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 error) +{ + myDebug("error!!!!\n" + mLocalSocket.errorString());//error.errorString()); +} + +void LibresapiLocalClient::read() +{ + receivedBytes = mLocalSocket.readAll(); + + if(parseResponse()){ // pensar en fer un buffer per parsejar, per evitar errors. + emit goodResponseReceived(QString(receivedBytes)); + return; + } + + 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; +} diff --git a/retroshare-qml-app/src/libresapilocalclient.h b/retroshare-qml-app/src/libresapilocalclient.h new file mode 100644 index 000000000..da2917359 --- /dev/null +++ b/retroshare-qml-app/src/libresapilocalclient.h @@ -0,0 +1,64 @@ +/* + * libresapi local socket client + * Copyright (C) 2016 Manu Pineda + * + * 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 . + */ + +#ifndef LIBRESAPILOCALCLIENT_H +#define LIBRESAPILOCALCLIENT_H + +#include +#include +#include +#include + +class LibresapiLocalClient : public QObject +{ + Q_OBJECT + + public: + + LibresapiLocalClient() {} + // LibresapiLocalClient(const LibresapiLocalClient & l); + LibresapiLocalClient(const QString & socketPath); + // 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(); + + private: + + QString mSocketPath; + QLocalSocket mLocalSocket; + QByteArray receivedBytes; + QJsonDocument json; + //QVector responses; + + bool parseResponse(); //std::string msg); + + private slots: + + void socketError(QLocalSocket::LocalSocketError error); + void read(); + + signals: + + void goodResponseReceived(const QString & msg);//, int requestId); + + public slots: + +}; + +#endif // LIBRESAPILOCALCLIENT_H diff --git a/retroshare-qml-app/src/main.cpp b/retroshare-qml-app/src/main.cpp index 2834d7908..05ada4369 100644 --- a/retroshare-qml-app/src/main.cpp +++ b/retroshare-qml-app/src/main.cpp @@ -18,30 +18,37 @@ #include #include +#include +#include #include #include #include #include +#include "libresapilocalclient.h" #include "retroshare/rsinit.h" int main(int argc, char *argv[]) { - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QGuiApplication app(argc, argv); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; - engine.load(QUrl(QLatin1String("qrc:/main.qml"))); + QQmlApplicationEngine engine; - QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory()); - sockPath.append("/libresapi.sock"); + QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory()); + sockPath.append("/libresapi.sock"); + LibresapiLocalClient llc(sockPath); + qmlRegisterType("LibresapiLocalClientQml", 1, 0, "LibresapiLocalClientComm"); - QFileInfo fileInfo(sockPath); + engine.rootContext()->setContextProperty("llc", &llc); + engine.load(QUrl(QLatin1String("qrc:/qml/main.qml"))); - qDebug() << "Is service.cpp running as a service?" << QtAndroid::androidService().isValid(); - qDebug() << "Is service.cpp running as an activity?" << QtAndroid::androidActivity().isValid(); - qDebug() << "QML APP:" << sockPath << fileInfo.exists() << fileInfo.lastModified().toString(); + QFileInfo fileInfo(sockPath); - return app.exec(); + qDebug() << "Is main.cpp running as a service?" << QtAndroid::androidService().isValid(); + qDebug() << "Is main.cpp running as an activity?" << QtAndroid::androidActivity().isValid(); + qDebug() << "QML APP:" << sockPath << fileInfo.exists() << fileInfo.lastModified().toString(); + + return app.exec(); } diff --git a/retroshare-qml-app/src/main.qml b/retroshare-qml-app/src/main.qml deleted file mode 100644 index 9e0707ad6..000000000 --- a/retroshare-qml-app/src/main.qml +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 - -ApplicationWindow { - visible: true - width: 640 - height: 480 - title: qsTr("Hello World") - - SwipeView { - id: swipeView - anchors.fill: parent - currentIndex: tabBar.currentIndex - - Page1 { - } - - Page { - Label { - text: qsTr("Second page") - anchors.centerIn: parent - } - } - } - - footer: TabBar { - id: tabBar - currentIndex: swipeView.currentIndex - TabButton { - text: qsTr("First") - } - TabButton { - text: qsTr("Second") - } - } -} diff --git a/retroshare-qml-app/src/qml.qrc b/retroshare-qml-app/src/qml.qrc index 67415af31..c2fd19fdc 100644 --- a/retroshare-qml-app/src/qml.qrc +++ b/retroshare-qml-app/src/qml.qrc @@ -3,5 +3,21 @@ main.qml Page1.qml Page1Form.ui.qml + qml/main.qml + qml/icons/star-2-128.png + qml/icons/settings-4-128.png + qml/icons/email-128.png + qml/icons/contacts-128.png + qml/PostedMsgDelegate.qml + qml/GxsService.qml + qml/GxsIdDelegate.qml + qml/GxsGroupDelegate.qml + qml/ForumMsgDelegate.qml + qml/ContactBox.qml + qml/ChannelMsgDelegate.qml + qml/ChannelGroupDelegate.qml + qml/ApplicationBar.qml + qml/AppButton.qml + qml/LibresapiLocalClientComm.qml diff --git a/retroshare-qml-app/src/qml/AppButton.qml b/retroshare-qml-app/src/qml/AppButton.qml new file mode 100644 index 000000000..6b3f9a881 --- /dev/null +++ b/retroshare-qml-app/src/qml/AppButton.qml @@ -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() + } + } +} + + diff --git a/retroshare-qml-app/src/qml/ApplicationBar.qml b/retroshare-qml-app/src/qml/ApplicationBar.qml new file mode 100644 index 000000000..3ec44349d --- /dev/null +++ b/retroshare-qml-app/src/qml/ApplicationBar.qml @@ -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" + } +} + + + diff --git a/retroshare-qml-app/src/qml/ChannelGroupDelegate.qml b/retroshare-qml-app/src/qml/ChannelGroupDelegate.qml new file mode 100644 index 000000000..a92cab36c --- /dev/null +++ b/retroshare-qml-app/src/qml/ChannelGroupDelegate.qml @@ -0,0 +1,33 @@ +import QtQuick 2.2 +import "." + +Item { + id: item + width: parent.width + height: 50 + + Column { + Text { text: '' + model.GroupName + '' } + 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 + } +} + + diff --git a/retroshare-qml-app/src/qml/ChannelMsgDelegate.qml b/retroshare-qml-app/src/qml/ChannelMsgDelegate.qml new file mode 100644 index 000000000..333d0fab0 --- /dev/null +++ b/retroshare-qml-app/src/qml/ChannelMsgDelegate.qml @@ -0,0 +1,42 @@ +import QtQuick 2.2 +import "." + +Item { + id: msgDelegate + + width: parent.width + height: 150 + + Column { + Text { text: 'MsgId: ' + AuthorId } + Text { text: 'AuthorId: ' + AuthorId } + Row { + Text { text: 'Name: ' + MsgName } + Text { text: ' PublishTs: ' + PublishTs } + } + Text { text: 'Msg: ' + Msg } + Row { + Text { text: 'NumberFiles: ' + NumberFiles } + Text { text: ' TotalFileSize: ' + TotalFileSize } + } + + Text { text: 'FileNames: ' + FileNames } + Text { text: 'FileSizes: ' + FileSizes } + Text { text: 'FileHashes: ' + FileHashes } + Row { + Text { text: 'HaveVoted: ' + HaveVoted } + Text { text: ' UpVotes: ' + UpVotes } + Text { text: ' DownVotes: ' + DownVotes } + Text { text: ' Comments: ' + Comments } + } + } + + MouseArea { + hoverEnabled: false + anchors.fill: parent + onClicked: { + item.ListView.view.currentIndex = index + } + } +} + diff --git a/retroshare-qml-app/src/qml/ContactBox.qml b/retroshare-qml-app/src/qml/ContactBox.qml new file mode 100644 index 000000000..9790ed677 --- /dev/null +++ b/retroshare-qml-app/src/qml/ContactBox.qml @@ -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" + } + } + } +} + + diff --git a/retroshare-qml-app/src/qml/ForumMsgDelegate.qml b/retroshare-qml-app/src/qml/ForumMsgDelegate.qml new file mode 100644 index 000000000..bdb8d9138 --- /dev/null +++ b/retroshare-qml-app/src/qml/ForumMsgDelegate.qml @@ -0,0 +1,41 @@ +import QtQuick 2.2 +import "." + +Item { + id: msgDelegate + + width: parent.width + height: col.height + + Column { + id: col + Text { text: 'MsgId: ' + AuthorId } + Text { text: 'AuthorId: ' + AuthorId } + Row { + Text { text: 'Name: ' + MsgName } + Text { text: ' PublishTs: ' + PublishTs } + } + Text { + wrapMode: Text.Wrap + text: 'Msg: ' + 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 + } + +} + diff --git a/retroshare-qml-app/src/qml/GxsGroupDelegate.qml b/retroshare-qml-app/src/qml/GxsGroupDelegate.qml new file mode 100644 index 000000000..0a0b14f73 --- /dev/null +++ b/retroshare-qml-app/src/qml/GxsGroupDelegate.qml @@ -0,0 +1,26 @@ +import QtQuick 2.2 +import "." + +Item { + id: item + property var msgModel: {} + + width: parent.width + height: 50 + + Column { + Text { text: 'Name: ' + model.GroupName } + Text { text: 'Number: ' + GroupId } + } + + MouseArea { + hoverEnabled: false + anchors.fill: parent + onClicked: { + item.ListView.view.currentIndex = index + item.msgModel.updateEntries(model.GroupId) + } + } +} + + diff --git a/retroshare-qml-app/src/qml/GxsIdDelegate.qml b/retroshare-qml-app/src/qml/GxsIdDelegate.qml new file mode 100644 index 000000000..8fd7d738d --- /dev/null +++ b/retroshare-qml-app/src/qml/GxsIdDelegate.qml @@ -0,0 +1,33 @@ +import QtQuick 2.2 +import "." + +Item { + id: item + width: parent.width + height: 50 + + Column { + Text { text: '' + model.GroupName + '' } + 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 + } +} + + diff --git a/retroshare-qml-app/src/qml/GxsService.qml b/retroshare-qml-app/src/qml/GxsService.qml new file mode 100644 index 000000000..7c2a4798d --- /dev/null +++ b/retroshare-qml-app/src/qml/GxsService.qml @@ -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") + } + } + + } + } +} + + diff --git a/retroshare-qml-app/src/qml/LibresapiLocalClientComm.qml b/retroshare-qml-app/src/qml/LibresapiLocalClientComm.qml new file mode 100644 index 000000000..75233c4ab --- /dev/null +++ b/retroshare-qml-app/src/qml/LibresapiLocalClientComm.qml @@ -0,0 +1,5 @@ +import LibresapiLocalClientQml 1.0 + +LibresapiLocalClientComm { + id: llc +} diff --git a/retroshare-qml-app/src/qml/PostedMsgDelegate.qml b/retroshare-qml-app/src/qml/PostedMsgDelegate.qml new file mode 100644 index 000000000..f700054aa --- /dev/null +++ b/retroshare-qml-app/src/qml/PostedMsgDelegate.qml @@ -0,0 +1,40 @@ +import QtQuick 2.2 +import "." + +Item { + id: msgDelegate + + width: parent.width + height: 150 + + Column { + Text { text: 'MsgId: ' + AuthorId } + Text { text: 'AuthorId: ' + AuthorId } + Row { + Text { text: 'Name: ' + MsgName } + Text { text: ' PublishTs: ' + PublishTs } + } + Text { text: 'Link: ' + Link } + Text { text: 'Notes: ' + Notes } + Row { + Text { text: 'Hot: ' + HotScore } + Text { text: ' Top: ' + HotScore } + Text { text: ' New: ' + HotScore } + } + Row { + Text { text: 'HaveVoted: ' + HaveVoted } + Text { text: ' UpVotes: ' + UpVotes } + Text { text: ' DownVotes: ' + DownVotes } + Text { text: ' Comments: ' + Comments } + } + } + + MouseArea { + hoverEnabled: false + anchors.fill: parent + onClicked: { + item.ListView.view.currentIndex = index + } + } +} + diff --git a/retroshare-qml-app/src/qml/icons/contacts-128.png b/retroshare-qml-app/src/qml/icons/contacts-128.png new file mode 100755 index 0000000000000000000000000000000000000000..41d04a8ae8504e0bcc18e8e1961f3d792a69e89b GIT binary patch literal 2399 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 N002ovPDHLkV1k^olt};p literal 0 HcmV?d00001 diff --git a/retroshare-qml-app/src/qml/icons/settings-4-128.png b/retroshare-qml-app/src/qml/icons/settings-4-128.png new file mode 100755 index 0000000000000000000000000000000000000000..44a65b18c9100670836845d49dd00f104f739fb0 GIT binary patch literal 3162 zcmV-g45jmlP) zd#qel6^Fld(~v@%rWR5WN`nocfH6=}NCj+b!CJ6Fc!&kDVpCs8h?x3_!4P6hLx^b# znkt}(JYo?Aq~+ZQAkR`B7OJJ10v5ufEwn&sd+*Ob)(o9{JNM4ax#yg9&fNL_y04kF z?%wO{*^jk;8`=a(ZD}iOhDAG&6iK6iDZpglc;FG>TRE9uB55?R0$2(xGqZPdvORQ> zG+xpVB|RW%hkEmDPCj%=+SJGPdy?*w^j%5&<>AMWLDJ|-!#=9UjLX5F;~V(UE$Kc< zvm}kk+Ml*X(lL^*t2|xJa!C$;UE6{`Z%O)%q)%k+S6d(-UQdzqa0`uG%j@#FL00}9 zDCzwKes#+~BBo~LTd9$Rq|+s>PT29a%+JuzTT}4wVM!-u75K3 zw3bbhCZ*u-naZZ~Yk5=BY_-t_Q@=<$KjX%%Wrw7TCGC;G&k>TYls~0;aaI;>UMS=< z{iQiJswAzGbe^Q)P53ub(uI=#m$Q#|DPRP!+%4iedcbO+VTYv5X5en%Az%&g2G9kJ z0S*I>1EvCdygHz z1E51N(E*V6K0p!qaHR3*02m)^zX%)_X*@arjt;h81SU!f>xVGIl7<1(qU;xlF~G4= z#v@07lktDP1AH&aaMWQCz~jJC5%vp64{)TJJ(IWLs1aZmozAbN3s_kBSj^pUu1Gor z$SiTQ#2f=$mbcMd13=PP;0|D9o_0&bg_7pxX|SmPkTh|y*(#MMe<^U#px&tcnI~z1 z5~Q(Jk*Bkzv$BwMkapF+wOo27&-tGvuafD|JgX#4OwisZN?I!~lG&%#*VlW)B{fdH zBWa#|C~x$-E=e=gTuonx`gF_Ne})FgXOutjGv!6IwJdDZPXjIk-?<^L&09}<- zqh~1J4EJr|G&9>8>4cfx1Y8m6Lz8R={tSEtUk0Ak>$mdc&7&kORQ4*KX)r6G5$hsp z52Yh?odrAOf|vWY@(+zub~?Ukuv`U`RaN7QBqI2)q+@H3I_Vv+y|)3v3N z#Zm%}2(UR;(kEMeQA+_JSDlIsfX@ZmZVI`8R@6w<@}XU;BfxB8kAjjH%2#3g|{R%bs=ZN5kS&3;MzgAPI`3F;xLy7l8(T|wTi$< z;4VoGN237)K+<`@trRC8u*%6wdzc#p@`>p}inX&k3b;qoT(x=+fuymL76lDo&GL#` z$#u^VNk5Kmj0UWhbh_#ULSKcDqwuxlEL=9F=qv-i5LFrmAZaSFgmOshyb9a~EXQ*e zo;0~G{f+pI75fD`my{cTv(56q{z$&_ww!VuR8`pue5kAP^c+DsJ0D!a<@d^YgGkZ@ z;2z4^`2bIv+0JUCg2E>KWW^}pXTW;-y*qOxH9V%3w3nnwk}kt5 ze3k%{vUN3gZmoXN&O(v>u@QI<&!XLoYy6C2msIQ_lw(bwlwLxSeK&%hr+pMLJJhGw z9YTHA&P6)(>5vWA)qc}=1lSK)PkRr6Lz&I^@c)6dU9S8-J|re5ikX zxgaNJI^;_ab<|br1;G8dzJ7=HVzHU+R<*oa08~!Zewl|y9dhNedOz%3962;-?czu? z+X-BnsY@O5i?s<`BwZlS*KDP&$4UB2O{G=wgr|$fW55Y{ zs-fkcOD$<8@p`&N zFV`i`gDvtaXWJin0^^RH8g{K*{4%MpC(0E`^Wbs$$k^UU8Ybzd@C&zE zJ5JKSGWK+$|$f!((jbuKEDnXB<&+FlUmuJvENe;J8JSh zf`RCkv|Q48%1OL>$RJ-i%$4+zcHc`_nxh}<`q+M7(mnE`*;2{w=YPvWO32svQ-R6& zZKijdSuXb)N?L@giav-dtuHgPt$En)&>>a+4{7b=b~#0Z7ytkO07*qoM6N<$g75+l AAOHXW literal 0 HcmV?d00001 diff --git a/retroshare-qml-app/src/qml/icons/star-2-128.png b/retroshare-qml-app/src/qml/icons/star-2-128.png new file mode 100755 index 0000000000000000000000000000000000000000..3409abc13a77ec066ea0f1862b4c9e32b8123174 GIT binary patch literal 1973 zcmV;m2TJ&fP)^pr{Cz zNBS0AupOLm~Al_8*550sdUrazP_0AZ_+ip{agtfdl}!$~(SL7;xtj zoe%J^cYL8BU=46=nFIiMuXmiG5a4TX(D?uldB+(F0H%SXLnOc%;62{)hRlFFhUol( z`@Q2083C(-!y_cX8Q?PSxI-qu?IU#lz%RVx4jBNefJ0*>z$sv}cl@PIc?VFzHc8`j z6KpUsl-r2mT4H_O5ddy%+&Vi#Kkr zSmXvtpQ>11F}+9trK#H5b=d{1s$6DvD?R~8i#E176un8(#~sSeYDH#ncl@1ITIlf^ z`PE}La9q;7q^Hg7zfN(C&AbCx3TeV+lTs&dlJwT|e&3)rllMPL$uKYJsqW{~lIG3q zInThB;+g=YJ8Xka-7M)X=l#8J_uyX}DY~DB&inltGdt@MRM7+=y?JAUF1#0SmbA8H z`76i?rDPZ+#9;K8m-G)aJ6)>ai4&kZ6P{J-(8YW4CZz=xVSJ}09nsQ@O#o$K&ckH;5_f9qUA+-GLLALT!f+;L`h1URgi4sFFu_vd*@kB$1D$36rAJ0;z% z9?T{5z+Oq89OqnN?9MZ@A4}Sybc_mqekSR*aZeO;oCI!@v`29s;Nf0LJIu!K#)*e- zGutca7D*>3-BuXM_cdYXOPP+}X7+%jk4l>8k|Yf6+h(?F($1GMPXqziNZKdqlAPNO zue00CzLRTX*=GWQD zq+87F*Ch+7vL2wjfi$P_Ue$6jdPUL)&1`?^f~w5po7oXbS4%orqr4UFxTG6ubiP!1 zMNqc_Xin0Wn&qw_$0c2BW{=k@u=FVy}xti*?a?R|xq-!Pp zp?28~J0ge9mmC*`0+%RF8(-rULn8*AKkrev+hUGxE!z!}ieBb4ZeG&+ygFZUUd>}> zCzb9Z{>n2BCx2Di^Ia#(ns_h-n3D8!`8?v~;h<9IyFV<_#CpE&p@`d*R=D)tY zfP2)R7c%`tY1nUW$y`$-z#=ES1ITEq#m<-7PJnlL2awTat-ehp5}=N0HF_(&$pio{ zm2|0h9GNwl&`lCtEBvH=9VRQhvYzyk1H&if89unM>x_*aGU0WSA!>m~uSg&X}8 z@Dt!o%fv7Ze1r6%=#sWqY}#eDbOZ-Tu&NhCXsD~ zTJeC($85xxfICUw7_1%h6tE3=YRuTbTs!7w0ozAxyanI~q_>WF$G#f)9PsRjb=cz_ zdozF^4%ujDfct=r-Z3u*tRam?!%k)$@Q%3|z{5i{*n^}OP&W-&-zD^`Z&05F8hu`{ zI^ftc4fP1{e(xAZ1#ATNu>7TCUspd5513h^ah?Ef^p0;*z!qTN5_P=QJ3e>7b&DG1 zFz^Y|i=%o2xB_@|QC;uyj>{eJ)vhs)0biujwY(SLCg91g&ilOMaR=N3e2WGjn<|Ag zhp-)Z#5)#uec$7kb1~OFgb+dqA%qY@2qA