mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-12-23 12:09:57 +00:00
Merge pull request #3292
e9b894d
Transfer: implement 'Grab QR code from screen' functionality (xiphon)
This commit is contained in:
commit
ec7bc577d6
7 changed files with 184 additions and 2 deletions
|
@ -93,12 +93,16 @@ Rectangle {
|
||||||
oaPopup.open()
|
oaPopup.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
|
function fillPaymentDetails(address, payment_id, amount, tx_description, recipient_name) {
|
||||||
console.log("updateFromQrCode")
|
|
||||||
addressLine.text = address
|
addressLine.text = address
|
||||||
setPaymentId(payment_id);
|
setPaymentId(payment_id);
|
||||||
amountLine.text = amount
|
amountLine.text = amount
|
||||||
setDescription((recipient_name ? recipient_name + " " : "") + tx_description);
|
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)
|
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +200,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 {
|
MoneroComponents.InlineButton {
|
||||||
fontFamily: FontAwesome.fontFamily
|
fontFamily: FontAwesome.fontFamily
|
||||||
text: FontAwesome.addressBook
|
text: FontAwesome.addressBook
|
||||||
|
|
|
@ -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 "Decoder.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
|
@ -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>
|
#include <QImage>
|
||||||
|
|
||||||
struct quirc;
|
struct quirc;
|
||||||
|
|
|
@ -27,10 +27,16 @@
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "oshelper.h"
|
#include "oshelper.h"
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QGuiApplication>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QScreen>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
#include <QWindow>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
@ -55,6 +61,40 @@
|
||||||
#include "qt/utils.h"
|
#include "qt/utils.h"
|
||||||
#endif
|
#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)
|
#if defined(Q_OS_WIN)
|
||||||
bool openFolderAndSelectItem(const QString &filePath)
|
bool openFolderAndSelectItem(const QString &filePath)
|
||||||
{
|
{
|
||||||
|
@ -99,6 +139,26 @@ QString OSHelper::downloadLocation() const
|
||||||
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
|
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
|
bool OSHelper::openContainingFolder(const QString &filePath) const
|
||||||
{
|
{
|
||||||
QString canonicalFilePath = QFileInfo(filePath).canonicalFilePath();
|
QString canonicalFilePath = QFileInfo(filePath).canonicalFilePath();
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
#ifndef OSHELPER_H
|
#ifndef OSHELPER_H
|
||||||
#define OSHELPER_H
|
#define OSHELPER_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
/**
|
/**
|
||||||
* @brief The OSHelper class - exports to QML some OS-related functions
|
* @brief The OSHelper class - exports to QML some OS-related functions
|
||||||
*/
|
*/
|
||||||
|
@ -43,6 +45,7 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void createDesktopEntry() const;
|
Q_INVOKABLE void createDesktopEntry() const;
|
||||||
Q_INVOKABLE QString downloadLocation() const;
|
Q_INVOKABLE QString downloadLocation() const;
|
||||||
|
Q_INVOKABLE QList<QString> grabQrCodesFromScreen() const;
|
||||||
Q_INVOKABLE bool openContainingFolder(const QString &filePath) 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 openSaveFileDialog(const QString &title, const QString &folder, const QString &filename) const;
|
||||||
Q_INVOKABLE QString temporaryFilename() const;
|
Q_INVOKABLE QString temporaryFilename() const;
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#ifndef MACOSHELPER_H
|
#ifndef MACOSHELPER_H
|
||||||
#define MACOSHELPER_H
|
#define MACOSHELPER_H
|
||||||
|
|
||||||
|
#include <QPixmap>
|
||||||
|
|
||||||
class MacOSHelper
|
class MacOSHelper
|
||||||
{
|
{
|
||||||
MacOSHelper() {}
|
MacOSHelper() {}
|
||||||
|
@ -36,6 +38,7 @@ class MacOSHelper
|
||||||
public:
|
public:
|
||||||
static bool isCapsLock();
|
static bool isCapsLock();
|
||||||
static bool openFolderAndSelectItem(const QUrl &path);
|
static bool openFolderAndSelectItem(const QUrl &path);
|
||||||
|
static QPixmap screenshot();
|
||||||
static QString bundlePath();
|
static QString bundlePath();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
// 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.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include <QtMac>
|
#include <QtMac>
|
||||||
|
@ -37,6 +39,8 @@
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#include <Availability.h>
|
#include <Availability.h>
|
||||||
|
|
||||||
|
#include "ScopeGuard.h"
|
||||||
|
|
||||||
bool MacOSHelper::isCapsLock()
|
bool MacOSHelper::isCapsLock()
|
||||||
{
|
{
|
||||||
#ifdef __MAC_10_12
|
#ifdef __MAC_10_12
|
||||||
|
@ -56,6 +60,41 @@ bool MacOSHelper::openFolderAndSelectItem(const QUrl &path)
|
||||||
return true;
|
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()
|
QString MacOSHelper::bundlePath()
|
||||||
{
|
{
|
||||||
NSBundle *main = [NSBundle mainBundle];
|
NSBundle *main = [NSBundle mainBundle];
|
||||||
|
|
Loading…
Reference in a new issue