← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-zoom-object into lp:ubuntu-docviewer-app

 

Stefano Verzegnassi has proposed merging lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-zoom-object into lp:ubuntu-docviewer-app.

Commit message:
LibreOffice QML plugin:
* Provide zoom settings as grouped properties
* Added a minimum and a maximum value for the zoom factor
* Removed any reference to zoomFactor from SGTileItem
* Expose to QML the values for 'fitToWidth', 'fitToHeight' and 'Automatic' zoom

Requested reviews:
  Ubuntu Document Viewer Developers (ubuntu-docviewer-dev)

For more details, see:
https://code.launchpad.net/~verzegnassi-stefano/ubuntu-docviewer-app/lok-zoom-object/+merge/283691

LibreOffice QML plugin:
*** Provide zoom settings as grouped properties
Well, with this branch the LibreOffice view has 8 properties about zoom settings.
I thought it's the case to gather those properties in a separate object, so that we're more comfortable when we have to deal with LOView.

*** Added a minimum and a maximum value for the zoom factor - 0.25 (min) and 4.0 (max).
On phones the default zoom factor was lower than the previous minimum value (0.5).
Values outside the interval [0.25, 4.0] are not longer accepted by the view.
We expose these values to QML so that we can set the ScalingPinchArea accordingly.
At the moment, they're only read-only. We could make them writable in future.

*** Removed any reference to zoomFactor from SGTileItem
I know Roman you wanted this. :)

*** Expose to QML the values for 'fitToWidth', 'fitToHeight' and 'Automatic' zoom
We may need them for setting the ScalingPinchArea when DocViewer is running on a phone.
-- 
Your team Ubuntu Document Viewer Developers is requested to review the proposed merge of lp:~verzegnassi-stefano/ubuntu-docviewer-app/lok-zoom-object into lp:ubuntu-docviewer-app.
=== modified file 'src/app/qml/loView/LOViewPage.qml'
--- src/app/qml/loView/LOViewPage.qml	2015-12-27 07:30:41 +0000
+++ src/app/qml/loView/LOViewPage.qml	2016-01-22 20:14:59 +0000
@@ -107,7 +107,7 @@
                     documentPath: file.path
 
                     function updateContentSize(tgtScale) {
-                        zoomFactor = tgtScale
+                        zoomSettings.zoomFactor = tgtScale
                     }
 
                     // Keyboard events

