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 }