Warning, /utilities/skanpage/src/qml/DocumentList.qml is written in an unsupported language. File is not indexed.
0001 /**
0002 * SPDX-FileCopyrightText: 2015 by Kåre Särs <kare.sars@iki .fi>
0003 * SPDX-FileCopyrightText: 2021 by Alexander Stippich <a.stippich@gmx.net>
0004 *
0005 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007
0008 import QtQuick 2.15
0009 import QtQuick.Controls 2.15
0010 import QtQuick.Layouts 1.1
0011
0012 import org.kde.kirigami 2.12 as Kirigami
0013 import org.kde.skanpage 1.0
0014
0015 ColumnLayout {
0016 id: documentList
0017
0018 signal saveSinglePage(int pageNumber)
0019 signal showScannedPage()
0020
0021 spacing: 0
0022 property int minimumWidth: {
0023 let res = listFooter.implicitWidth
0024 for (var i = 0; i < listView.count; i++) {
0025 const el = listView.itemAtIndex(i)
0026 if (el !== null) {
0027 const w = el.implicitWidth + scrollView.ScrollBar.vertical.width
0028 if (w > res) res = w
0029 }
0030 }
0031 return res
0032 }
0033
0034 //copied from Kirigami.Separator
0035 property var midColor: Kirigami.ColorUtils.linearInterpolation(Kirigami.Theme.backgroundColor, Kirigami.Theme.textColor, 0.15)
0036
0037 ScrollView {
0038 id: scrollView
0039
0040 Layout.fillWidth: true
0041 Layout.fillHeight: true
0042
0043 ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
0044 ScrollBar.vertical.policy: ScrollBar.AlwaysOn
0045
0046 ListView {
0047 id: listView
0048 anchors.fill: parent
0049
0050 spacing: Kirigami.Units.smallSpacing
0051
0052 clip: true
0053
0054 Connections {
0055 target: skanpage.documentModel
0056 function onActivePageChanged() {
0057 listView.positionViewAtIndex(skanpage.documentModel.activePageIndex, ListView.Contain)
0058 }
0059 }
0060
0061 displaced: Transition {
0062 NumberAnimation {
0063 properties: "x,y"
0064 easing.type: Easing.OutQuad
0065 }
0066 }
0067
0068 model: skanpage.documentModel
0069
0070 onCurrentItemChanged: skanpage.documentModel.activePageIndex = currentIndex
0071
0072 ShortcutsAction {
0073 id: selectUpAction
0074 text: i18n("Select previous page")
0075 shortcut: "UP"
0076 onTriggered: skanpage.documentModel.activePageIndex--
0077 }
0078 ShortcutsAction {
0079 id: selectDownAction
0080 text: i18n("Select next page")
0081 shortcut: "DOWN"
0082 onTriggered: skanpage.documentModel.activePageIndex++
0083 }
0084 ShortcutsAction {
0085 id: moveUpAction
0086 text: i18n("Move selected page up")
0087 shortcut: "CTRL+SHIFT+UP"
0088 onTriggered: {
0089 const i = skanpage.documentModel.activePageIndex
0090 skanpage.documentModel.moveImage(i, i - 1);
0091 }
0092 }
0093 ShortcutsAction {
0094 id: moveDownAction
0095 text: i18n("Move selected page down")
0096 shortcut: "CTRL+SHIFT+DOWN"
0097 onTriggered: {
0098 const i = skanpage.documentModel.activePageIndex
0099 skanpage.documentModel.moveImage(i, i + 1);
0100 }
0101 }
0102
0103 delegate: MouseArea {
0104 id: mouseArea
0105 width: Math.max(listView.width - scrollView.ScrollBar.vertical.width, delegateRoot.implicitWidth)
0106 implicitWidth: delegateRoot.implicitWidth
0107 implicitHeight: delegateRoot.implicitHeight
0108
0109 property int actualIndex: index // Needs to be redeclared so it shows up from the dragged-into item
0110
0111 drag.target: delegateRoot
0112 drag.axis: Drag.YAxis
0113
0114 DropArea {
0115 anchors.fill: parent
0116 onEntered: function(drag) {
0117 if (drag.source.actualIndex !== mouseArea.actualIndex)
0118 skanpage.documentModel.moveImage(drag.source.actualIndex, mouseArea.actualIndex)
0119 }
0120 }
0121
0122 onClicked: {
0123 skanpage.documentModel.activePageIndex = index
0124 showScannedPage()
0125 }
0126
0127 Control {
0128 id: delegateRoot
0129
0130 readonly property bool landscape: model.rotationAngle === 270 || model.rotationAngle === 90
0131 focus: index === skanpage.documentModel.activePageIndex
0132
0133 width: mouseArea.width
0134 padding: 2
0135
0136 Drag.active: mouseArea.drag.active
0137 Drag.source: mouseArea
0138 Drag.hotSpot: Qt.point(width / 2, height / 2)
0139
0140 states: [
0141 State {
0142 name: ""
0143 ParentChange {
0144 target: delegateRoot
0145 parent: mouseArea // Reset parent
0146 }
0147 PropertyChanges {
0148 target: delegateRoot
0149 x: 0; y: 0 // Snap back to parent's origin (they are the same size)
0150 }
0151 },
0152 State {
0153 name: "dragging"
0154 when: mouseArea.drag.active
0155 ParentChange {
0156 target: delegateRoot
0157 parent: listView // Lift the item up so it's always visible
0158 }
0159 }
0160 ]
0161
0162 background: Rectangle {
0163 color: Kirigami.Theme.backgroundColor
0164 border.width: delegateRoot.padding
0165 border.color: delegateRoot.focus ? Kirigami.Theme.focusColor : documentList.midColor
0166 radius: 3
0167 }
0168
0169 contentItem: ColumnLayout {
0170 id: contentColumn
0171
0172 Item {
0173 Layout.fillWidth: true
0174 implicitHeight: delegateRoot.landscape ?
0175 width / model.aspectRatio : width * model.aspectRatio
0176 Image {
0177 visible: model.isSaved
0178 width: delegateRoot.landscape ? parent.height : parent.width
0179 height: delegateRoot.landscape ? parent.width : parent.height
0180 anchors.centerIn: parent
0181
0182 source: model.imageUrl
0183 sourceSize.height: model.previewHeight
0184 sourceSize.width: model.previewWidth
0185
0186 rotation: model.rotationAngle
0187 asynchronous: true
0188 }
0189
0190 ColumnLayout {
0191 visible: !model.isSaved
0192 anchors.fill: parent
0193
0194 BusyIndicator {
0195 running: visible
0196
0197 Layout.preferredWidth: Kirigami.Units.iconSizes.huge
0198 Layout.preferredHeight: Layout.preferredWidth
0199 Layout.maximumHeight: parent.height
0200 Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
0201 }
0202
0203 Kirigami.PlaceholderMessage {
0204 visible: parent.height > Kirigami.Units.iconSizes.huge + height
0205 Layout.maximumWidth: parent.width
0206 Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
0207 text: xi18nc("@info", "Processing page...")
0208 }
0209 }
0210 }
0211
0212 RowLayout {
0213 id: bottomRow
0214 Layout.fillWidth: true
0215 spacing: Kirigami.Units.smallSpacing
0216
0217 Kirigami.Heading {
0218 Layout.alignment: Qt.AlignLeft
0219 level: 2
0220 text: i18nc("Page index", "Page %1", model.index + 1)
0221 }
0222
0223 Kirigami.ActionToolBar {
0224 Layout.alignment: Qt.AlignRight
0225 alignment: Qt.AlignRight
0226 flat: false
0227 display: Button.IconOnly
0228 actions: [
0229 Kirigami.Action {
0230 icon.name: "go-up"
0231 text: i18n("Move Up")
0232 onTriggered: {
0233 skanpage.documentModel.moveImage(index, index - 1, 1);
0234 listView.positionViewAtIndex(index, ListView.Center);
0235 }
0236 enabled: index > 0
0237 },
0238
0239 Kirigami.Action {
0240 icon.name: "go-down"
0241 text: i18n("Move Down")
0242 onTriggered: {
0243 skanpage.documentModel.moveImage(index, index + 1, 1);
0244 listView.positionViewAtIndex(index, ListView.Center);
0245 }
0246 enabled: index < listView.count - 1
0247 },
0248
0249 Kirigami.Action {
0250 icon.name: "object-rotate-left"
0251 text: i18n("Rotate Left")
0252 onTriggered: skanpage.documentModel.rotateImage(index, DocumentModel.Rotate90negative)
0253 },
0254
0255 Kirigami.Action {
0256 icon.name: "object-rotate-right"
0257 text: i18n("Rotate Right")
0258 onTriggered: skanpage.documentModel.rotateImage(index, DocumentModel.Rotate90positive)
0259 },
0260
0261 Kirigami.Action {
0262 icon.name: "object-flip-vertical"
0263 text: i18n("Flip")
0264 onTriggered: skanpage.documentModel.rotateImage(index, DocumentModel.Flip180)
0265 },
0266
0267 Kirigami.Action {
0268 icon.name: "document-save"
0269 text: i18n("Save Page")
0270 onTriggered: documentList.saveSinglePage(index)
0271 },
0272
0273 Kirigami.Action {
0274 icon.name: "delete"
0275 text: i18n("Delete Page")
0276 onTriggered: skanpage.documentModel.removeImage(index)
0277 }
0278 ]
0279 }
0280 }
0281 }
0282 }
0283 }
0284 }
0285 }
0286
0287 RowLayout {
0288 id: listFooter
0289 Layout.fillWidth: true
0290 Layout.preferredHeight: Kirigami.Units.gridUnit * 2
0291
0292 Label {
0293 Layout.margins: Kirigami.Units.largeSpacing
0294 text: i18np("%1 page", "%1 pages", skanpage.documentModel.count)
0295 }
0296
0297 Kirigami.ActionToolBar {
0298 alignment: Qt.AlignRight
0299 actions: [
0300 Kirigami.Action {
0301 id: reorderAction
0302 icon.name: "exchange-positions"
0303 text: i18n("Reorder Pages")
0304 enabled: skanpage.documentModel.count > 1
0305
0306 Kirigami.Action {
0307 id: reorderDuplexAction
0308 text: i18nc("Indicates how pages are going to be reordered", "13 24 → 1234")
0309 onTriggered: skanpage.documentModel.reorderPages(DocumentModel.ReorderDuplex)
0310 enabled: skanpage.documentModel.count > 2
0311 }
0312
0313 Kirigami.Action {
0314 id: reorderDuplexReverseAction
0315 text: i18nc("Indicates how pages are going to be reordered", "13 42 → 1234")
0316 onTriggered: skanpage.documentModel.reorderPages(DocumentModel.ReorderDuplexReversed)
0317 enabled: skanpage.documentModel.count > 2
0318 }
0319
0320 Kirigami.Action {
0321 id: reverseAction
0322 text: i18n("Reverse Order")
0323 onTriggered: skanpage.documentModel.reorderPages(DocumentModel.Reverse)
0324 enabled: skanpage.documentModel.count > 1
0325 }
0326 }
0327 ]
0328 }
0329 }
0330 }