diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 5db418df..71fa77cf 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -37,7 +37,7 @@ Files: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png, src/qt/res/icons/history.png, src/qt/res/icons/key.png, src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png, src/qt/res/icons/receive.png, src/qt/res/icons/send.png, - src/qt/res/icons/synced.png + src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png Copyright: David Vignoni (david@icon-king.com) ICON KING - www.icon-king.com License: LGPL diff --git a/doc/assets-attribution.txt b/doc/assets-attribution.txt index 5cf0a734..fabcdeea 100644 --- a/doc/assets-attribution.txt +++ b/doc/assets-attribution.txt @@ -7,7 +7,7 @@ Icon: src/qt/res/icons/address-book.png, src/qt/res/icons/export.png, src/qt/res/icons/history.png, src/qt/res/icons/key.png, src/qt/res/icons/lock_*.png, src/qt/res/icons/overview.png, src/qt/res/icons/receive.png, src/qt/res/icons/send.png, - src/qt/res/icons/synced.png + src/qt/res/icons/synced.png, src/qt/res/icons/filesave.png Icon Pack: NUVOLA ICON THEME for KDE 3.x Designer: David Vignoni (david@icon-king.com) ICON KING - www.icon-king.com diff --git a/src/db.cpp b/src/db.cpp index 3bdda615..9a904ec2 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -6,6 +6,7 @@ #include "headers.h" #include "db.h" #include "net.h" +#include #include #include @@ -1064,14 +1065,19 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) filesystem::path pathDest(strDest); if (filesystem::is_directory(pathDest)) pathDest = pathDest / wallet.strWalletFile; + + try { #if BOOST_VERSION >= 104000 - filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); + filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists); #else - filesystem::copy_file(pathSrc, pathDest); + filesystem::copy_file(pathSrc, pathDest); #endif - printf("copied wallet.dat to %s\n", pathDest.string().c_str()); - - return true; + printf("copied wallet.dat to %s\n", pathDest.string().c_str()); + return true; + } catch(const filesystem::filesystem_error &e) { + printf("error copying wallet.dat to %s - %s\n", pathDest.string().c_str(), e.what()); + return false; + } } } Sleep(100); diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 5693ae18..d823752c 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -37,6 +37,7 @@ res/icons/lock_closed.png res/icons/lock_open.png res/icons/key.png + res/icons/filesave.png res/images/about.png diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index b72f1282..f3b1d0e4 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -46,6 +46,8 @@ #include #include #include +#include +#include #include #include @@ -243,6 +245,8 @@ void BitcoinGUI::createActions() encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet"), this); encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet")); encryptWalletAction->setCheckable(true); + backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet"), this); + backupWalletAction->setToolTip(tr("Backup wallet to another location")); changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this); changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption")); @@ -252,6 +256,7 @@ void BitcoinGUI::createActions() connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal())); connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool))); + connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet())); connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase())); } @@ -277,6 +282,7 @@ void BitcoinGUI::createMenuBar() QMenu *settings = appMenuBar->addMenu(tr("&Settings")); settings->addAction(encryptWalletAction); settings->addAction(changePassphraseAction); + settings->addAction(backupWalletAction); settings->addSeparator(); settings->addAction(optionsAction); @@ -778,6 +784,17 @@ void BitcoinGUI::encryptWallet(bool status) setEncryptionStatus(walletModel->getEncryptionStatus()); } +void BitcoinGUI::backupWallet() +{ + QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); + QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)")); + if(!filename.isEmpty()) { + if(!walletModel->backupWallet(filename)) { + QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location.")); + } + } +} + void BitcoinGUI::changePassphrase() { AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 37ab1257..a5224290 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -86,6 +86,7 @@ private: QAction *openBitcoinAction; QAction *exportAction; QAction *encryptWalletAction; + QAction *backupWalletAction; QAction *changePassphraseAction; QAction *aboutQtAction; @@ -162,6 +163,8 @@ private slots: void incomingTransaction(const QModelIndex & parent, int start, int end); /** Encrypt the wallet */ void encryptWallet(bool status); + /** Backup the wallet */ + void backupWallet(); /** Change encrypted wallet passphrase */ void changePassphrase(); /** Ask for pass phrase to unlock wallet temporarily */ diff --git a/src/qt/res/icons/filesave.png b/src/qt/res/icons/filesave.png new file mode 100644 index 00000000..ae13a151 Binary files /dev/null and b/src/qt/res/icons/filesave.png differ diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index f028f10f..8344a653 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -5,6 +5,7 @@ #include "transactiontablemodel.h" #include "headers.h" +#include "db.h" // for BackupWallet #include #include @@ -239,6 +240,11 @@ bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureStri return retval; } +bool WalletModel::backupWallet(const QString &filename) +{ + return BackupWallet(*wallet, filename.toLocal8Bit().data()); +} + // WalletModel::UnlockContext implementation WalletModel::UnlockContext WalletModel::requestUnlock() { diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 89e8cdd2..4123240e 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -77,6 +77,8 @@ public: // Passphrase only needed when unlocking bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString()); bool changePassphrase(const SecureString &oldPass, const SecureString &newPass); + // Wallet backup + bool backupWallet(const QString &filename); // RAI object for unlocking wallet, returned by requestUnlock() class UnlockContext