Commit 2273767a authored by Camilo Higuita's avatar Camilo Higuita

work on android support, search view ready but missing features close #32,...

work on android support, search view ready but missing features close #32, using luv icons now on android as default fix #28, now working on android #14 and sharing on android ready #8
parent 7211ba17
android {
QT += androidextras webview
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/
}
RESOURCES += \
$$PWD/android.qrc
$$PWD/android.qrc \
$$PWD/../kirigami-icons.qrc
HEADERS += \
$$PWD/android.h
SOURCES += \
$$PWD/android.cpp
DISTFILES += \
$$PWD/src/MyService.java \
$$PWD/src/SendIntent.java
#include "android.h"
#include <QException>
#include <QColor>
#include <QDebug>
class InterfaceConnFailedException : public QException
{
public:
void raise() const { throw *this; }
InterfaceConnFailedException *clone() const { return new InterfaceConnFailedException(*this); }
};
Android::Android(QObject *parent) : QObject(parent)
{
}
void Android::statusbarColor(const QString &bg, const QString &fg)
{
QtAndroid::runOnAndroidThread([=]() {
QAndroidJniObject window = QtAndroid::androidActivity().callObjectMethod("getWindow", "()Landroid/view/Window;");
window.callMethod<void>("addFlags", "(I)V", 0x80000000);
window.callMethod<void>("clearFlags", "(I)V", 0x04000000);
window.callMethod<void>("setStatusBarColor", "(I)V", QColor(bg).rgba());
QAndroidJniObject decorView = window.callObjectMethod("getDecorView", "()Landroid/view/View;");
decorView.callMethod<void>("setSystemUiVisibility", "(I)V", 0x00002000);
});
}
void Android::shareDialog(const QString &url)
{
qDebug()<< "trying to share dialog";
QAndroidJniEnvironment _env;
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;"); //activity is valid
if (_env->ExceptionCheck()) {
_env->ExceptionClear();
throw InterfaceConnFailedException();
}
if ( activity.isValid() )
{
QAndroidJniObject::callStaticMethod<void>("com/example/android/tools/SendIntent",
"sendPic",
"(Landroid/app/Activity;Ljava/lang/String;)V",
activity.object<jobject>(),
QAndroidJniObject::fromString(url).object<jstring>());
if (_env->ExceptionCheck()) {
_env->ExceptionClear();
throw InterfaceConnFailedException();
}
}else
throw InterfaceConnFailedException();
}
#ifndef ANDROID_H
#define ANDROID_H
#include <QObject>
#include <QString>
#include <QAndroidActivityResultReceiver>
#include <QObject>
#include <QAndroidJniObject>
#include <QAndroidJniEnvironment>
#include <QtAndroid>
class Android : public QObject
{
Q_OBJECT
public:
explicit Android(QObject *parent = nullptr);
Q_INVOKABLE void statusbarColor(const QString &bg, const QString &fg);
Q_INVOKABLE void shareDialog(const QString &url);
signals:
public slots:
};
#endif // ANDROID_H
package com.kdab.training;
import org.qtproject.qt5.android.bindings.QtService;
import android.content.Intent;
import android.content.Context;
public class MyService extends QtService
{
public static void startMyService(Context ctx)
{
ctx.startService(new Intent(ctx, MyService.class));
}
}
package com.example.android.tools;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.net.Uri;
import java.io.File;
public class SendIntent
{
private static final int READ_REQUEST_CODE = 42;
public static void sendText(Activity context,String text)
{
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, text));
}
public static void sendUrl(Activity context, String text)
{
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, text));
}
public static void sendPic(Activity context, String url)
{
File file = new File(url);
System.out.println(file.exists());
Uri uri = Uri.fromFile(file);
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.setType("image/*");
context.startActivity(Intent.createChooser(sendIntent, "Share Pic"));
}
public static void openFile(Activity context, String url)
{
File file = new File(url);
Uri uri = Uri.fromFile(file);
String mime = context.getContentResolver().getType(uri);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(uri, mime);
context.startActivity(Intent.createChooser(intent, "Open folder"));
}
public static void fileChooser(Activity context)
{
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("audio/*");
context.startActivityForResult(intent, READ_REQUEST_CODE);
}
}
<RCC>
<qresource prefix="/">
<file alias="org/kde/kirigami/icons/application-menu.svg">3rdparty/breeze-icons/icons/actions/32/application-menu.svg</file>
<file alias="org/kde/kirigami/icons/document-decrypt.svg">3rdparty/breeze-icons/icons/actions/32/document-decrypt.svg</file>
<file alias="org/kde/kirigami/icons/folder-sync.svg">3rdparty/breeze-icons/icons/actions/32/folder-sync.svg</file>
<file alias="org/kde/kirigami/icons/go-next-symbolic.svg">3rdparty/breeze-icons/icons/actions/symbolic/go-next-symbolic.svg</file>
<file alias="org/kde/kirigami/icons/go-previous-symbolic.svg">3rdparty/breeze-icons/icons/actions/symbolic/go-previous-symbolic.svg</file>
<file alias="org/kde/kirigami/icons/go-up.svg">3rdparty/breeze-icons/icons/actions/22/go-up.svg</file>
<file alias="org/kde/kirigami/icons/handle-left.svg">3rdparty/breeze-icons/icons/actions/22/handle-left.svg</file>
<file alias="org/kde/kirigami/icons/overflow-menu.svg">3rdparty/breeze-icons/icons/actions/22/overflow-menu.svg</file>
<file alias="org/kde/kirigami/icons/handle-right.svg">3rdparty/breeze-icons/icons/actions/22/handle-right.svg</file>
<file alias="org/kde/kirigami/icons/view-list-icons.svg">3rdparty/breeze-icons/icons/actions/32/view-list-icons.svg</file>
<file alias="org/kde/kirigami/icons/applications-graphics.svg">3rdparty/breeze-icons/icons/categories/32/applications-graphics.svg</file>
<file alias="org/kde/kirigami/icons/media-record-symbolic.svg">3rdparty/breeze-icons/icons/actions/symbolic/media-record-symbolic.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/folder-new.svg</file>
<file>3rdparty/breeze-icons/icons/places/22/folder.svg</file>
<file alias="org/kde/kirigami/icons/image-multiple.svg">3rdparty/breeze-icons/icons/actions/22/image-multiple.svg</file>
<file alias="org/kde/kirigami/icons/image-frames.svg">3rdparty/breeze-icons/icons/actions/22/image-frames.svg</file>
<file alias="org/kde/kirigami/icons/image-folder-view.svg">3rdparty/breeze-icons/icons/actions/22/image-folder-view.svg</file>
<file alias="org/kde/kirigami/icons/object-rotate-right.svg">3rdparty/breeze-icons/icons/actions/22/object-rotate-right.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/process-stop.svg</file>
<file alias="org/kde/kirigami/icons/tag.svg">3rdparty/breeze-icons/icons/actions/22/tag.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/view-list-icons.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/view-list-details.svg</file>
<file alias="org/kde/kirigami/icons/view-fullscreen.svg">3rdparty/breeze-icons/icons/actions/22/view-fullscreen.svg</file>
<file alias="org/kde/kirigami/icons/view-preview.svg">3rdparty/breeze-icons/icons/actions/22/view-preview.svg</file>
<file alias="org/kde/kirigami/icons/view-refresh.svg">3rdparty/breeze-icons/icons/actions/22/view-refresh.svg</file>
<file alias="org/kde/kirigami/icons/window-close.svg">3rdparty/breeze-icons/icons/actions/22/window-close.svg</file>
<file alias="org/kde/kirigami/icons/list-add.svg">3rdparty/breeze-icons/icons/actions/22/list-add.svg</file>
<file alias="org/kde/kirigami/icons/list-remove.svg">3rdparty/breeze-icons/icons/actions/22/list-remove.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/image.svg</file>
<file alias="org/kde/kirigami/icons/go-previous.svg">3rdparty/breeze-icons/icons/actions/22/go-previous.svg</file>
<file alias="org/kde/kirigami/icons/go-next.svg">3rdparty/breeze-icons/icons/actions/22/go-next.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/go-last.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/go-home.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/go-first.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/go-down.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/edit-undo.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/edit-redo.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/draw-text.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/edit-clear.svg</file>
<file alias="org/kde/kirigami/icons/edit-find.svg">3rdparty/breeze-icons/icons/actions/22/edit-find.svg</file>
<file alias="org/kde/kirigami/icons/document-save-as.svg">3rdparty/breeze-icons/icons/actions/22/document-save-as.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/document-save.svg</file>
<file alias="org/kde/kirigami/icons/document-share.svg">3rdparty/breeze-icons/icons/actions/22/document-share.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/document-open.svg</file>
<file alias="org/kde/kirigami/icons/dialog-close.svg">3rdparty/breeze-icons/icons/actions/22/dialog-close.svg</file>
<file>3rdparty/breeze-icons/icons/actions/22/configure.svg</file>
<file alias="org/kde/kirigami/icons/love.svg">3rdparty/breeze-icons/icons/actions/22/love.svg</file>
<file alias="org/kde/kirigami/icons/application-menu.svg">3rdparty/breeze-icons/icons/actions/22/application-menu.svg</file>
<file alias="org/kde/kirigami/icons/folder.svg">3rdparty/breeze-icons/icons/places/32/folder.svg</file>
</qresource>
</RCC>
......@@ -29,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef Q_OS_ANDROID
#include "./3rdparty/kirigami/src/kirigamiplugin.h"
#include "android/android.h"
#endif
QStringList getFolderImages(const QString &path)
......@@ -85,14 +86,6 @@ int main(int argc, char *argv[])
if(!args.isEmpty())
pics = openFiles(args);
#ifdef Q_OS_ANDROID
KirigamiPlugin::getInstance().registerTypes();
//#else
// if(QQuickStyle::availableStyles().contains("nomad"))
// QQuickStyle::setStyle("nomad");
#endif
Pix pix;
QQmlApplicationEngine engine;
......@@ -107,6 +100,15 @@ int main(int argc, char *argv[])
auto context = engine.rootContext();
context->setContextProperty("pix", &pix);
#ifdef Q_OS_ANDROID
KirigamiPlugin::getInstance().registerTypes();
Android android;
context->setContextProperty("android", &android);
//#else
// if(QQuickStyle::availableStyles().contains("nomad"))
// QQuickStyle::setStyle("nomad");
#endif
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
......
......@@ -24,8 +24,6 @@ linux:unix:!android {
include(android/Android.pri)
include(3rdparty/kirigami/kirigami.pri)
RESOURCES += kirigami-icons.qrc
} else {
message("Unknown configuration")
}
......
......@@ -23,7 +23,8 @@ import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.0 as Kirigami
import QtQuick.Controls.Material 2.1
import QtQuick.Window 2.0
import "widgets"
import "widgets/views/Albums"
import "widgets/views/Folders"
......@@ -45,11 +46,18 @@ Kirigami.ApplicationWindow
{
id: root
visible: true
width: 400
height: 500
title: qsTr("Pixs")
title: qsTr("Pix")
width: Screen.width * (isMobile ? 1 : 0.5)
// height: Screen.height * (isMobile ? 1 : 0.4)
visibility: fullScreen ? ApplicationWindow.FullScreen : ApplicationWindow.Windowed
/* FOR MATERIAL*/
Material.theme: Material.Light
Material.accent: pixColor
Material.background: viewBackgroundColor
Material.primary: backgroundColor
Material.foreground: textColor
/*READONLY PROPS*/
readonly property bool isMobile : Kirigami.Settings.isMobile
......@@ -90,8 +98,13 @@ Kirigami.ApplicationWindow
property int iconSize : Kirigami.Units.iconSizes.medium
property int rowHeight : 32
// pageStack.defaultColumnWidth: 400
// pageStack.initialPage: [mainPage]
// pageStack.interactive: isMobile
// pageStack.separatorVisible: pageStack.wideMode
overlay.modal: Rectangle {
color: isMobile ? darkColor : "transparent"
color: isMobile ? altColor : "transparent"
opacity: 0.5
height: root.height
}
......@@ -125,47 +138,53 @@ Kirigami.ApplicationWindow
{
id: pixFooter
}
SwipeView
Page
{
id: swipeView
id: mainPage
anchors.fill: parent
interactive: isMobile
currentIndex: currentView
clip: true
SwipeView
{
id: swipeView
width: parent.width
height: parent.height
interactive: isMobile
currentIndex: currentView
onCurrentIndexChanged: currentView = currentIndex
onCurrentIndexChanged: currentView = currentIndex
PixViewer
{
id: pixViewer
}
PixViewer
{
id: pixViewer
}
GalleryView
{
id: galleryView
}
GalleryView
{
id: galleryView
}
FoldersView
{
id: foldersView
}
FoldersView
{
id: foldersView
}
AlbumsView
{
id: albumsView
}
AlbumsView
{
id: albumsView
}
TagsView
{
id: tagsView
}
TagsView
{
id: tagsView
}
SearchView
{
id: searchView
}
SearchView
{
id: searchView
}
}
}
PicMenu
......@@ -173,7 +192,7 @@ Kirigami.ApplicationWindow
id: picMenu
onFavClicked: VIEWER.fav(url)
onRemoveClicked: PIX.removePic(url)
onShareClicked: shareDialog.show(url)
onShareClicked: isMobile ? android.shareDialog(url) : shareDialog.show(url)
onAddClicked: albumsDialog.show(url)
onTagsClicked: tagsDialog.show(url)
onShowFolderClicked: pix.showInFolder(url)
......@@ -203,4 +222,6 @@ Kirigami.ApplicationWindow
onRefreshViews: PIX.refreshViews()
onViewPics: VIEWER.open(pics, 0)
}
Component.onCompleted: if(isMobile) android.statusbarColor(backgroundColor, textColor)
}
......@@ -7,9 +7,9 @@ PixPage
id: gridPage
/*props*/
property int picSize : 150
property int picSpacing: 50
property int picRadius : 4
property int itemSize : isMobile ? 80 : 150
property int itemSpacing: isMobile ? 10 : 50
property int itemRadius : 4
property alias grid: grid
property alias holder: holder
......@@ -42,8 +42,8 @@ PixPage
width: parent.width
height: parent.height
cellWidth: picSize + picSpacing
cellHeight: picSize + picSpacing
cellWidth: itemSize + itemSpacing
cellHeight: itemSize + itemSpacing
focus: true
......@@ -62,19 +62,19 @@ PixPage
highlightFollowsCurrentItem: true
highlight: Rectangle
{
width: picSize + picSpacing
height: picSize + picSpacing
width: itemSize + itemSpacing
height: itemSize + itemSpacing
color: highlightColor
radius: 4
}
onWidthChanged:
{
var amount = parseInt(grid.width/(picSize + picSpacing),10)
var leftSpace = parseInt(grid.width-(amount*(picSize + picSpacing)), 10)
var size = parseInt((picSize + picSpacing)+(parseInt(leftSpace/amount, 10)), 10)
var amount = parseInt(grid.width/(itemSize + itemSpacing),10)
var leftSpace = parseInt(grid.width-(amount*(itemSize + itemSpacing)), 10)
var size = parseInt((itemSize + itemSpacing)+(parseInt(leftSpace/amount, 10)), 10)
size = size > picSize + picSpacing ? size : picSize + picSpacing
size = size > itemSize + itemSpacing ? size : itemSize + itemSpacing
grid.cellWidth = size
// grid.cellHeight = size
......@@ -84,22 +84,24 @@ PixPage
{
id: delegate
picSize : gridPage.picSize
picRadius : 4
picSize : itemSize
picRadius : itemRadius
Connections
{
target: delegate
onClicked:
{
grid.currentIndex = index
if(isMobile)
openPic(index)
}
onDoubleClicked:
{
//picClicked(index)
console.log("pic clicked")
openPic(index)
if(!isMobile)
openPic(index)
}
onPressAndHold: picMenu.show(gridModel.get(index).url)
onRightClicked: picMenu.show(gridModel.get(index).url)
}
......
......@@ -32,7 +32,8 @@ ToolBar
ToolTip.visible: hovered
ToolTip.text: qsTr("Share")
onClicked: shareDialog.show(pixViewer.currentPic.url)
onClicked: isMobile ? android.shareDialog(url) :
shareDialog.show(pixViewer.currentPic.url)
}
}
......
......@@ -34,22 +34,22 @@ Item
onTagRemoved: tagRemovedClicked(index)
}
TextInput
{
Layout.fillHeight: true
Layout.fillWidth:true
Layout.maximumWidth: parent.width-(tagsList.count*64)
Layout.minimumWidth: 100
Layout.alignment: Qt.AlignLeft
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
selectByMouse: !isMobile
focus: true
wrapMode: TextEdit.Wrap
selectionColor: highlightColor
selectedTextColor: highlightedTextColor
onAccepted: tagsDialog.addTagsToPic(currentPic.url, text.split(","))
}
// TextInput
// {
// Layout.fillHeight: true
// Layout.fillWidth:true
// Layout.maximumWidth: parent.width-(tagsList.count*64)
// Layout.minimumWidth: 100
// Layout.alignment: Qt.AlignLeft
// horizontalAlignment: Text.AlignHCenter
// verticalAlignment: Text.AlignVCenter
// selectByMouse: !isMobile
// focus: true
// wrapMode: TextEdit.Wrap
// selectionColor: highlightColor
// selectedTextColor: highlightedTextColor
// onAccepted: tagsDialog.addTagsToPic(currentPic.url, text.split(","))
// }
}
}
......@@ -21,34 +21,49 @@ ItemDelegate
{
source: "qrc:/img/assets/tag.svg"
sourceSize.width: tagWidth
sourceSize.height: tagHeight
width: tagWidth
height: tagHeight
}
RowLayout
{
anchors.fill: parent
Label
Item
{
id: tagLabel
text: tag
height: parent.height
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: contentMargins*2
verticalAlignment: Qt.AlignVCenter
horizontalAlignment: Qt.AlignHCenter
elide: Qt.ElideRight
font.pointSize: fontSizes.small
Layout.fillWidth: true
Label
{
id: tagLabel
text: tag
height: parent.height
width: parent.width
anchors.centerIn: parent
verticalAlignment: Qt.AlignVCenter
horizontalAlignment: Qt.AlignHCenter
elide: Qt.ElideRight
font.pointSize: fontSizes.small
}
}
PixButton
Item
{
iconName: "window-close"
iconSize: 16
Layout.fillHeight: true
onClicked: removeTag(index)
width: 16
Layout.maximumWidth: 16
Layout.margins: 5
PixButton
{
anchors.centerIn: parent
iconName: "window-close"
iconSize: 16
onClicked: removeTag(index)
}
}
}
}
......@@ -14,6 +14,8 @@ ListView
{
height: parent.height
width: parent.width
verticalAlignment: Qt.AlignVCenter
horizontalAlignment: Qt.AlignHCenter
text: qsTr("Add tags...")
opacity: 0.7
visible: count === 0
......
......@@ -28,8 +28,8 @@ import "../../../view_models"
PixGrid
{
picSize: Math.sqrt(root.width*root.height)*0.25
picRadius: 2
// picSize: Math.sqrt(root.width*root.height)*0.25
// picRadius: 2
function populate(url)
{
......
......@@ -11,8 +11,8 @@ PixGrid
headerbarExit: false
visible: true
picSize: Math.sqrt(root.width*root.height)*0.25
picRadius: 2
// picSize: Math.sqrt(root.width*root.height)*0.25
// picRadius: 2
function populate()
{
......
......@@ -21,7 +21,7 @@ Item
anchors.centerIn: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
height: parent.height
width: parent.width
source: "file://"+currentPic.url
fillMode: Image.PreserveAspectFit
cache: true
......@@ -60,22 +60,22 @@ Item
function zoomIn()
{
pic.height = pic.height + 50
pic.width = pic.width + 50
}
function zoomOut()
{
pic.height = pic.height - 50
pic.width = pic.width - 50
}
function fit()
{
pic.height = pic.sourceSize.height
pic.width = pic.sourceSize.width
}
function fill()
{
pic.height = parent.height
pic.width = parent.width
}
function rotateLeft()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment