diff --git a/applets/clipboard/contents/ui/BarcodePage.qml b/applets/clipboard/contents/ui/BarcodePage.qml index bebb2181d..682a53fcd 100644 --- a/applets/clipboard/contents/ui/BarcodePage.qml +++ b/applets/clipboard/contents/ui/BarcodePage.qml @@ -1,123 +1,129 @@ /******************************************************************** This file is part of the KDE project. Copyright (C) 2015 Martin Gräßlin 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 QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.kquickcontrolsaddons 2.0 ColumnLayout { id: barcodeView property var uuid: "" property int barcodeType: 0 function show(uuid) { barcodeView.uuid = uuid; barcodePreview.image = undefined; barcodePreview.busy = true; var service = clipboardSource.serviceForSource(uuid) var operation = service.operationDescription("barcode"); operation.width = barcodePreview.width; operation.height = barcodePreview.height; operation.barcodeType = barcodeView.barcodeType; var serviceJob = service.startOperationCall(operation); serviceJob.finished.connect(function (job) { if (!job.error) { barcodePreview.image = job.result; barcodePreview.busy = false; } }); } RowLayout { Layout.fillWidth: true PlasmaComponents.Button { Layout.fillWidth: true iconSource: "go-previous-view" text: i18n("Return to Clipboard") onClicked: stack.pop() } PlasmaComponents.ContextMenu { id: menu visualParent: configureButton placement: PlasmaCore.Types.BottomPosedLeftAlignedPopup onStatusChanged: { if (status == PlasmaComponents.DialogStatus.Closed) { configureButton.checked = false; } } function change(type) { barcodeView.barcodeType = type; barcodeView.show(barcodeView.uuid); } PlasmaComponents.MenuItem { text: i18n("QR Code") checkable: true checked: barcodeView.barcodeType == 0 onClicked: menu.change(0) } PlasmaComponents.MenuItem { text: i18n("Data Matrix") checkable: true checked: barcodeView.barcodeType == 1 onClicked: menu.change(1) } + PlasmaComponents.MenuItem { + text: i18nc("Aztec barcode", "Aztec") + checkable: true + checked: barcodeView.barcodeType == 4 + onClicked: menu.change(4) + } PlasmaComponents.MenuItem { text: i18n("Code 39") checkable: true checked: barcodeView.barcodeType == 2 onClicked: menu.change(2) } PlasmaComponents.MenuItem { text: i18n("Code 93") checkable: true checked: barcodeView.barcodeType == 3 onClicked: menu.change(3) } } PlasmaComponents.ToolButton { id: configureButton checkable: true iconSource: "configure" tooltip: i18n("Change the barcode type") onClicked: menu.openRelative() } } QImageItem { id: barcodePreview property alias busy: busyIndicator.visible fillMode: QImageItem.PreserveAspectFit Layout.fillWidth: true Layout.fillHeight: true onWidthChanged: barcodeView.show(barcodeView.uuid) onHeightChanged: barcodeView.show(barcodeView.uuid) PlasmaComponents.BusyIndicator { id: busyIndicator anchors.centerIn: parent } PlasmaComponents.Label { anchors.centerIn: parent text: i18n("Creating barcode failed") visible: !barcodePreview.busy && barcodePreview.null } } } diff --git a/klipper/clipboardjob.cpp b/klipper/clipboardjob.cpp index ebeb1ab3b..dd5112b52 100644 --- a/klipper/clipboardjob.cpp +++ b/klipper/clipboardjob.cpp @@ -1,205 +1,209 @@ /******************************************************************** This file is part of the KDE project. Copyright (C) 2014 Martin Gräßlin 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 . *********************************************************************/ #include "clipboardjob.h" #include "klipper.h" #include "history.h" #include "historyitem.h" #include #include #include #include "klipper_debug.h" #include #ifdef HAVE_PRISON #include #endif const static QString s_iconKey = QStringLiteral("icon"); const static QString s_previewKey = QStringLiteral("preview"); const static QString s_previewWidthKey = QStringLiteral("previewWidth"); const static QString s_previewHeightKey = QStringLiteral("previewHeight"); const static QString s_urlKey = QStringLiteral("url"); ClipboardJob::ClipboardJob(Klipper *klipper, const QString &destination, const QString &operation, const QVariantMap ¶meters, QObject *parent) : Plasma::ServiceJob(destination, operation, parameters, parent) , m_klipper(klipper) { } void ClipboardJob::start() { const QString operation = operationName(); // first check for operations not needing an item if (operation == QLatin1String("clearHistory")) { m_klipper->slotAskClearHistory(); setResult(true); emitResult(); return; } else if (operation == QLatin1String("configureKlipper")) { m_klipper->slotConfigure(); setResult(true); emitResult(); return; } // other operations need the item HistoryItemConstPtr item = m_klipper->history()->find(QByteArray::fromBase64(destination().toUtf8())); if (item.isNull()) { setResult(false); emitResult(); return; } if (operation == QLatin1String("select")) { m_klipper->history()->slotMoveToTop(item->uuid()); setResult(true); } else if (operation == QLatin1String("remove")) { m_klipper->history()->remove(item); setResult(true); } else if (operation == QLatin1String("edit")) { connect(m_klipper, &Klipper::editFinished, this, [this, item](HistoryItemConstPtr editedItem, int result) { if (item != editedItem) { // not our item return; } setResult(result); emitResult(); } ); m_klipper->editData(item); return; } else if (operation == QLatin1String("barcode")) { #ifdef HAVE_PRISON int pixelWidth = parameters().value(QStringLiteral("width")).toInt(); int pixelHeight = parameters().value(QStringLiteral("height")).toInt(); Prison::AbstractBarcode *code = nullptr; switch (parameters().value(QStringLiteral("barcodeType")).toInt()) { case 1: { code = Prison::createBarcode(Prison::DataMatrix); const int size = qMin(pixelWidth, pixelHeight); pixelWidth = size; pixelHeight = size; break; } case 2: { code = Prison::createBarcode(Prison::Code39); break; } case 3: { code = Prison::createBarcode(Prison::Code93); break; } + case 4: { + code = Prison::createBarcode(Prison::Aztec); + break; + } case 0: default: { code = Prison::createBarcode(Prison::QRCode); const int size = qMin(pixelWidth, pixelHeight); pixelWidth = size; pixelHeight = size; break; } } if (code) { code->setData(item->text()); QFutureWatcher *watcher = new QFutureWatcher(this); connect(watcher, &QFutureWatcher::finished, this, [this, watcher, code] { setResult(watcher->result()); watcher->deleteLater(); delete code; emitResult(); } ); auto future = QtConcurrent::run(code, &Prison::AbstractBarcode::toImage, QSizeF(pixelWidth, pixelHeight)); watcher->setFuture(future); return; } else { setResult(false); } #else setResult(false); #endif } else if (operation == QLatin1String("action")) { m_klipper->urlGrabber()->invokeAction(item); setResult(true); } else if (operation == s_previewKey) { const int pixelWidth = parameters().value(s_previewWidthKey).toInt(); const int pixelHeight = parameters().value(s_previewHeightKey).toInt(); QUrl url = parameters().value(s_urlKey).toUrl(); qCDebug(KLIPPER_LOG) << "URL: " << url; KFileItem item(url); if (pixelWidth <= 0 || pixelHeight <= 0) { qCWarning(KLIPPER_LOG) << "Preview size invalid: " << pixelWidth << "x" << pixelHeight; iconResult(item); return; } if (!url.isValid() || !url.isLocalFile()) { // no remote files qCWarning(KLIPPER_LOG) << "Invalid or non-local url for preview: " << url; iconResult(item); return; } KFileItemList urls; urls << item; KIO::PreviewJob* job = KIO::filePreview(urls, QSize(pixelWidth, pixelHeight)); job->setIgnoreMaximumSize(true); connect(job, &KIO::PreviewJob::gotPreview, this, [this](const KFileItem &item, const QPixmap &preview) { QVariantMap res; res.insert(s_urlKey, item.url()); res.insert(s_previewKey, preview); res.insert(s_iconKey, false); res.insert(s_previewWidthKey, preview.size().width()); res.insert(s_previewHeightKey, preview.size().height()); setResult(res); emitResult(); } ); connect(job, &KIO::PreviewJob::failed, this, [this](const KFileItem &item) { iconResult(item); } ); job->start(); return; } else { setResult(false); } emitResult(); } void ClipboardJob::iconResult(const KFileItem& item) { QVariantMap res; res.insert(s_urlKey, item.url()); QPixmap pix = QIcon::fromTheme(item.determineMimeType().iconName()).pixmap(128, 128); res.insert(s_previewKey, pix); res.insert(s_iconKey, true); res.insert(QStringLiteral("iconName"), item.currentMimeType().iconName()); res.insert(s_previewWidthKey, pix.size().width()); res.insert(s_previewHeightKey, pix.size().height()); setResult(res); emitResult(); }