=== modified file 'src/app/qml/loView/ZoomSelector.qml'
--- src/app/qml/loView/ZoomSelector.qml	2015-12-27 17:41:17 +0000
+++ src/app/qml/loView/ZoomSelector.qml	2016-01-22 20:14:59 +0000
@@ -39,14 +39,14 @@
 
     onHighlightedChanged: {
         if (highlighted) {
-            text = parseInt(textField.view.zoomFactor * 100)
+            text = parseInt(textField.view.zoomSettings.zoomFactor * 100)
         } else text = ""
     }
 
     Label {
         anchors.centerIn: parent
         visible: !textField.highlighted
-        text: "%1%".arg(parseInt(textField.view.zoomFactor*100))
+        text: "%1%".arg(parseInt(textField.view.zoomSettings.zoomFactor*100))
     }
 
     popover: TextFieldButtonPopover {
@@ -66,7 +66,7 @@
                 Layout.fillHeight: true
                 Layout.fillWidth: true
 
-                onClicked: textField.view.setZoom(textField.view.zoomFactor + 0.1)
+                onClicked: textField.view.setZoom(textField.view.zoomSettings.zoomFactor + 0.1)
 
                 Icon {
                     width: units.gu(2); height: width
@@ -85,7 +85,7 @@
                 Layout.fillHeight: true
                 Layout.fillWidth: true
 
-                onClicked: textField.view.setZoom(textField.view.zoomFactor - 0.1)
+                onClicked: textField.view.setZoom(textField.view.zoomSettings.zoomFactor - 0.1)
 
                 Icon {
                     width: units.gu(2); height: width
@@ -105,30 +105,30 @@
             id: zoomModesRepeater
 
             function delegate_onClicked(mode) {
-                if (mode === LibreOffice.View.FitToWidth)
+                if (mode === LibreOffice.Zoom.FitToWidth)
                     textField.view.adjustZoomToWidth()
 
-                if (mode === LibreOffice.View.FitToHeight)
+                if (mode === LibreOffice.Zoom.FitToHeight)
                     textField.view.adjustZoomToHeight()
 
-                if (mode === LibreOffice.View.Automatic)
+                if (mode === LibreOffice.Zoom.Automatic)
                     textField.view.adjustAutomaticZoom()
             }
 
             // Used for hiding the HorizontalDivider below.
-            visible: view.zoomModesAvailable > LibreOffice.View.Manual
+            visible: view.zoomSettings.zoomModesAvailable > LibreOffice.Zoom.Manual
 
             model: [
-                { text: i18n.tr("Fit width"),  mode: LibreOffice.View.FitToWidth  },
-                { text: i18n.tr("Fit height"), mode: LibreOffice.View.FitToHeight },
-                { text: i18n.tr("Automatic"),  mode: LibreOffice.View.Automatic   }
+                { text: i18n.tr("Fit width"),  mode: LibreOffice.Zoom.FitToWidth  },
+                { text: i18n.tr("Fit height"), mode: LibreOffice.Zoom.FitToHeight },
+                { text: i18n.tr("Automatic"),  mode: LibreOffice.Zoom.Automatic   }
             ]
 
             ListItem {
                 height: units.gu(4)
                 divider.visible: false
 
-                visible: view.zoomModesAvailable & modelData.mode
+                visible: view.zoomSettings.zoomModesAvailable & modelData.mode
 
                 onClicked: {
                     zoomSelectorDialogue.close()
@@ -148,7 +148,7 @@
                         width: units.gu(2); height: width
                         name: "tick"
                         color: UbuntuColors.green
-                        visible: textField.view.zoomMode == modelData.mode
+                        visible: textField.view.zoomSettings.zoomMode == modelData.mode
                     }
                 }
             }   // ListItem

=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt'
--- src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt	2016-01-18 00:02:05 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/CMakeLists.txt	2016-01-22 20:14:59 +0000
@@ -26,6 +26,7 @@
     lopartsmodel.cpp
     lorendertask.cpp
     ucunits.cpp
+    lozoom.cpp
     ${QML_SRCS}
 )
 

=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.cpp	2016-01-17 22:57:05 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.cpp	2016-01-22 20:14:59 +0000
@@ -16,6 +16,7 @@
 
 #include "loview.h"
 #include "lodocument.h"
+#include "lozoom.h"
 #include "sgtileitem.h"
 #include "twips.h"
 #include "config.h"
@@ -24,42 +25,33 @@
 #include <QTimer>
 #include <QtCore/qmath.h>
 
-static qreal zoomValueToFitWidth;
-static qreal zoomValueToFitHeight;
-
-static qreal getZoomToFitWidth(const qreal &width, int documentWidth)
-{
-    return qreal(width / Twips::convertTwipsToPixels(documentWidth, 1.0));
-}
-
-static qreal getZoomToFitHeight(const qreal &height, int documentHeight)
-{
-    return qreal(height / Twips::convertTwipsToPixels(documentHeight, 1.0));
-}
-
 LOView::LOView(QQuickItem *parent)
     : QQuickItem(parent)
     , m_parentFlickable(nullptr)
     , m_document(nullptr)
+    , m_zoomSettings(new LOZoom(this))
     , m_partsModel(nullptr)
     , m_currentPart(0)
-    , m_zoomFactor(1.0)
-    , m_zoomModesAvailable(ZoomMode::Manual)
     , m_cacheBuffer(TILE_SIZE * 3)
     , m_visibleArea(0, 0, 0, 0)
     , m_bufferArea(0, 0, 0, 0)
     , m_error(LibreOfficeError::NoError)
+    , m_zoomValueHasChanged(false)
 {
     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()));
+    connect(this, &LOView::documentChanged, this, &LOView::updateViewSize);
+    connect(this, &LOView::parentFlickableChanged, this, &LOView::updateVisibleRect);
+    connect(this, &LOView::cacheBufferChanged, this, &LOView::updateVisibleRect);
+    connect(&m_updateTimer, &QTimer::timeout, this, &LOView::updateVisibleRect);
 
     connect(RenderEngine::instance(), &RenderEngine::taskRenderFinished,
             this, &LOView::slotTaskRenderFinished);
+
+    connect(m_zoomSettings, &LOZoom::zoomFactorChanged, [&]() {
+        m_zoomValueHasChanged = true;
+        updateViewSize();
+    });
 }
 
 // Returns the parent QML Flickable
@@ -127,21 +119,32 @@
 
     Q_EMIT documentChanged();
 
-    // Set the proper zoom mode, according to the type of the loaded document.
-    setZoomModesAvailability();
-
-    switch (m_document.data()->documentType()) {
-    case LODocument::DocumentType::SpreadsheetDocument:
-        setZoomMode(ZoomMode::Manual);
-        setZoomFactor(1.0);
-        break;
-    case LODocument::DocumentType::PresentationDocument:
-        setZoomMode(ZoomMode::Automatic);
-        break;
-    default:
-        setZoomMode(ZoomMode::FitToWidth);
-        break;
-    }
+    // Init zoom settings
+    m_zoomSettings->init();
+}
+
+bool LOView::adjustZoomToWidth()
+{
+    if (!m_zoomSettings)
+        return false;
+
+    return m_zoomSettings->adjustZoomToWidth();
+}
+
+bool LOView::adjustZoomToHeight()
+{
+    if (!m_zoomSettings)
+        return false;
+
+    return m_zoomSettings->adjustZoomToHeight();
+}
+
+bool LOView::adjustAutomaticZoom()
+{
+    if (!m_zoomSettings)
+        return false;
+
+    return m_zoomSettings->adjustAutomaticZoom();
 }
 
 // Return the LODocument rendered by this class
@@ -155,6 +158,11 @@
     return m_partsModel;
 }
 
