diff --git a/mobile/android/AndroidManifest.xml b/mobile/android/AndroidManifest.xml
index 5e889e1fd..d8689ea21 100644
--- a/mobile/android/AndroidManifest.xml
+++ b/mobile/android/AndroidManifest.xml
@@ -1,75 +1,48 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/mobile/android/src/OpenFileActivity.java b/mobile/android/src/OpenFileActivity.java
index 9971fa75d..c92e4aac1 100644
--- a/mobile/android/src/OpenFileActivity.java
+++ b/mobile/android/src/OpenFileActivity.java
@@ -1,43 +1,79 @@
package org.kde.something;
import android.content.ContentResolver;
import android.content.Intent;
import android.util.Log;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.net.Uri;
+import android.app.Activity;
import org.qtproject.qt5.android.bindings.QtActivity;
class FileClass
{
public static native void openUri(String uri);
}
-public class OpenFileActivity extends QtActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- final Intent bundleIntent = getIntent();
- if (bundleIntent == null)
+public class OpenFileActivity extends QtActivity
+{
+ private void displayUri(Uri uri)
+ {
+ if (uri == null)
return;
- final String action = bundleIntent.getAction();
- Uri uri = bundleIntent.getData();
if (!uri.getScheme().equals("file")) {
try {
ContentResolver resolver = getBaseContext().getContentResolver();
ParcelFileDescriptor fdObject = resolver.openFileDescriptor(uri, "r");
uri = Uri.parse("fd:///" + fdObject.detachFd());
} catch (Exception e) {
e.printStackTrace();
//TODO: emit warning that couldn't be opened
- Log.v("Okular", "failed to open");
+ Log.e("Okular", "failed to open");
return;
}
}
+ Log.e("Okular", "opening url: " + uri.toString());
FileClass.openUri(uri.toString());
}
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final Intent bundleIntent = getIntent();
+ if (bundleIntent == null)
+ return;
+
+ final String action = bundleIntent.getAction();
+ Log.v("Okular", "Starting action: " + action);
+ if (action == "android.intent.action.VIEW") {
+ displayUri(bundleIntent.getData());
+ }
+ }
+
+ private static int OpenDocumentRequest = 42;
+
+ public static void openFile(Activity context, String title, String mimes)
+ {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_GET_CONTENT);
+ intent.setType("application/pdf");
+ Log.v("Okular", "opening: " + mimes);
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, mimes.split(";"));
+
+ context.startActivityForResult(intent, OpenDocumentRequest);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ Log.v("Okular", "Activity Result: " + String.valueOf(requestCode) + " with code: " + String.valueOf(resultCode));
+ if (requestCode == OpenDocumentRequest) {
+ Uri uri = intent.getData();
+ Log.v("Okular", "Opening document: " + uri.toString());
+ displayUri(uri);
+ }
+ }
}
diff --git a/mobile/app/CMakeLists.txt b/mobile/app/CMakeLists.txt
index f4f06ef88..3def6ef53 100644
--- a/mobile/app/CMakeLists.txt
+++ b/mobile/app/CMakeLists.txt
@@ -1,11 +1,13 @@
set(CMAKE_AUTORCC ON)
add_executable(okularkirigami main.cpp app.qrc)
target_link_libraries(okularkirigami Qt5::Widgets Qt5::Qml KF5::I18n)
if (ANDROID)
+ find_package(Qt5 COMPONENTS AndroidExtras)
target_sources(okularkirigami PRIVATE android.cpp)
+ target_link_libraries(okularkirigami Qt5::AndroidExtras)
endif()
install(TARGETS okularkirigami ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES package/metadata.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} RENAME org.kde.okular.kirigami.desktop)
install( FILES org.kde.okular.kirigami.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} )
diff --git a/mobile/app/android.cpp b/mobile/app/android.cpp
index 40afc3982..8a91e35ce 100644
--- a/mobile/app/android.cpp
+++ b/mobile/app/android.cpp
@@ -1,30 +1,60 @@
/*************************************************************************************
* Copyright (C) 2018 by Aleix Pol *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#include "android.h"
+#include
+#include
+#include
+#include
+
+static AndroidInstance* s_instance = nullptr;
+
+void AndroidInstance::openFile(const QString &title, const QStringList &mimes)
+{
+ s_instance = this;
+ QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); //activity is valid
+ Q_ASSERT ( activity.isValid() );
+
+ QAndroidJniEnvironment _env;
+ QAndroidJniObject::callStaticMethod("org/kde/something/OpenFileActivity",
+ "openFile",
+ "(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;)V",
+ activity.object(),
+ QAndroidJniObject::fromString(title).object(),
+ QAndroidJniObject::fromString(mimes.join(';')).object()
+ );
+ if (_env->ExceptionCheck()) {
+ _env->ExceptionClear();
+ qWarning() << "couldn't launch intent";
+ }
+}
void Java_org_kde_something_FileClass_openUri(JNIEnv *env,
jobject /*obj*/,
jstring uri)
{
jboolean isCopy = false;
const char* utf = env->GetStringUTFChars(uri, &isCopy);
- handler.openUri(QString::fromUtf8(utf));
+ const QString uriString = QString::fromUtf8(utf);
+ if (s_instance)
+ s_instance->openUri(QUrl(uriString));
+ else
+ handler.openUri(uriString);
env->ReleaseStringUTFChars(uri, utf);
}
diff --git a/mobile/app/android.h b/mobile/app/android.h
index 358c70f0e..7c456084b 100644
--- a/mobile/app/android.h
+++ b/mobile/app/android.h
@@ -1,45 +1,56 @@
/*************************************************************************************
* Copyright (C) 2018 by Aleix Pol *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#ifndef ANDROID_H
#define ANDROID_H
-#include
+#include
+#include
#include
class URIHandler {
public:
void openUri(const QString &uri) {
m_lastUrl = uri;
}
QString m_lastUrl;
};
static URIHandler handler;
+class AndroidInstance : public QObject
+{
+ Q_OBJECT
+public:
+ Q_SCRIPTABLE void openFile(const QString &title, const QStringList &mimes);
+
+Q_SIGNALS:
+ void openUri(const QUrl &uri);
+};
+
extern "C" {
JNIEXPORT void JNICALL
Java_org_kde_something_FileClass_openUri(JNIEnv *env,
jobject /*obj*/,
jstring uri);
}
#endif
diff --git a/mobile/app/main.cpp b/mobile/app/main.cpp
index 139c587b2..57fdf72ea 100644
--- a/mobile/app/main.cpp
+++ b/mobile/app/main.cpp
@@ -1,72 +1,74 @@
/*************************************************************************************
* Copyright (C) 2010 by Aleix Pol *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
*************************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef __ANDROID__
#include "android.h"
Q_DECL_EXPORT
#endif
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
app.setApplicationName(QStringLiteral("okularkirigami"));
QCommandLineParser parser;
parser.addVersionOption();
parser.addHelpOption();
//parser.setApplicationDescription(i18n("Okular mobile"));
parser.process(app);
QQmlApplicationEngine engine;
#ifdef __ANDROID__
+ qmlRegisterSingletonType("org.kde.okular.app", 2, 0, "AndroidInstance", [](QQmlEngine*, QJSEngine*) -> QObject* { return new AndroidInstance; });
const QString uri = handler.m_lastUrl;
#else
+ qmlRegisterSingletonType("org.kde.okular.app", 2, 0, "AndroidInstance", [](QQmlEngine*, QJSEngine*) -> QObject* { return new QObject; });
const QString uri = parser.positionalArguments().count() == 1
? QUrl::fromUserInput(parser.positionalArguments().constFirst(), {}, QUrl::AssumeLocalFile).toString()
: QString();
#endif
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
engine.rootContext()->setContextProperty(QStringLiteral("uri"), uri);
QVariantMap paths;
paths[QStringLiteral("desktop")] = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
paths[QStringLiteral("documents")] = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
paths[QStringLiteral("music")] = QStandardPaths::writableLocation(QStandardPaths::MusicLocation);
paths[QStringLiteral("movies")] = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation);
paths[QStringLiteral("pictures")] = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
paths[QStringLiteral("home")] = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
engine.rootContext()->setContextProperty(QStringLiteral("userPaths"), paths);
engine.setBaseUrl(QUrl("qrc:/package/contents/ui/"));
engine.load(QUrl("qrc:/package/contents/ui/main.qml"));
return app.exec();
}
diff --git a/mobile/app/package/contents/ui/main.qml b/mobile/app/package/contents/ui/main.qml
index 3091b573f..b25cb3d74 100644
--- a/mobile/app/package/contents/ui/main.qml
+++ b/mobile/app/package/contents/ui/main.qml
@@ -1,79 +1,96 @@
/*
* Copyright 2012 Marco Martin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 2.1
import QtQuick.Dialogs 1.3 as QQD
import org.kde.okular 2.0 as Okular
import org.kde.kirigami 2.0 as Kirigami
+import org.kde.okular.app 2.0
Kirigami.AbstractApplicationWindow {
id: fileBrowserRoot
visible: true
header: null
globalDrawer: Kirigami.GlobalDrawer {
title: i18n("Okular")
titleIcon: "okular"
QQD.FileDialog {
id: fileDialog
nameFilters: Okular.Okular.nameFilters
folder: "file://" + userPaths.documents
onAccepted: {
documentItem.url = fileDialog.fileUrl
}
}
actions: [
Kirigami.Action {
text: i18n("Open...")
icon.name: "document-open"
onTriggered: {
fileDialog.open()
}
+ },
+ Kirigami.Action {
+ text: i18n("Open Android...")
+ icon.name: "document-open"
+ readonly property var p0: Connections {
+ target: AndroidInstance
+ enabled: AndroidInstance.hasOwnProperty("openFile")
+ onOpenUri: {
+ console.log("open uri!", uri)
+ documentItem.url = uri
+ }
+ }
+ onTriggered: {
+// var mimetypes = Okular.Okular.mimeTypes.join(",")
+ AndroidInstance.openFile(i18n("Document to open..."), "*/*")
+ }
}
]
}
contextDrawer: OkularDrawer {}
title: documentItem.windowTitleForDocument
Okular.DocumentItem {
id: documentItem
onUrlChanged: { currentPage = 0 }
}
MainView {
id: pageArea
anchors.fill: parent
document: documentItem
}
//FIXME: this is due to global vars being binded after the parse is done, do the 2 steps parsing
Timer {
interval: 100
running: true
onTriggered: {
if (uri) {
documentItem.url = uri
} else {
globalDrawer.open();
}
}
}
}