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()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
fontFamily: FontAwesome.fontFamily
|
||||
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 <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>
|
||||
|
||||
struct quirc;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue