aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pages/Transfer.qml25
-rw-r--r--src/QR-Code-scanner/Decoder.cpp28
-rw-r--r--src/QR-Code-scanner/Decoder.h28
-rw-r--r--src/main/oshelper.cpp60
-rw-r--r--src/main/oshelper.h3
-rw-r--r--src/qt/macoshelper.h3
-rw-r--r--src/qt/macoshelper.mm39
7 files changed, 184 insertions, 2 deletions
diff --git a/pages/Transfer.qml b/pages/Transfer.qml
index 2e0624f7..828d7b5d 100644
--- a/pages/Transfer.qml
+++ b/pages/Transfer.qml
@@ -93,12 +93,16 @@ Rectangle {
oaPopup.open()
}
- function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
- console.log("updateFromQrCode")
+ function fillPaymentDetails(address, payment_id, amount, tx_description, recipient_name) {
addressLine.text = address
setPaymentId(payment_id);
amountLine.text = amount
setDescription((recipient_name ? recipient_name + " " : "") + tx_description);
+ }
+
+ function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
+ console.log("updateFromQrCode")
+ fillPaymentDetails(address, payment_id, amount, tx_description, recipient_name);
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
}
@@ -198,6 +202,23 @@ Rectangle {
MoneroComponents.InlineButton {
fontFamily: FontAwesome.fontFamily
+ fontPixelSize: 18
+ text: FontAwesome.desktop
+ onClicked: {
+ clearFields();
+ const codes = oshelper.grabQrCodesFromScreen();
+ for (var index = 0; index < codes.length; ++index) {
+ const parsed = walletManager.parse_uri_to_object(codes[index]);
+ if (!parsed.error) {
+ fillPaymentDetails(parsed.address, parsed.payment_id, parsed.amount, parsed.tx_description, parsed.recipient_name);
+ break;
+ }
+ }
+ }
+ }
+
+ MoneroComponents.InlineButton {
+ fontFamily: FontAwesome.fontFamily
text: FontAwesome.addressBook
onClicked: {
middlePanel.addressBookView.selectAndSend = true;
diff --git a/src/QR-Code-scanner/Decoder.cpp b/src/QR-Code-scanner/Decoder.cpp
index a814969b..1bb99140 100644
--- a/src/QR-Code-scanner/Decoder.cpp
+++ b/src/QR-Code-scanner/Decoder.cpp
@@ -1,3 +1,31 @@
+// Copyright (c) 2020, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
#include "Decoder.h"
#include <limits>
diff --git a/src/QR-Code-scanner/Decoder.h b/src/QR-Code-scanner/Decoder.h
index e25c3936..9efaca67 100644
--- a/src/QR-Code-scanner/Decoder.h
+++ b/src/QR-Code-scanner/Decoder.h
@@ -1,3 +1,31 @@
+// Copyright (c) 2020, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
#include <QImage>
struct quirc;
diff --git a/src/main/oshelper.cpp b/src/main/oshelper.cpp
index 7584732e..7037e21e 100644
--- a/src/main/oshelper.cpp
+++ b/src/main/oshelper.cpp
@@ -27,10 +27,16 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "oshelper.h"
+
+#include <unordered_set>
+
#include <QCoreApplication>
+#include <QGuiApplication>
#include <QFileDialog>
+#include <QScreen>
#include <QStandardPaths>
#include <QTemporaryFile>
+#include <QWindow>
#include <QDir>
#include <QDebug>
#include <QDesktopServices>
@@ -55,6 +61,40 @@
#include "qt/utils.h"
#endif
+#include "QR-Code-scanner/Decoder.h"
+#include "qt/ScopeGuard.h"
+
+namespace
+{
+
+QPixmap screenshot()
+{
+#ifdef Q_OS_MAC
+ return MacOSHelper::screenshot();
+#else
+ std::unordered_set<QWindow *> hidden;
+ const QWindowList windows = QGuiApplication::allWindows();
+ for (QWindow *window : windows)
+ {
+ if (window->isVisible())
+ {
+ hidden.emplace(window);
+ window->hide();
+ }
+ }
+ const auto unhide = sg::make_scope_guard([&hidden]() {
+ for (QWindow *window : hidden)
+ {
+ window->show();
+ }
+ });
+
+ return QGuiApplication::primaryScreen()->grabWindow(0);
+#endif
+}
+
+} // namespace
+
#if defined(Q_OS_WIN)
bool openFolderAndSelectItem(const QString &filePath)
{
@@ -99,6 +139,26 @@ QString OSHelper::downloadLocation() const
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
}
+QList<QString> OSHelper::grabQrCodesFromScreen() const
+{
+ QList<QString> codes;
+
+ try
+ {
+ const QImage image = screenshot().toImage();
+ const std::vector<std::string> decoded = QrDecoder().decode(image);
+ std::for_each(decoded.begin(), decoded.end(), [&codes](const std::string &code) {
+ codes.push_back(QString::fromStdString(code));
+ });
+ }
+ catch (const std::exception &e)
+ {
+ qWarning() << e.what();
+ }
+
+ return codes;
+}
+
bool OSHelper::openContainingFolder(const QString &filePath) const
{
QString canonicalFilePath = QFileInfo(filePath).canonicalFilePath();
diff --git a/src/main/oshelper.h b/src/main/oshelper.h
index 96f58073..f4168071 100644
--- a/src/main/oshelper.h
+++ b/src/main/oshelper.h
@@ -29,7 +29,9 @@
#ifndef OSHELPER_H
#define OSHELPER_H
+#include <QList>
#include <QObject>
+#include <QString>
/**
* @brief The OSHelper class - exports to QML some OS-related functions
*/
@@ -43,6 +45,7 @@ public:
Q_INVOKABLE void createDesktopEntry() const;
Q_INVOKABLE QString downloadLocation() const;
+ Q_INVOKABLE QList<QString> grabQrCodesFromScreen() const;
Q_INVOKABLE bool openContainingFolder(const QString &filePath) const;
Q_INVOKABLE QString openSaveFileDialog(const QString &title, const QString &folder, const QString &filename) const;
Q_INVOKABLE QString temporaryFilename() const;
diff --git a/src/qt/macoshelper.h b/src/qt/macoshelper.h
index e8dabfbe..c8e86b05 100644
--- a/src/qt/macoshelper.h
+++ b/src/qt/macoshelper.h
@@ -29,6 +29,8 @@
#ifndef MACOSHELPER_H
#define MACOSHELPER_H
+#include <QPixmap>
+
class MacOSHelper
{
MacOSHelper() {}
@@ -36,6 +38,7 @@ class MacOSHelper
public:
static bool isCapsLock();
static bool openFolderAndSelectItem(const QUrl &path);
+ static QPixmap screenshot();
static QString bundlePath();
};
diff --git a/src/qt/macoshelper.mm b/src/qt/macoshelper.mm
index 8f7b4b0f..1d3b812a 100644
--- a/src/qt/macoshelper.mm
+++ b/src/qt/macoshelper.mm
@@ -26,6 +26,8 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <unordered_set>
+
#include <QtCore>
#include <QtGui>
#include <QtMac>
@@ -37,6 +39,8 @@
#include <ApplicationServices/ApplicationServices.h>
#include <Availability.h>
+#include "ScopeGuard.h"
+
bool MacOSHelper::isCapsLock()
{
#ifdef __MAC_10_12
@@ -56,6 +60,41 @@ bool MacOSHelper::openFolderAndSelectItem(const QUrl &path)
return true;
}
+QPixmap MacOSHelper::screenshot()
+{
+ std::unordered_set<uintptr_t> appWindowIds;
+ for (NSWindow *window in [NSApp windows])
+ {
+ appWindowIds.insert((uintptr_t)[window windowNumber]);
+ }
+
+ CFArrayRef onScreenWindows = CGWindowListCreate(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
+ const auto onScreenWindowsClenaup = sg::make_scope_guard([&onScreenWindows]() {
+ CFRelease(onScreenWindows);
+ });
+
+ CFMutableArrayRef foreignWindows = CFArrayCreateMutable(NULL, CFArrayGetCount(onScreenWindows), NULL);
+ const auto foreignWindowsClenaup = sg::make_scope_guard([&foreignWindows]() {
+ CFRelease(foreignWindows);
+ });
+
+ for (CFIndex index = 0, count = CFArrayGetCount(onScreenWindows); index < count; ++index)
+ {
+ const uintptr_t windowId = reinterpret_cast<const uintptr_t>(CFArrayGetValueAtIndex(onScreenWindows, index));
+ if (appWindowIds.find(windowId) == appWindowIds.end())
+ {
+ CFArrayAppendValue(foreignWindows, reinterpret_cast<const void *>(windowId));
+ }
+ }
+
+ CGImageRef image = CGWindowListCreateImageFromArray(CGRectInfinite, foreignWindows, kCGWindowListOptionAll);
+ const auto imageClenaup = sg::make_scope_guard([&image]() {
+ CFRelease(image);
+ });
+
+ return QtMac::fromCGImageRef(image);
+}
+
QString MacOSHelper::bundlePath()
{
NSBundle *main = [NSBundle mainBundle];