ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #04848
[Merge] lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-update-emptystate-string-sdcard into lp:ubuntu-docviewer-app
Stefano Verzegnassi has proposed merging lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-update-emptystate-string-sdcard into lp:ubuntu-docviewer-app.
Commit message:
Updated documents list empty state
Requested reviews:
Ubuntu Document Viewer Developers (ubuntu-docviewer-dev)
For more details, see:
https://code.launchpad.net/~verzegnassi-stefano/ubuntu-docviewer-app/reboot-update-emptystate-string-sdcard/+merge/270534
Updated documents list empty state
--
Your team Ubuntu Document Viewer Developers is requested to review the proposed merge of lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-update-emptystate-string-sdcard into lp:ubuntu-docviewer-app.
=== modified file 'README'
--- README 2015-01-30 19:20:39 +0000
+++ README 2015-09-09 13:32:03 +0000
@@ -8,13 +8,32 @@
=========
Install poppler's development files:
-sudo apt-get install libpoppler-qt5-dev
+ sudo apt install libpoppler-qt5-dev
Install Qt5 private development files:
-sudo apt-get install qtdeclarative5-private-dev qtbase5-private-dev
-
-If you want to compile an arm click package, you need to install that package to the arm compilation environment. For example when using QtCreator for Ubuntu Touch, open Options -> Ubuntu -> Maintain, and then enter:
-
-apt-get install libpoppler-qt5-dev:armhf qtdeclarative5-private-dev:armhf qtbase5-private-dev:armhf
-
-
+ sudo apt install qtdeclarative5-private-dev qtbase5-private-dev
+
+If you want to compile an arm click package, you need to install that package
+to the arm compilation environment. For example when using QtCreator for
+Ubuntu Touch, open Options -> Ubuntu -> Maintain, and then enter:
+
+ apt install libpoppler-qt5-dev:armhf qtdeclarative5-private-dev:armhf qtbase5-private-dev:armhf
+
+LibreOffice viewer support
+==========================
+
+If you want to enable the LibreOffice viewer feature, you'll need to have a
+LibreOffice 5.0 installation on your development environment. At the time of
+writing, LibreOffice 5.0 is not yet in the archive, but you can easily install
+it from the pre-releases PPA. To do so, type the following commands on a
+terminal:
+
+ sudo apt-get purge libreoffice-core
+ sudo add-apt-repository ppa:libreoffice/libreoffice-prereleases
+ sudo apt-get update
+ sudo apt-get install libreoffice
+
+Then to compile the LibreOffice viewer plugin you'll simply need to install
+the LibreOffice Kit development files:
+
+ sudo apt install libreofficekit-dev
=== modified file 'po/com.ubuntu.docviewer.pot'
--- po/com.ubuntu.docviewer.pot 2015-07-24 09:12:38 +0000
+++ po/com.ubuntu.docviewer.pot 2015-09-09 13:32:03 +0000
@@ -8,7 +8,11 @@
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
+<<<<<<< TREE
"POT-Creation-Date: 2015-07-24 11:10+0200\n"
+=======
+"POT-Creation-Date: 2015-08-30 18:02+0200\n"
+>>>>>>> MERGE-SOURCE
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -33,11 +37,16 @@
msgstr ""
#: ../src/app/docviewer-application.cpp:171
+<<<<<<< TREE
#: /home/stefano/Progetti/docviewer/build-ubuntu-docviewer-app-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
+=======
+#: /home/stefano/Progetti/docviewer/Libreoffice/build-reboot-update-emptystate-string-sdcard-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:1
+>>>>>>> MERGE-SOURCE
msgid "Document Viewer"
msgstr ""
#: ../src/app/qml/common/DetailsPage.qml:27
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:112
#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:97
#: ../src/app/qml/textView/TextViewDefaultHeader.qml:83
msgid "Details"
@@ -76,6 +85,7 @@
#: ../src/app/qml/common/RejectedImportDialog.qml:38
#: ../src/app/qml/documentPage/DocumentPageSelectionModeHeader.qml:32
#: ../src/app/qml/documentPage/SortSettingsDialog.qml:53
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:76
#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:61
#: ../src/app/qml/textView/TextViewDefaultHeader.qml:61
msgid "Close"
@@ -167,6 +177,7 @@
#: ../src/app/qml/documentPage/DeleteFileDialog.qml:44
#: ../src/app/qml/documentPage/DocumentPagePickModeHeader.qml:27
+#: ../src/app/qml/loView/LOViewGotoDialog.qml:52
#: ../src/app/qml/pdfView/PdfViewGotoDialog.qml:52
msgid "Cancel"
msgstr ""
@@ -181,10 +192,10 @@
msgid "No document found"
msgstr ""
-#: ../src/app/qml/documentPage/DocumentEmptyState.qml:28
+#: ../src/app/qml/documentPage/DocumentEmptyState.qml:25
msgid ""
"Connect your device to any computer and simply drag files to the Documents "
-"folder."
+"folder or insert removable media with documents."
msgstr ""
#. TRANSLATORS: %1 refers to a time formatted as Locale.ShortFormat (e.g. hh:mm). It depends on system settings.
@@ -265,6 +276,7 @@
msgstr ""
#: ../src/app/qml/documentPage/DocumentPageSearchHeader.qml:27
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:76
#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:61
#: ../src/app/qml/textView/TextViewDefaultHeader.qml:61
msgid "Back"
@@ -311,50 +323,80 @@
msgid "Reverse order"
msgstr ""
-#. TRANSLATORS: "Contents" refers to the "Table of Contents" of a PDF document.
-#: ../src/app/qml/pdfView/PdfContentsPage.qml:32
-#: ../src/app/qml/pdfView/PdfView.qml:37
-msgid "Contents"
-msgstr ""
-
-#: ../src/app/qml/pdfView/PdfContentsPage.qml:38
-msgid "Hide table of contents"
-msgstr ""
-
#. TRANSLATORS: the first argument (%1) refers to the page currently shown on the screen,
#. while the second one (%2) refers to the total pages count.
-#: ../src/app/qml/pdfView/PdfView.qml:34
+#: ../src/app/qml/loView/LOView.qml:34 ../src/app/qml/pdfView/PdfView.qml:34
#, qt-format
msgid "Page %1 of %2"
msgstr ""
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:57
+msgid "LibreOffice text document"
+msgstr ""
+
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:59
+msgid "LibreOffice spread sheet"
+msgstr ""
+
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:61
+msgid "LibreOffice presentation"
+msgstr ""
+
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:63
+msgid "LibreOffice Draw document"
+msgstr ""
+
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:65
+msgid "Unknown LibreOffice document"
+msgstr ""
+
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:67
+msgid "Unknown type document"
+msgstr ""
+
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:100
#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:85
msgid "Go to page..."
msgstr ""
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:106
#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:91
#: ../src/app/qml/textView/TextViewDefaultHeader.qml:77
msgid "Disable night mode"
msgstr ""
+#: ../src/app/qml/loView/LOViewDefaultHeader.qml:106
#: ../src/app/qml/pdfView/PdfViewDefaultHeader.qml:91
#: ../src/app/qml/textView/TextViewDefaultHeader.qml:77
msgid "Enable night mode"
msgstr ""
+#: ../src/app/qml/loView/LOViewGotoDialog.qml:25
#: ../src/app/qml/pdfView/PdfViewGotoDialog.qml:25
msgid "Go to page"
msgstr ""
+#: ../src/app/qml/loView/LOViewGotoDialog.qml:26
#: ../src/app/qml/pdfView/PdfViewGotoDialog.qml:26
#, qt-format
msgid "Choose a page between 1 and %1"
msgstr ""
+#: ../src/app/qml/loView/LOViewGotoDialog.qml:44
#: ../src/app/qml/pdfView/PdfViewGotoDialog.qml:44
msgid "GO!"
msgstr ""
+#. TRANSLATORS: "Contents" refers to the "Table of Contents" of a PDF document.
+#: ../src/app/qml/pdfView/PdfContentsPage.qml:32
+#: ../src/app/qml/pdfView/PdfView.qml:37
+msgid "Contents"
+msgstr ""
+
+#: ../src/app/qml/pdfView/PdfContentsPage.qml:38
+msgid "Hide table of contents"
+msgstr ""
+
#: ../src/app/qml/textView/TextView.qml:42
msgid "Loading..."
msgstr ""
@@ -369,6 +411,10 @@
msgid "Open"
msgstr ""
+<<<<<<< TREE
#: /home/stefano/Progetti/docviewer/build-ubuntu-docviewer-app-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2
+=======
+#: /home/stefano/Progetti/docviewer/Libreoffice/build-reboot-update-emptystate-string-sdcard-Desktop-Default/po/com.ubuntu.docviewer.desktop.in.in.h:2
+>>>>>>> MERGE-SOURCE
msgid "documents;viewer;pdf;reader;"
msgstr ""
=== modified file 'src/app/content-communicator.cpp'
--- src/app/content-communicator.cpp 2015-04-27 15:58:12 +0000
+++ src/app/content-communicator.cpp 2015-09-09 13:32:03 +0000
@@ -241,11 +241,17 @@
*/
bool ContentCommunicator::isSupportedMimetype(QString mimetype)
{
- if (mimetype.startsWith("text/"))
- return true;
-
- if (mimetype == "application/pdf")
- return true;
-
- return false;
+ // TODO: We should use a common shared code for DocumentViewer.DocumentsModel
+ // QML component and ContentHub. That will happen when we'll switch to
+ // QML ContentHub APIs.
+ return (mimetype.startsWith("text/")
+ || mimetype == "application/pdf"
+ || mimetype.startsWith("application/vnd.oasis.opendocument")
+ || mimetype == "application/msword")
+ || mimetype == "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+ || mimetype == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+ || mimetype == "application/vnd.openxmlformats-officedocument.presentationml.presentation"
+ || mimetype == "application/msword"
+ || mimetype == "application/vnd.ms-excel"
+ || mimetype == "application/vnd.ms-powerpoint";
}
=== modified file 'src/app/qml/common/loadComponent.js'
--- src/app/qml/common/loadComponent.js 2015-02-13 15:30:01 +0000
+++ src/app/qml/common/loadComponent.js 2015-09-09 13:32:03 +0000
@@ -27,6 +27,16 @@
if (mimetype === "application/pdf")
qmlToLoad = Qt.resolvedUrl("../pdfView/PdfView.qml");
+ // Check if LibreOffice document
+ if (mimetype.indexOf("application/vnd.oasis.opendocument") > -1
+ || mimetype === "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+ || mimetype === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+ || mimetype === "application/vnd.openxmlformats-officedocument.presentationml.presentation"
+ || mimetype === "application/msword"
+ || mimetype === "application/vnd.ms-excel"
+ || mimetype === "application/vnd.ms-powerpoint")
+ qmlToLoad = Qt.resolvedUrl("../loView/LOView.qml")
+
if (qmlToLoad != "") {
pageStack.push(qmlToLoad);
} else {
=== modified file 'src/app/qml/documentPage/DocumentEmptyState.qml'
--- src/app/qml/documentPage/DocumentEmptyState.qml 2015-02-26 20:16:32 +0000
+++ src/app/qml/documentPage/DocumentEmptyState.qml 2015-09-09 13:32:03 +0000
@@ -22,10 +22,7 @@
EmptyState {
title: i18n.tr("No document found")
-
- // TODO: Add "or insert removable media with documents." to subTitle when
- // the support for SD card will be implemented.
- subTitle: i18n.tr("Connect your device to any computer and simply drag files to the Documents folder.")
+ subTitle: i18n.tr("Connect your device to any computer and simply drag files to the Documents folder or insert removable media with documents.")
iconName: "edit-copy"
anchors.centerIn: parent
=== modified file 'src/app/qml/documentPage/DocumentGridDelegate.qml'
--- src/app/qml/documentPage/DocumentGridDelegate.qml 2015-07-14 13:43:17 +0000
+++ src/app/qml/documentPage/DocumentGridDelegate.qml 2015-09-09 13:32:03 +0000
@@ -46,6 +46,7 @@
return Qt.formatDateTime(date, i18n.tr("dd-MM-yyyy hh:mm"))
}
+<<<<<<< TREE
title: model.name
text: formattedDateTime()
subText: Utils.printSize(i18n, model.size)
@@ -110,4 +111,171 @@
}*/
DocumentDelegateActions { id: documentDelegateActions }
+=======
+ Rectangle {
+ anchors { fill: parent; margins: units.gu(0.5) }
+
+ color: Qt.lighter(UbuntuColors.lightGrey)
+ clip: true
+
+ Loader {
+ id: selectionIcon
+
+ anchors {
+ right: parent.right
+ top: parent.top
+ }
+
+ z: 10
+
+ width: (status === Loader.Ready) ? item.implicitWidth : 0
+ visible: (status === Loader.Ready) && (item.width === item.implicitWidth)
+ Behavior on opacity {
+ NumberAnimation {
+ duration: UbuntuAnimation.SnapDuration
+ }
+ }
+ }
+
+ Icon {
+ id: extStorageIcon
+
+ width: units.gu(4)
+ height: units.gu(4)
+ anchors {
+ left: parent.left
+ top: parent.top
+ margins: units.gu(0.5)
+ }
+
+ visible: model.isFromExternalStorage
+ source: Qt.resolvedUrl("../../graphics/sd-card-symbolic.png")
+ }
+
+ // Document mimetype icon
+ Icon {
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: - infoColumn.height * 0.3
+
+ width: units.gu(8); height: width
+
+ // At the moment the suru icon theme doesn't have much icons.
+ // Just some note for the future:
+ // TODO: Add icons for Office/ODF documents
+ // TODO: Whenever there will be icons for source code files, add them.
+ name: {
+ if (model.mimetype.substring(0, 5) === "text/")
+ return "text-x-generic-symbolic"
+
+ if (model.mimetype.substring(0, 5) === "image")
+ return "image-x-generic-symbolic"
+
+ if (model.mimetype === "application/pdf")
+ return "application-pdf-symbolic"
+
+ if (model.mimetype === "application/vnd.oasis.opendocument.text"
+ || model.mimetype === "application/msword"
+ || model.mimetype === "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
+ return "x-office-document-symbolic"
+
+ if (model.mimetype === "application/vnd.oasis.opendocument.spreadsheet"
+ || model.mimetype === "application/vnd.ms-excel"
+ || model.mimetype === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+ return "x-office-spreadsheet-symbolic"
+
+ if (model.mimetype === "application/vnd.oasis.opendocument.presentation"
+ || model.mimetype === "application/vnd.ms-powerpoint"
+ || model.mimetype === "application/vnd.openxmlformats-officedocument.presentationml.presentation")
+ return "x-office-presentation-symbolic"
+
+ return "package-x-generic-symbolic"
+ }
+ }
+
+ // Cover
+ /* Image {
+ anchors.fill: parent
+
+ source: {
+ if (model.cover !== "" && typeof model.cover !== "undefined")
+ return model.cover
+
+ if (model.mimetype.toString().indexOf("image") !== -1)
+ return model.path
+
+ return ""
+ }
+
+ sourceSize.width: width
+ fillMode: Image.PreserveAspectCrop
+ }*/
+
+ // Document info overlay
+ Rectangle {
+ id: overlay
+
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+
+ height: infoColumn.height + units.gu(1)
+
+ color: UbuntuColors.darkGrey
+ opacity: 0.75
+ layer.enabled: true
+
+ // Document info
+ Column {
+ id: infoColumn
+ anchors {
+ left: parent.left;
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ margins: units.gu(0.5)
+ }
+
+ Label {
+ text: model.name
+ color: "white"
+
+ elide: Text.ElideRight
+ font.weight: Font.DemiBold
+ fontSize: "small"
+
+ anchors { left: parent.left; right: parent.right }
+ }
+
+ Label {
+ text: formattedDateTime()
+ color: "white"
+ fontSize: "small"
+
+ anchors { left: parent.left; right: parent.right }
+ }
+
+ Label {
+ text: Utils.printSize(i18n, model.size)
+ color: "white"
+ fontSize: "small"
+
+ anchors { left: parent.left; right: parent.right }
+ }
+ } // Document info end
+ }
+
+ states: [
+ State {
+ name: "select"
+ when: selectionMode || selected
+ PropertyChanges {
+ target: selectionIcon
+ source: Qt.resolvedUrl("../upstreamComponents/ListItemWithActionsCheckBox.qml")
+ anchors.margins: units.gu(1)
+ }
+ }
+ ]
+ }
+>>>>>>> MERGE-SOURCE
}
=== modified file 'src/app/qml/documentPage/DocumentListDelegate.qml'
--- src/app/qml/documentPage/DocumentListDelegate.qml 2015-07-24 09:12:38 +0000
+++ src/app/qml/documentPage/DocumentListDelegate.qml 2015-09-09 13:32:03 +0000
@@ -92,6 +92,21 @@
if (model.mimetype === "application/pdf")
return "application-pdf-symbolic"
+ if (model.mimetype === "application/vnd.oasis.opendocument.text"
+ || model.mimetype === "application/msword"
+ || model.mimetype === "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
+ return "x-office-document-symbolic"
+
+ if (model.mimetype === "application/vnd.oasis.opendocument.spreadsheet"
+ || model.mimetype === "application/vnd.ms-excel"
+ || model.mimetype === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+ return "x-office-spreadsheet-symbolic"
+
+ if (model.mimetype === "application/vnd.oasis.opendocument.presentation"
+ || model.mimetype === "application/vnd.ms-powerpoint"
+ || model.mimetype === "application/vnd.openxmlformats-officedocument.presentationml.presentation")
+ return "x-office-presentation-symbolic"
+
return "package-x-generic-symbolic"
}
=== added directory 'src/app/qml/loView'
=== added file 'src/app/qml/loView/LOView.qml'
--- src/app/qml/loView/LOView.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/loView/LOView.qml 2015-09-09 13:32:03 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2013-2015 Canonical, Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.3
+import Ubuntu.Components 1.1
+import DocumentViewer.LibreOffice 1.0 as LO
+
+import "../common/utils.js" as Utils
+import "../upstreamComponents"
+
+Page {
+ id: loPage
+ title: Utils.getNameOfFile(file.path);
+
+ // Disable header auto-hide.
+ // TODO: Show/hide header if a user taps the page
+ flickable: null
+
+ // TRANSLATORS: the first argument (%1) refers to the page currently shown on the screen,
+ // while the second one (%2) refers to the total pages count.
+ property string currentPage: i18n.tr("Page %1 of %2").arg(loView.currentPageIndex + 1).arg(loView.count)
+
+ // Reset night mode shader settings when closing the page
+ // Component.onDestruction: mainView.nightModeEnabled = false
+
+ LO.Viewer {
+ id: loView
+ objectName: "loView"
+ anchors.fill: parent
+
+ clip: true
+ document: loDocument
+
+ Component.onCompleted: {
+ // WORKAROUND: Fix for wrong grid unit size
+ flickDeceleration = 1500 * units.gridUnit / 8
+ maximumFlickVelocity = 2500 * units.gridUnit / 8
+ }
+ }
+
+ Scrollbar { flickableItem: loView }
+ Scrollbar { flickableItem: loView; align: Qt.AlignBottom }
+
+ LO.Document {
+ id: loDocument
+
+ property bool isLoading: true
+ path: file.path
+
+ /* onPagesLoaded: {
+ isLoading = false;
+
+ var title = getDocumentInfo("Title")
+ if (title !== "")
+ loPage.title = title;
+
+ // Hide header when the document is ready
+ mainView.setHeaderVisibility(false);
+ }*/
+ }
+
+ // *** HEADER ***
+ state: "default"
+ states: LOViewDefaultHeader {
+ name: "default"
+ targetPage: loPage
+ //activityRunning: loView.currentPageItem.status == Image.Loading || loDocument.isLoading
+ }
+}
=== added file 'src/app/qml/loView/LOViewDefaultHeader.qml'
--- src/app/qml/loView/LOViewDefaultHeader.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/loView/LOViewDefaultHeader.qml 2015-09-09 13:32:03 +0000
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014-2015 Canonical, Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.3
+import Ubuntu.Components 1.1
+import QtQuick.Layouts 1.1
+import Ubuntu.Components.Popups 1.0
+
+PageHeadState {
+ id: rootItem
+
+ property Page targetPage
+ property alias activityRunning: activity.running
+
+ head: targetPage.head
+
+ contents: RowLayout {
+ anchors.fill: parent
+ spacing: units.gu(1)
+
+ ActivityIndicator { id: activity }
+
+ Column {
+ id: layout
+ Layout.fillWidth: true
+
+ Label {
+ width: parent.width
+ //horizontalAlignment: Text.AlignHCenter
+ elide: Text.ElideMiddle
+
+ font.weight: Font.DemiBold
+ text: targetPage.title
+ }
+ Label {
+ width: parent.width
+ //horizontalAlignment: Text.AlignHCenter
+ elide: Text.ElideMiddle
+
+ fontSize: "small"
+ text: {
+ switch(loDocument.documentType) {
+ case 0:
+ return i18n.tr("LibreOffice text document")
+ case 1:
+ return i18n.tr("LibreOffice spread sheet")
+ case 2:
+ return i18n.tr("LibreOffice presentation")
+ case 3:
+ return i18n.tr("LibreOffice Draw document")
+ case 4:
+ return i18n.tr("Unknown LibreOffice document")
+ default:
+ return i18n.tr("Unknown type document")
+ }
+ }
+ }
+ }
+ }
+
+ backAction: Action {
+ iconName: "back"
+ text: (pageStack.depth > 1) ? i18n.tr("Back") : i18n.tr("Close")
+ onTriggered: {
+ if (pageStack.depth > 1) {
+ // Go back to Welcome page
+ pageStack.pop();
+ } else {
+ // File has been imported through Content Hub (or was not chosen through WelcomePage)
+ // Close the application and show our source app (e.g. ubuntu-filemanager-app, if used to open a document)
+ Qt.quit()
+ }
+ }
+ }
+
+ actions: [
+ Action {
+ iconName: "search"
+ // onTriggered: pageMain.state = "search"
+ //Disable it until we provide search in Poppler plugin.
+ enabled: false
+ },
+
+ Action {
+ objectName:"gotopage"
+ iconName: "browser-tabs"
+ text: i18n.tr("Go to page...")
+ onTriggered: PopupUtils.open(Qt.resolvedUrl("LOViewGotoDialog.qml"), targetPage)
+ },
+
+ Action {
+ iconName: "night-mode"
+ text: mainView.nightModeEnabled ? i18n.tr("Disable night mode") : i18n.tr("Enable night mode")
+ onTriggered: mainView.nightModeEnabled = !mainView.nightModeEnabled
+ },
+
+ Action {
+ objectName: "detailsAction"
+ text: i18n.tr("Details")
+ iconName: "info"
+ onTriggered: pageStack.push(Qt.resolvedUrl("../common/DetailsPage.qml"))
+ }
+ ]
+}
=== added file 'src/app/qml/loView/LOViewDelegate.qml'
--- src/app/qml/loView/LOViewDelegate.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/loView/LOViewDelegate.qml 2015-09-09 13:32:03 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013-2015 Canonical, Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.3
+import Ubuntu.Components 1.1
+
+Rectangle {
+ id: loPage
+
+ property int index: model.index
+ property bool _previewFetched: false
+
+ property alias status: pageImg.status
+
+ width: parent.width
+ height: width * (model.height / model.width)
+ color: "#E6E6E6"
+
+ // Preview page rendering. Used as placeholder while zooming the page.
+ // We generate the low resolution preview from the texture of the PDF page,
+ // so that we can keep page rendering as fast as possible.
+ ShaderEffectSource {
+ id: previewImg
+ anchors.fill: parent
+
+ // We cannot change its opacity or visibility, otherwise the texture will be refreshed,
+ // even if live is false.
+ live: false
+ textureSize: Qt.size(256, 256 * (model.height / model.width))
+ }
+
+ Image {
+ id: pageImg
+ anchors.fill: parent
+
+ source: "image://libreoffice/page/" + index;
+ sourceSize.width: loPage.width
+
+ onStatusChanged: {
+ // This is supposed to run the first time PdfViewDelegate gets the page rendering.
+ if (!_previewFetched) {
+ if (status == Image.Ready) {
+ previewImg.sourceItem = pageImg
+ // Re-assign sourceItem property, so the texture is not updated when Image status changes.
+ previewImg.sourceItem = loPage
+ }
+ }
+ }
+
+ // Request a new page rendering. The order, which pages are requested with, depends on the distance from the currentPage
+ Timer {
+ id: _zoomTimer
+ interval: {
+ var diff = Math.abs(loView.currentPageIndex - model.index)
+ var prov = loDocument.providersNumber * 0.5
+
+ if (diff < prov)
+ return 0
+ else
+ return (diff - prov) * 10
+ }
+
+ onTriggered: {
+ pageImg.sourceSize.width = loPage.width;
+ }
+ }
+ }
+
+ // Page rendering depends on the width of PdfViewDelegate.
+ // Because of this, we have multiple callings to ImageProvider while zooming.
+ // Just avoid it.
+ Connections {
+ target: pinchy
+
+ onPinchStarted: _zoomTimer.stop();
+ onPinchUpdated: {
+ // This ensures that page image is not reloaded when the maximumScale or minimumScale has already been reached.
+ if ( !(_zoomHelper.scale >= 2.5 && pinch.scale > 1.0) && !(_zoomHelper.scale <= 1.0 && pinch.scale < 1.0) )
+ pageImg.sourceSize.width = 0;
+ }
+ onPinchFinished: _zoomTimer.restart();
+ }
+}
=== added file 'src/app/qml/loView/LOViewGotoDialog.qml'
--- src/app/qml/loView/LOViewGotoDialog.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/loView/LOViewGotoDialog.qml 2015-09-09 13:32:03 +0000
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014-2015 Canonical, Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.3
+import Ubuntu.Components 1.1
+import Ubuntu.Components.Popups 1.0
+
+Dialog {
+ id: goToPageDialog
+ objectName:"LOViewGotoDialog"
+
+ title: i18n.tr("Go to page")
+ text: i18n.tr("Choose a page between 1 and %1").arg(loView.count)
+
+ TextField {
+ id: goToPageTextField
+ objectName:"goToPageTextField"
+
+ width: parent.width
+
+ hasClearButton: true
+ inputMethodHints: Qt.ImhFormattedNumbersOnly
+ validator: IntValidator{ bottom: 1; top: loView.count }
+
+ Keys.onReturnPressed: goToPage()
+ Component.onCompleted: forceActiveFocus()
+ }
+
+ Button {
+ objectName:"GOButton"
+ text: i18n.tr("GO!")
+ color: UbuntuColors.green
+
+ enabled: goToPageTextField.acceptableInput
+ onClicked: goToPage()
+ }
+
+ Button {
+ text: i18n.tr("Cancel")
+ onClicked: PopupUtils.close(goToPageDialog)
+ }
+
+ function goToPage() {
+ loView.positionAtIndex((goToPageTextField.text - 1))
+ PopupUtils.close(goToPageDialog)
+ }
+}
=== modified file 'src/plugin/CMakeLists.txt'
--- src/plugin/CMakeLists.txt 2014-10-20 21:38:36 +0000
+++ src/plugin/CMakeLists.txt 2015-09-09 13:32:03 +0000
@@ -1,2 +1,3 @@
add_subdirectory(file-qml-plugin)
add_subdirectory(poppler-qml-plugin)
+add_subdirectory(libreofficetoolkit-qml-plugin)
=== modified file 'src/plugin/file-qml-plugin/documentmodel.cpp'
--- src/plugin/file-qml-plugin/documentmodel.cpp 2015-07-30 11:06:22 +0000
+++ src/plugin/file-qml-plugin/documentmodel.cpp 2015-09-09 13:32:03 +0000
@@ -118,7 +118,16 @@
QMimeDatabase db;
QString mimetype = db.mimeTypeForFile(path).name();
- return (mimetype.startsWith("text/") || mimetype == "application/pdf");
+ return (mimetype.startsWith("text/")
+ || mimetype == "application/pdf"
+ || mimetype.startsWith("application/vnd.oasis.opendocument")
+ || mimetype == "application/msword")
+ || mimetype == "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+ || mimetype == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+ || mimetype == "application/vnd.openxmlformats-officedocument.presentationml.presentation"
+ || mimetype == "application/msword"
+ || mimetype == "application/vnd.ms-excel"
+ || mimetype == "application/vnd.ms-powerpoint";
}
QHash<int, QByteArray> DocumentModel::roleNames() const
=== added directory 'src/plugin/libreofficetoolkit-qml-plugin'
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt'
--- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-09-09 13:32:03 +0000
@@ -0,0 +1,46 @@
+set(PLUGIN_DIR DocumentViewer/LibreOffice)
+
+file(GLOB_RECURSE QML_SRCS *.qml *.js)
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/LibreOfficeKit/
+)
+
+#add the sources to compile
+set(libreofficetoolkitqmlplugin_SRCS
+ plugin.cpp
+ lodocument.cpp
+ loview.cpp
+ tileitem.cpp
+ ${QML_SRCS}
+)
+
+#add the headers to compile
+set(libreofficetoolkitqmlplugin_HDRS
+ twips.h
+ config.h
+)
+
+add_library(libreofficetoolkitqmlplugin MODULE
+ ${libreofficetoolkitqmlplugin_SRCS}
+ ${libreofficetoolkitqmlplugin_HDRS}
+)
+
+#target_link_libraries(libreofficetoolkitqmlplugin dl)
+qt5_use_modules(libreofficetoolkitqmlplugin Gui Qml Quick)
+
+# Copy the plugin, the qmldir file and other assets to the build dir for running in QtCreator
+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+add_custom_command(TARGET libreofficetoolkitqmlplugin POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:libreofficetoolkitqmlplugin> ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
+ COMMAND ${CMAKE_COMMAND} -E copy ${QML_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
+)
+endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+
+# Install plugin file
+install(TARGETS libreofficetoolkitqmlplugin DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
+install(FILES qmldir DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
+install(FILES ${QML_SRCS} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml'
--- src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LOViewer.qml 2015-09-09 13:32:03 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import DocumentViewer.LibreOffice 1.0 as LibreOffice
+
+Flickable {
+ id: rootFlickable
+
+ property alias document: view.document
+ property alias zoomFactor: view.zoomFactor
+ property alias cacheBuffer: view.cacheBuffer
+
+ contentHeight: view.height * view.zoomFactor
+ contentWidth: view.width * view.zoomFactor
+
+ boundsBehavior: Flickable.StopAtBounds
+
+ LibreOffice.View {
+ id: view
+
+ parentFlickable: rootFlickable
+ }
+}
=== added directory 'src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit'
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKit.h'
--- src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKit.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKit.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,171 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_H
+#define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_H
+
+#include <stddef.h>
+
+#include <LibreOfficeKit/LibreOfficeKitTypes.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct _LibreOfficeKit LibreOfficeKit;
+typedef struct _LibreOfficeKitClass LibreOfficeKitClass;
+
+typedef struct _LibreOfficeKitDocument LibreOfficeKitDocument;
+typedef struct _LibreOfficeKitDocumentClass LibreOfficeKitDocumentClass;
+
+// Do we have an extended member in this struct ?
+#define LIBREOFFICEKIT_HAS_MEMBER(strct,member,nSize) \
+ (offsetof(strct, member) < (nSize))
+
+#define LIBREOFFICEKIT_HAS(pKit,member) LIBREOFFICEKIT_HAS_MEMBER(LibreOfficeKitClass,member,(pKit)->pClass->nSize)
+
+struct _LibreOfficeKit
+{
+ LibreOfficeKitClass* pClass;
+};
+
+struct _LibreOfficeKitClass
+{
+ size_t nSize;
+
+ void (*destroy) (LibreOfficeKit* pThis);
+
+ LibreOfficeKitDocument* (*documentLoad) (LibreOfficeKit* pThis,
+ const char* pURL);
+
+ char* (*getError) (LibreOfficeKit* pThis);
+
+ LibreOfficeKitDocument* (*documentLoadWithOptions) (LibreOfficeKit* pThis,
+ const char* pURL,
+ const char* pOptions);
+#ifdef LOK_USE_UNSTABLE_API
+ void (*registerCallback) (LibreOfficeKit* pThis,
+ LibreOfficeKitCallback pCallback,
+ void* pData);
+#endif
+};
+
+#define LIBREOFFICEKIT_DOCUMENT_HAS(pDoc,member) LIBREOFFICEKIT_HAS_MEMBER(LibreOfficeKitDocumentClass,member,(pDoc)->pClass->nSize)
+
+struct _LibreOfficeKitDocument
+{
+ LibreOfficeKitDocumentClass* pClass;
+};
+
+struct _LibreOfficeKitDocumentClass
+{
+ size_t nSize;
+
+ void (*destroy) (LibreOfficeKitDocument* pThis);
+
+ int (*saveAs) (LibreOfficeKitDocument* pThis,
+ const char* pUrl,
+ const char* pFormat,
+ const char* pFilterOptions);
+
+#ifdef LOK_USE_UNSTABLE_API
+ /// @see lok::Document::getDocumentType().
+ int (*getDocumentType) (LibreOfficeKitDocument* pThis);
+
+ /// @see lok::Document::getParts().
+ int (*getParts) (LibreOfficeKitDocument* pThis);
+
+ /// @see lok::Document::getPart().
+ int (*getPart) (LibreOfficeKitDocument* pThis);
+
+ /// @see lok::Document::setPart().
+ void (*setPart) (LibreOfficeKitDocument* pThis,
+ int nPart);
+
+ /// @see lok::Document::getPartName().
+ char* (*getPartName) (LibreOfficeKitDocument* pThis,
+ int nPart);
+
+ /** Sets mode of the current part.
+ *
+ * @param nMode - element from the LibreOfficeKitPartMode enum.
+ */
+ void (*setPartMode) (LibreOfficeKitDocument* pThis,
+ int nMode);
+
+ /// @see lok::Document::paintTile().
+ void (*paintTile) (LibreOfficeKitDocument* pThis,
+ unsigned char* pBuffer,
+ const int nCanvasWidth,
+ const int nCanvasHeight,
+ const int nTilePosX,
+ const int nTilePosY,
+ const int nTileWidth,
+ const int nTileHeight);
+
+ /// @see lok::Document::getDocumentSize().
+ void (*getDocumentSize) (LibreOfficeKitDocument* pThis,
+ long* pWidth,
+ long* pHeight);
+
+ /// @see lok::Document::initializeForRendering().
+ void (*initializeForRendering) (LibreOfficeKitDocument* pThis);
+
+ void (*registerCallback) (LibreOfficeKitDocument* pThis,
+ LibreOfficeKitCallback pCallback,
+ void* pData);
+
+ /// @see lok::Document::postKeyEvent
+ void (*postKeyEvent) (LibreOfficeKitDocument* pThis,
+ int nType,
+ int nCharCode,
+ int nKeyCode);
+
+ /// @see lok::Document::postMouseEvent
+ void (*postMouseEvent) (LibreOfficeKitDocument* pThis,
+ int nType,
+ int nX,
+ int nY,
+ int nCount);
+
+ /// @see lok::Document::postUnoCommand
+ void (*postUnoCommand) (LibreOfficeKitDocument* pThis,
+ const char* pCommand,
+ const char* pArguments);
+
+ /// @see lok::Document::setTextSelection
+ void (*setTextSelection) (LibreOfficeKitDocument* pThis,
+ int nType,
+ int nX,
+ int nY);
+
+ /// @see lok::Document::getTextSelection
+ char* (*getTextSelection) (LibreOfficeKitDocument* pThis,
+ const char* pMimeType,
+ char** pUsedMimeType);
+
+ /// @see lok::Document::setGraphicSelection
+ void (*setGraphicSelection) (LibreOfficeKitDocument* pThis,
+ int nType,
+ int nX,
+ int nY);
+
+ /// @see lok::Document::resetSelection
+ void (*resetSelection) (LibreOfficeKitDocument* pThis);
+#endif // LOK_USE_UNSTABLE_API
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKit.hxx'
--- src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKit.hxx 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKit.hxx 2015-09-09 13:32:03 +0000
@@ -0,0 +1,310 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX
+#define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX
+
+#include "LibreOfficeKit.h"
+
+/*
+ * The reasons this C++ code is not as pretty as it could be are:
+ * a) provide a pure C API - that's useful for some people
+ * b) allow ABI stability - C++ vtables are not good for that.
+ * c) avoid C++ types as part of the API.
+ */
+namespace lok
+{
+
+/// The lok::Document class represents one loaded document instance.
+class Document
+{
+private:
+ LibreOfficeKitDocument* mpDoc;
+
+public:
+ /// A lok::Document is typically created by the lok::Office::documentLoad() method.
+ inline Document(LibreOfficeKitDocument* pDoc) :
+ mpDoc(pDoc)
+ {}
+
+ inline ~Document()
+ {
+ mpDoc->pClass->destroy(mpDoc);
+ }
+
+ /**
+ * Stores the document's persistent data to a URL and
+ * continues to be a representation of the old URL.
+ *
+ * @param pUrl the location where to store the document
+ * @param pFormat the format to use while exporting, when omitted, then deducted from pURL's extension
+ * @param pFilterOptions options for the export filter, e.g. SkipImages.
+ */
+ inline bool saveAs(const char* pUrl, const char* pFormat = NULL, const char* pFilterOptions = NULL)
+ {
+ return mpDoc->pClass->saveAs(mpDoc, pUrl, pFormat, pFilterOptions) != 0;
+ }
+
+ /// Gives access to the underlying C pointer.
+ inline LibreOfficeKitDocument *get() { return mpDoc; }
+
+#ifdef LOK_USE_UNSTABLE_API
+ /**
+ * Get document type.
+ *
+ * @return an element of the LibreOfficeKitDocumentType enum.
+ */
+ inline int getDocumentType()
+ {
+ return mpDoc->pClass->getDocumentType(mpDoc);
+ }
+
+ /**
+ * Get number of part that the document contains.
+ *
+ * Part refers to either indivual sheets in a Calc, or slides in Impress,
+ * and has no relevance for Writer.
+ */
+ inline int getParts()
+ {
+ return mpDoc->pClass->getParts(mpDoc);
+ }
+
+ /// Get the current part of the document.
+ inline int getPart()
+ {
+ return mpDoc->pClass->getPart(mpDoc);
+ }
+
+ /// Set the current part of the document.
+ inline void setPart(int nPart)
+ {
+ mpDoc->pClass->setPart(mpDoc, nPart);
+ }
+
+ /// Get the current part's name.
+ inline char* getPartName(int nPart)
+ {
+ return mpDoc->pClass->getPartName(mpDoc, nPart);
+ }
+
+ /**
+ * Renders a subset of the document to a pre-allocated buffer.
+ *
+ * Note that the buffer size and the tile size implicitly supports
+ * rendering at different zoom levels, as the number of rendered pixels and
+ * the rendered rectangle of the document are independent.
+ *
+ * @param pBuffer pointer to the buffer, its size is determined by nCanvasWidth and nCanvasHeight.
+ * @param nCanvasWidth number of pixels in a row of pBuffer.
+ * @param nCanvasHeight number of pixels in a column of pBuffer.
+ * @param nTilePosX logical X position of the top left corner of the rendered rectangle, in TWIPs.
+ * @param nTilePosY logical Y position of the top left corner of the rendered rectangle, in TWIPs.
+ * @param nTileWidth logical width of the rendered rectangle, in TWIPs.
+ * @param nTileHeight logical height of the rendered rectangle, in TWIPs.
+ */
+ inline void paintTile(
+ unsigned char* pBuffer,
+ const int nCanvasWidth,
+ const int nCanvasHeight,
+ const int nTilePosX,
+ const int nTilePosY,
+ const int nTileWidth,
+ const int nTileHeight)
+ {
+ return mpDoc->pClass->paintTile(mpDoc, pBuffer, nCanvasWidth, nCanvasHeight,
+ nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+ }
+
+ /// Get the document sizes in TWIPs.
+ inline void getDocumentSize(long* pWidth, long* pHeight)
+ {
+ mpDoc->pClass->getDocumentSize(mpDoc, pWidth, pHeight);
+ }
+
+ /**
+ * Initialize document for rendering.
+ *
+ * Sets the rendering and document parameters to default values that are
+ * needed to render the document correctly using tiled rendering. This
+ * method has to be called right after documentLoad() in case any of the
+ * tiled rendering methods are to be used later.
+ */
+ inline void initializeForRendering()
+ {
+ mpDoc->pClass->initializeForRendering(mpDoc);
+ }
+
+ /**
+ * Registers a callback. LOK will invoke this function when it wants to
+ * inform the client about events.
+ *
+ * @param pCallback the callback to invoke
+ * @param pData the user data, will be passed to the callback on invocation
+ */
+ inline void registerCallback(LibreOfficeKitCallback pCallback, void* pData)
+ {
+ mpDoc->pClass->registerCallback(mpDoc, pCallback, pData);
+ }
+
+ /**
+ * Posts a keyboard event to the focused frame.
+ *
+ * @param nType Event type, like press or release.
+ * @param nCharCode contains the Unicode character generated by this event or 0
+ * @param nKeyCode contains the integer code representing the key of the event (non-zero for control keys)
+ */
+ inline void postKeyEvent(int nType, int nCharCode, int nKeyCode)
+ {
+ mpDoc->pClass->postKeyEvent(mpDoc, nType, nCharCode, nKeyCode);
+ }
+
+ /**
+ * Posts a mouse event to the document.
+ *
+ * @param nType Event type, like down, move or up.
+ * @param nX horizontal position in document coordinates
+ * @param nY vertical position in document coordinates
+ * @param nCount number of clicks: 1 for single click, 2 for double click
+ */
+ inline void postMouseEvent(int nType, int nX, int nY, int nCount)
+ {
+ mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY, nCount);
+ }
+
+ /**
+ * Posts an UNO command to the document.
+ *
+ * Example argument string:
+ *
+ * {
+ * "SearchItem.SearchString":
+ * {
+ * "type": "string",
+ * "value": "foobar"
+ * },
+ * "SearchItem.Backward":
+ * {
+ * "type": "boolean",
+ * "value": "false"
+ * }
+ * }
+ *
+ * @param pCommand uno command to be posted to the document, like ".uno:Bold"
+ * @param pArguments arguments of the uno command.
+ */
+ inline void postUnoCommand(const char* pCommand, const char* pArguments = 0)
+ {
+ mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments);
+ }
+
+ /**
+ * Sets the start or end of a text selection.
+ *
+ * @param nType @see LibreOfficeKitSetTextSelectionType
+ * @param nX horizontal position in document coordinates
+ * @param nY vertical position in document coordinates
+ */
+ inline void setTextSelection(int nType, int nX, int nY)
+ {
+ mpDoc->pClass->setTextSelection(mpDoc, nType, nX, nY);
+ }
+
+ /**
+ * Gets the currently selected text.
+ *
+ * @param pMimeType suggests the return format, for example text/plain;charset=utf-8.
+ * @param pUsedMimeType output parameter to inform about the determined format (suggested one or plain text).
+ */
+ inline char* getTextSelection(const char* pMimeType, char** pUsedMimeType = 0)
+ {
+ return mpDoc->pClass->getTextSelection(mpDoc, pMimeType, pUsedMimeType);
+ }
+
+ /**
+ * Adjusts the graphic selection.
+ *
+ * @param nType @see LibreOfficeKitSetGraphicSelectionType
+ * @param nX horizontal position in document coordinates
+ * @param nY vertical position in document coordinates
+ */
+ inline void setGraphicSelection(int nType, int nX, int nY)
+ {
+ mpDoc->pClass->setGraphicSelection(mpDoc, nType, nX, nY);
+ }
+
+ /**
+ * Gets rid of any text or graphic selection.
+ */
+ inline void resetSelection()
+ {
+ mpDoc->pClass->resetSelection(mpDoc);
+ }
+#endif // LOK_USE_UNSTABLE_API
+};
+
+/// The lok::Office class represents one started LibreOfficeKit instance.
+class Office
+{
+private:
+ LibreOfficeKit* mpThis;
+
+public:
+ /// A lok::Office is typically created by the lok_cpp_init() function.
+ inline Office(LibreOfficeKit* pThis) :
+ mpThis(pThis)
+ {}
+
+ inline ~Office()
+ {
+ mpThis->pClass->destroy(mpThis);
+ }
+
+ /**
+ * Loads a document from an URL.
+ *
+ * @param pUrl the URL of the document to load
+ * @param pFilterOptions options for the import filter, e.g. SkipImages.
+ */
+ inline Document* documentLoad(const char* pUrl, const char* pFilterOptions = NULL)
+ {
+ LibreOfficeKitDocument* pDoc = NULL;
+
+ if (LIBREOFFICEKIT_HAS(mpThis, documentLoadWithOptions))
+ pDoc = mpThis->pClass->documentLoadWithOptions(mpThis, pUrl, pFilterOptions);
+ else
+ pDoc = mpThis->pClass->documentLoad(mpThis, pUrl);
+
+ if (pDoc == NULL)
+ return NULL;
+
+ return new Document(pDoc);
+ }
+
+ /// Returns the last error as a string, the returned pointer has to be freed by the caller.
+ inline char* getError()
+ {
+ return mpThis->pClass->getError(mpThis);
+ }
+};
+
+/// Factory method to create a lok::Office instance.
+inline Office* lok_cpp_init(const char* pInstallPath, const char* pUserProfilePath = NULL)
+{
+ LibreOfficeKit* pThis = lok_init_2(pInstallPath, pUserProfilePath);
+ if (pThis == NULL || pThis->pClass->nSize == 0)
+ return NULL;
+ return new ::lok::Office(pThis);
+}
+
+}
+
+#endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitEnums.h'
--- src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitEnums.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitEnums.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,229 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITENUMS_H
+#define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITENUMS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef LOK_USE_UNSTABLE_API
+typedef enum
+{
+ LOK_DOCTYPE_TEXT,
+ LOK_DOCTYPE_SPREADSHEET,
+ LOK_DOCTYPE_PRESENTATION,
+ LOK_DOCTYPE_DRAWING,
+ LOK_DOCTYPE_OTHER
+}
+LibreOfficeKitDocumentType;
+
+typedef enum
+{
+ LOK_PARTMODE_DEFAULT,
+ LOK_PARTMODE_SLIDE,
+ LOK_PARTMODE_NOTES,
+ LOK_PARTMODE_SLIDENOTES,
+ LOK_PARTMODE_EMBEDDEDOBJ
+}
+LibreOfficeKitPartMode;
+
+typedef enum
+{
+ /**
+ * Any tiles which are over the rectangle described in the payload are no
+ * longer valid.
+ *
+ * Rectangle format: "width, height, x, y", where all numbers are document
+ * coordinates, in twips. When all tiles are supposed to be dropped, the
+ * format is the "EMPTY" string.
+ */
+ LOK_CALLBACK_INVALIDATE_TILES,
+ /**
+ * The size and/or the position of the visible cursor changed.
+ *
+ * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
+ */
+ LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
+ /**
+ * The list of rectangles representing the current text selection changed.
+ *
+ * List format is "rectangle1[; rectangle2[; ...]]" (without quotes and
+ * brackets), where rectangleN has the same format as
+ * LOK_CALLBACK_INVALIDATE_TILES. When there is no selection, an empty
+ * string is provided.
+ */
+ LOK_CALLBACK_TEXT_SELECTION,
+ /**
+ * The position and size of the cursor rectangle at the text
+ * selection start. It is used to draw the selection handles.
+ *
+ * This callback must be called prior to LOK_CALLBACK_TEXT_SELECTION every
+ * time the selection is updated.
+ *
+ * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
+ */
+ LOK_CALLBACK_TEXT_SELECTION_START,
+ /**
+ * The position and size of the cursor rectangle at the text
+ * selection end. It is used to draw the selection handles.
+ *
+ * This callback must be called prior to LOK_CALLBACK_TEXT_SELECTION every
+ * time the selection is updated.
+ *
+ * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
+ */
+ LOK_CALLBACK_TEXT_SELECTION_END,
+ /**
+ * The blinking text cursor is now visible or not.
+ *
+ * Clients should assume that this is true initially and are expected to
+ * hide the blinking cursor at the rectangle described by
+ * LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR once it becomes false. Payload is
+ * either the "true" or the "false" string.
+ */
+ LOK_CALLBACK_CURSOR_VISIBLE,
+ /**
+ * The size and/or the position of the graphic selection changed.
+ *
+ * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
+ */
+ LOK_CALLBACK_GRAPHIC_SELECTION,
+
+ /**
+ * User clicked on an hyperlink that should be handled by other
+ * applications accordingly.
+ */
+ LOK_CALLBACK_HYPERLINK_CLICKED,
+
+ /**
+ * Emit state update to the client.
+ * For example, when cursor is on bold text, this callback is triggered
+ * with payload: ".uno:Bold=true"
+ */
+ LOK_CALLBACK_STATE_CHANGED,
+
+ /**
+ * Start a "status indicator" (here restricted to a progress bar type
+ * indicator). The payload is the descriptive text (or empty). Even if
+ * there is no documentation that would promise so, we assume that de facto
+ * for a document being viewed or edited, there will be at most one status
+ * indicator, and its descriptive text will not change.
+ *
+ * Note that for the case of the progress indication during loading of a
+ * document, the status indicator callbacks will arrive to the callback
+ * registered for the LibreOfficeKit (singleton) object, not a
+ * LibreOfficeKitDocument one, because we are in the very progress of
+ * loading a docuemnt and then constructing a LibreOfficeKitDocument
+ * object.
+ */
+ LOK_CALLBACK_STATUS_INDICATOR_START,
+
+ /**
+ * Sets the numeric value of the status indicator.
+ * The payload should be a percentage, an integer between 0 and 100.
+ */
+ LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE,
+
+ /**
+ * Ends the status indicator.
+ *
+ * Not necessarily ever emitted.
+ */
+ LOK_CALLBACK_STATUS_INDICATOR_FINISH,
+
+ /**
+ * No match was found for the search input
+ */
+ LOK_CALLBACK_SEARCH_NOT_FOUND,
+
+ /**
+ * Size of the document changed.
+ *
+ * Payload format is "width, height", i.e. clients get the new size without
+ * having to do an explicit lok::Document::getDocumentSize() call.
+ */
+ LOK_CALLBACK_DOCUMENT_SIZE_CHANGED,
+
+ /**
+ * The current part number is changed.
+ *
+ * Payload is a single 0-based integer.
+ */
+ LOK_CALLBACK_SET_PART
+}
+LibreOfficeKitCallbackType;
+
+typedef enum
+{
+ /// A key on the keyboard is pressed.
+ LOK_KEYEVENT_KEYINPUT,
+ /// A key on the keyboard is released.
+ LOK_KEYEVENT_KEYUP
+}
+LibreOfficeKitKeyEventType;
+
+typedef enum
+{
+ /// A pressed gesture has started.
+ LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+ /// A pressed gesture has finished.
+ LOK_MOUSEEVENT_MOUSEBUTTONUP,
+ /// A change has happened during a press gesture.
+ LOK_MOUSEEVENT_MOUSEMOVE
+}
+LibreOfficeKitMouseEventType;
+
+typedef enum
+{
+ /// The start of selection is to be adjusted.
+ LOK_SETTEXTSELECTION_START,
+ /// The end of selection is to be adjusted.
+ LOK_SETTEXTSELECTION_END,
+ /// Both the start and the end of selection is to be adjusted.
+ LOK_SETTEXTSELECTION_RESET
+}
+LibreOfficeKitSetTextSelectionType;
+
+typedef enum
+{
+ /**
+ * A move or a resize action starts. It is assumed that there is a valid
+ * graphic selection (see LOK_CALLBACK_GRAPHIC_SELECTION) and the supplied
+ * coordinates are the ones the user tapped on.
+ *
+ * The type of the action is move by default, unless the coordinates are
+ * the position of a handle (see below), in which case it's a resize.
+ *
+ * There are 8 handles for a graphic selection:
+ * - top-left, top-center, top-right
+ * - middle-left, middle-right
+ * - bottom-left, bottom-center, bottom-right
+ */
+ LOK_SETGRAPHICSELECTION_START,
+ /**
+ * A move or resize action stops. It is assumed that this is always used
+ * only after a LOK_SETTEXTSELECTION_START. The supplied coordinates are
+ * the ones where the user released the screen.
+ */
+ LOK_SETGRAPHICSELECTION_END
+}
+LibreOfficeKitSetGraphicSelectionType;
+
+#endif // LOK_USE_UNSTABLE_API
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITENUMS_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitGtk.h'
--- src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitGtk.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitGtk.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITGTK_H
+#define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITGTK_H
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#define LOK_USE_UNSTABLE_API
+#include <LibreOfficeKit/LibreOfficeKit.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define LOK_DOCVIEW(obj) GTK_CHECK_CAST (obj, lok_docview_get_type(), LOKDocView)
+#define LOK_DOCVIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, lok_docview_get_type(), LOKDocViewClass)
+#define IS_LOK_DOCVIEW(obj) GTK_CHECK_TYPE (obj, lok_docview_get_type())
+
+typedef struct _LOKDocView LOKDocView;
+typedef struct _LOKDocViewClass LOKDocViewClass;
+
+struct _LOKDocView
+{
+ GtkScrolledWindow aScrollWindow;
+ struct LOKDocView_Impl* m_pImpl;
+};
+
+struct _LOKDocViewClass
+{
+ GtkScrolledWindowClass parent_class;
+ void (* edit_changed) (LOKDocView* pView, gboolean was_edit);
+ void (* command_changed) (LOKDocView* pView, char* new_state);
+ void (* search_not_found) (LOKDocView* pView, char* new_state);
+ void (* part_changed) (LOKDocView* pView, int new_part);
+};
+
+guint lok_docview_get_type (void);
+GtkWidget* lok_docview_new ( LibreOfficeKit* pOffice );
+gboolean lok_docview_open_document (LOKDocView* pDocView,
+ char* pPath);
+
+/// Gets the document the viewer displays.
+LibreOfficeKitDocument* lok_docview_get_document(LOKDocView* pDocView);
+
+void lok_docview_set_zoom (LOKDocView* pDocView,
+ float fZoom);
+float lok_docview_get_zoom (LOKDocView* pDocView);
+
+int lok_docview_get_parts (LOKDocView* pDocView);
+int lok_docview_get_part (LOKDocView* pDocView);
+void lok_docview_set_part (LOKDocView* pDocView,
+ int nPart);
+char* lok_docview_get_part_name (LOKDocView* pDocView,
+ int nPart);
+void lok_docview_set_partmode (LOKDocView* pDocView,
+ int nPartMode);
+/// Sets if the viewer is actually an editor or not.
+void lok_docview_set_edit (LOKDocView* pDocView,
+ gboolean bEdit);
+/// Gets if the viewer is actually an editor or not.
+gboolean lok_docview_get_edit (LOKDocView* pDocView);
+
+/// Posts the .uno: command to the LibreOfficeKit.
+void lok_docview_post_command (LOKDocView* pDocView, const char* pCommand, const char* pArguments);
+
+/// Posts a keyboard event to LibreOfficeKit.
+void lok_docview_post_key (GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData);
+
+/// Get the visible area of the document (in twips).
+void lok_docview_get_visarea(LOKDocView* pThis, GdkRectangle* pArea);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITGTK_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitInit.h'
--- src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitInit.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitInit.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,257 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITINIT_H
+#define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITINIT_H
+
+#include "LibreOfficeKit.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if defined(__linux__) || defined (__FreeBSD_kernel__) || defined(_AIX) || defined(_WIN32) || defined(__APPLE__)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifndef _WIN32
+
+ #include "dlfcn.h"
+
+ #ifdef _AIX
+ # include <sys/ldr.h>
+ #endif
+ #ifdef __APPLE__
+ #define TARGET_LIB "lib" "sofficeapp" ".dylib"
+ #define TARGET_MERGED_LIB "lib" "mergedlo" ".dylib"
+ #else
+ #define TARGET_LIB "lib" "sofficeapp" ".so"
+ #define TARGET_MERGED_LIB "lib" "mergedlo" ".so"
+ #endif
+ #define SEPARATOR '/'
+
+ void *_dlopen(const char *pFN)
+ {
+ return dlopen(pFN, RTLD_LAZY
+#if defined __clang__ && defined __linux__ \
+ && defined ENABLE_RUNTIME_OPTIMIZATIONS
+#if !ENABLE_RUNTIME_OPTIMIZATIONS
+ | RTLD_GLOBAL
+#endif
+#endif
+ );
+ }
+
+ char *_dlerror(void)
+ {
+ return dlerror();
+ }
+
+ void *_dlsym(void *Hnd, const char *pName)
+ {
+ return dlsym(Hnd, pName);
+ }
+
+ int _dlclose(void *Hnd)
+ {
+ return dlclose(Hnd);
+ }
+
+ void extendUnoPath(const char *pPath)
+ {
+ (void)pPath;
+ }
+
+#else
+
+ #include <windows.h>
+ #define TARGET_LIB "sofficeapp" ".dll"
+ #define TARGET_MERGED_LIB "mergedlo" ".dll"
+ #define SEPARATOR '\\'
+ #define UNOPATH "\\..\\URE\\bin"
+
+ void *_dlopen(const char *pFN)
+ {
+ return (void *) LoadLibrary(pFN);
+ }
+
+ char *_dlerror(void)
+ {
+ LPSTR buf = NULL;
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, reinterpret_cast<LPSTR>(&buf), 0, NULL);
+ return buf;
+ }
+
+ void *_dlsym(void *Hnd, const char *pName)
+ {
+ return GetProcAddress((HINSTANCE) Hnd, pName);
+ }
+
+ int _dlclose(void *Hnd)
+ {
+ return FreeLibrary((HINSTANCE) Hnd);
+ }
+
+ void extendUnoPath(const char *pPath)
+ {
+ if (!pPath)
+ return;
+
+ char* sEnvPath = NULL;
+ DWORD cChars = GetEnvironmentVariable("PATH", sEnvPath, 0);
+ if (cChars > 0)
+ {
+ sEnvPath = new char[cChars];
+ cChars = GetEnvironmentVariable("PATH", sEnvPath, cChars);
+ //If PATH is not set then it is no error
+ if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND)
+ {
+ delete[] sEnvPath;
+ return;
+ }
+ }
+ //prepare the new PATH. Add the Ure/bin directory at the front.
+ //note also adding ';'
+ char * sNewPath = new char[strlen(sEnvPath) + strlen(pPath) + strlen(UNOPATH) + 2];
+ sNewPath[0] = L'\0';
+ strcat(sNewPath, pPath);
+ strcat(sNewPath, UNOPATH);
+ if (strlen(sEnvPath))
+ {
+ strcat(sNewPath, ";");
+ strcat(sNewPath, sEnvPath);
+ }
+
+ SetEnvironmentVariable("PATH", sNewPath);
+
+ delete[] sEnvPath;
+ delete[] sNewPath;
+ }
+#endif
+
+typedef LibreOfficeKit *(HookFunction)( const char *install_path);
+
+typedef LibreOfficeKit *(HookFunction2)( const char *install_path, const char *user_profile_path );
+
+static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_profile_path )
+{
+ char *imp_lib;
+ void *dlhandle;
+ HookFunction *pSym;
+ HookFunction2 *pSym2;
+
+#if !(defined(__APPLE__) && defined(__arm__))
+ size_t partial_length;
+
+ if (!install_path)
+ return NULL;
+
+ // allocate large enough buffer
+ partial_length = strlen(install_path);
+ imp_lib = (char *) malloc(partial_length + sizeof(TARGET_LIB) + sizeof(TARGET_MERGED_LIB) + 2);
+ if (!imp_lib)
+ {
+ fprintf( stderr, "failed to open library : not enough memory\n");
+ return NULL;
+ }
+
+ strcpy(imp_lib, install_path);
+
+ extendUnoPath(install_path);
+
+ imp_lib[partial_length++] = SEPARATOR;
+ strcpy(imp_lib + partial_length, TARGET_LIB);
+
+ dlhandle = _dlopen(imp_lib);
+ if (!dlhandle)
+ {
+ // If TARGET_LIB exists, and likely is a real library (not a
+ // small one-line text stub as in the --enable-mergedlib
+ // case), but dlopen failed for some reason, don't try
+ // TARGET_MERGED_LIB.
+ struct stat st;
+ if (stat(imp_lib, &st) == 0 && st.st_size > 100)
+ {
+ fprintf(stderr, "failed to open library '%s': %s\n",
+ imp_lib, _dlerror());
+ free(imp_lib);
+ return NULL;
+ }
+
+ strcpy(imp_lib + partial_length, TARGET_MERGED_LIB);
+
+ dlhandle = _dlopen(imp_lib);
+ if (!dlhandle)
+ {
+ fprintf(stderr, "failed to open library '%s': %s\n",
+ imp_lib, _dlerror());
+ free(imp_lib);
+ return NULL;
+ }
+ }
+#else
+ imp_lib = strdup("the app executable");
+ dlhandle = RTLD_MAIN_ONLY;
+#endif
+
+ pSym2 = (HookFunction2 *) _dlsym( dlhandle, "libreofficekit_hook_2" );
+ if (!pSym2)
+ {
+ if (user_profile_path != NULL)
+ {
+ fprintf( stderr, "the LibreOffice version in '%s' does not support passing a user profile to the hook function\n",
+ imp_lib );
+ _dlclose( dlhandle );
+ free( imp_lib );
+ return NULL;
+ }
+ pSym = (HookFunction *) _dlsym( dlhandle, "libreofficekit_hook" );
+ if (!pSym)
+ {
+ fprintf( stderr, "failed to find hook in library '%s'\n", imp_lib );
+ _dlclose( dlhandle );
+ free( imp_lib );
+ return NULL;
+ }
+ free( imp_lib );
+ // dlhandle is "leaked"
+ // coverity[leaked_storage]
+ return pSym( install_path );
+ }
+
+ free( imp_lib );
+ // dlhandle is "leaked"
+ // coverity[leaked_storage]
+ return pSym2( install_path, user_profile_path );
+}
+
+static
+#ifdef __GNUC__
+__attribute__((used))
+#endif
+LibreOfficeKit *lok_init( const char *install_path )
+{
+ return lok_init_2( install_path, NULL );
+}
+
+#undef SEPARATOR // It is used at least in enum class MenuItemType
+
+#endif // defined(__linux__) || defined (__FreeBSD_kernel__) || defined(_AIX) || defined(_WIN32) || defined(__APPLE__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITINIT_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitTypes.h'
--- src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitTypes.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/LibreOfficeKit/LibreOfficeKitTypes.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_TYPES_H
+#define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_TYPES_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef LOK_USE_UNSTABLE_API
+typedef void (*LibreOfficeKitCallback)(int nType, const char* pPayload, void* pData);
+#endif // LOK_USE_UNSTABLE_API
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_TYPES_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/config.h'
--- src/plugin/libreofficetoolkit-qml-plugin/config.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/config.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+// This is the hardcoded Ubuntu/Debian paths to find the LibreOffice
+// installation. If you want to use a parallel installation, change the path
+// in the following line.
+#define LO_PATH "/usr/lib/libreoffice/program/"
+
+// FIXME: Perhaps we want to use smaller tiles on mobile devices?
+#define TILE_SIZE 256.0
+
+// Uncomment it if you want to see tiles boundaries
+//#define DEBUG_SHOW_TILE_BORDER
+
+// Uncomment for benchmarking tile rendering performance
+//#define DEBUG_TILE_BENCHMARK
+
+// Uncomment if you want more verbose application output
+//#define DEBUG_VERBOSE
+
+#endif // CONFIG_H
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-09-09 13:32:03 +0000
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013-2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "lodocument.h"
+#include "twips.h"
+#include "config.h"
+
+#include <QImage>
+#include <QDebug>
+
+#define LOK_USE_UNSTABLE_API
+#include <LibreOfficeKit/LibreOfficeKitInit.h>
+#include <LibreOfficeKit/LibreOfficeKit.hxx>
+
+// TODO: Error management
+
+lok::Office *LODocument::s_office = nullptr;
+
+LODocument::LODocument()
+ : m_path("")
+ , m_document(nullptr)
+{
+ // This space is intentionally empty.
+}
+
+// Return the path of the loaded document
+QString LODocument::path() const
+{
+ return m_path;
+}
+
+// Set the path of the document, then it tries to load it.
+void LODocument::setPath(QString &pathName)
+{
+ if (pathName.isEmpty())
+ return;
+
+ m_path = pathName;
+ Q_EMIT pathChanged();
+
+ // Load the new document
+ this->loadDocument(m_path);
+}
+
+// Load the document
+bool LODocument::loadDocument(QString &pathName)
+{
+ qDebug() << "Loading document...";
+
+ if (pathName.isEmpty()) {
+ qDebug() << "Can't load the document, path is empty.";
+ return false;
+ }
+
+ if (!s_office)
+ s_office = lok::lok_cpp_init(LO_PATH);
+
+ m_document = s_office->documentLoad(m_path.toUtf8().constData());
+
+ m_docType = DocumentType(m_document->getDocumentType());
+ Q_EMIT documentTypeChanged();
+
+ m_document->initializeForRendering();
+ qDebug() << "Document loaded successfully !";
+
+ return true;
+}
+
+// Return the type of the loaded document (e.g. text document,
+// spreadsheet or presentation).
+LODocument::DocumentType LODocument::documentType() const
+{
+ return m_docType;
+}
+
+// Return the size of the document, in TWIPs
+QSize LODocument::documentSize() const
+{
+ if (!m_document)
+ return QSize(0, 0);
+
+ long pWidth(0);
+ long pHeight(0);
+ m_document->getDocumentSize(&pWidth, &pHeight);
+
+ return QSize(pWidth, pHeight);
+}
+
+// Paint a tile, with size=canvasSize, of the part of the document defined by
+// the rect tileSize.
+QImage LODocument::paintTile(QSize canvasSize, QRect tileSize)
+{
+ QImage result = QImage(canvasSize.width(), canvasSize.height(), QImage::Format_RGB32);
+ m_document->paintTile(result.bits(),
+ canvasSize.width(), canvasSize.height(),
+ Twips::convertPixelsToTwips(tileSize.x()),
+ Twips::convertPixelsToTwips(tileSize.y()),
+ Twips::convertPixelsToTwips(tileSize.width()),
+ Twips::convertPixelsToTwips(tileSize.height()));
+
+ return result.rgbSwapped();
+}
+
+/* Export the file in a given format:
+ * - url is a mandatory argument.
+ * - format is optional. If not specified, lok will try to get it from the file
+ * extension given at the 'url' argument.
+ * - filerOptions is also optional.
+ */
+// TODO: Is there some documentation on safe formats or filterOptions that can
+// be used?
+bool LODocument::saveAs(QString url, QString format = QString(), QString filterOptions = QString())
+{
+ if (!m_document) {
+ qDebug() << "No loaded document. It's not possible to save this file.";
+ return false;
+ }
+
+ return m_document->saveAs(url.toLatin1().constData(),
+ format.toLatin1().constData(),
+ filterOptions.toLatin1().constData());
+}
+
+LODocument::~LODocument()
+{
+ delete m_document;
+}
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013-2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef LODOCUMENT_H
+#define LODOCUMENT_H
+
+#include <QObject>
+
+namespace lok {
+class Office;
+class Document;
+}
+
+class LODocument : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(LODocument)
+
+ Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
+ Q_PROPERTY(DocumentType documentType READ documentType NOTIFY documentTypeChanged)
+ Q_ENUMS(DocumentType)
+
+public:
+ explicit LODocument();
+ virtual ~LODocument();
+
+ enum DocumentType {
+ TextDocument = 0,
+ SpreadsheetDocument = 1,
+ PresentationDocument = 2,
+ DrawingDocument = 3,
+ OtherDocument = 4
+ };
+
+ QString path() const;
+ void setPath(QString &pathName);
+
+ DocumentType documentType() const;
+
+ QSize documentSize() const;
+ QImage paintTile(QSize canvasSize, QRect tileSize);
+
+ Q_INVOKABLE bool saveAs(QString url, QString format, QString filterOptions);
+
+Q_SIGNALS:
+ void pathChanged();
+ void documentTypeChanged();
+
+private:
+ QString m_path;
+ DocumentType m_docType;
+
+ bool loadDocument(QString &pathNAme);
+
+ lok::Document *m_document;
+
+ static lok::Office *s_office;
+};
+
+#endif // LODOCUMENT_H
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/loview.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2015-09-09 13:32:03 +0000
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "loview.h"
+#include "lodocument.h"
+#include "tileitem.h"
+#include "twips.h"
+#include "config.h"
+
+#include <QPainter>
+#include <QImage>
+#include <QTimer>
+#include <QtCore/qmath.h>
+
+// TODO: Use a QQuickItem and implement painting through
+// updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData * data)
+
+LOView::LOView(QQuickItem *parent)
+ : QQuickPaintedItem(parent)
+ , m_parentFlickable(nullptr)
+ , m_document(nullptr)
+ , m_zoomFactor(1.0)
+ , m_cacheBuffer(TILE_SIZE * 3)
+ , m_visibleArea(0, 0, 0, 0)
+ , m_bufferArea(0, 0, 0, 0)
+{
+ Q_UNUSED(parent)
+
+ connect(this, SIGNAL(documentChanged()), this, SLOT(updateViewSize()));
+ connect(this, SIGNAL(zoomFactorChanged()), this, SLOT(updateViewSize()));
+ connect(this, SIGNAL(parentFlickableChanged()), this, SLOT(updateVisibleRect()));
+ connect(this, SIGNAL(cacheBufferChanged()), this, SLOT(updateVisibleRect()));
+ connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateVisibleRect()));
+}
+
+void LOView::paint(QPainter *painter)
+{
+ Q_FOREACH(TileItem* tile, m_tiles) {
+ painter->drawImage(tile->area(), tile->texture());
+ tile->setPainted(true);
+
+#ifdef DEBUG_SHOW_TILE_BORDER
+ painter->drawRect(tile->area());
+#endif
+ }
+}
+
+// Returns the parent QML Flickable
+QQuickItem* LOView::parentFlickable() const
+{
+ return m_parentFlickable;
+}
+
+// Set the parent QML Flickable
+void LOView::setParentFlickable(QQuickItem *flickable)
+{
+ if (m_parentFlickable == flickable)
+ return;
+
+ if (m_parentFlickable)
+ m_parentFlickable->disconnect(this);
+
+ m_parentFlickable = flickable;
+
+ connect(m_parentFlickable, SIGNAL(widthChanged()), this, SLOT(updateVisibleRect()));
+ connect(m_parentFlickable, SIGNAL(heightChanged()), this, SLOT(updateVisibleRect()));
+
+ connect(m_parentFlickable, SIGNAL(contentXChanged()), this, SLOT(scheduleVisibleRectUpdate()));
+ connect(m_parentFlickable, SIGNAL(contentYChanged()), this, SLOT(scheduleVisibleRectUpdate()));
+
+ Q_EMIT parentFlickableChanged();
+}
+
+// Return the LODocument rendered by this class
+LODocument* LOView::document() const
+{
+ return m_document;
+}
+
+// Set the LODocument
+void LOView::setDocument(LODocument *doc)
+{
+ if (m_document == doc)
+ return;
+
+ m_document = doc;
+ Q_EMIT documentChanged();
+}
+
+// Not used yet.
+qreal LOView::zoomFactor() const
+{
+ return m_zoomFactor;
+}
+
+// Not used yet.
+void LOView::setZoomFactor(qreal zoom)
+{
+ if (m_zoomFactor == zoom)
+ return;
+
+ m_zoomFactor = zoom;
+ Q_EMIT zoomFactorChanged();
+}
+
+int LOView::cacheBuffer() const
+{
+ return m_cacheBuffer;
+}
+
+void LOView::setCacheBuffer(int cacheBuffer)
+{
+ if (m_cacheBuffer == cacheBuffer)
+ return;
+
+ m_cacheBuffer = cacheBuffer;
+ Q_EMIT cacheBufferChanged();
+}
+
+// Update the size of LOView, according to the size of the loaded document.
+void LOView::updateViewSize()
+{
+ if (!m_document)
+ return;
+
+ QSize docSize = m_document->documentSize();
+
+ // FIXME: Area may become too large, resulting in a black texture.
+ this->setWidth(Twips::convertTwipsToPixels(docSize.width()) * m_zoomFactor);
+ this->setHeight(Twips::convertTwipsToPixels(docSize.height()) * m_zoomFactor);
+
+ // TODO: Consider to use connections to widthChanged and heightChanged
+ this->updateVisibleRect();
+}
+
+// Update the informations of the currently visible area of the parent
+// Flickable, then generate/delete all the required tiles, according to these
+// informations.
+void LOView::updateVisibleRect()
+{
+ if (!m_parentFlickable)
+ return;
+
+ // Update information about the visible area
+ m_visibleArea.setRect(m_parentFlickable->property("contentX").toInt(),
+ m_parentFlickable->property("contentY").toInt(),
+ m_parentFlickable->width(),
+ m_parentFlickable->height());
+
+ // Update information about the buffer area
+ m_bufferArea.setRect(qMax(0, m_visibleArea.x() - this->cacheBuffer()),
+ qMax(0, m_visibleArea.y() - this->cacheBuffer()),
+ qMin(int(this->width() - m_bufferArea.x()), m_visibleArea.width() + (this->cacheBuffer() * 2)),
+ qMin(int(this->height() - m_bufferArea.y()), m_visibleArea.height() + (this->cacheBuffer() * 2)));
+
+ // Delete tiles that are outside the loading area
+ if (!m_tiles.isEmpty()) {
+ auto i = m_tiles.begin();
+ while (i != m_tiles.end()) {
+ TileItem* tile = i.value();
+
+ if (!m_bufferArea.intersects(tile->area())) {
+ tile->releaseTexture();
+ i = m_tiles.erase(i);
+
+#ifdef DEBUG_VERBOSE
+ qDebug() << "Removing tile indexed as" << i.key();
+#endif
+ } else {
+ ++i;
+ }
+ }
+ }
+
+ // Number of tiles per row
+ int tilesPerWidth = qCeil(this->width() / TILE_SIZE);
+
+ // Get indexes for visible tiles
+ int visiblesFromWidth = int(m_visibleArea.left() / TILE_SIZE);
+ int visiblesFromHeight = int(m_visibleArea.top() / TILE_SIZE);
+ int visiblesToWidth = qCeil(qreal(m_visibleArea.right()) / TILE_SIZE);
+ int visiblesToHeight = qCeil(qreal(m_visibleArea.bottom()) / TILE_SIZE);
+
+ // Get indexes for tiles in the visible area
+ int bufferFromWidth = int(m_bufferArea.left() / TILE_SIZE);
+ int bufferFromHeight = int(m_bufferArea.top() / TILE_SIZE);
+ int bufferToWidth = qCeil(qreal(m_bufferArea.right()) / TILE_SIZE);
+ int bufferToHeight = qCeil(qreal(m_bufferArea.bottom()) / TILE_SIZE);
+
+ this->generateTiles(visiblesFromWidth, visiblesFromHeight, visiblesToWidth, visiblesToHeight, tilesPerWidth);
+ this->generateTiles(bufferFromWidth, bufferFromHeight, bufferToWidth, bufferToHeight, tilesPerWidth);
+}
+
+void LOView::generateTiles(int x1, int y1, int x2, int y2, int tilesPerWidth)
+{
+ for (int x = x1; x < x2; x++) {
+ for (int y = y1; y < y2; y++) {
+ QRect tileRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
+ int index = y * tilesPerWidth + x;
+
+ this->createTile(index, tileRect);
+ }
+ }
+}
+
+void LOView::createTile(int index, QRect rect)
+{
+ if (!m_tiles.contains(index)) {
+#ifdef DEBUG_VERBOSE
+ qDebug() << "Creating tile indexed as" << index;
+#endif
+
+ auto tile = new TileItem(rect, m_document);
+ connect(tile, SIGNAL(textureChanged()), this, SLOT(update()));
+ tile->requestTexture();
+
+ // Append the tile in the map
+ m_tiles.insert(index, tile);
+ }
+#ifdef DEBUG_VERBOSE
+ else {
+ qDebug() << "tile" << x << "x" << y << "already exists";
+ }
+#endif
+}
+
+void LOView::scheduleVisibleRectUpdate()
+{
+ if (!m_updateTimer.isActive())
+ m_updateTimer.start(20);
+}
+
+LOView::~LOView()
+{
+ //
+}
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LOVIEW_H
+#define LOVIEW_H
+
+#include <QQuickPaintedItem>
+#include <QTimer>
+
+class LODocument;
+class TileItem;
+
+class LOView : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickItem* parentFlickable READ parentFlickable WRITE setParentFlickable NOTIFY parentFlickableChanged)
+ Q_PROPERTY(LODocument* document READ document WRITE setDocument NOTIFY documentChanged)
+
+ // TODO: Implement zoom!
+ Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
+ Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
+
+public:
+ LOView(QQuickItem *parent = 0);
+ ~LOView();
+
+ void paint(QPainter *painter);
+
+ QQuickItem* parentFlickable() const;
+ void setParentFlickable(QQuickItem* flickable);
+
+ LODocument* document() const;
+ void setDocument(LODocument* doc);
+
+ qreal zoomFactor() const;
+ void setZoomFactor(qreal zoom);
+
+ int cacheBuffer() const;
+ void setCacheBuffer(int cacheBuffer);
+
+Q_SIGNALS:
+ void parentFlickableChanged();
+ void documentChanged();
+ void zoomFactorChanged();
+ void cacheBufferChanged();
+
+private Q_SLOTS:
+ void updateViewSize();
+ void updateVisibleRect();
+ void scheduleVisibleRectUpdate();
+
+private:
+ QQuickItem* m_parentFlickable;
+ LODocument* m_document;
+
+ qreal m_zoomFactor;
+ int m_cacheBuffer;
+
+ QRect m_visibleArea;
+ QRect m_bufferArea;
+
+ QTimer m_updateTimer;
+
+ QMap<int, TileItem*> m_tiles;
+
+ void generateTiles(int x1, int y1, int x2, int y2, int tilesPerWidth);
+ void createTile(int index, QRect rect);
+};
+
+#endif // LOVIEW_H
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp 2015-09-09 13:32:03 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <QtQml>
+#include <QtQml/QQmlContext>
+
+#include "plugin.h"
+#include "lodocument.h"
+#include "loview.h"
+
+void LOPlugin::registerTypes(const char *uri)
+{
+ Q_ASSERT(uri == QLatin1String("DocumentViewer.LibreOffice"));
+
+ //@uri DocumentViewer.LibreOffice
+ qmlRegisterType<LODocument>(uri, 1, 0, "Document");
+ qmlRegisterType<LOView>(uri, 1, 0, "View");
+}
+
+void LOPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
+{
+ QQmlExtensionPlugin::initializeEngine(engine, uri);
+}
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/plugin.h'
--- src/plugin/libreofficetoolkit-qml-plugin/plugin.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/plugin.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef LOPLUGIN_H
+#define LOPLUGIN_H
+
+#include <QQmlExtensionPlugin>
+
+class LOPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ void registerTypes(const char *uri);
+ void initializeEngine(QQmlEngine *engine, const char *uri);
+};
+
+#endif // LO_H
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/qmldir'
--- src/plugin/libreofficetoolkit-qml-plugin/qmldir 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/qmldir 2015-09-09 13:32:03 +0000
@@ -0,0 +1,4 @@
+module DocumentViewer.LibreOffice
+plugin libreofficetoolkitqmlplugin
+
+Viewer 1.0 LOViewer.qml
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/tileitem.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/tileitem.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/tileitem.cpp 2015-09-09 13:32:03 +0000
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Stefano Verzegnassi <stefano92.100@xxxxxxxxx>
+ */
+
+#include "tileitem.h"
+#include "lodocument.h"
+#include "config.h"
+
+#include <QThreadPool>
+#include <QDebug>
+
+#ifdef DEBUG_TILE_BENCHMARK
+#include <QElapsedTimer>
+#endif
+
+/* ****************
+ * TileItem class *
+ ******************/
+
+TileItem::TileItem(const QRect &area, LODocument *document)
+ : m_painted(false)
+ , m_document(nullptr)
+{
+ this->setArea(area);
+ this->setDocument(document);
+}
+
+// Destructor
+TileItem::~TileItem()
+{
+ this->releaseTexture();
+}
+
+QRect TileItem::area() const
+{
+ return m_area;
+}
+
+void TileItem::setArea(const QRect &area)
+{
+ if (m_area == area)
+ return;
+
+ m_area = area;
+ Q_EMIT areaChanged();
+}
+
+QImage TileItem::texture() const
+{
+ return m_texture;
+}
+
+bool TileItem::isPainted() const
+{
+ return m_painted;
+}
+
+void TileItem::setPainted(bool isPainted)
+{
+ if (m_painted == isPainted)
+ return;
+
+ m_painted = isPainted;
+ Q_EMIT isPaintedChanged();
+}
+
+LODocument* TileItem::document() const
+{
+ return m_document;
+}
+
+void TileItem::setDocument(LODocument* document)
+{
+ if (m_document == document)
+ return;
+
+ m_document = document;
+ Q_EMIT documentChanged();
+}
+
+void TileItem::requestTexture()
+{
+ auto task = new RenderTask(this->area(), this->document());
+ connect(task, SIGNAL(renderCompleted(QImage)), this, SLOT(updateTexture(QImage)));
+
+ task->setAutoDelete(true);
+ QThreadPool::globalInstance()->start(task);
+}
+
+// Free memory used by the texture
+void TileItem::releaseTexture()
+{
+ if (m_texture.isNull())
+ return;
+
+ m_texture = QImage();
+ Q_EMIT textureChanged();
+}
+
+// This is a slot, connect to renderCompleted() signal from RenderTask class.
+void TileItem::updateTexture(QImage t)
+{
+ m_texture = t;
+ Q_EMIT textureChanged();
+}
+
+/* ******************
+ * RenderTask class *
+ ********************/
+
+RenderTask::RenderTask(const QRect &area, LODocument* document)
+{
+ this->setArea(area);
+ this->setDocument(document);
+}
+
+
+QRect RenderTask::area() const
+{
+ return m_area;
+}
+
+void RenderTask::setArea(const QRect &area)
+{
+ if (m_area == area)
+ return;
+
+ m_area = area;
+ Q_EMIT areaChanged();
+}
+
+LODocument* RenderTask::document() const
+{
+ return m_document;
+}
+
+void RenderTask::setDocument(LODocument* document)
+{
+ if (m_document == document)
+ return;
+
+ m_document = document;
+ Q_EMIT documentChanged();
+}
+
+// Render the texture for this tile.
+void RenderTask::run()
+{
+#ifdef DEBUG_TILE_BENCHMARK
+ QElapsedTimer renderTimer;
+ renderTimer.start();
+#endif
+
+ QImage render = this->document()->paintTile(this->area().size(),
+ this->area());
+
+ Q_EMIT renderCompleted(render);
+
+#ifdef DEBUG_TILE_BENCHMARK
+ qDebug() << "Time to render the tile:" << renderTimer.elapsed() << "ms";
+#endif
+}
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/tileitem.h'
--- src/plugin/libreofficetoolkit-qml-plugin/tileitem.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/tileitem.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Stefano Verzegnassi <stefano92.100@xxxxxxxxx>
+ */
+
+#ifndef TILEITEM_H
+#define TILEITEM_H
+
+#include <QRunnable>
+#include <QImage>
+
+class LODocument;
+
+class TileItem : public QObject
+{
+ Q_OBJECT
+
+public:
+ TileItem(const QRect &area, LODocument* document);
+ ~TileItem();
+
+ QRect area() const;
+ void setArea(const QRect &area);
+
+ QImage texture() const;
+
+ bool isPainted() const;
+ void setPainted(bool isPainted);
+
+ LODocument* document() const;
+ void setDocument(LODocument* document);
+
+public Q_SLOTS:
+ void requestTexture();
+ void releaseTexture();
+
+Q_SIGNALS:
+ void areaChanged();
+ void textureChanged();
+ void isPaintedChanged();
+ void documentChanged();
+
+private Q_SLOTS:
+ void updateTexture(QImage t);
+
+private:
+ QRect m_area;
+ QImage m_texture;
+ bool m_painted;
+
+ LODocument* m_document;
+};
+
+class RenderTask : public QObject, public QRunnable
+{
+ Q_OBJECT
+
+public:
+ RenderTask(const QRect &area, LODocument* document);
+
+ QRect area() const;
+ void setArea(const QRect &area);
+
+ LODocument* document() const;
+ void setDocument(LODocument* document);
+
+ void run();
+
+Q_SIGNALS:
+ void areaChanged();
+ void documentChanged();
+ void renderCompleted(QImage t);
+
+private:
+ QRect m_area;
+ LODocument* m_document;
+};
+
+#endif // TILEITEM_H
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/twips.h'
--- src/plugin/libreofficetoolkit-qml-plugin/twips.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/twips.h 2015-09-09 13:32:03 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Stefano Verzegnassi <stefano92.100@xxxxxxxxx>
+ */
+
+#ifndef TWIPS_H
+#define TWIPS_H
+
+// FIXME: Should we check for the real DPI of the screen, since we'll have in
+// future to support HiDPI devices and Full/Ultra-HD smartphones/tablet?
+// FIXME: Not common, but DPI on the X axis, and DPI on the Y axis may be
+// different.
+#define VIRTUAL_DPI 96.0
+
+#include <QtGlobal>
+
+class Twips
+{
+public:
+ static inline int convertTwipsToPixels(int twips, qreal zoom = 1.0) {
+ return int(twips / 1440.0 * VIRTUAL_DPI * zoom);
+ }
+
+ static inline int convertPixelsToTwips(int pixels, qreal zoom = 1.0) {
+ return int(pixels * 1440.0 / VIRTUAL_DPI / zoom);
+ }
+};
+
+#endif // TWIPS_H