+LOZoom *LOView::zoomSettings() const
+{
+    return m_zoomSettings;
+}
+
 int LOView::currentPart() {
     return m_currentPart;
 }
@@ -171,43 +179,6 @@
     Q_EMIT currentPartChanged();
 }
 
-qreal LOView::zoomFactor() const
-{
-    return m_zoomFactor;
-}
-
-void LOView::setZoomFactor(const qreal zoom)
-{
-    if (m_zoomFactor == zoom)
-        return;
-
-    m_zoomFactor = zoom;
-
-   if (m_zoomFactor != zoomValueToFitWidth && m_zoomFactor != zoomValueToFitHeight)
-        setZoomMode(LOView::Manual);
-
-    Q_EMIT zoomFactorChanged();
-}
-
-LOView::ZoomMode LOView::zoomMode() const
-{
-    return m_zoomMode;
-}
-
-LOView::ZoomModes LOView::zoomModesAvailable() const
-{
-    return m_zoomModesAvailable;
-}
-
-void LOView::setZoomMode(const ZoomMode zoomMode)
-{
-    if (m_zoomMode == zoomMode)
-        return;
-
-    m_zoomMode = zoomMode;
-    Q_EMIT zoomModeChanged();
-}
-
 int LOView::cacheBuffer() const
 {
     return m_cacheBuffer;
@@ -227,81 +198,16 @@
     return m_error;
 }
 
-bool LOView::adjustZoomToWidth(bool changeMode)
-{
-    if (!m_document)
-        return false;
-
-    if (changeMode)
-        setZoomMode(LOView::FitToWidth);
-
-    zoomValueToFitWidth = getZoomToFitWidth(m_parentFlickable->width(),
-                                            m_document->documentSize().width());
-
-    if (m_zoomFactor != zoomValueToFitWidth) {
-        setZoomFactor(zoomValueToFitWidth);
-
-        qDebug() << Q_FUNC_INFO << "- value:" << m_zoomFactor << "- changeMode:" << changeMode;
-        return true;
-    }
-
-    return false;
-}
-
-bool LOView::adjustZoomToHeight(bool changeMode)
-{
-    if (!m_document)
-        return false;
-
-    if (changeMode)
-        setZoomMode(LOView::FitToHeight);
-
-    zoomValueToFitHeight = getZoomToFitHeight(m_parentFlickable->height(),
-                                              m_document->documentSize().height());
-
-    if (m_zoomFactor != zoomValueToFitHeight) {
-        setZoomFactor(zoomValueToFitHeight);
-
-        qDebug() << Q_FUNC_INFO << "- value:" << m_zoomFactor << "- changeMode:" << changeMode;
-        return true;
-    }
-
-    return false;
-}
-
-bool LOView::adjustAutomaticZoom(bool changeMode)
-{
-    if (!m_document)
-        return false;
-
-    if (changeMode)
-        setZoomMode(LOView::Automatic);
-
-    zoomValueToFitWidth = getZoomToFitWidth(m_parentFlickable->width(),
-                                            m_document->documentSize().width());
-
-    zoomValueToFitHeight = getZoomToFitHeight(m_parentFlickable->height(),
-                                              m_document->documentSize().height());
-
-    if (m_zoomFactor != qMin(zoomValueToFitHeight, zoomValueToFitWidth)) {
-        setZoomFactor(qMin(zoomValueToFitHeight, zoomValueToFitWidth));
-
-        qDebug() << Q_FUNC_INFO << "- value:" << m_zoomFactor << "- changeMode:" << changeMode;
-        return true;
-    }
-
-    return false;
-}
-
 void LOView::updateViewSize()
 {
     if (!m_document)
         return;
 
     QSize docSize = m_document->documentSize();
+    qreal zoomFactor = m_zoomSettings->zoomFactor();
 
-    this->setWidth(Twips::convertTwipsToPixels(docSize.width(), m_zoomFactor));
-    this->setHeight(Twips::convertTwipsToPixels(docSize.height(), m_zoomFactor));
+    this->setWidth(Twips::convertTwipsToPixels(docSize.width(), zoomFactor));
+    this->setHeight(Twips::convertTwipsToPixels(docSize.height(), zoomFactor));
 
     updateVisibleRect();
 }
@@ -361,32 +267,29 @@
      *                                 L-> zoomFactorChanged() -> updateViewSize() -> updateVisibleRect()
      */
 
