Commit 99f9773c authored by Marco Martin's avatar Marco Martin
Browse files

a very simple active app

parent fd84427c
macro_optional_find_package(ActiveApp)
macro_log_feature(ACTIVEAPP_FOUND "ActiveApp" "Support for developing applications for Plasma Active" FALSE "" "")
if (ACTIVEAPP_FOUND)
add_subdirectory( app )
endif (ACTIVEAPP_FOUND)
add_subdirectory( components )
include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} )
add_subdirectory(src)
# QML-only thing
install(DIRECTORY package/ DESTINATION ${DATA_INSTALL_DIR}/plasma/packages/org.kde.active.documentviewer)
install(FILES active-documentviewer.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
[Desktop Entry]
Name=Reader
GenericName=Document viewer
Comment=Viewer for various types of documents
Exec=active-documentviewer -graphicssystem raster %u
Terminal=false
Icon=okular
Type=Application
Categories=Qt;KDE;Graphics;Office;Viewer;
InitialPreference=7
NoDisplay=true
MimeType=application/vnd.kde.okular-archive;application/pdf;application/x-gzpdf;application/x-bzpdf;application/x-wwf;application/epub+zip;
\ No newline at end of file
/*
* Copyright 2011 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library 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 1.1
import org.kde.plasma.components 0.1 as PlasmaComponents
import org.kde.plasma.extras 0.1 as PlasmaExtras
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.mobilecomponents 0.1 as MobileComponents
import org.kde.qtextracomponents 0.1
import org.kde.okular 0.1 as Okular
PlasmaComponents.Page {
id: resourceBrowser
state: "toolsClosed"
property string currentUdi
anchors.fill: parent
MouseEventListener {
id: pageArea
anchors.fill: parent
//enabled: !delegate.interactive
property Item delegate: delegate1
property Item oldDelegate: delegate2
property bool incrementing: delegate.delta > 0
Connections {
target: pageArea.delegate
onDeltaChanged: {
pageArea.oldDelegate.delta = pageArea.delegate.delta
if (pageArea.delegate.delta > 0) {
pageArea.oldDelegate.visible = true
pageArea.oldDelegate.pageNumber = pageArea.delegate.pageNumber + 1
pageArea.oldDelegate.visible = !(pageArea.delegate.pageNumber == documentItem.pageCount-1)
} else if (pageArea.delegate.delta < 0) {
pageArea.oldDelegate.pageNumber = pageArea.delegate.pageNumber - 1
pageArea.oldDelegate.visible = pageArea.delegate.pageNumber != 0
}
}
}
property int startX
property int starty
onPressed: {
startX = mouse.screenX
startY = mouse.screenY
}
onReleased: {
if (Math.abs(mouse.screenX - startX) < 20 &&
Math.abs(mouse.screenY - startY) < 20) {
if (resourceBrowser.state == "toolsOpen") {
resourceBrowser.state = "toolsClosed"
} else {
resourceBrowser.state = "toolsOpen"
}
} else if (oldDelegate.visible && delegate.delta != 0 && delegate.doSwitch) {
oldDelegate = delegate
delegate = (delegate == delegate1) ? delegate2 : delegate1
switchAnimation.running = true
}
}
FullScreenDelegate {
id: delegate2
width: parent.width
height: parent.height
}
FullScreenDelegate {
id: delegate1
width: parent.width
height: parent.height
}
SequentialAnimation {
id: switchAnimation
NumberAnimation {
target: pageArea.oldDelegate
properties: "x"
to: pageArea.incrementing ? -pageArea.oldDelegate.width : pageArea.oldDelegate.width
easing.type: Easing.InQuad
duration: 250
}
ScriptAction {
script: {
pageArea.oldDelegate.z = 0
pageArea.delegate.z = 10
pageArea.oldDelegate.x = 0
pageArea.delegate.x = 0
}
}
ScriptAction {
script: delegate1.delta = delegate2.delta = 0
}
}
}
Image {
id: browserFrame
z: 100
source: "image://appbackgrounds/standard"
fillMode: Image.Tile
anchors {
top: parent.top
bottom: parent.bottom
}
width: parent.width - handleGraphics.width
x: parent.width
property bool open: false
PlasmaExtras.ScrollArea {
anchors.fill: parent
GridView {
id: resultsGrid
anchors.fill: parent
model: documentItem.pageCount
cellWidth: theme.defaultFont.mSize.width * 14
cellHeight: theme.defaultFont.mSize.height * 12
delegate: Item {
width: resultsGrid.cellWidth
height: resultsGrid.cellHeight
PlasmaCore.FrameSvgItem {
anchors.centerIn: parent
imagePath: "widgets/media-delegate"
prefix: "picture"
width: thumbnail.width + margins.left + margins.right
//FIXME: why bindings with thumbnail.height doesn't work?
height: thumbnail.height + margins.top + margins.bottom
Okular.ThumbnailItem {
id: thumbnail
x: parent.margins.left
y: parent.margins.top
document: documentItem
pageNumber: modelData
width: theme.defaultFont.mSize.width * 10
height: Math.round(width / (implicitWidth/implicitHeight))
Rectangle {
width: childrenRect.width
height: childrenRect.height
color: theme.backgroundColor
radius: width
smooth: true
anchors {
bottom: parent.bottom
right: parent.right
}
PlasmaComponents.Label {
text: modelData + 1
}
}
}
MouseArea {
anchors.fill: parent
onClicked: {
resultsGrid.currentIndex = index
pageArea.delegate.pageNumber = index
browserFrame.open = false
browserFrameSlideAnimation.to = resourceBrowser.width
browserFrameSlideAnimation.running = true
}
}
}
}
}
}
Image {
source: "image://appbackgrounds/shadow-left"
fillMode: Image.TileVertically
anchors {
right: parent.left
top: parent.top
bottom: parent.bottom
rightMargin: -1
}
}
PlasmaCore.FrameSvgItem {
id: handleGraphics
imagePath: "dialogs/background"
enabledBorders: "LeftBorder|TopBorder|BottomBorder"
width: handleIcon.width + margins.left + margins.right + 4
height: handleIcon.width * 1.6 + margins.top + margins.bottom + 4
anchors {
right: parent.left
verticalCenter: parent.verticalCenter
}
PlasmaCore.SvgItem {
id: handleIcon
svg: PlasmaCore.Svg {imagePath: "toolbar-icons/show"}
elementId: "show-menu"
x: parent.margins.left
y: parent.margins.top
width: theme.smallMediumIconSize
height: width
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors {
top: parent.top
bottom: parent.bottom
left: handleGraphics.left
right: handleGraphics.right
}
drag {
target: browserFrame
axis: Drag.XAxis
//-50, an overshoot to make it look smooter
minimumX: handleGraphics.width
maximumX: resourceBrowser.width
}
property int startX
property bool toggle: true
onPressed: {
startX = browserFrame.x
toggle = true
}
onPositionChanged: {
if (Math.abs(browserFrame.x - startX) > 20) {
toggle = false
}
}
onReleased: {
if (toggle) {
browserFrame.open = !browserFrame.open
} else {
browserFrame.open = (browserFrame.x < resourceBrowser.width/2)
}
browserFrameSlideAnimation.to = browserFrame.open ? handleGraphics.width : resourceBrowser.width
browserFrameSlideAnimation.running = true
}
}
//FIXME: use a state machine
SequentialAnimation {
id: browserFrameSlideAnimation
property alias to: actualSlideAnimation.to
NumberAnimation {
id: actualSlideAnimation
target: browserFrame
properties: "x"
duration: 250
easing.type: Easing.InOutQuad
}
}
}
}
/*
* Copyright 2011 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library 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 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.extras 0.1 as PlasmaExtras
import org.kde.plasma.mobilecomponents 0.1 as MobileComponents
import org.kde.qtextracomponents 0.1
import org.kde.okular 0.1 as Okular
Item {
id: root
//+1: switch to next image on mouse release
//-1: switch to previous image on mouse release
//0: do nothing
property int delta
//if true when released will switch the delegate
property bool doSwitch: false
property alias document: mainPage.document
property alias pageNumber: mainPage.pageNumber
property string label: model["label"]
Rectangle {
x: -mainFlickable.contentX + mainPage.x
y: 0
anchors {
top: parent.top
bottom: parent.bottom
}
width: mainPage.width
color: "white"
Image {
source: "image://appbackgrounds/shadow-left"
fillMode: Image.TileVertically
opacity: 0.5
anchors {
right: parent.left
top: parent.top
bottom: parent.bottom
rightMargin: -1
}
}
Image {
source: "image://appbackgrounds/shadow-right"
fillMode: Image.TileVertically
opacity: 0.5
anchors {
left: parent.right
top: parent.top
bottom: parent.bottom
leftMargin: -1
}
}
}
Flickable {
id: mainFlickable
property real ratio : width / height
anchors.fill: parent
width: parent.width
height: parent.height
contentWidth: imageMargin.width
contentHeight: imageMargin.height
onContentXChanged: {
if (atXBeginning && contentX < 0) {
root.delta = -1
root.doSwitch = (contentX < -mainFlickable.width/3)
} else if (atXEnd) {
root.delta = +1
root.doSwitch = (contentX + mainFlickable.width - contentWidth > mainFlickable.width/3)
} else {
root.delta = 0
root.doSwitch = false
}
}
PinchArea {
id: imageMargin
width: Math.max(mainFlickable.width+1, mainPage.width)
height: Math.max(mainFlickable.height, mainPage.height)
property real startWidth
property real startHeight
property real startY
property real startX
onPinchStarted: {
startWidth = mainPage.width
startHeight = mainPage.height
startY = pinch.center.y
startX = pinch.center.x
}
onPinchUpdated: {
var deltaWidth = mainPage.width < imageMargin.width ? ((startWidth * pinch.scale) - mainPage.width) : 0
var deltaHeight = mainPage.height < imageMargin.height ? ((startHeight * pinch.scale) - mainPage.height) : 0
mainPage.width = startWidth * pinch.scale
mainPage.height = startHeight * pinch.scale
mainFlickable.contentY += pinch.previousCenter.y - pinch.center.y + startY * (pinch.scale - pinch.previousScale) - deltaHeight
mainFlickable.contentX += pinch.previousCenter.x - pinch.center.x + startX * (pinch.scale - pinch.previousScale) - deltaWidth
}
Okular.PageItem {
id: mainPage
document: documentItem
anchors.centerIn: parent
property real ratio: implicitWidth / implicitHeight
width: implicitWidth
height: implicitHeight
}
}
}
}
/*
* Copyright 2011 Marco Martin <mart@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library 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 1.1
import org.kde.okular 0.1 as Okular
import org.kde.plasma.extras 0.1 as PlasmaExtras
import org.kde.plasma.components 0.1 as PlasmaComponents
Image {
id: fileBrowserRoot
objectName: "fileBrowserRoot"
source: "image://appbackgrounds/contextarea"
fillMode: Image.Tile
width: 360
height: 360
PlasmaExtras.ResourceInstance {
id: resourceInstance
uri: documentItem.path
}
Okular.DocumentItem {
id: documentItem
}
PlasmaComponents.PageStack {
id: mainStack
clip: false
toolBar: toolBar
//initialPage: Qt.createComponent("Browser.qml")
anchors.fill: parent
}
Timer {
interval: 500
running: true
onTriggered: mainStack.push(Qt.createComponent("Browser.qml"))
}
//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 (application.startupArguments.length > 0) {
documentItem.path = application.startupArguments[0]
}
}
}
}
[Desktop Entry]
Name=Document viewer
Encoding=UTF-8
Type=Service
Icon=system-file-manager
X-KDE-ParentApp=
X-KDE-PluginInfo-Author=Marco Martin
X-KDE-PluginInfo-Email=mart@kde.org
X-KDE-PluginInfo-Name=org.kde.active.documentviewer
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://kde.org
X-KDE-PluginInfo-Category=Office
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-Plasma-MainScript=ui/main.qml
include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES})
set(active-documentviewer_SRCS
main.cpp
documentviewer.cpp
)
kde4_add_kdeinit_executable(active-documentviewer ${active-documentviewer_SRCS})
find_package(ActiveApp REQUIRED)
target_link_libraries(kdeinit_active-documentviewer
${QT_QTDECLARATIVE_LIBRARY}
${QT_QTOPENGL_LIBRARY}
${KDE4_KDEUI_LIBS}
${KDE4_PLASMA_LIBS}
${ACTIVEAPP_LIBRARIES}
)
install(TARGETS active-documentviewer ${INSTALL_TARGETS_DEFAULT_ARGS} )
install(TARGETS kdeinit_active-documentviewer ${INSTALL_TARGETS_DEFAULT_ARGS} )
/***************************************************************************
* *
* Copyright 2011 Sebastian Kügler <sebas@kde.org> *
* Copyright 2012 Marco Martin <mart@kde.org> *
* *
* 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 "documentviewer.h"
#include "kdeclarativeview.h"
DocumentViewer::DocumentViewer()
: KDeclarativeMainWindow()
{
declarativeView()->setPackageName("org.kde.active.documentviewer");
}
DocumentViewer::~DocumentViewer()
{
}
#include "documentviewer.moc"
/***************************************************************************
* *
* Copyright 2011 Sebastian Kügler <sebas@kde.org> *
* Copyright 2012 Marco Martin <mart@kde.org> *
* *
* 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., *