diff --git a/applets/clipboard/contents/ui/ClipboardItemDelegate.qml b/applets/clipboard/contents/ui/ClipboardItemDelegate.qml --- a/applets/clipboard/contents/ui/ClipboardItemDelegate.qml +++ b/applets/clipboard/contents/ui/ClipboardItemDelegate.qml @@ -27,17 +27,18 @@ PlasmaComponents.ListItem { id: menuItem - property alias supportsBarcodes: barcodeToolButton.visible + property bool supportsBarcodes property int maximumNumberOfPreviews: Math.floor(width / (units.gridUnit * 4 + units.smallSpacing)) - readonly property real gradientThreshold: (label.width - toolButtonsLayout.width) / label.width + readonly property real gradientThreshold: (label.width - toolButtonsLoader.width) / label.width signal itemSelected(string uuid) signal remove(string uuid) signal edit(string uuid) signal barcode(string uuid) signal action(string uuid) - height: Math.max(label.height, toolButtonsLayout.implicitHeight) + 2 * units.smallSpacing + // the 1.6 comes from ToolButton's default height + height: Math.max(label.height, Math.round(units.gridUnit * 1.6)) + 2 * units.smallSpacing enabled: true @@ -98,182 +99,28 @@ right: parent.right verticalCenter: parent.verticalCenter } - PlasmaComponents.Label { - width: parent.width - height: undefined // unset PlasmaComponents.Label default height - maximumLineCount: 3 - verticalAlignment: Text.AlignVCenter - - text: { - var highlightFontTag = "%1" - - var text = DisplayRole - - // first escape any HTML characters to prevent privacy issues - text = text.replace(/&/g, "&").replace(//g, ">") - // color code leading or trailing whitespace - // the first regex is basically "trim" - text = text.replace(/^\s+|\s+$/gm, function(match) { - // then inside the trimmed characters ("match") we replace each one individually - match = match.replace(/ /g, "␣") // space - .replace(/\t/g, "↹") // tab - .replace(/\n/g, "↵") // return - return highlightFontTag.arg(match) - }) - - // finally turn line breaks into HTML br tags - text = text.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, "
") - - return text - } - visible: TypeRole == 0 // TypeRole: 0: Text, 1: Image, 2: Url - elide: Text.ElideRight - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - textFormat: Text.StyledText - } - KQuickControlsAddons.QPixmapItem { - id: previewPixmap + Loader { width: parent.width - height: Math.round(width * (nativeHeight/nativeWidth) + units.smallSpacing * 2) - pixmap: DecorationRole - visible: TypeRole == 1 - fillMode: KQuickControlsAddons.QPixmapItem.PreserveAspectFit - } - Item { - id: previewItem - visible: TypeRole == 2 - // visible updates recursively, our label becomes invisible when hovering, hence no visible check here - height: TypeRole == 2 ? (units.gridUnit * 4 + units.smallSpacing * 2) : 0 - width: parent.width - - ListView { - id: previewList - model: TypeRole == 2 ? DisplayRole.split(" ", maximumNumberOfPreviews) : 0 - property int itemWidth: units.gridUnit * 4 - property int itemHeight: units.gridUnit * 4 - interactive: false - - spacing: units.smallSpacing - orientation: Qt.Horizontal - width: (itemWidth + spacing) * model.length - anchors { - top: parent.top - left: parent.left - bottom: parent.bottom - } - - delegate: Item { - width: previewList.itemWidth - height: previewList.itemHeight - y: Math.round((parent.height - previewList.itemHeight) / 2) - clip: true - - KQuickControlsAddons.QPixmapItem { - id: previewPixmap - - anchors.centerIn: parent - - Component.onCompleted: { - function result(job) { - if (!job.error) { - pixmap = job.result.preview; - previewPixmap.width = job.result.previewWidth - previewPixmap.height = job.result.previewHeight - } - } - var service = clipboardSource.serviceForSource(UuidRole) - var operation = service.operationDescription("preview"); - operation.url = modelData; - // We request a bigger size and then clip out a square in the middle - // so we get uniform delegate sizes without distortion - operation.previewWidth = previewList.itemWidth * 2; - operation.previewHeight = previewList.itemHeight * 2; - var serviceJob = service.startOperationCall(operation); - serviceJob.finished.connect(result); - } - } - Rectangle { - id: overlay - color: theme.textColor - opacity: 0.6 - height: units.gridUnit - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - } - } - PlasmaComponents.Label { - font.pointSize: theme.smallestFont.pointSize - color: theme.backgroundColor - maximumLineCount: 1 - anchors { - verticalCenter: overlay.verticalCenter - left: overlay.left - right: overlay.right - leftMargin: units.smallSpacing - rightMargin: units.smallSpacing - } - elide: Text.ElideRight - horizontalAlignment: Text.AlignHCenter - text: { - var u = modelData.split("/"); - return decodeURIComponent(u[u.length - 1]); - } - } - } - } - PlasmaComponents.Label { - property int additionalItems: DisplayRole.split(" ").length - maximumNumberOfPreviews - visible: additionalItems > 0 - opacity: 0.6 - text: i18nc("Indicator that there are more urls in the clipboard than previews shown", "+%1", additionalItems) - anchors { - left: previewList.right - right: parent.right - bottom: parent.bottom - margins: units.smallSpacing - - } - verticalAlignment: Text.AlignBottom - horizontalAlignment: Text.AlignCenter - font.pointSize: theme.smallestFont.pointSize - } + source: ["Text", "Image", "Url"][TypeRole] + "ItemDelegate.qml" } } - Row { - id: toolButtonsLayout + Loader { + id: toolButtonsLoader anchors { right: label.right verticalCenter: parent.verticalCenter } - visible: menuItem.ListView.isCurrentItem - - PlasmaComponents.ToolButton { - // TODO: only show for items supporting actions? - iconSource: "system-run" - tooltip: i18n("Invoke action") - onClicked: menuItem.action(UuidRole) - } - PlasmaComponents.ToolButton { - id: barcodeToolButton - iconSource: "view-barcode" - tooltip: i18n("Show barcode") - onClicked: menuItem.barcode(UuidRole) - } - PlasmaComponents.ToolButton { - iconSource: "document-edit" - enabled: !clipboardSource.editing - visible: TypeRole === 0 - tooltip: i18n("Edit contents") - onClicked: menuItem.edit(UuidRole) - } - PlasmaComponents.ToolButton { - iconSource: "edit-delete" - tooltip: i18n("Remove from history") - onClicked: menuItem.remove(UuidRole) + source: "DelegateToolButtons.qml" + active: menuItem.ListView.isCurrentItem + onActiveChanged: { + if (active) { + // break binding, once it was loaded, never unload + active = true; + } } + + onStatusChanged: console.log("TUHL", index, status) } } diff --git a/applets/clipboard/contents/ui/DelegateToolButtons.qml b/applets/clipboard/contents/ui/DelegateToolButtons.qml new file mode 100644 --- /dev/null +++ b/applets/clipboard/contents/ui/DelegateToolButtons.qml @@ -0,0 +1,53 @@ +/******************************************************************** +This file is part of the KDE project. + +Copyright (C) 2014 Martin Gräßlin +Copyright 2014 Sebastian Kügler + +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; either version 2 of the License, or +(at your option) any later version. + +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, see . +*********************************************************************/ + +import QtQuick 2.0 + +import org.kde.plasma.components 2.0 as PlasmaComponents + +Row { + id: toolButtonsLayout + visible: menuItem.ListView.isCurrentItem + + PlasmaComponents.ToolButton { + // TODO: only show for items supporting actions? + iconSource: "system-run" + tooltip: i18n("Invoke action") + onClicked: menuItem.action(UuidRole) + } + PlasmaComponents.ToolButton { + id: barcodeToolButton + iconSource: "view-barcode" + tooltip: i18n("Show barcode") + onClicked: menuItem.barcode(UuidRole) + } + PlasmaComponents.ToolButton { + iconSource: "document-edit" + enabled: !clipboardSource.editing + visible: TypeRole === 0 + tooltip: i18n("Edit contents") + onClicked: menuItem.edit(UuidRole) + } + PlasmaComponents.ToolButton { + iconSource: "edit-delete" + tooltip: i18n("Remove from history") + onClicked: menuItem.remove(UuidRole) + } +} diff --git a/applets/clipboard/contents/ui/ImageItemDelegate.qml b/applets/clipboard/contents/ui/ImageItemDelegate.qml new file mode 100644 --- /dev/null +++ b/applets/clipboard/contents/ui/ImageItemDelegate.qml @@ -0,0 +1,30 @@ +/******************************************************************** +This file is part of the KDE project. + +Copyright (C) 2014 Martin Gräßlin +Copyright 2014 Sebastian Kügler + +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; either version 2 of the License, or +(at your option) any later version. + +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, see . +*********************************************************************/ + +import QtQuick 2.0 + +import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons + +KQuickControlsAddons.QPixmapItem { + id: previewPixmap + height: Math.round(width * (nativeHeight/nativeWidth) + units.smallSpacing * 2) + pixmap: DecorationRole + fillMode: KQuickControlsAddons.QPixmapItem.PreserveAspectFit +} diff --git a/applets/clipboard/contents/ui/TextItemDelegate.qml b/applets/clipboard/contents/ui/TextItemDelegate.qml new file mode 100644 --- /dev/null +++ b/applets/clipboard/contents/ui/TextItemDelegate.qml @@ -0,0 +1,56 @@ +/******************************************************************** +This file is part of the KDE project. + +Copyright (C) 2014 Martin Gräßlin +Copyright 2014 Sebastian Kügler + +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; either version 2 of the License, or +(at your option) any later version. + +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, see . +*********************************************************************/ + +import QtQuick 2.0 + +import org.kde.plasma.components 2.0 as PlasmaComponents + +PlasmaComponents.Label { + height: undefined // unset PlasmaComponents.Label default height + maximumLineCount: 3 + verticalAlignment: Text.AlignVCenter + + text: { + var highlightFontTag = "%1" + + var text = DisplayRole + + // first escape any HTML characters to prevent privacy issues + text = text.replace(/&/g, "&").replace(//g, ">") + + // color code leading or trailing whitespace + // the first regex is basically "trim" + text = text.replace(/^\s+|\s+$/gm, function(match) { + // then inside the trimmed characters ("match") we replace each one individually + match = match.replace(/ /g, "␣") // space + .replace(/\t/g, "↹") // tab + .replace(/\n/g, "↵") // return + return highlightFontTag.arg(match) + }) + + // finally turn line breaks into HTML br tags + text = text.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, "
") + + return text + } + elide: Text.ElideRight + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + textFormat: Text.StyledText +} diff --git a/applets/clipboard/contents/ui/UrlItemDelegate.qml b/applets/clipboard/contents/ui/UrlItemDelegate.qml new file mode 100644 --- /dev/null +++ b/applets/clipboard/contents/ui/UrlItemDelegate.qml @@ -0,0 +1,123 @@ +/******************************************************************** +This file is part of the KDE project. + +Copyright (C) 2014 Martin Gräßlin +Copyright 2014 Sebastian Kügler + +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; either version 2 of the License, or +(at your option) any later version. + +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, see . +*********************************************************************/ + +import QtQuick 2.0 + +import org.kde.plasma.components 2.0 as PlasmaComponents +import org.kde.kquickcontrolsaddons 2.0 as KQuickControlsAddons + +Item { + id: previewItem + height: units.gridUnit * 4 + units.smallSpacing * 2 + + ListView { + id: previewList + model: DisplayRole.split(" ", maximumNumberOfPreviews) + property int itemWidth: units.gridUnit * 4 + property int itemHeight: units.gridUnit * 4 + interactive: false + + spacing: units.smallSpacing + orientation: Qt.Horizontal + width: (itemWidth + spacing) * model.length + anchors { + top: parent.top + left: parent.left + bottom: parent.bottom + } + + delegate: Item { + width: previewList.itemWidth + height: previewList.itemHeight + y: Math.round((parent.height - previewList.itemHeight) / 2) + clip: true + + KQuickControlsAddons.QPixmapItem { + id: previewPixmap + + anchors.centerIn: parent + + Component.onCompleted: { + function result(job) { + if (!job.error) { + pixmap = job.result.preview; + previewPixmap.width = job.result.previewWidth + previewPixmap.height = job.result.previewHeight + } + } + var service = clipboardSource.serviceForSource(UuidRole) + var operation = service.operationDescription("preview"); + operation.url = modelData; + // We request a bigger size and then clip out a square in the middle + // so we get uniform delegate sizes without distortion + operation.previewWidth = previewList.itemWidth * 2; + operation.previewHeight = previewList.itemHeight * 2; + var serviceJob = service.startOperationCall(operation); + serviceJob.finished.connect(result); + } + } + Rectangle { + id: overlay + color: theme.textColor + opacity: 0.6 + height: units.gridUnit + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + } + PlasmaComponents.Label { + font.pointSize: theme.smallestFont.pointSize + color: theme.backgroundColor + maximumLineCount: 1 + anchors { + verticalCenter: overlay.verticalCenter + left: overlay.left + right: overlay.right + leftMargin: units.smallSpacing + rightMargin: units.smallSpacing + } + elide: Text.ElideRight + horizontalAlignment: Text.AlignHCenter + text: { + var u = modelData.split("/"); + return decodeURIComponent(u[u.length - 1]); + } + } + } + } + PlasmaComponents.Label { + property int additionalItems: DisplayRole.split(" ").length - maximumNumberOfPreviews + visible: additionalItems > 0 + opacity: 0.6 + text: i18nc("Indicator that there are more urls in the clipboard than previews shown", "+%1", additionalItems) + anchors { + left: previewList.right + right: parent.right + bottom: parent.bottom + margins: units.smallSpacing + + } + verticalAlignment: Text.AlignBottom + horizontalAlignment: Text.AlignCenter + font.pointSize: theme.smallestFont.pointSize + } +}