-    if (m_zoomMode == LOView::FitToWidth) {
-        if (adjustZoomToWidth(false))
-            return;
-    }
-
-    else if (m_zoomMode == LOView::FitToHeight) {
-        if (adjustZoomToHeight(false))
-            return;
-    }
-
-    else if (m_zoomMode == LOView::Automatic) {
-        if (adjustAutomaticZoom(false))
+    if (m_zoomSettings->zoomMode() == LOZoom::FitToWidth) {
+        if (m_zoomSettings->adjustZoomToWidth(false))
+            return;
+    }
+
+    else if (m_zoomSettings->zoomMode() == LOZoom::FitToHeight) {
+        if (m_zoomSettings->adjustZoomToHeight(false))
+            return;
+    }
+
+    else if (m_zoomSettings->zoomMode() == LOZoom::Automatic) {
+        if (m_zoomSettings->adjustAutomaticZoom(false))
             return;
     }
 
     // Check if current tiles have a different zoom value
-    if (!m_tiles.isEmpty()) {
-        SGTileItem* tile = m_tiles.first();
-
-        if (tile->zoomFactor() != m_zoomFactor) {
-            clearView();
-
+    if (m_zoomValueHasChanged && !m_tiles.isEmpty()) {
+        m_zoomValueHasChanged = false;
 #ifdef DEBUG_VERBOSE
-            qDebug() << "Zoom value of tiles is different than the current zoom value. Erasing cache...";
+        qDebug() << "Zoom value of tiles is different than the current zoom value. Erasing cache...";
 #endif
-        }
+
+        clearView();
     }
 
     // Just for convenience.
@@ -502,7 +405,7 @@
         qDebug() << "Creating tile indexed as" << index << "- Rect:" << rect;
 #endif
 
-        auto tile = new SGTileItem(rect, m_zoomFactor, RenderEngine::getNextId(), this);
+        auto tile = new SGTileItem(rect, RenderEngine::getNextId(), this);
         m_tiles.insert(index, tile);
         RenderEngine::instance()->enqueueTask(createTask(rect, tile->id()));
     }
@@ -522,8 +425,6 @@
     m_updateTimer.start(20);
 }
 
-
-
 void LOView::clearView()
 {
     for (auto i = m_tiles.begin(); i != m_tiles.end(); ++i)
@@ -544,7 +445,7 @@
     task->setPart(m_currentPart);
     task->setDocument(m_document);
     task->setArea(rect);
-    task->setZoom(m_zoomFactor);
+    task->setZoom(m_zoomSettings->zoomFactor());
     return task;
 }
 
@@ -577,41 +478,15 @@
     Q_EMIT errorChanged();
 }
 
-void LOView::setZoomModesAvailability()
-{
-    if (!m_document)
-        return;
-
-    ZoomModes newZoomModesAvailable;
-    newZoomModesAvailable |= ZoomMode::Manual;
-
-    switch (m_document.data()->documentType()) {
-    case LODocument::DocumentType::TextDocument:
-        newZoomModesAvailable |= ZoomMode::FitToWidth;
-        break;
-    case LODocument::DocumentType::SpreadsheetDocument:
-        break;
-    default:
-        newZoomModesAvailable |= ZoomMode::FitToWidth;
-        newZoomModesAvailable |= ZoomMode::FitToHeight;
-        newZoomModesAvailable |= ZoomMode::Automatic;
-        break;
-    }
-
-    if (m_zoomModesAvailable != newZoomModesAvailable) {
-        m_zoomModesAvailable = newZoomModesAvailable;
-        Q_EMIT zoomModesAvailableChanged();
-    }
-}
-
 LOView::~LOView()
 {
-    delete m_partsModel;
-
     disconnect(RenderEngine::instance(), &RenderEngine::taskRenderFinished,
             this, &LOView::slotTaskRenderFinished);
 
     // Remove all tasks from rendering queue.
     for (auto i = m_tiles.begin(); i != m_tiles.end(); ++i)
         RenderEngine::instance()->dequeueTask(i.value()->id());
+
+    delete m_partsModel;
+    delete m_zoomSettings;
 }

=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/loview.h'
--- src/plugin/libreofficetoolkit-qml-plugin/loview.h	2016-01-17 22:57:05 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/loview.h	2016-01-22 20:14:59 +0000
@@ -31,71 +31,53 @@
 
 class LODocument;
 class SGTileItem;
