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 }