Warning, /graphics/peruse/src/app/qml/viewers/okular.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 * Copyright (C) 2015 Dan Leinir Turthra Jensen <admin@leinir.dk>
0003 *
0004 * This library is free software; you can redistribute it and/or
0005 * modify it under the terms of the GNU Lesser General Public
0006 * License as published by the Free Software Foundation; either
0007 * version 2.1 of the License, or (at your option) version 3, or any
0008 * later version accepted by the membership of KDE e.V. (or its
0009 * successor approved by the membership of KDE e.V.), which shall
0010 * act as a proxy defined in Section 6 of version 3 of the license.
0011 *
0012 * This library is distributed in the hope that it will be useful,
0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015 * Lesser General Public License for more details.
0016 *
0017 * You should have received a copy of the GNU Lesser General Public
0018 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
0019 *
0020 */
0021
0022 import QtQuick 2.12
0023 import QtQuick.Controls 2.12 as QtControls
0024
0025 import org.kde.kirigami 2.7 as Kirigami
0026 import org.kde.okular 2.0 as Okular
0027
0028 import "helpers" as Helpers
0029
0030 /**
0031 * @brief a ViewerBase intended as a fallback for unsupported books.
0032 *
0033 * It is called from Book when the opened book has no other specialised viewers.
0034 *
0035 * It does not use the ImageBrowser because it needs to access
0036 * Okular Page items for the images.
0037 */
0038 ViewerBase {
0039 id: root;
0040 title: documentItem.windowTitleForDocument;
0041 onFileChanged: documentItem.url = "file://" + file;
0042 onCurrentPageChanged: {
0043 if(documentItem.currentPage !== currentPage) {
0044 documentItem.currentPage = currentPage;
0045 }
0046 if(currentPage !== imageBrowser.currentIndex) {
0047 pageChangeAnimation.running = false;
0048 var currentPos = imageBrowser.contentX;
0049 var newPos;
0050 imageBrowser.positionViewAtIndex(currentPage, ListView.Center);
0051 imageBrowser.currentIndex = currentPage;
0052 newPos = imageBrowser.contentX;
0053 pageChangeAnimation.from = currentPos;
0054 pageChangeAnimation.to = newPos;
0055 pageChangeAnimation.running = true;
0056 }
0057 }
0058 NumberAnimation { id: pageChangeAnimation; target: imageBrowser; property: "contentX"; duration: applicationWindow().animationDuration; easing.type: Easing.InOutQuad; }
0059 onRtlModeChanged: {
0060 if(rtlMode === true) {
0061 imageBrowser.layoutDirection = Qt.RightToLeft;
0062 }
0063 else {
0064 imageBrowser.layoutDirection = Qt.LeftToRight;
0065 }
0066 root.restoreCurrentPage();
0067 }
0068 onRestoreCurrentPage: {
0069 // This is un-pretty, quite obviously. But thanks to the ListView's inability to
0070 // stay in place when the geometry changes, well, this makes things simple.
0071 imageBrowser.positionViewAtIndex(imageBrowser.currentIndex, ListView.Center);
0072
0073 }
0074 pageCount: documentItem.pageCount;
0075 thumbnailComponent: thumbnailComponent;
0076 pagesModel: documentItem.matchingPages;
0077 Component {
0078 id: thumbnailComponent;
0079 Item {
0080 width: parent.width;
0081 height: Kirigami.Units.gridUnit * 6;
0082 MouseArea {
0083 anchors.fill: parent;
0084 onClicked: viewLoader.item.currentPage = model.index;
0085 }
0086 Rectangle {
0087 anchors.fill: parent;
0088 color: Kirigami.Theme.highlightColor;
0089 opacity: root.currentPage === model.index ? 1 : 0;
0090 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.shortDuration; } }
0091 }
0092 Okular.ThumbnailItem {
0093 id: thumbnail
0094 anchors {
0095 top: parent.top;
0096 horizontalCenter: parent.horizontalCenter;
0097 margins: Kirigami.Units.smallSpacing;
0098 }
0099 document: documentItem
0100 pageNumber: modelData
0101 height: parent.height - pageTitle.height - Kirigami.Units.smallSpacing * 2;
0102 function updateWidth() {
0103 width = Math.round(height * (implicitWidth / implicitHeight));
0104 }
0105 Component.onCompleted: updateWidth();
0106 onHeightChanged: updateWidth();
0107 onImplicitHeightChanged: updateWidth();
0108 }
0109 QtControls.Label {
0110 id: pageTitle;
0111 anchors {
0112 left: parent.left;
0113 right: parent.right;
0114 bottom: parent.bottom;
0115 }
0116 height: paintedHeight;
0117 text: modelData + 1;
0118 elide: Text.ElideMiddle;
0119 horizontalAlignment: Text.AlignHCenter;
0120 }
0121 }
0122 }
0123 Okular.DocumentItem {
0124 id: documentItem
0125 onOpenedChanged: {
0126 if(opened === true) {
0127 root.loadingCompleted(true);
0128 initialPageChange.start();
0129 } else {
0130 console.debug("Well then, error loading the file...");
0131 }
0132 }
0133 onCurrentPageChanged: {
0134 if(root.currentPage !== currentPage) {
0135 root.currentPage = currentPage;
0136 }
0137 }
0138 }
0139
0140 Timer {
0141 id: initialPageChange;
0142 interval: applicationWindow().animationDuration;
0143 running: false;
0144 repeat: false;
0145 onTriggered: root.currentPage = imageBrowser.currentIndex;
0146 }
0147 ListView {
0148 id: imageBrowser
0149 anchors.fill: parent;
0150 model: documentItem.matchingPages;
0151
0152 interactive: false // No interactive flicky stuff here, we'll handle that with the navigator instance
0153 property int imageWidth: root.width + Kirigami.Units.largeSpacing;
0154 property int imageHeight: root.height;
0155
0156 orientation: ListView.Horizontal
0157 snapMode: ListView.SnapOneItem
0158
0159 // This ensures that the current index is always up to date, which we need to ensure we can track the current page
0160 // as required by the thumbnail navigator, and the resume-reading-from functionality
0161 onMovementEnded: {
0162 var indexHere = indexAt(contentX + width / 2, contentY + height / 2);
0163 if(currentIndex !== indexHere) {
0164 currentIndex = indexHere;
0165 }
0166 }
0167
0168 delegate: Flickable {
0169 id: flick
0170 width: imageBrowser.imageWidth
0171 height: imageBrowser.imageHeight
0172 contentWidth: imageBrowser.imageWidth
0173 contentHeight: imageBrowser.imageHeight
0174 interactive: contentWidth > width || contentHeight > height
0175 z: interactive ? 1000 : 0
0176 PinchArea {
0177 width: Math.max(flick.contentWidth, flick.width)
0178 height: Math.max(flick.contentHeight, flick.height)
0179
0180 property real initialWidth
0181 property real initialHeight
0182
0183 onPinchStarted: {
0184 initialWidth = flick.contentWidth
0185 initialHeight = flick.contentHeight
0186 }
0187
0188 onPinchUpdated: {
0189 // adjust content pos due to drag
0190 flick.contentX += pinch.previousCenter.x - pinch.center.x
0191 flick.contentY += pinch.previousCenter.y - pinch.center.y
0192
0193 // resize content
0194 flick.resizeContent(Math.max(imageBrowser.imageWidth, initialWidth * pinch.scale), Math.max(imageBrowser.imageHeight, initialHeight * pinch.scale), pinch.center)
0195 }
0196
0197 onPinchFinished: {
0198 // Move its content within bounds.
0199 flick.returnToBounds();
0200 }
0201
0202 Item {
0203 implicitWidth: page.implicitWidth
0204 implicitHeight: page.implicitHeight
0205 width: flick.contentWidth
0206 height: flick.contentHeight
0207 Okular.PageItem {
0208 id: page;
0209 document: documentItem;
0210 pageNumber: index;
0211 anchors.centerIn: parent;
0212 property real pageRatio: implicitWidth / implicitHeight
0213 property bool sameOrientation: root.width / root.height > pageRatio
0214 width: sameOrientation ? parent.height * pageRatio : parent.width
0215 height: !sameOrientation ? parent.width / pageRatio : parent.height
0216 }
0217 MouseArea {
0218 anchors.fill: parent;
0219 enabled: flick.interactive
0220 onClicked: startToggleControls()
0221 onDoubleClicked: {
0222 abortToggleControls();
0223 flick.resizeContent(imageBrowser.imageWidth, imageBrowser.imageHeight, Qt.point(imageBrowser.imageWidth/2, imageBrowser.imageHeight/2));
0224 flick.returnToBounds();
0225 }
0226 }
0227 }
0228 }
0229 }
0230 }
0231
0232 Helpers.Navigator {
0233 enabled: !imageBrowser.currentItem.interactive;
0234 anchors.fill: parent;
0235 onLeftRequested: imageBrowser.layoutDirection == Qt.RightToLeft? root.goNextPage(): root.goPreviousPage();
0236 onRightRequested: imageBrowser.layoutDirection == Qt.RightToLeft? root.goPreviousPage(): root.goNextPage();
0237 onTapped: startToggleControls();
0238 onDoubleTapped: {
0239 abortToggleControls();
0240 imageBrowser.currentItem.resizeContent(imageBrowser.imageWidth * 2, imageBrowser.imageHeight * 2, Qt.point(eventPoint.x, eventPoint.y));
0241 imageBrowser.currentItem.returnToBounds();
0242 }
0243 }
0244 }