ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #04254
[Merge] lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-impress-support into lp:ubuntu-docviewer-app/reboot
Stefano Verzegnassi has proposed merging lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-impress-support into lp:ubuntu-docviewer-app/reboot with lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-lok-zoom as a prerequisite.
Commit message:
* Improved support for presentations
* Added keyboard support in loView
Requested reviews:
Ubuntu Document Viewer Developers (ubuntu-docviewer-dev)
For more details, see:
https://code.launchpad.net/~verzegnassi-stefano/ubuntu-docviewer-app/reboot-impress-support/+merge/267984
DO NOT MERGE YET. I propose this in order to discuss about its implementation.
- Added keyboard controls (PgUp, PgDown, Up, Down, Left, Right) in the LOK plugin (see src/app/qml/loView/KeybHelper.js)
- Improved support for presentation document type
- Conditional layout for the presentation view: use a bottom edge or a sidebar to show the list of slides
- Added an image provider for slides' thumbnails
Known issues:
- Thumbnails provides may require a bit more of work
- Invalidation for tiles is not definitive yet. We need it so that we're able to switch the current slide. It still requires the changes from lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-lok-zoom though.
- The slide shown in the viewer is badly rendered when the provider is still fetching the thumbnail.
The LOK library requires to switch the current visible part for doing this (see LibreOffice Viewer for Android), and we need to find out a way to pause the main rendering when this happens.
--
Your team Ubuntu Document Viewer Developers is requested to review the proposed merge of lp:~verzegnassi-stefano/ubuntu-docviewer-app/reboot-impress-support into lp:ubuntu-docviewer-app/reboot.
=== added file 'src/app/qml/loView/KeybHelper.js'
--- src/app/qml/loView/KeybHelper.js 1970-01-01 00:00:00 +0000
+++ src/app/qml/loView/KeybHelper.js 2015-08-13 18:29:47 +0000
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 Stefano Verzegnassi
+ *
+ * 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/>.
+ */
+
+function parseEvent(event) {
+ var pixelDiff = 5;
+
+ if (event.key == Qt.Key_PageUp) {
+ if (loDocument.documentType == LO.Document.PresentationDocument)
+ loDocument.currentPart -= 1
+ else
+ loPage.moveView("vertical", -loView.height)
+
+ return;
+ }
+
+ if (event.key == Qt.Key_PageDown) {
+ if (loDocument.documentType == LO.Document.PresentationDocument)
+ loDocument.currentPart += 1
+ else
+ loPage.moveView("vertical", loView.height)
+
+ return;
+ }
+
+ if (event.key == Qt.Key_Up) {
+ loPage.moveView("vertical", -pixelDiff)
+ return;
+ }
+
+ if (event.key == Qt.Key_Down) {
+ loPage.moveView("vertical", pixelDiff)
+ return;
+ }
+
+ if (event.key == Qt.Key_Left) {
+ loPage.moveView("horizontal", -pixelDiff)
+ return;
+ }
+
+ if (event.key == Qt.Key_Right) {
+ loPage.moveView("horizontal", pixelDiff)
+ return;
+ }
+}
=== added file 'src/app/qml/loView/LOPartsView.qml'
--- src/app/qml/loView/LOPartsView.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/loView/LOPartsView.qml 2015-08-13 18:29:47 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2015 Stefano Verzegnassi
+ *
+ * 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 DocumentViewer.LibreOffice 1.0 as LibreOffice
+
+import "../upstreamComponents"
+
+ListView {
+ id: view
+ objectName: "view"
+ clip: true
+
+ property bool expanded: true
+
+ currentIndex: view.model ? view.model.document.currentPart : -1
+
+ delegate: ListItemWithActions {
+ id: delegate
+
+ width: parent.width
+ height: units.gu(16)
+
+ color: (view.model.document.currentPart === model.index) ? Theme.palette.selected.background
+ : "transparent"
+
+ AbstractButton {
+ objectName: "abstractbutton"
+ anchors.fill: parent
+
+ onClicked: {
+ view.model.document.currentPart = model.index
+ pageStack.pop();
+ }
+ }
+
+ RowLayout {
+ anchors.fill: parent
+ spacing: units.gu(1)
+
+ Image {
+ Layout.fillHeight: true
+ Layout.preferredWidth: height
+ fillMode: Image.PreserveAspectFit
+
+ source: "image://lok/part/" + model.index
+ }
+
+ Label {
+ Layout.fillWidth: true
+ wrapMode: Text.WordWrap
+ text: model.name
+ color: (view.model.document.currentPart === model.index) ? UbuntuColors.orange
+ : Theme.palette.selected.backgroundText
+ }
+
+ Label {
+ text: model.index + 1
+ color: (view.model.document.currentPart === model.index) ? UbuntuColors.orange
+ : Theme.palette.selected.backgroundText
+ }
+ }
+ }
+
+ Scrollbar { flickableItem: view; parent: view.parent }
+}
=== modified file 'src/app/qml/loView/LOView.qml'
--- src/app/qml/loView/LOView.qml 2015-07-04 16:00:33 +0000
+++ src/app/qml/loView/LOView.qml 2015-08-13 18:29:47 +0000
@@ -16,60 +16,162 @@
import QtQuick 2.3
import Ubuntu.Components 1.1
+import Ubuntu.Layouts 1.0
import DocumentViewer.LibreOffice 1.0 as LO
+import "../upstreamComponents"
+
import "../common/utils.js" as Utils
-import "../upstreamComponents"
+import "KeybHelper.js" as KeybHelper
-Page {
+PageWithBottomEdge {
id: loPage
title: Utils.getNameOfFile(file.path);
+ readonly property bool wideWindow: width > units.gu(120)
+
+ function moveView(axis, diff) {
+ if (axis == "vertical") {
+ var maxContentY = Math.max(0, loView.contentHeight - loView.height)
+ loView.contentY = Math.max(0, Math.min(loView.contentY + diff, maxContentY ))
+ } else {
+ var maxContentX = Math.max(0, loView.contentWidth - loView.width)
+ loView.contentX = Math.max(0, Math.min(loView.contentX + diff, maxContentX ))
+ }
+ }
+
// 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"
+ // Keyboard events
+ focus: true
+ Keys.onPressed: KeybHelper.parseEvent(event)
+
+ // LibreOfficeKit parts are only supported for Presentation type
+ bottomEdgeEnabled: loDocument.documentType == LO.Document.PresentationDocument && !wideWindow
+ bottomEdgeTitle: i18n.tr("Slides")
+ bottomEdgePageComponent: Page {
+ title: i18n.tr("Slides")
+ head.backAction: Action {
+ text: i18n.tr("Back")
+ iconName: "down"
+ onTriggered: pageStack.pop()
+ }
+
+ flickable: null
+
+ LOPartsView {
+ anchors.fill: parent
+ model: partsModelLoader.item
+ }
+ }
+
+ Layouts {
+ id: layouts
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
+ layouts: [
+ ConditionalLayout {
+ when: wideWindow
+ name: "wideWindowLayout"
+
+ Item {
+ anchors.fill: parent
+
+ // TODO: Add a setting to show/hide sidebar when width > units.gu(80)
+ LOPartsView {
+ id: partsView
+ anchors {
+ top: parent.top
+ bottom: bottomBarLayoutItem.top
+ left: parent.left
+ }
+
+ model: partsModelLoader.item
+ visible: model
+ width: visible ? units.gu(40) : 0
+ }
+
+ Item {
+ anchors {
+ left: partsView.right
+ right: parent.right
+ top: parent.top
+ bottom: bottomBarLayoutItem.top
+ }
+ ItemLayout { item: "loView"; anchors.fill: parent }
+ }
+
+ Item {
+ id: bottomBarLayoutItem
+ visible: loDocument.documentType == LO.Document.PresentationDocument
+ height: visible ? units.gu(5) : 0
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+
+ ItemLayout { item: "bottomBar"; anchors.fill: parent }
+ }
+ }
+ }
+ ]
+
+ LO.Viewer {
+ id: loView
+ objectName: "loView"
+ Layouts.item: "loView"
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: parent.top
+ bottom: bottomBar.top
+ }
+
+ 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; parent: loView.parent }
+ Scrollbar { flickableItem: loView; parent: loView.parent; align: Qt.AlignBottom }
+ }
+
+ // TODO: When we'll have to merge this with the zooming branch, replace this
+ // and use a single bottom panel
+ SlideControllerPanel {
+ id: bottomBar
+ Layouts.item: "bottomBar"
+ visible: loDocument.documentType == LO.Document.PresentationDocument
+ height: visible ? units.gu(5) : 0
+ anchors {
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
}
}
- 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);
- }*/
+ }
+
+ // We use a loader here, since not all the document types support LOK:Parts
+ // This prevents the thumbnail provider to try a tile rendering of the part.
+ Loader {
+ id: partsModelLoader
+ active: loDocument.documentType == LO.Document.PresentationDocument
+ sourceComponent: LO.PartsModel { document: loDocument }
}
// *** HEADER ***
=== added file 'src/app/qml/loView/SlideControllerPanel.qml'
--- src/app/qml/loView/SlideControllerPanel.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/loView/SlideControllerPanel.qml 2015-08-13 18:29:47 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 Stefano Verzegnassi
+ *
+ * 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.ListItems 1.0 as ListItems
+
+Rectangle {
+ id: bottomBar
+ color: "transparent"
+ height: units.gu(5)
+
+ ListItems.ThinDivider {
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ }
+
+ Row {
+ anchors.centerIn: parent
+ spacing: units.gu(2)
+
+ AbstractButton {
+ width: units.gu(4); height: parent.height
+ onClicked: loDocument.currentPart -= 1
+
+ Icon {
+ id: icon
+ anchors.centerIn: parent
+ width: units.gu(2.5); height: width
+ name: "go-previous"
+ }
+ }
+
+ Label {
+ text: "%1 of %2".arg(loDocument.currentPart + 1).arg(loDocument.partsCount)
+ }
+
+ AbstractButton {
+ width: units.gu(4); height: parent.height
+ onClicked: loDocument.currentPart += 1
+
+ Icon {
+ anchors.centerIn: parent
+ width: units.gu(2.5); height: width
+ name: "go-next"
+ }
+ }
+ }
+}
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt'
--- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-07-22 16:44:39 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt 2015-08-13 18:29:47 +0000
@@ -13,6 +13,8 @@
lodocument.cpp
loview.cpp
tileitem.cpp
+ lopartsimageprovider.cpp
+ lopartsmodel.cpp
${QML_SRCS}
)
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-07-23 01:05:20 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.cpp 2015-08-13 18:29:47 +0000
@@ -56,6 +56,25 @@
this->loadDocument(m_path);
}
+int LODocument::currentPart() {
+ if (!m_document)
+ return int(-1);
+
+ return m_document->getPart();
+}
+
+void LODocument::setCurrentPart(int index)
+{
+ if (!m_document)
+ return;
+
+ if (this->currentPart() == index || index < 0 || index > partsCount() - 1)
+ return;
+
+ m_document->setPart(index);
+ Q_EMIT currentPartChanged();
+}
+
// Load the document
bool LODocument::loadDocument(QString &pathName)
{
@@ -115,6 +134,33 @@
return result.rgbSwapped();
}
+int LODocument::partsCount()
+{
+ if (!m_document)
+ return int(0);
+
+ return m_document->getParts();
+}
+
+QString LODocument::getPartName(int index) const
+{
+ if (!m_document)
+ return QString();
+
+ return QString::fromLatin1(m_document->getPartName(index));
+}
+
+// This is used by LOPartsImageProvider to temporarily change the current part,
+// in order to generate thumbnails.
+// FIXME: We need to disable tiled rendering when we're generating the thumbnail.
+int LODocument::swapCurrentPart(int newPartIndex)
+{
+ int oldIndex = this->currentPart();
+
+ m_document->setPart(newPartIndex);
+ return oldIndex;
+}
+
/* 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
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/lodocument.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2015-07-23 01:05:20 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lodocument.h 2015-08-13 18:29:47 +0000
@@ -31,6 +31,9 @@
Q_DISABLE_COPY(LODocument)
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
+ Q_PROPERTY(int currentPart READ currentPart WRITE setCurrentPart NOTIFY currentPartChanged)
+ // Declare partsCount as constant at the moment, since LOK-plugin is just a viewer for now.
+ Q_PROPERTY(int partsCount READ partsCount CONSTANT)
Q_PROPERTY(DocumentType documentType READ documentType NOTIFY documentTypeChanged)
Q_ENUMS(DocumentType)
@@ -49,15 +52,26 @@
QString path() const;
void setPath(QString &pathName);
+ int currentPart();
+ void setCurrentPart(int index);
+
DocumentType documentType() const;
QSize documentSize() const;
QImage paintTile(QSize canvasSize, QRect tileSize);
+ int partsCount();
+
+ QString getPartName(int index) const;
+ int swapCurrentPart(int newPartIndex);
+
+ void setPart(int index);
+
Q_INVOKABLE bool saveAs(QString url, QString format, QString filterOptions);
Q_SIGNALS:
void pathChanged();
+ void currentPartChanged();
void documentTypeChanged();
private:
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.cpp 2015-08-13 18:29:47 +0000
@@ -0,0 +1,78 @@
+/*
+ * 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 "lopartsimageprovider.h"
+#include "lodocument.h"
+#include "config.h"
+#include "twips.h"
+
+#include <QDebug>
+
+LOPartsImageProvider::LOPartsImageProvider(LODocument *document)
+ : QQuickImageProvider(QQuickImageProvider::Image, QQuickImageProvider::ForceAsynchronousImageLoading)
+{
+ m_document = document;
+}
+
+QImage LOPartsImageProvider::requestImage(const QString & id, QSize * size, const QSize & requestedSize)
+{
+ Q_UNUSED(size)
+ Q_UNUSED(requestedSize)
+
+ // Here's the tricky magic. For getting a thumbnail of a document part
+ // (e.g. a specific slide in a Impress document), we need to change the
+ // current active part in LODocument, render the thumbnail, then re-set
+ // the previous value through lok::Document::setPath(index).
+
+ QString type = id.section("/", 0, 0);
+ QImage result;
+
+ if (type == "part")
+ {
+ int partNumber = id.section("/", 1, 1).toInt();
+ QSize partSize;
+ QSize resultSize;
+
+ // Get the current part index and set the index of the part to be rendered.
+ int currentPart = m_document->swapCurrentPart(partNumber);
+
+ // Get the size of the part
+ partSize = m_document->documentSize();
+ partSize.setHeight(Twips::convertTwipsToPixels(partSize.height()));
+ partSize.setWidth(Twips::convertTwipsToPixels(partSize.width()));
+
+ // Set the size of the rendered thumbnail
+ if (partSize.width() > partSize.height()) {
+ resultSize.setWidth(TILE_SIZE);
+ resultSize.setHeight(TILE_SIZE * partSize.height() / partSize.width());
+ } else {
+ resultSize.setHeight(TILE_SIZE);
+ resultSize.setWidth(TILE_SIZE * partSize.width() / partSize.height());
+ }
+
+ // Render the part to QImage
+ result = m_document->paintTile(resultSize, QRect(QPoint(0, 0), partSize));
+
+ // Re-set the earlier current part
+ m_document->swapCurrentPart(currentPart);
+ }
+
+ return result;
+
+
+ // Requested size is 0, so return a null image.
+ // return QImage();
+}
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsimageprovider.h 2015-08-13 18:29:47 +0000
@@ -0,0 +1,35 @@
+/*
+ * 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 LOPARTSIMAGEPROVIDER_H
+#define LOPARTSIMAGEPROVIDER_H
+
+#include <QQuickImageProvider>
+
+class LODocument;
+
+class LOPartsImageProvider : public QQuickImageProvider
+{
+public:
+ LOPartsImageProvider(LODocument *document);
+ QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize);
+
+private:
+ LODocument *m_document;
+};
+
+#endif // LOPARTSIMAGEPROVIDER_H
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.cpp 2015-08-13 18:29:47 +0000
@@ -0,0 +1,125 @@
+/*
+ * 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 "lopartsmodel.h"
+#include "lodocument.h"
+#include "lopartsimageprovider.h"
+
+#include <QQmlContext>
+#include <QQmlEngine>
+#include <QDebug>
+
+LOPartsModel::LOPartsModel(QAbstractListModel *parent):
+ QAbstractListModel(parent)
+{
+ connect(this, SIGNAL(documentChanged()), this, SLOT(fillModel()));
+}
+
+void LOPartsModel::setDocument(LODocument *document)
+{
+ if (m_document == document)
+ return;
+
+ m_document = document;
+ Q_EMIT documentChanged();
+
+ QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
+ QString imageProviderName = "lok";
+
+ if (engine->imageProvider(imageProviderName))
+ engine->removeImageProvider(imageProviderName);
+
+ engine->addImageProvider(imageProviderName, new LOPartsImageProvider(m_document));
+
+}
+
+QHash<int, QByteArray> LOPartsModel::roleNames() const
+{
+ QHash<int, QByteArray> roles;
+ roles[IndexRole] = "index";
+ roles[NameRole] = "name";
+
+ return roles;
+}
+
+int LOPartsModel::rowCount(const QModelIndex & parent) const
+{
+ Q_UNUSED(parent)
+ return m_entries.count();
+}
+
+QVariant LOPartsModel::data(const QModelIndex & index, int role) const
+{
+ if (index.row() < 0 || index.row() > m_entries.count())
+ return QVariant();
+
+ const LOPartEntry &part = m_entries.at(index.row());
+
+ switch (role) {
+ case IndexRole:
+ return part.index;
+ case NameRole:
+ return part.name;
+
+ default:
+ return 0;
+ }
+}
+
+QVariantMap LOPartsModel::get(int index) const
+{
+ if (index < 0 || index > m_entries.count() - 1) {
+ qWarning() << Q_FUNC_INFO << "Index not valid, return undefined";
+ return QVariantMap();
+ }
+
+ const LOPartEntry &part = m_entries.at(index);
+
+ QVariantMap map;
+ map["name"] = part.name;
+ map["index"] = part.index;
+
+ return map;
+}
+
+void LOPartsModel::fillModel() {
+ if (m_document) {
+ if (!m_entries.isEmpty()) {
+ beginRemoveRows(QModelIndex(), 0, rowCount());
+ m_entries.clear();
+ endRemoveRows();
+ }
+
+ int partsCount = m_document->partsCount();
+
+ for (int i = 0; i < partsCount; i++) {
+ LOPartEntry part;
+ part.index = i;
+ part.name = m_document->getPartName(i);
+
+ beginRemoveRows(QModelIndex(), rowCount(), rowCount());
+ m_entries.append(part);
+ endRemoveRows();
+ }
+
+ Q_EMIT countChanged();
+ }
+}
+
+LOPartsModel::~LOPartsModel()
+{
+}
=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lopartsmodel.h 2015-08-13 18:29:47 +0000
@@ -0,0 +1,70 @@
+/*
+ * 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 LOPARTSMODEL_H
+#define LOPARTSMODEL_H
+
+#include <QAbstractListModel>
+
+class LODocument;
+
+class LOPartEntry
+{
+public:
+ QString name;
+ int index = 0;
+};
+
+class LOPartsModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(LOPartsModel)
+ Q_PROPERTY(LODocument* document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
+
+public:
+ enum Roles {
+ NameRole,
+ IndexRole
+ };
+
+ explicit LOPartsModel(QAbstractListModel *parent = 0);
+ ~LOPartsModel();
+
+ LODocument* document() { return m_document; }
+ void setDocument(LODocument* document);
+
+ QHash<int, QByteArray> roleNames() const;
+
+ int rowCount(const QModelIndex & parent = QModelIndex()) const;
+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
+
+ Q_INVOKABLE QVariantMap get(int index) const;
+
+Q_SIGNALS:
+ void documentChanged();
+ void countChanged();
+
+private slots:
+ void fillModel();
+
+private:
+ LODocument* m_document;
+ QList<LOPartEntry> m_entries;
+};
+
+#endif // LOPARTSMODEL_H
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2015-07-26 17:33:51 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.cpp 2015-08-13 18:29:47 +0000
@@ -96,8 +96,13 @@
if (m_document == doc)
return;
+ if (m_document)
+ m_document->disconnect(this);
+
m_document = doc;
Q_EMIT documentChanged();
+
+ connect(m_document, SIGNAL(currentPartChanged()), this, SLOT(invalidateAllTiles()));
}
// Not used yet.
@@ -216,6 +221,14 @@
}
}
+// FIXME: Just for the moment. In zoom branch we have all we need :)
+void LOView::invalidateAllTiles()
+{
+ m_tiles.clear();
+
+ this->updateViewSize();
+}
+
void LOView::createTile(int index, QRect rect)
{
if (!m_tiles.contains(index)) {
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-07-26 17:33:51 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.h 2015-08-13 18:29:47 +0000
@@ -61,6 +61,7 @@
void updateViewSize();
void updateVisibleRect();
void scheduleVisibleRectUpdate();
+ void invalidateAllTiles();
private:
QQuickItem* m_parentFlickable;
=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp 2015-07-04 16:00:33 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp 2015-08-13 18:29:47 +0000
@@ -21,6 +21,7 @@
#include "plugin.h"
#include "lodocument.h"
#include "loview.h"
+#include "lopartsmodel.h"
void LOPlugin::registerTypes(const char *uri)
{
@@ -29,6 +30,7 @@
//@uri DocumentViewer.LibreOffice
qmlRegisterType<LODocument>(uri, 1, 0, "Document");
qmlRegisterType<LOView>(uri, 1, 0, "View");
+ qmlRegisterType<LOPartsModel>(uri, 1, 0, "PartsModel");
}
void LOPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
Follow ups