diff --git a/CMakeLists.txt b/CMakeLists.txt index cc0156e..47a5251 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ if(DEBUG) set(CMAKE_VERBOSE_MAKEFILE ON) endif() -set(MONERO_HEAD "fe3c05952281773684e20a964110a9aeb7a4fc74") +set(MONERO_HEAD "f6587d7943a19c55a5b78af1a89b22c130513b73") set(BUILD_GUI_DEPS ON) set(ARCH "x86-64") set(BUILD_64 ON) diff --git a/monero b/monero index fe3c059..f6587d7 160000 --- a/monero +++ b/monero @@ -1 +1 @@ -Subproject commit fe3c05952281773684e20a964110a9aeb7a4fc74 +Subproject commit f6587d7943a19c55a5b78af1a89b22c130513b73 diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 7eb33bd..400fc84 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -457,9 +457,9 @@ quint64 Wallet::daemonBlockChainTargetHeight() const return m_daemonBlockChainTargetHeight; } -bool Wallet::exportKeyImages(const QString& path) +bool Wallet::exportKeyImages(const QString& path, bool all) { - return m_walletImpl->exportKeyImages(path.toStdString()); + return m_walletImpl->exportKeyImages(path.toStdString(), all); } bool Wallet::importKeyImages(const QString& path) @@ -467,6 +467,14 @@ bool Wallet::importKeyImages(const QString& path) return m_walletImpl->importKeyImages(path.toStdString()); } +bool Wallet::exportOutputs(const QString& path, bool all) { + return m_walletImpl->exportOutputs(path.toStdString(), all); +} + +bool Wallet::importOutputs(const QString& path) { + return m_walletImpl->importOutputs(path.toStdString()); +} + bool Wallet::refresh(bool historyAndSubaddresses /* = true */) { refreshingSet(true); diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 83e892b..c26120c 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -192,9 +192,13 @@ public: Q_INVOKABLE void refreshHeightAsync(); //! export/import key images - Q_INVOKABLE bool exportKeyImages(const QString& path); + Q_INVOKABLE bool exportKeyImages(const QString& path, bool all = false); Q_INVOKABLE bool importKeyImages(const QString& path); + //! export/import outputs + Q_INVOKABLE bool exportOutputs(const QString& path, bool all = false); + Q_INVOKABLE bool importOutputs(const QString& path); + //! refreshes the wallet Q_INVOKABLE bool refresh(bool historyAndSubaddresses = true); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e4f8cc5..9524098 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -404,6 +404,10 @@ void MainWindow::initMenu() { connect(ui->actionUpdate_balance, &QAction::triggered, [&]{ m_ctx->updateBalance(); }); + connect(ui->actionExportKeyImages, &QAction::triggered, this, &MainWindow::exportKeyImages); + connect(ui->actionImportKeyImages, &QAction::triggered, this, &MainWindow::importKeyImages); + connect(ui->actionExportOutputs, &QAction::triggered, this, &MainWindow::exportOutputs); + connect(ui->actionImportOutputs, &QAction::triggered, this, &MainWindow::importOutputs); // set restore height connect(ui->actionChange_restore_height, &QAction::triggered, this, &MainWindow::showRestoreHeightDialog); @@ -1068,6 +1072,58 @@ void MainWindow::showWSNodeExhaustedMessage() { QMessageBox::warning(this, "Could not connect to a node", msg); } +void MainWindow::exportKeyImages() { + QString fn = QFileDialog::getSaveFileName(this, "Save key images to file", QDir::homePath(), "Key Images (*_keyImages)"); + if (fn.isEmpty()) return; + if (!fn.endsWith("_keyImages")) fn += "_keyImages"; + m_ctx->currentWallet->exportKeyImages(fn, true); + auto err = m_ctx->currentWallet->errorString(); + if (!err.isEmpty()) { + QMessageBox::warning(this, "Key image export", QString("Failed to export key images.\nReason: %1").arg(err)); + } else { + QMessageBox::information(this, "Key image export", "Successfully exported key images."); + } +} + +void MainWindow::importKeyImages() { + QString fn = QFileDialog::getOpenFileName(this, "Import key image file", QDir::homePath(), "Key Images (*_keyImages)"); + if (fn.isEmpty()) return; + m_ctx->currentWallet->importKeyImages(fn); + auto err = m_ctx->currentWallet->errorString(); + if (!err.isEmpty()) { + QMessageBox::warning(this, "Key image import", QString("Failed to import key images.\n\n%1").arg(err)); + } else { + QMessageBox::information(this, "Key image import", "Successfully imported key images"); + m_ctx->refreshModels(); + } +} + +void MainWindow::exportOutputs() { + QString fn = QFileDialog::getSaveFileName(this, "Save outputs to file", QDir::homePath(), "Outputs (*_outputs)"); + if (fn.isEmpty()) return; + if (!fn.endsWith("_outputs")) fn += "_outputs"; + m_ctx->currentWallet->exportOutputs(fn, true); + auto err = m_ctx->currentWallet->errorString(); + if (!err.isEmpty()) { + QMessageBox::warning(this, "Outputs export", QString("Failed to export outputs.\nReason: %1").arg(err)); + } else { + QMessageBox::information(this, "Outputs export", "Successfully exported outputs."); + } +} + +void MainWindow::importOutputs() { + QString fn = QFileDialog::getOpenFileName(this, "Import outputs file", QDir::homePath(), "Outputs (*_outputs)"); + if (fn.isEmpty()) return; + m_ctx->currentWallet->importOutputs(fn); + auto err = m_ctx->currentWallet->errorString(); + if (!err.isEmpty()) { + QMessageBox::warning(this, "Outputs import", QString("Failed to import outputs.\n\n%1").arg(err)); + } else { + QMessageBox::information(this, "Outputs import", "Successfully imported outputs"); + m_ctx->refreshModels(); + } +} + MainWindow::~MainWindow() { delete ui; } diff --git a/src/mainwindow.h b/src/mainwindow.h index 5633826..772703d 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -100,6 +100,11 @@ public slots: void onAddContact(const QString &address, const QString &name); void showRestoreHeightDialog(); + void exportKeyImages(); + void importKeyImages(); + void exportOutputs(); + void importOutputs(); + // libwalletqt void onBalanceUpdated(double balance, double unlocked, const QString &balance_str, const QString &unlocked_str); void onSynchronized(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 3019609..3a58cb5 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -291,7 +291,7 @@ 0 0 894 - 22 + 30 @@ -324,10 +324,27 @@ Advanced + + + Export + + + + + + + Import + + + + + + + @@ -534,6 +551,46 @@ View-Only + + + Export key images + + + + + Import key images + + + + + Export outputs + + + + + Import outputs + + + + + Key Images + + + + + Outputs + + + + + Key images + + + + + Outputs + + diff --git a/src/model/CoinsModel.cpp b/src/model/CoinsModel.cpp index f81cf52..04b6046 100644 --- a/src/model/CoinsModel.cpp +++ b/src/model/CoinsModel.cpp @@ -168,6 +168,8 @@ QVariant CoinsModel::parseTransactionInfo(const CoinsInfo &cInfo, int column, in { switch (column) { + case KeyImageKnown: + return ""; case PubKey: return cInfo.pubKey().mid(0,8); case OutputPoint: