diff --git a/pdf/pdfcanvas.cpp b/pdf/pdfcanvas.cpp index bd0a2778..9b12b64f 100644 --- a/pdf/pdfcanvas.cpp +++ b/pdf/pdfcanvas.cpp @@ -51,6 +51,7 @@ class PDFCanvas::Private Private( PDFCanvas* qq ) : q{ qq } , pageCount{ 0 } + , currentPage{ 0 } , renderWidth{ 0 } , document{ nullptr } , flickable(0) @@ -63,6 +64,7 @@ class PDFCanvas::Private QHash< int, PDFPage > pages; int pageCount; + int currentPage; int renderWidth; @@ -170,6 +172,11 @@ qreal PDFCanvas::pagePosition(int index) const return d->pages.value( index ).rect.y(); } +int PDFCanvas::currentPage() const +{ + return d->currentPage; +} + float PDFCanvas::spacing() const { return d->spacing; @@ -333,6 +340,7 @@ QSGNode* PDFCanvas::updatePaintNode(QSGNode* node, QQuickItem::UpdatePaintNodeDa } QList > priorityRequests; + bool currentPageSet = false; for( int i = 0; i < d->pageCount; ++i ) { @@ -381,6 +389,14 @@ QSGNode* PDFCanvas::updatePaintNode(QSGNode* node, QQuickItem::UpdatePaintNodeDa m.translate( 0, page.rect.y() ); t->setMatrix(m); + if (showPage && !currentPageSet) { + currentPageSet = true; + if (d->currentPage != i + 1) { + d->currentPage = i + 1; + emit currentPageChanged(); + } + } + if( page.texture && showPage ) { QSGSimpleTextureNode *tn = static_cast(t->firstChild()); diff --git a/pdf/pdfcanvas.h b/pdf/pdfcanvas.h index 77c21310..7910d114 100644 --- a/pdf/pdfcanvas.h +++ b/pdf/pdfcanvas.h @@ -30,6 +30,7 @@ class PDFCanvas : public QQuickItem Q_PROPERTY( QQuickItem* flickable READ flickable WRITE setFlickable NOTIFY flickableChanged ) Q_PROPERTY( float spacing READ spacing WRITE setSpacing NOTIFY spacingChanged ) Q_PROPERTY( QColor linkColor READ linkColor WRITE setLinkColor NOTIFY linkColorChanged ) + Q_PROPERTY( int currentPage READ currentPage NOTIFY currentPageChanged ) public: PDFCanvas(QQuickItem* parent = 0); @@ -61,6 +62,11 @@ class PDFCanvas : public QQuickItem */ void setLinkColor( const QColor& color ); + /** + * Getter for property #currentPage. + */ + int currentPage() const; + void layout(); /** @@ -73,6 +79,7 @@ class PDFCanvas : public QQuickItem void flickableChanged(); void spacingChanged(); void linkColorChanged(); + void currentPageChanged(); protected: virtual void geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry); diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt index b6dd2383..aa731939 100755 --- a/plugin/CMakeLists.txt +++ b/plugin/CMakeLists.txt @@ -23,6 +23,7 @@ install(FILES TextDocumentPage.qml TextDocumentToCPage.qml ZoomableThumbnail.qml + ToolBar.qml DetailsPage.qml DetailsItem.qml DocumentPages.qml diff --git a/plugin/DocumentPage.qml b/plugin/DocumentPage.qml index 0defe2ff..8180f125 100644 --- a/plugin/DocumentPage.qml +++ b/plugin/DocumentPage.qml @@ -37,10 +37,21 @@ Page { property url source; property int indexCount; + property bool _forceNavigation: false allowedOrientations: Orientation.All; - backNavigation: drawer.opened; - forwardNavigation: drawer.opened; + backNavigation: drawer.opened || _forceNavigation; + forwardNavigation: drawer.opened || _forceNavigation; + + function pushAttachedPage() { + if (pageStack.nextPage(base) === null) { + pageStack.push(base.attachedPage) + } else { + _forceNavigation = true + pageStack.navigateForward() + _forceNavigation = false + } + } BusyIndicator { id: busyIndicator; anchors.centerIn: parent; size: BusyIndicatorSize.Large; } diff --git a/plugin/PDFDocumentPage.qml b/plugin/PDFDocumentPage.qml index 19b91670..61d56ad3 100644 --- a/plugin/PDFDocumentPage.qml +++ b/plugin/PDFDocumentPage.qml @@ -26,6 +26,7 @@ DocumentPage { attachedPage: Component { PDFDocumentToCPage { tocModel: pdfDocument.tocModel + pageCount: pdfDocument.pageCount onPageSelected: view.goToPage( pageNumber ); } } @@ -78,7 +79,55 @@ DocumentPage { onFocusChanged: if (focus) base.open = false } } + } + + ToolBar { + id: toolbar + width: parent.width + height: base.orientation == Orientation.Portrait || base.orientation == Orientation.InvertedPortrait + ? Theme.itemSizeLarge + : Theme.itemSizeSmall + parentHeight: base.height + flickable: view + hidden: base.open + // Toolbar contain. + Row { + id: row + height: parent.height + + Item { + anchors.verticalCenter: parent.verticalCenter + width: pageCount.width + height: pageCount.height + Row { + id: pageCount + Image { + source: "image://theme/icon-m-document" + anchors.verticalCenter: parent.verticalCenter + } + Label { + anchors.verticalCenter: parent.verticalCenter + text: view.currentPage + " / " + view.document.pageCount + } + } + MouseArea { + anchors.fill: parent + onClicked: base.pushAttachedPage() + } + } + Item { + // Spacer, to be replaced later with a search field. + width: toolbar.width - pageCount.width - pdfTOC.width + height: parent.height + } + IconButton { + id: pdfTOC + anchors.verticalCenter: parent.verticalCenter + icon.source: "image://theme/icon-m-menu" + onClicked: base.pushAttachedPage() + } + } } PDF.Document { diff --git a/plugin/PDFDocumentToCPage.qml b/plugin/PDFDocumentToCPage.qml index b1222498..5a068ae9 100644 --- a/plugin/PDFDocumentToCPage.qml +++ b/plugin/PDFDocumentToCPage.qml @@ -23,13 +23,16 @@ Page { id: page; signal pageSelected(int pageNumber); + property int pageCount property alias tocModel: tocListView.model; allowedOrientations: Orientation.All; SilicaListView { id: tocListView - anchors.fill: parent; + width: parent.width + height: parent.height - gotoPage.height + clip: true //: Page with PDF index //% "Index" @@ -75,4 +78,31 @@ Page { } } } + + PanelBackground { + id: gotoPage + anchors.top: tocListView.bottom + width: parent.width + height: Theme.itemSizeMedium + + TextField { + x: Theme.paddingLarge + width: parent.width - Theme.paddingMedium - Theme.paddingLarge + anchors.verticalCenter: parent.verticalCenter + + //% "Go to page" + placeholderText: qsTrId("sailfish-office-lb-goto-page") + //% "document has %n pages" + label: qsTrId("sailfish-office-lb-%n-pages", page.pageCount) + + // We enter page numbers + inputMethodHints: Qt.ImhDigitsOnly + EnterKey.enabled: text.length > 0 && Math.round(text) > 0 && Math.round(text) <= page.pageCount + EnterKey.iconSource: "image://theme/icon-m-enter-accept" + EnterKey.onClicked: { + page.pageSelected(Math.round(text) - 1); + pageStack.navigateBack(PageStackAction.Animated); + } + } + } } diff --git a/plugin/PDFView.qml b/plugin/PDFView.qml index 9c058798..05964994 100644 --- a/plugin/PDFView.qml +++ b/plugin/PDFView.qml @@ -29,6 +29,7 @@ SilicaFlickable { property alias itemWidth: pdfCanvas.width; property alias itemHeight: pdfCanvas.height; property alias document: pdfCanvas.document; + property alias currentPage: pdfCanvas.currentPage property bool scaled: pdfCanvas.width != width; diff --git a/plugin/ToolBar.qml b/plugin/ToolBar.qml new file mode 100644 index 00000000..41efe008 --- /dev/null +++ b/plugin/ToolBar.qml @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Caliste Damien. + * Contact: Damien Caliste + * + * 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 2 only. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.0 +import Sailfish.Silica 1.0 + +PanelBackground { + id: toolbar + + property variant flickable: undefined + property int parentHeight + property bool hidden: false + + anchors.top: flickable.bottom + + states: [ + State { + name: "visible" + when: !hidden && _dragUp + PropertyChanges { target: flickable; height: parentHeight - toolbar.height } + }, + State { + name: "hidden" + when: hidden || !_dragUp + PropertyChanges { target: flickable; height: parentHeight } + } + ] + transitions: Transition { + NumberAnimation { target: flickable; property: "height"; duration: 400; easing.type: Easing.InOutQuad } + } + + Binding { + target: flickable + property: "clip" + value: enabled + } + property int _previousContentY + property bool _dragUp + Connections { + target: flickable + onContentYChanged: { + if (!flickable.movingVertically) return + + _dragUp = (flickable.contentY < _previousContentY) + if (_dragUp) autoHideTimer.restart() + + _previousContentY = flickable.contentY + } + } + + // Auto hide toolbar + Timer { + id: autoHideTimer + interval: 4000 + onTriggered: _dragUp = false + } +}