mirror of
https://github.com/monero-project/monero-gui.git
synced 2024-12-23 20:20:02 +00:00
IPC and custom protocol handler for monero://
This commit is contained in:
parent
ff6ce6294b
commit
18f2accc7f
13 changed files with 354 additions and 15 deletions
|
@ -43,6 +43,13 @@ filter::filter(QObject *parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
bool filter::eventFilter(QObject *obj, QEvent *ev) {
|
bool filter::eventFilter(QObject *obj, QEvent *ev) {
|
||||||
|
// macOS sends fileopen signal for incoming uri handlers
|
||||||
|
if (ev->type() == QEvent::FileOpen) {
|
||||||
|
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(ev);
|
||||||
|
QUrl scheme = openEvent->url();
|
||||||
|
emit uriHandler(scheme);
|
||||||
|
}
|
||||||
|
|
||||||
if(ev->type() == QEvent::KeyPress || ev->type() == QEvent::MouseButtonRelease){
|
if(ev->type() == QEvent::KeyPress || ev->type() == QEvent::MouseButtonRelease){
|
||||||
emit userActivity();
|
emit userActivity();
|
||||||
}
|
}
|
||||||
|
|
1
filter.h
1
filter.h
|
@ -49,6 +49,7 @@ signals:
|
||||||
void mousePressed(const QVariant &o, const QVariant &x, const QVariant &y);
|
void mousePressed(const QVariant &o, const QVariant &x, const QVariant &y);
|
||||||
void mouseReleased(const QVariant &o, const QVariant &x, const QVariant &y);
|
void mouseReleased(const QVariant &o, const QVariant &x, const QVariant &y);
|
||||||
void userActivity();
|
void userActivity();
|
||||||
|
void uriHandler(const QUrl &url);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILTER_H
|
#endif // FILTER_H
|
||||||
|
|
41
main.cpp
41
main.cpp
|
@ -32,6 +32,7 @@
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QDesktopServices>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
@ -60,6 +61,9 @@
|
||||||
#include "wallet/api/wallet2_api.h"
|
#include "wallet/api/wallet2_api.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "MainApp.h"
|
#include "MainApp.h"
|
||||||
|
#include "qt/ipc.h"
|
||||||
|
#include "qt/utils.h"
|
||||||
|
#include "qt/mime.h"
|
||||||
|
|
||||||
// IOS exclusions
|
// IOS exclusions
|
||||||
#ifndef Q_OS_IOS
|
#ifndef Q_OS_IOS
|
||||||
|
@ -82,6 +86,8 @@ int main(int argc, char *argv[])
|
||||||
// platform dependant settings
|
// platform dependant settings
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
bool isDesktop = true;
|
bool isDesktop = true;
|
||||||
|
#elif defined(Q_OS_LINUX)
|
||||||
|
bool isLinux = true;
|
||||||
#elif defined(Q_OS_ANDROID)
|
#elif defined(Q_OS_ANDROID)
|
||||||
bool isAndroid = true;
|
bool isAndroid = true;
|
||||||
#elif defined(Q_OS_IOS)
|
#elif defined(Q_OS_IOS)
|
||||||
|
@ -127,6 +133,7 @@ int main(int argc, char *argv[])
|
||||||
QCommandLineOption logPathOption(QStringList() << "l" << "log-file",
|
QCommandLineOption logPathOption(QStringList() << "l" << "log-file",
|
||||||
QCoreApplication::translate("main", "Log to specified file"),
|
QCoreApplication::translate("main", "Log to specified file"),
|
||||||
QCoreApplication::translate("main", "file"));
|
QCoreApplication::translate("main", "file"));
|
||||||
|
|
||||||
parser.addOption(logPathOption);
|
parser.addOption(logPathOption);
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
|
@ -138,11 +145,33 @@ int main(int argc, char *argv[])
|
||||||
Monero::Wallet::init(argv[0], "monero-wallet-gui", logPath.toStdString().c_str(), true);
|
Monero::Wallet::init(argv[0], "monero-wallet-gui", logPath.toStdString().c_str(), true);
|
||||||
qInstallMessageHandler(messageHandler);
|
qInstallMessageHandler(messageHandler);
|
||||||
|
|
||||||
|
// Get default account name
|
||||||
|
QString accountName = getAccountName();
|
||||||
|
|
||||||
// loglevel is configured in main.qml. Anything lower than
|
// loglevel is configured in main.qml. Anything lower than
|
||||||
// qWarning is not shown here.
|
// qWarning is not shown here.
|
||||||
qWarning().noquote() << "app startd" << "(log: " + logPath + ")";
|
qWarning().noquote() << "app startd" << "(log: " + logPath + ")";
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
registerXdgMime(app);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IPC *ipc = new IPC(&app);
|
||||||
|
QStringList posArgs = parser.positionalArguments();
|
||||||
|
|
||||||
|
for(int i = 0; i != posArgs.count(); i++){
|
||||||
|
QString arg = QString(posArgs.at(i));
|
||||||
|
if(arg.isEmpty() || arg.length() >= 512) continue;
|
||||||
|
if(arg.contains(reURI)){
|
||||||
|
if(!ipc->saveCommand(arg)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start listening
|
||||||
|
QTimer::singleShot(0, ipc, SLOT(bind()));
|
||||||
|
|
||||||
// screen settings
|
// screen settings
|
||||||
// Mobile is designed on 128dpi
|
// Mobile is designed on 128dpi
|
||||||
qreal ref_dpi = 128;
|
qreal ref_dpi = 128;
|
||||||
|
@ -252,6 +281,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("mainApp", &app);
|
engine.rootContext()->setContextProperty("mainApp", &app);
|
||||||
|
|
||||||
|
engine.rootContext()->setContextProperty("IPC", ipc);
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("qtRuntimeVersion", qVersion());
|
engine.rootContext()->setContextProperty("qtRuntimeVersion", qVersion());
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("walletLogPath", logPath);
|
engine.rootContext()->setContextProperty("walletLogPath", logPath);
|
||||||
|
@ -295,14 +326,6 @@ int main(int argc, char *argv[])
|
||||||
engine.rootContext()->setContextProperty("moneroAccountsDir", moneroAccountsDir);
|
engine.rootContext()->setContextProperty("moneroAccountsDir", moneroAccountsDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get default account name
|
|
||||||
QString accountName = qgetenv("USER"); // mac/linux
|
|
||||||
if (accountName.isEmpty())
|
|
||||||
accountName = qgetenv("USERNAME"); // Windows
|
|
||||||
if (accountName.isEmpty())
|
|
||||||
accountName = "My monero Account";
|
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("defaultAccountName", accountName);
|
engine.rootContext()->setContextProperty("defaultAccountName", accountName);
|
||||||
engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
|
engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
|
||||||
engine.rootContext()->setContextProperty("idealThreadCount", QThread::idealThreadCount());
|
engine.rootContext()->setContextProperty("idealThreadCount", QThread::idealThreadCount());
|
||||||
|
@ -312,7 +335,6 @@ int main(int argc, char *argv[])
|
||||||
builtWithScanner = true;
|
builtWithScanner = true;
|
||||||
#endif
|
#endif
|
||||||
engine.rootContext()->setContextProperty("builtWithScanner", builtWithScanner);
|
engine.rootContext()->setContextProperty("builtWithScanner", builtWithScanner);
|
||||||
|
|
||||||
// Load main window (context properties needs to be defined obove this line)
|
// Load main window (context properties needs to be defined obove this line)
|
||||||
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
||||||
if (engine.rootObjects().isEmpty())
|
if (engine.rootObjects().isEmpty())
|
||||||
|
@ -345,5 +367,6 @@ int main(int argc, char *argv[])
|
||||||
QObject::connect(eventFilter, SIGNAL(mousePressed(QVariant,QVariant,QVariant)), rootObject, SLOT(mousePressed(QVariant,QVariant,QVariant)));
|
QObject::connect(eventFilter, SIGNAL(mousePressed(QVariant,QVariant,QVariant)), rootObject, SLOT(mousePressed(QVariant,QVariant,QVariant)));
|
||||||
QObject::connect(eventFilter, SIGNAL(mouseReleased(QVariant,QVariant,QVariant)), rootObject, SLOT(mouseReleased(QVariant,QVariant,QVariant)));
|
QObject::connect(eventFilter, SIGNAL(mouseReleased(QVariant,QVariant,QVariant)), rootObject, SLOT(mouseReleased(QVariant,QVariant,QVariant)));
|
||||||
QObject::connect(eventFilter, SIGNAL(userActivity()), rootObject, SLOT(userActivity()));
|
QObject::connect(eventFilter, SIGNAL(userActivity()), rootObject, SLOT(userActivity()));
|
||||||
|
QObject::connect(eventFilter, SIGNAL(uriHandler(QUrl)), ipc, SLOT(parseCommand(QUrl)));
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
50
main.qml
50
main.qml
|
@ -399,6 +399,49 @@ ApplicationWindow {
|
||||||
leftPanel.balanceLabelText = qsTr("Balance (#%1%2)").arg(currentWallet.currentSubaddressAccount).arg(accountLabel === "" ? "" : (" – " + accountLabel));
|
leftPanel.balanceLabelText = qsTr("Balance (#%1%2)").arg(currentWallet.currentSubaddressAccount).arg(accountLabel === "" ? "" : (" – " + accountLabel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onUriHandler(uri){
|
||||||
|
if(uri.startsWith("monero://")){
|
||||||
|
var address = uri.substring("monero://".length);
|
||||||
|
|
||||||
|
var params = {}
|
||||||
|
if(address.length === 0) return;
|
||||||
|
var spl = address.split("?");
|
||||||
|
|
||||||
|
if(spl.length > 2) return;
|
||||||
|
if(spl.length >= 1) {
|
||||||
|
// parse additional params
|
||||||
|
address = spl[0];
|
||||||
|
|
||||||
|
if(spl.length === 2){
|
||||||
|
spl.shift();
|
||||||
|
var item = spl[0];
|
||||||
|
|
||||||
|
var _spl = item.split("&");
|
||||||
|
for (var param in _spl){
|
||||||
|
var _item = _spl[param];
|
||||||
|
if(!_item.indexOf("=") > 0) continue;
|
||||||
|
|
||||||
|
var __spl = _item.split("=");
|
||||||
|
if(__spl.length !== 2) continue;
|
||||||
|
|
||||||
|
params[__spl[0]] = __spl[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill fields
|
||||||
|
middlePanel.transferView.sendTo(address, params["tx_payment_id"], params["tx_description"], params["tx_amount"]);
|
||||||
|
|
||||||
|
// Raise window
|
||||||
|
appWindow.raise();
|
||||||
|
appWindow.show();
|
||||||
|
|
||||||
|
// @TODO: remove after paymentID deprecation
|
||||||
|
if(params.hasOwnProperty("tx_payment_id"))
|
||||||
|
persistentSettings.showPid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onWalletConnectionStatusChanged(status){
|
function onWalletConnectionStatusChanged(status){
|
||||||
console.log("Wallet connection status changed " + status)
|
console.log("Wallet connection status changed " + status)
|
||||||
middlePanel.updateStatus();
|
middlePanel.updateStatus();
|
||||||
|
@ -489,6 +532,12 @@ ApplicationWindow {
|
||||||
|
|
||||||
// Force switch normal view
|
// Force switch normal view
|
||||||
rootItem.state = "normal";
|
rootItem.state = "normal";
|
||||||
|
|
||||||
|
// Process queued IPC command
|
||||||
|
if(typeof IPC !== "undefined" && IPC.queuedCmd().length > 0){
|
||||||
|
var queuedCmd = IPC.queuedCmd();
|
||||||
|
if(/^\w+:\/\/(.*)$/.test(queuedCmd)) appWindow.onUriHandler(queuedCmd); // uri
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWalletClosed(walletAddress) {
|
function onWalletClosed(walletAddress) {
|
||||||
|
@ -1086,6 +1135,7 @@ ApplicationWindow {
|
||||||
walletManager.deviceButtonPressed.connect(onDeviceButtonPressed);
|
walletManager.deviceButtonPressed.connect(onDeviceButtonPressed);
|
||||||
walletManager.checkUpdatesComplete.connect(onWalletCheckUpdatesComplete);
|
walletManager.checkUpdatesComplete.connect(onWalletCheckUpdatesComplete);
|
||||||
walletManager.walletPassphraseNeeded.connect(onWalletPassphraseNeeded);
|
walletManager.walletPassphraseNeeded.connect(onWalletPassphraseNeeded);
|
||||||
|
IPC.uriHandler.connect(onUriHandler);
|
||||||
|
|
||||||
if(typeof daemonManager != "undefined") {
|
if(typeof daemonManager != "undefined") {
|
||||||
daemonManager.daemonStarted.connect(onDaemonStarted);
|
daemonManager.daemonStarted.connect(onDaemonStarted);
|
||||||
|
|
|
@ -61,7 +61,10 @@ HEADERS += \
|
||||||
src/zxcvbn-c/zxcvbn.h \
|
src/zxcvbn-c/zxcvbn.h \
|
||||||
src/libwalletqt/UnsignedTransaction.h \
|
src/libwalletqt/UnsignedTransaction.h \
|
||||||
Logger.h \
|
Logger.h \
|
||||||
MainApp.h
|
MainApp.h \
|
||||||
|
src/qt/ipc.h \
|
||||||
|
src/qt/mime.h \
|
||||||
|
src/qt/utils.h
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
filter.cpp \
|
filter.cpp \
|
||||||
|
@ -89,7 +92,10 @@ SOURCES += main.cpp \
|
||||||
src/zxcvbn-c/zxcvbn.c \
|
src/zxcvbn-c/zxcvbn.c \
|
||||||
src/libwalletqt/UnsignedTransaction.cpp \
|
src/libwalletqt/UnsignedTransaction.cpp \
|
||||||
Logger.cpp \
|
Logger.cpp \
|
||||||
MainApp.cpp
|
MainApp.cpp \
|
||||||
|
src/qt/ipc.cpp \
|
||||||
|
src/qt/mime.cpp \
|
||||||
|
src/qt/utils.cpp
|
||||||
|
|
||||||
CONFIG(DISABLE_PASS_STRENGTH_METER) {
|
CONFIG(DISABLE_PASS_STRENGTH_METER) {
|
||||||
HEADERS -= src/zxcvbn-c/zxcvbn.h
|
HEADERS -= src/zxcvbn-c/zxcvbn.h
|
||||||
|
|
|
@ -708,10 +708,20 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Popuplate fields from addressbook.
|
// Popuplate fields from addressbook.
|
||||||
function sendTo(address, paymentId, description){
|
function sendTo(address, paymentId, description, amount){
|
||||||
addressLine.text = address
|
middlePanel.state = 'Transfer';
|
||||||
setPaymentId(paymentId);
|
|
||||||
setDescription(description);
|
if(typeof address !== 'undefined')
|
||||||
|
addressLine.text = address
|
||||||
|
|
||||||
|
if(typeof paymentId !== 'undefined')
|
||||||
|
setPaymentId(paymentId);
|
||||||
|
|
||||||
|
if(typeof description !== 'undefined')
|
||||||
|
setDescription(description);
|
||||||
|
|
||||||
|
if(typeof amount !== 'undefined')
|
||||||
|
amountLine.text = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSendButton(){
|
function updateSendButton(){
|
||||||
|
|
|
@ -31,5 +31,25 @@
|
||||||
|
|
||||||
<key>NSRequiresAquaSystemAppearance</key>
|
<key>NSRequiresAquaSystemAppearance</key>
|
||||||
<string>True</string>
|
<string>True</string>
|
||||||
|
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<string>monero Handler</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>monero</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<string>moneroseed Handler</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>moneroseed</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
106
src/qt/ipc.cpp
Normal file
106
src/qt/ipc.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <QtNetwork>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// Start listening for incoming IPC commands on UDS (Unix) or named pipe (Windows)
|
||||||
|
void IPC::bind(){
|
||||||
|
QString path = QString(this->m_socketFile.absoluteFilePath());
|
||||||
|
qDebug() << path;
|
||||||
|
|
||||||
|
this->m_server = new QLocalServer(this);
|
||||||
|
this->m_server->setSocketOptions(QLocalServer::UserAccessOption);
|
||||||
|
|
||||||
|
bool restarted = false;
|
||||||
|
if(!this->m_server->listen(path)){
|
||||||
|
// On Unix if the server crashes without closing listen will fail with AddressInUseError.
|
||||||
|
// To create a new server the file should be removed. On Windows two local servers can listen
|
||||||
|
// to the same pipe at the same time, but any connections will go to one of the server.
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
qDebug() << QString("Unable to start IPC server in \"%1\": \"%2\". Retrying.").arg(path).arg(this->m_server->errorString());
|
||||||
|
if(this->m_socketFile.exists()){
|
||||||
|
QFile file(path);
|
||||||
|
file.remove();
|
||||||
|
|
||||||
|
if(this->m_server->listen(path)){
|
||||||
|
restarted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(!restarted)
|
||||||
|
qDebug() << QString("Unable to start IPC server in \"%1\": \"%2\".").arg(path).arg(this->m_server->errorString());
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(this->m_server, &QLocalServer::newConnection, this, &IPC::handleConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process incoming IPC command. First check if monero-wallet-gui is
|
||||||
|
// already running. If it is, send it to that instance instead, if not,
|
||||||
|
// queue the command for later use inside our QML engine. Returns true
|
||||||
|
// when queued, false if sent to another instance, at which point we can
|
||||||
|
// kill the current process.
|
||||||
|
bool IPC::saveCommand(QString cmdString){
|
||||||
|
qDebug() << QString("saveCommand called: %1").arg(cmdString);
|
||||||
|
|
||||||
|
QLocalSocket ls;
|
||||||
|
QByteArray buffer;
|
||||||
|
buffer = buffer.append(cmdString);
|
||||||
|
QString socketFilePath = this->socketFile().filePath();
|
||||||
|
|
||||||
|
ls.connectToServer(socketFilePath, QIODevice::WriteOnly);
|
||||||
|
if(ls.waitForConnected(1000)){
|
||||||
|
ls.write(buffer);
|
||||||
|
if (!ls.waitForBytesWritten(1000)){
|
||||||
|
qDebug() << QString("Could not send command \"%1\" over IPC %2: \"%3\"").arg(cmdString, socketFilePath, ls.errorString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << QString("Sent command \"%1\" over IPC \"%2\"").arg(cmdString, socketFilePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ls.isOpen())
|
||||||
|
ls.disconnectFromServer();
|
||||||
|
|
||||||
|
// Queue for later
|
||||||
|
this->SetQueuedCmd(cmdString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPC::saveCommand(const QUrl &url){;
|
||||||
|
this->saveCommand(url.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPC::handleConnection(){
|
||||||
|
QLocalSocket *clientConnection = this->m_server->nextPendingConnection();
|
||||||
|
connect(clientConnection, &QLocalSocket::disconnected,
|
||||||
|
clientConnection, &QLocalSocket::deleteLater);
|
||||||
|
|
||||||
|
clientConnection->waitForReadyRead(2);
|
||||||
|
QByteArray cmdArray = clientConnection->readAll();
|
||||||
|
QString cmdString = QTextCodec::codecForMib(106)->toUnicode(cmdArray); // UTF-8
|
||||||
|
qDebug() << cmdString;
|
||||||
|
|
||||||
|
this->parseCommand(cmdString);
|
||||||
|
|
||||||
|
clientConnection->close();
|
||||||
|
delete clientConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPC::parseCommand(const QUrl &url){
|
||||||
|
this->parseCommand(url.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPC::parseCommand(QString cmdString){
|
||||||
|
if(cmdString.contains(reURI)){
|
||||||
|
this->emitUriHandler(cmdString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IPC::emitUriHandler(QString uriString){
|
||||||
|
emit uriHandler(uriString);
|
||||||
|
}
|
35
src/qt/ipc.h
Normal file
35
src/qt/ipc.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef IPC_H
|
||||||
|
#define IPC_H
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <qt/utils.h>
|
||||||
|
|
||||||
|
class IPC : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
IPC(QObject *parent = 0) : QObject(parent) {}
|
||||||
|
QFileInfo socketFile() const { return m_socketFile; }
|
||||||
|
Q_INVOKABLE QString queuedCmd() { return m_queuedCmd; }
|
||||||
|
void SetQueuedCmd(const QString cmdString) { m_queuedCmd = cmdString; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void bind();
|
||||||
|
void handleConnection();
|
||||||
|
bool saveCommand(QString cmdString);
|
||||||
|
bool saveCommand(const QUrl &url);
|
||||||
|
void parseCommand(QString cmdString);
|
||||||
|
void parseCommand(const QUrl &url);
|
||||||
|
void emitUriHandler(QString uriString);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void uriHandler(QString uriString);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLocalServer *m_server;
|
||||||
|
QString m_queuedCmd;
|
||||||
|
QFileInfo m_socketFile = QFileInfo(QString(QDir::tempPath() + "/xmr-gui_%2.sock").arg(getAccountName()));
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IPC_H
|
42
src/qt/mime.cpp
Normal file
42
src/qt/mime.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
#include "mime.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
void registerXdgMime(QApplication &app){
|
||||||
|
// MacOS handled via Info.plist
|
||||||
|
// Windows handled in the installer by rbrunner7
|
||||||
|
|
||||||
|
QString xdg = QString(
|
||||||
|
"[Desktop Entry]\n"
|
||||||
|
"Name=Monero GUI\n"
|
||||||
|
"GenericName=Monero-GUI\n"
|
||||||
|
"X-GNOME-FullName=Monero-GUI\n"
|
||||||
|
"Comment=Monero GUI\n"
|
||||||
|
"Keywords=Monero;\n"
|
||||||
|
"Exec=%1 %u\n"
|
||||||
|
"Terminal=false\n"
|
||||||
|
"Type=Application\n"
|
||||||
|
"Icon=monero\n"
|
||||||
|
"Categories=Network;GNOME;Qt;\n"
|
||||||
|
"MimeType=x-scheme-handler/monero;x-scheme-handler/moneroseed\n"
|
||||||
|
"StartupNotify=true\n"
|
||||||
|
"X-GNOME-Bugzilla-Bugzilla=GNOME\n"
|
||||||
|
"X-GNOME-UsesNotifications=true\n"
|
||||||
|
).arg(app.applicationFilePath());
|
||||||
|
|
||||||
|
QString appPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
|
||||||
|
QString filePath = QString("%1/monero-gui.desktop").arg(appPath);
|
||||||
|
|
||||||
|
qDebug() << QString("Writing %1").arg(filePath);
|
||||||
|
QFile file(filePath);
|
||||||
|
if(file.open(QIODevice::WriteOnly)){
|
||||||
|
QTextStream out(&file); out << xdg << endl;
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
file.close();
|
||||||
|
}
|
8
src/qt/mime.h
Normal file
8
src/qt/mime.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef MIME_H
|
||||||
|
#define MIME_H
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
void registerXdgMime(QApplication &app);
|
||||||
|
|
||||||
|
#endif // MIME_H
|
20
src/qt/utils.cpp
Normal file
20
src/qt/utils.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
bool fileExists(QString path) {
|
||||||
|
QFileInfo check_file(path);
|
||||||
|
if (check_file.exists() && check_file.isFile())
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getAccountName(){
|
||||||
|
QString accountName = qgetenv("USER"); // mac/linux
|
||||||
|
if (accountName.isEmpty())
|
||||||
|
accountName = qgetenv("USERNAME"); // Windows
|
||||||
|
if (accountName.isEmpty())
|
||||||
|
accountName = "My monero Account";
|
||||||
|
return accountName;
|
||||||
|
}
|
11
src/qt/utils.h
Normal file
11
src/qt/utils.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
|
bool fileExists(QString path);
|
||||||
|
QString getAccountName();
|
||||||
|
const static QRegExp reURI = QRegExp("^\\w+:\\/\\/([\\w+\\-?\\-_\\-=\\-&]+)");
|
||||||
|
|
||||||
|
#endif // UTILS_H
|
Loading…
Reference in a new issue