+class LOZoom;
 
 class LOView : public QQuickItem
 {
     Q_OBJECT
-    Q_ENUMS(ZoomMode)
-    Q_FLAGS(ZoomModes)
     Q_PROPERTY(QQuickItem*              parentFlickable    READ parentFlickable WRITE setParentFlickable NOTIFY parentFlickableChanged)
     Q_PROPERTY(LODocument*              document           READ document        /*WRITE setDocument*/    NOTIFY documentChanged)
     Q_PROPERTY(int                      currentPart        READ currentPart     WRITE setCurrentPart     NOTIFY currentPartChanged)
     Q_PROPERTY(LOPartsModel*            partsModel         READ partsModel                               NOTIFY partsModelChanged)
-    Q_PROPERTY(qreal                    zoomFactor         READ zoomFactor      WRITE setZoomFactor      NOTIFY zoomFactorChanged)
-    Q_PROPERTY(ZoomMode                 zoomMode           READ zoomMode                                 NOTIFY zoomModeChanged)
+    Q_PROPERTY(LOZoom*                  zoomSettings       READ zoomSettings)
     Q_PROPERTY(int                      cacheBuffer        READ cacheBuffer     WRITE setCacheBuffer     NOTIFY cacheBufferChanged)
     Q_PROPERTY(LibreOfficeError::Error  error              READ error                                    NOTIFY errorChanged)
-    Q_PROPERTY(ZoomModes                zoomModesAvailable READ zoomModesAvailable                       NOTIFY zoomModesAvailableChanged)
 
 public:
     LOView(QQuickItem *parent = 0);
     ~LOView();
 
-    enum ZoomMode {
-        Manual = 0x0,
-        FitToWidth = 0x1,
-        FitToHeight = 0x2,
-        Automatic = 0x4
-    };
-    Q_DECLARE_FLAGS(ZoomModes, ZoomMode)
-
     QQuickItem* parentFlickable() const;
-    void        setParentFlickable(QQuickItem* flickable);
-
-    Q_INVOKABLE void initializeDocument(const QString& path);
+    void setParentFlickable(QQuickItem* flickable);
 
     LODocument* document() const;
+
     LOPartsModel* partsModel() const;
 
+    LOZoom* zoomSettings() const;
+
     int currentPart();
     void setCurrentPart(int index);
 
-    qreal       zoomFactor() const;
-    void        setZoomFactor(const qreal zoom);
-
-    ZoomMode    zoomMode() const;
-
-    ZoomModes   zoomModesAvailable() const;
-
-    int         cacheBuffer() const;
-    void        setCacheBuffer(int cacheBuffer);
+    int cacheBuffer() const;
+    void setCacheBuffer(int cacheBuffer);
 
     LibreOfficeError::Error error() const;
 
-    Q_INVOKABLE bool adjustZoomToWidth(bool changeMode = true);
-    Q_INVOKABLE bool adjustZoomToHeight(bool changeMode = true);
-    Q_INVOKABLE bool adjustAutomaticZoom(bool changeMode = true);
+    Q_INVOKABLE void initializeDocument(const QString& path);
+
+    Q_INVOKABLE bool adjustZoomToWidth();
+    Q_INVOKABLE bool adjustZoomToHeight();
+    Q_INVOKABLE bool adjustAutomaticZoom();
 
 Q_SIGNALS:
     void parentFlickableChanged();
     void documentChanged();
     void partsModelChanged();
     void currentPartChanged();
-    void zoomFactorChanged();
-    void zoomModeChanged();
     void cacheBufferChanged();
     void errorChanged();
-    void zoomModesAvailableChanged();
 
 private Q_SLOTS:
     void updateViewSize();
@@ -108,13 +90,11 @@
 
     QQuickItem*                 m_parentFlickable;
     QSharedPointer<LODocument>  m_document;
+    LOZoom*                     m_zoomSettings;
     LOPartsModel*               m_partsModel; // TODO MB move to document.
     LOPartsImageProvider*       m_imageProvider; // The QQmlEngine takes ownership of provider.
 
     int                         m_currentPart;
-    qreal                       m_zoomFactor;
-    ZoomMode                    m_zoomMode;
-    ZoomModes                   m_zoomModesAvailable;
     int                         m_cacheBuffer;
 
     QRect                       m_visibleArea;
@@ -126,17 +106,17 @@
 
     QMap<int, SGTileItem*>      m_tiles;
 
+    bool                        m_zoomValueHasChanged;
+
 private:
     void generateTiles(int x1, int y1, int x2, int y2, int tilesPerWidth, int tilesPerHeight);
     void createTile(int index, const QRect& rect);
-    void setZoomMode(const ZoomMode zoomMode);
     void clearView();
     TileRenderTask* createTask(const QRect& rect, int id) const;
     void updateTileData(AbstractRenderTask* task, QImage img);
     void updateThumbnailModel(AbstractRenderTask* task, QImage img);
 
     void setError(const LibreOfficeError::Error &error);
-    void setZoomModesAvailability();
 };
 
 #endif // LOVIEW_H

=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lozoom.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/lozoom.cpp	1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lozoom.cpp	2016-01-22 20:14:59 +0000
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2016 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/>.
+ */
+
+#include "lozoom.h"
+#include "loview.h"
+#include "twips.h"
+
+static qreal getZoomToFitWidth(const qreal &width, int documentWidth)
+{
+    return qreal(width / Twips::convertTwipsToPixels(documentWidth, 1.0));
+}
+
+static qreal getZoomToFitHeight(const qreal &height, int documentHeight)
+{
+    return qreal(height / Twips::convertTwipsToPixels(documentHeight, 1.0));
+}
+
+LOZoom::LOZoom(LOView *view)
+    : QObject(view)
+    , m_view(view)
+    , m_zoomMode(ZoomMode::Manual)
+    , m_zoomModesAvailable(ZoomMode::Manual)
+    , m_zoomFactor(1.0)
+    , m_minimumZoom(0.25)
+    , m_maximumZoom(4.0)
+{   }
+
+LOZoom::~LOZoom()
+{   }
+
+LOZoom::ZoomMode LOZoom::zoomMode() const
+{
+    return m_zoomMode;
+}
+
+void LOZoom::setZoomMode(const LOZoom::ZoomMode zoomMode)
+{
+    if (m_zoomMode == zoomMode)
+        return;
+
+    m_zoomMode = zoomMode;
+    Q_EMIT zoomModeChanged();
+}
+
+LOZoom::ZoomModes LOZoom::zoomModesAvailable() const
+{
+    return m_zoomModesAvailable;
+}
+
+void LOZoom::setZoomModesAvailability()
+{
+    if (!m_view->document())
+        return;
+
+    ZoomModes newZoomModesAvailable;
+    newZoomModesAvailable |= ZoomMode::Manual;
+
+    switch (m_view->document()->documentType()) {
+    case LODocument::DocumentType::TextDocument:
+        newZoomModesAvailable |= ZoomMode::FitToWidth;
+        break;
+    case LODocument::DocumentType::SpreadsheetDocument:
+        break;
+    default:
+        newZoomModesAvailable |= ZoomMode::FitToWidth;
+        newZoomModesAvailable |= ZoomMode::FitToHeight;
+        newZoomModesAvailable |= ZoomMode::Automatic;
+        break;
+    }
+
+    if (m_zoomModesAvailable != newZoomModesAvailable) {
+        m_zoomModesAvailable = newZoomModesAvailable;
+        Q_EMIT zoomModesAvailableChanged();
+    }
+}
+
+qreal LOZoom::zoomFactor() const
+{
+    return m_zoomFactor;
+}
+
+void LOZoom::setZoomFactor(const qreal zoom)
+{
+    if (m_zoomFactor == zoom || zoom < m_minimumZoom || zoom > m_maximumZoom)
+        return;
+
+    m_zoomFactor = zoom;
+
+    // m_valueAutomaticZoom is necessary equal to the fitToWidth or fitToHeight value.
+    if (m_zoomFactor != m_valueFitToWidthZoom && m_zoomFactor != m_valueFitToHeightZoom)
+        setZoomMode(LOZoom::Manual);
+
+    Q_EMIT zoomFactorChanged();
+}
+
+qreal LOZoom::minimumZoom() const
+{
+    return m_minimumZoom;
+}
+
+/*
+void LOZoom::setMinimumZoom(const qreal newValue)
+{
+    if (m_minimumZoom == newValue)
+        return;
+
+    m_minimumZoom = newValue;
+    Q_EMIT minimumZoomChanged();
+}
+*/
+
+qreal LOZoom::maximumZoom() const
+{
+    return m_maximumZoom;
+}
+
+/*
+void LOZoom::setMaximumZoom(const qreal newValue)
+{
+    if (m_maximumZoom == newValue)
+        return;
+
+    m_maximumZoom = newValue;
+    Q_EMIT maximumZoomChanged();
+}
+*/
+
+qreal LOZoom::valueFitToWidthZoom() const
+{
+    return m_valueFitToWidthZoom;
+}
+
+qreal LOZoom::valueFitToHeightZoom() const
+{
+    return m_valueFitToHeightZoom;
+}
+
+qreal LOZoom::valueAutomaticZoom() const
+{
+    return m_valueAutomaticZoom;
+}
+
+bool LOZoom::adjustZoomToWidth(bool changeMode)
+{
+    if (!m_view->document())
+        return false;
+
+    if (changeMode)
+        setZoomMode(LOZoom::FitToWidth);
+
+    m_valueFitToWidthZoom = getZoomToFitWidth(m_view->parentFlickable()->width(),
+                                              m_view->document()->documentSize().width());
+
+    if (m_zoomFactor != m_valueFitToWidthZoom) {
+        setZoomFactor(m_valueFitToWidthZoom);
+
+        qDebug() << Q_FUNC_INFO << "- value:" << m_zoomFactor << "- changeMode:" << changeMode;
+        return true;
+    }
+
+    return false;
+}
+
+bool LOZoom::adjustZoomToHeight(bool changeMode)
+{
+    if (!m_view->document())
+        return false;
+
+    if (changeMode)
+        setZoomMode(LOZoom::FitToHeight);
+
+    m_valueFitToHeightZoom = getZoomToFitHeight(m_view->parentFlickable()->height(),
+                                                m_view->document()->documentSize().height());
+
+    if (m_zoomFactor != m_valueFitToHeightZoom) {
+        setZoomFactor(m_valueFitToHeightZoom);
+
+        qDebug() << Q_FUNC_INFO << "- value:" << m_zoomFactor << "- changeMode:" << changeMode;
+        return true;
+    }
+
+    return false;
+}
+
+bool LOZoom::adjustAutomaticZoom(bool changeMode)
+{
+    if (!m_view->document())
+        return false;
+
+    if (changeMode)
+        setZoomMode(LOZoom::Automatic);
+
+    m_valueFitToWidthZoom = getZoomToFitWidth(m_view->parentFlickable()->width(),
+                                              m_view->document()->documentSize().width());
+
+    m_valueFitToHeightZoom = getZoomToFitHeight(m_view->parentFlickable()->height(),
+                                                m_view->document()->documentSize().height());
+
+    m_valueAutomaticZoom = qMin(m_valueFitToWidthZoom, m_valueFitToHeightZoom);
+
+    if (m_zoomFactor != m_valueAutomaticZoom) {
+        setZoomFactor(m_valueAutomaticZoom);
+
+        qDebug() << Q_FUNC_INFO << "- value:" << m_zoomFactor << "- changeMode:" << changeMode;
+        return true;
+    }
+
+    return false;
+}
+
+void LOZoom::init()
+{
+    setZoomModesAvailability();
+
+    switch (m_view->document()->documentType()) {
+    case LODocument::DocumentType::SpreadsheetDocument:
+        setZoomMode(ZoomMode::Manual);
+        setZoomFactor(1.0);
+        break;
+    case LODocument::DocumentType::PresentationDocument:
+        setZoomMode(ZoomMode::Automatic);
+        break;
+    default:
+        setZoomMode(ZoomMode::FitToWidth);
+        break;
+    }
+}

=== added file 'src/plugin/libreofficetoolkit-qml-plugin/lozoom.h'
--- src/plugin/libreofficetoolkit-qml-plugin/lozoom.h	1970-01-01 00:00:00 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/lozoom.h	2016-01-22 20:14:59 +0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 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/>.
+ */
+
+#ifndef LOZOOM_H
+#define LOZOOM_H
+
+#include <QObject>
+#include <QSharedPointer>
+
+class LOView;
+
+class LOZoom : public QObject
+{
+    Q_OBJECT
+    Q_ENUMS(ZoomMode)
+    Q_FLAGS(ZoomModes)
+    Q_PROPERTY(ZoomMode zoomMode READ zoomMode NOTIFY zoomModeChanged)
+    Q_PROPERTY(ZoomModes zoomModesAvailable READ zoomModesAvailable NOTIFY zoomModesAvailableChanged)
+    Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor NOTIFY zoomFactorChanged)
+    Q_PROPERTY(qreal minimumZoom READ minimumZoom CONSTANT)     //WRITE setMinimumZoom NOTIFY minimumZoomChanged)
+    Q_PROPERTY(qreal maximumZoom READ maximumZoom CONSTANT)     //WRITE setMaximumZoom NOTIFY maximumZoomChanged)
+    Q_PROPERTY(qreal valueFitToWidthZoom READ valueFitToWidthZoom NOTIFY valueFitToWidthZoomChanged)
+    Q_PROPERTY(qreal valueFitToHeightZoom READ valueFitToHeightZoom NOTIFY valueFitToHeightZoomChanged)
+    Q_PROPERTY(qreal valueAutomaticZoom READ valueAutomaticZoom NOTIFY valueAutomaticZoomChanged)
+
+public:
+    LOZoom(LOView *view);
+    ~LOZoom();
+
+    enum ZoomMode {
+        Manual = 0x0,
+        FitToWidth = 0x1,
+        FitToHeight = 0x2,
+        Automatic = 0x4
+    };
+    Q_DECLARE_FLAGS(ZoomModes, ZoomMode)
+
+    ZoomMode    zoomMode() const;
+    ZoomModes   zoomModesAvailable() const;
+
+    qreal       zoomFactor() const;
+    void        setZoomFactor(const qreal zoom);
+
+    qreal       minimumZoom() const;
+//    void        setMinimumZoom(const qreal newValue);
+
+    qreal       maximumZoom() const;
+//    void        setMaximumZoom(const qreal newValue);
+
+    qreal       valueFitToWidthZoom() const;
+    qreal       valueFitToHeightZoom() const;
+    qreal       valueAutomaticZoom() const;
+
+    bool adjustZoomToWidth(bool changeMode = true);
+    bool adjustZoomToHeight(bool changeMode = true);
+    bool adjustAutomaticZoom(bool changeMode = true);
+
+    void init();
+
+Q_SIGNALS:
+    void zoomModeChanged();
+    void zoomModesAvailableChanged();
+    void zoomFactorChanged();
+//    void minimumZoomChanged();
+//    void maximumZoomChanged();
+    void valueFitToWidthZoomChanged();
+    void valueFitToHeightZoomChanged();
+    void valueAutomaticZoomChanged();
+
+private:
+    LOView* m_view;
+
+    ZoomMode m_zoomMode;
+    ZoomModes m_zoomModesAvailable;
+
+    qreal m_zoomFactor;
+
+    qreal m_minimumZoom;
+    qreal m_maximumZoom;
+
+    qreal m_valueFitToWidthZoom;
+    qreal m_valueFitToHeightZoom;
+    qreal m_valueAutomaticZoom;
+
+private:
+    void setZoomMode(const ZoomMode zoomMode);
+    void setZoomModesAvailability();
+};
+
+#endif // LOZOOM_H

=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp	2015-11-22 13:35:56 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/plugin.cpp	2016-01-22 20:14:59 +0000
@@ -23,6 +23,7 @@
 #include "loview.h"
 #include "lopartsmodel.h"
 #include "loerror.h"
+#include "lozoom.h"
 
 void LOPlugin::registerTypes(const char *uri)
 {
@@ -31,6 +32,7 @@
     //@uri DocumentViewer.LibreOffice
     qmlRegisterType<LODocument>(uri, 1, 0, "Document");
     qmlRegisterType<LOView>(uri, 1, 0, "View");
+    qmlRegisterUncreatableType<LOZoom>(uri, 1, 0, "Zoom", "Not creatable as an object, use only to retrieve error enums (e.g. LibreOffice.Zoom.Manual)");
     qmlRegisterUncreatableType<LOPartsModel>(uri, 1, 0, "PartsModel", "You shouldn't create LOPartsModel in QML");
     qmlRegisterUncreatableType<LibreOfficeError>(uri, 1, 0, "Error", "Not creatable as an object, use only to retrieve error enums (e.g. LibreOffice.Error.DocumentNotFound)");
 }

=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml'
--- src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml	2016-01-17 22:57:05 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/qml/Viewer.qml	2016-01-22 20:14:59 +0000
@@ -20,52 +20,49 @@
 Flickable {
     id: rootFlickable
 
-    property alias document:    view.document
-    property alias zoomFactor:  view.zoomFactor
-    property alias cacheBuffer: view.cacheBuffer
-    property alias partsModel:  view.partsModel
-    property alias zoomMode:    view.zoomMode
-    property alias error:       view.error
-    property alias currentPart: view.currentPart
-
-    property alias zoomModesAvailable: view.zoomModesAvailable
+    property alias document:     view.document
+    property alias zoomSettings: view.zoomSettings
+    property alias cacheBuffer:  view.cacheBuffer
+    property alias partsModel:   view.partsModel
+    property alias error:        view.error
+    property alias currentPart:  view.currentPart
 
     property string documentPath: ""
 
     function adjustZoomToWidth()
     {
-        var oldZoom = view.zoomFactor
+        var oldZoom = view.zoomSettings.zoomFactor
         view.adjustZoomToWidth()
 
-        var zoomScale = view.zoomFactor / oldZoom
+        var zoomScale = view.zoomSettings.zoomFactor / oldZoom
         rootFlickable.contentX *= zoomScale
         rootFlickable.contentY *= zoomScale
     }
 
     function adjustZoomToHeight()
     {
-        var oldZoom = view.zoomFactor
+        var oldZoom = view.zoomSettings.zoomFactor
         view.adjustZoomToHeight()
 
-        var zoomScale = view.zoomFactor / oldZoom
+        var zoomScale = view.zoomSettings.zoomFactor / oldZoom
         rootFlickable.contentX *= zoomScale
         rootFlickable.contentY *= zoomScale
     }
 
     function adjustAutomaticZoom()
     {
-        var oldZoom = view.zoomFactor
+        var oldZoom = view.zoomSettings.zoomFactor
         view.adjustAutomaticZoom()
 
-        var zoomScale = view.zoomFactor / oldZoom
+        var zoomScale = view.zoomSettings.zoomFactor / oldZoom
         rootFlickable.contentX *= zoomScale
         rootFlickable.contentY *= zoomScale
     }
 
     function setZoom(newValue)
     {
-        var zoomScale = newValue / view.zoomFactor;
-        view.zoomFactor = newValue;
+        var zoomScale = newValue / view.zoomSettings.zoomFactor;
+        view.zoomSettings.zoomFactor = newValue;
 
         rootFlickable.contentX *= zoomScale;
         rootFlickable.contentY *= zoomScale;
@@ -114,8 +111,6 @@
 
     boundsBehavior: Flickable.StopAtBounds
 
-    //Component.onCompleted: adjustZoomToWidth()
-
     LibreOffice.View {
         id: view
 

=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp'
--- src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp	2015-11-13 17:00:45 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.cpp	2016-01-22 20:14:59 +0000
@@ -9,10 +9,9 @@
 #include <QSGFlatColorMaterial>
 #endif
 
-SGTileItem::SGTileItem(const QRect& area, qreal zoom, int id, QQuickItem *parent)
+SGTileItem::SGTileItem(const QRect& area, int id, QQuickItem *parent)
     : QQuickItem(parent)
     , m_area(area)
-    , m_zoomFactor(zoom)
     , m_id (id)
 {
     setFlag(ItemHasContents, true);

=== modified file 'src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h'
--- src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h	2015-11-13 17:00:45 +0000
+++ src/plugin/libreofficetoolkit-qml-plugin/sgtileitem.h	2016-01-22 20:14:59 +0000
@@ -16,15 +16,12 @@
 {
     Q_OBJECT
 public:
-    SGTileItem(const QRect& area, qreal zoom, int id, QQuickItem *parent = 0);
+    SGTileItem(const QRect& area, int id, QQuickItem *parent = 0);
     ~SGTileItem();
 
     inline const QRect& area() { return m_area; }
     inline void setArea(const QRect& rect) { m_area = rect; }
 
-    inline const qreal& zoomFactor() const { return m_zoomFactor; }
-    inline void setZoomFactor(const qreal &zoom) { m_zoomFactor = zoom; }
-
     inline int id() { return m_id; }
     inline void setId(int id) { m_id = id; }
 
@@ -42,7 +39,6 @@
 
 private:
     QRect m_area;
-    qreal m_zoomFactor;
     QImage m_data;
     int m_id;
 };


References