File indexing completed on 2024-04-28 05:35:26
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "clipboardjob.h" 0008 #include "history.h" 0009 #include "historyitem.h" 0010 #include "historystringitem.h" 0011 #include "klipper.h" 0012 0013 #include "klipper_debug.h" 0014 #include <KIO/PreviewJob> 0015 #include <QIcon> 0016 0017 #include <Prison/Barcode> 0018 0019 const static QString s_iconKey = QStringLiteral("icon"); 0020 const static QString s_previewKey = QStringLiteral("preview"); 0021 const static QString s_previewWidthKey = QStringLiteral("previewWidth"); 0022 const static QString s_previewHeightKey = QStringLiteral("previewHeight"); 0023 const static QString s_urlKey = QStringLiteral("url"); 0024 0025 ClipboardJob::ClipboardJob(Klipper *klipper, const QString &destination, const QString &operation, const QVariantMap ¶meters, QObject *parent) 0026 : Plasma5Support::ServiceJob(destination, operation, parameters, parent) 0027 , m_klipper(klipper) 0028 { 0029 } 0030 0031 void ClipboardJob::start() 0032 { 0033 const QString operation = operationName(); 0034 // first check for operations not needing an item 0035 if (operation == QLatin1String("clearHistory")) { 0036 m_klipper->slotAskClearHistory(); 0037 setResult(true); 0038 return; 0039 } else if (operation == QLatin1String("configureKlipper")) { 0040 m_klipper->slotConfigure(); 0041 setResult(true); 0042 return; 0043 } 0044 0045 // other operations need the item 0046 HistoryItemConstPtr item = m_klipper->history()->find(QByteArray::fromBase64(destination().toUtf8())); 0047 if (!item) { 0048 setResult(false); 0049 return; 0050 } 0051 if (operation == QLatin1String("select")) { 0052 m_klipper->history()->slotMoveToTop(item->uuid()); 0053 setResult(true); 0054 } else if (operation == QLatin1String("remove")) { 0055 m_klipper->history()->remove(item); 0056 setResult(true); 0057 } else if (operation == QLatin1String("edit")) { 0058 if (parameters().contains(QLatin1String("text"))) { 0059 const QString text = parameters()[QLatin1String("text")].toString(); 0060 m_klipper->history()->remove(item); 0061 m_klipper->history()->insert(HistoryItemPtr(new HistoryStringItem(text))); 0062 if (m_klipper->urlGrabber()) { 0063 m_klipper->urlGrabber()->checkNewData(HistoryItemConstPtr(m_klipper->history()->first())); 0064 } 0065 setResult(true); 0066 return; 0067 } 0068 return; 0069 } else if (operation == QLatin1String("barcode")) { 0070 int pixelWidth = parameters().value(QStringLiteral("width")).toInt(); 0071 int pixelHeight = parameters().value(QStringLiteral("height")).toInt(); 0072 std::optional<Prison::Barcode> code; 0073 switch (parameters().value(QStringLiteral("barcodeType")).toInt()) { 0074 case 1: { 0075 code = Prison::Barcode::create(Prison::DataMatrix); 0076 const int size = qMin(pixelWidth, pixelHeight); 0077 pixelWidth = size; 0078 pixelHeight = size; 0079 break; 0080 } 0081 case 2: { 0082 code = Prison::Barcode::create(Prison::Code39); 0083 break; 0084 } 0085 case 3: { 0086 code = Prison::Barcode::create(Prison::Code93); 0087 break; 0088 } 0089 case 4: { 0090 code = Prison::Barcode::create(Prison::Aztec); 0091 break; 0092 } 0093 case 0: 0094 default: { 0095 code = Prison::Barcode::create(Prison::QRCode); 0096 const int size = qMin(pixelWidth, pixelHeight); 0097 pixelWidth = size; 0098 pixelHeight = size; 0099 break; 0100 } 0101 } 0102 if (code) { 0103 code->setData(item->text()); 0104 setResult(code->toImage(QSizeF(pixelWidth, pixelHeight))); 0105 return; 0106 } else { 0107 setResult(false); 0108 } 0109 } else if (operation == QLatin1String("action")) { 0110 m_klipper->urlGrabber()->invokeAction(item); 0111 setResult(true); 0112 0113 } else if (operation == s_previewKey) { 0114 const int pixelWidth = parameters().value(s_previewWidthKey).toInt(); 0115 const int pixelHeight = parameters().value(s_previewHeightKey).toInt(); 0116 QUrl url = parameters().value(s_urlKey).toUrl(); 0117 qCDebug(KLIPPER_LOG) << "URL: " << url; 0118 KFileItem item(url); 0119 0120 if (pixelWidth <= 0 || pixelHeight <= 0) { 0121 qCWarning(KLIPPER_LOG) << "Preview size invalid: " << pixelWidth << "x" << pixelHeight; 0122 iconResult(item); 0123 return; 0124 } 0125 0126 if (!url.isValid() || !url.isLocalFile()) { // no remote files 0127 qCWarning(KLIPPER_LOG) << "Invalid or non-local url for preview: " << url; 0128 iconResult(item); 0129 return; 0130 } 0131 0132 KFileItemList urls; 0133 urls << item; 0134 0135 KIO::PreviewJob *job = KIO::filePreview(urls, QSize(pixelWidth, pixelHeight)); 0136 job->setIgnoreMaximumSize(true); 0137 connect(job, &KIO::PreviewJob::gotPreview, this, [this](const KFileItem &item, const QPixmap &preview) { 0138 QVariantMap res; 0139 res.insert(s_urlKey, item.url()); 0140 res.insert(s_previewKey, preview); 0141 res.insert(s_iconKey, false); 0142 res.insert(s_previewWidthKey, preview.size().width()); 0143 res.insert(s_previewHeightKey, preview.size().height()); 0144 setResult(res); 0145 }); 0146 connect(job, &KIO::PreviewJob::failed, this, [this](const KFileItem &item) { 0147 iconResult(item); 0148 }); 0149 0150 job->start(); 0151 0152 return; 0153 } else { 0154 setResult(false); 0155 } 0156 emitResult(); 0157 } 0158 0159 void ClipboardJob::iconResult(const KFileItem &item) 0160 { 0161 QVariantMap res; 0162 res.insert(s_urlKey, item.url()); 0163 QPixmap pix = QIcon::fromTheme(item.determineMimeType().iconName()).pixmap(128, 128); 0164 res.insert(s_previewKey, pix); 0165 res.insert(s_iconKey, true); 0166 res.insert(QStringLiteral("iconName"), item.currentMimeType().iconName()); 0167 res.insert(s_previewWidthKey, pix.size().width()); 0168 res.insert(s_previewHeightKey, pix.size().height()); 0169 setResult(res); 0170 }