X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fqt%2Fbitcoingui.cpp;h=70a33133099e0496fb1c1fd18cf79b21d2695a58;hb=fa2544e79faf75923766624acd638e3cbdb9be0d;hp=c9a892fd1de51135fb12f24b3317cbb21571afa9;hpb=609acbf43d8d66102878e47a826c037edc270e46;p=novacoin.git diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index c9a892f..70a3313 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1,12 +1,14 @@ /* * Qt4 bitcoin GUI. * - * W.J. van der Laan 2011 + * W.J. van der Laan 20011-2012 + * The Bitcoin Developers 20011-2012 */ #include "bitcoingui.h" #include "transactiontablemodel.h" #include "addressbookpage.h" #include "sendcoinsdialog.h" +#include "messagepage.h" #include "optionsdialog.h" #include "aboutdialog.h" #include "clientmodel.h" @@ -22,6 +24,10 @@ #include "askpassphrasedialog.h" #include "notificator.h" +#ifdef Q_WS_MAC +#include "macdockiconhandler.h" +#endif + #include #include #include @@ -40,6 +46,9 @@ #include #include #include +#include +#include +#include #include #include @@ -52,45 +61,32 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): walletModel(0), encryptWalletAction(0), changePassphraseAction(0), + aboutQtAction(0), trayIcon(0), notificator(0) { resize(850, 550); setWindowTitle(tr("Bitcoin Wallet")); +#ifndef Q_WS_MAC setWindowIcon(QIcon(":icons/bitcoin")); +#else + setUnifiedTitleAndToolBarOnMac(true); + QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); +#endif // Accept D&D of URIs setAcceptDrops(true); + // Create actions for the toolbar, menu bar and tray/dock icon createActions(); - // Menus - QMenu *file = menuBar()->addMenu(tr("&File")); - file->addAction(sendCoinsAction); - file->addAction(receiveCoinsAction); - file->addSeparator(); - file->addAction(quitAction); - - QMenu *settings = menuBar()->addMenu(tr("&Settings")); - settings->addAction(encryptWalletAction); - settings->addAction(changePassphraseAction); - settings->addSeparator(); - settings->addAction(optionsAction); + // Create application menu bar + createMenuBar(); - QMenu *help = menuBar()->addMenu(tr("&Help")); - help->addAction(aboutAction); - - // Toolbars - QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); - toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - toolbar->addAction(overviewAction); - toolbar->addAction(sendCoinsAction); - toolbar->addAction(receiveCoinsAction); - toolbar->addAction(historyAction); - toolbar->addAction(addressBookAction); + // Create the toolbars + createToolBars(); - QToolBar *toolbar2 = addToolBar(tr("Actions toolbar")); - toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - toolbar2->addAction(exportAction); + // Create the tray icon (or setup the dock icon) + createTrayIcon(); // Create tabs overviewPage = new OverviewPage(); @@ -107,12 +103,17 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): sendCoinsPage = new SendCoinsDialog(this); + messagePage = new MessagePage(this); + centralWidget = new QStackedWidget(this); centralWidget->addWidget(overviewPage); centralWidget->addWidget(transactionsPage); centralWidget->addWidget(addressBookPage); centralWidget->addWidget(receiveCoinsPage); centralWidget->addWidget(sendCoinsPage); +#ifdef FIRST_CLASS_MESSAGING + centralWidget->addWidget(messagePage); +#endif setCentralWidget(centralWidget); // Create status bar @@ -120,7 +121,6 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): // Status bar notification icons QFrame *frameBlocks = new QFrame(); - //frameBlocks->setFrameStyle(QFrame::Panel | QFrame::Sunken); frameBlocks->setContentsMargins(0,0,0,0); frameBlocks->setMinimumWidth(56); frameBlocks->setMaximumWidth(56); @@ -138,18 +138,19 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): frameBlocksLayout->addWidget(labelBlocksIcon); frameBlocksLayout->addStretch(); - // Progress bar for blocks download - progressBarLabel = new QLabel(tr("Synchronizing with network...")); + // Progress bar and label for blocks download + progressBarLabel = new QLabel(); progressBarLabel->setVisible(false); progressBar = new QProgressBar(); - progressBar->setToolTip(tr("Block chain synchronization in progress")); progressBar->setVisible(false); statusBar()->addWidget(progressBarLabel); statusBar()->addWidget(progressBar); statusBar()->addPermanentWidget(frameBlocks); - createTrayIcon(); + // define OS independent progress bar style (has to be placed after addWidget(), otherwise we crash) + // we did this, because with some OSes default style, text on the progress bar is unreadable + progressBar->setStyleSheet("QProgressBar { background-color: transparent; border: 1px solid grey; border-radius: 2px; padding: 1px; text-align: center; } QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); margin: 0px; }"); syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this); @@ -162,6 +163,15 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): gotoOverviewPage(); } +BitcoinGUI::~BitcoinGUI() +{ + if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu) + trayIcon->hide(); +#ifdef Q_WS_MAC + delete appMenuBar; +#endif +} + void BitcoinGUI::createActions() { QActionGroup *tabGroup = new QActionGroup(this); @@ -169,130 +179,238 @@ void BitcoinGUI::createActions() overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this); overviewAction->setToolTip(tr("Show general overview of wallet")); overviewAction->setCheckable(true); + overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1)); tabGroup->addAction(overviewAction); historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setToolTip(tr("Browse transaction history")); historyAction->setCheckable(true); + historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4)); tabGroup->addAction(historyAction); addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Address Book"), this); addressBookAction->setToolTip(tr("Edit the list of stored addresses and labels")); addressBookAction->setCheckable(true); + addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5)); tabGroup->addAction(addressBookAction); receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this); receiveCoinsAction->setToolTip(tr("Show the list of addresses for receiving payments")); receiveCoinsAction->setCheckable(true); + receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); tabGroup->addAction(receiveCoinsAction); sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this); sendCoinsAction->setToolTip(tr("Send coins to a bitcoin address")); sendCoinsAction->setCheckable(true); + sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); tabGroup->addAction(sendCoinsAction); + messageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message"), this); + messageAction->setToolTip(tr("Prove you control an address")); +#ifdef FIRST_CLASS_MESSAGING + messageAction->setCheckable(true); +#endif + tabGroup->addAction(messageAction); + + connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); + connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); + connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); + connect(messageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(messageAction, SIGNAL(triggered()), this, SLOT(gotoMessagePage())); - quitAction = new QAction(QIcon(":/icons/quit"), tr("&Exit"), this); + quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setToolTip(tr("Quit application")); - aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About"), this); + quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); + quitAction->setMenuRole(QAction::QuitRole); + aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About %1").arg(qApp->applicationName()), this); aboutAction->setToolTip(tr("Show information about Bitcoin")); + aboutAction->setMenuRole(QAction::AboutRole); + aboutQtAction = new QAction(tr("About &Qt"), this); + aboutQtAction->setToolTip(tr("Show information about Qt")); + aboutQtAction->setMenuRole(QAction::AboutQtRole); optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setToolTip(tr("Modify configuration options for bitcoin")); + optionsAction->setMenuRole(QAction::PreferencesRole); openBitcoinAction = new QAction(QIcon(":/icons/bitcoin"), tr("Open &Bitcoin"), this); openBitcoinAction->setToolTip(tr("Show the Bitcoin window")); exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this); - exportAction->setToolTip(tr("Export the current view to a file")); + exportAction->setToolTip(tr("Export the data in the current tab to a file")); 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")); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); - connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal())); + connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool))); + connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet())); connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase())); } +void BitcoinGUI::createMenuBar() +{ +#ifdef Q_WS_MAC + // Create a decoupled menu bar on Mac which stays even if the window is closed + appMenuBar = new QMenuBar(); +#else + // Get the main window's menu bar on other platforms + appMenuBar = menuBar(); +#endif + + // Configure the menus + QMenu *file = appMenuBar->addMenu(tr("&File")); + file->addAction(backupWalletAction); + file->addAction(exportAction); +#ifndef FIRST_CLASS_MESSAGING + file->addAction(messageAction); +#endif + file->addSeparator(); + file->addAction(quitAction); + + QMenu *settings = appMenuBar->addMenu(tr("&Settings")); + settings->addAction(encryptWalletAction); + settings->addAction(changePassphraseAction); + settings->addSeparator(); + settings->addAction(optionsAction); + + QMenu *help = appMenuBar->addMenu(tr("&Help")); + help->addAction(aboutAction); + help->addAction(aboutQtAction); +} + +void BitcoinGUI::createToolBars() +{ + QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); + toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar->addAction(overviewAction); + toolbar->addAction(sendCoinsAction); + toolbar->addAction(receiveCoinsAction); + toolbar->addAction(historyAction); + toolbar->addAction(addressBookAction); +#ifdef FIRST_CLASS_MESSAGING + toolbar->addAction(messageAction); +#endif + + QToolBar *toolbar2 = addToolBar(tr("Actions toolbar")); + toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar2->addAction(exportAction); +} + void BitcoinGUI::setClientModel(ClientModel *clientModel) { this->clientModel = clientModel; - - if(clientModel->isTestNet()) + if(clientModel) { - QString title_testnet = windowTitle() + QString(" ") + tr("[testnet]"); - setWindowTitle(title_testnet); - setWindowIcon(QIcon(":icons/bitcoin_testnet")); - if(trayIcon) + if(clientModel->isTestNet()) { - trayIcon->setToolTip(title_testnet); - trayIcon->setIcon(QIcon(":/icons/toolbar_testnet")); + QString title_testnet = windowTitle() + QString(" ") + tr("[testnet]"); + setWindowTitle(title_testnet); +#ifndef Q_WS_MAC + setWindowIcon(QIcon(":icons/bitcoin_testnet")); +#else + MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet")); +#endif + if(trayIcon) + { + trayIcon->setToolTip(title_testnet); + trayIcon->setIcon(QIcon(":/icons/toolbar_testnet")); + } } - } - // Keep up to date with client - setNumConnections(clientModel->getNumConnections()); - connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + // Keep up to date with client + setNumConnections(clientModel->getNumConnections()); + connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); - setNumBlocks(clientModel->getNumBlocks()); - connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int))); + setNumBlocks(clientModel->getNumBlocks()); + connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int))); - // Report errors from network/worker thread - connect(clientModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString))); + // Report errors from network/worker thread + connect(clientModel, SIGNAL(error(QString,QString, bool)), this, SLOT(error(QString,QString,bool))); + } } void BitcoinGUI::setWalletModel(WalletModel *walletModel) { this->walletModel = walletModel; + if(walletModel) + { + // Report errors from wallet thread + connect(walletModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool))); - // Report errors from wallet thread - connect(walletModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString))); + // Put transaction list in tabs + transactionView->setModel(walletModel); - // Put transaction list in tabs - transactionView->setModel(walletModel); + overviewPage->setModel(walletModel); + addressBookPage->setModel(walletModel->getAddressTableModel()); + receiveCoinsPage->setModel(walletModel->getAddressTableModel()); + sendCoinsPage->setModel(walletModel); + messagePage->setModel(walletModel); - overviewPage->setModel(walletModel); - addressBookPage->setModel(walletModel->getAddressTableModel()); - receiveCoinsPage->setModel(walletModel->getAddressTableModel()); - sendCoinsPage->setModel(walletModel); + setEncryptionStatus(walletModel->getEncryptionStatus()); + connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int))); - setEncryptionStatus(walletModel->getEncryptionStatus()); - connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int))); + // Balloon popup for new transaction + connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(incomingTransaction(QModelIndex,int,int))); - // Balloon popup for new transaction - connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(incomingTransaction(QModelIndex,int,int))); - - // Ask for passphrase if needed - connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); + // Ask for passphrase if needed + connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); + } } void BitcoinGUI::createTrayIcon() { - QMenu *trayIconMenu = new QMenu(this); - trayIconMenu->addAction(openBitcoinAction); - trayIconMenu->addAction(optionsAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(quitAction); - + QMenu *trayIconMenu; +#ifndef Q_WS_MAC trayIcon = new QSystemTrayIcon(this); + trayIconMenu = new QMenu(this); trayIcon->setContextMenu(trayIconMenu); - trayIcon->setToolTip("Bitcoin client"); + trayIcon->setToolTip(tr("Bitcoin client")); trayIcon->setIcon(QIcon(":/icons/toolbar")); connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); trayIcon->show(); +#else + // Note: On Mac, the dock icon is used to provide the tray's functionality. + MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); + connect(dockIconHandler, SIGNAL(dockIconClicked()), openBitcoinAction, SLOT(trigger())); + trayIconMenu = dockIconHandler->dockMenu(); +#endif + + // Configuration of the tray icon (or dock icon) icon menu + trayIconMenu->addAction(openBitcoinAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(messageAction); +#ifndef FIRST_CLASS_MESSAGING + trayIconMenu->addSeparator(); +#endif + trayIconMenu->addAction(receiveCoinsAction); + trayIconMenu->addAction(sendCoinsAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(optionsAction); +#ifndef Q_WS_MAC // This is built-in on Mac + trayIconMenu->addSeparator(); + trayIconMenu->addAction(quitAction); +#endif notificator = new Notificator(tr("bitcoin-qt"), trayIcon); } +#ifndef Q_WS_MAC void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) { if(reason == QSystemTrayIcon::Trigger) @@ -300,11 +418,13 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) // Click on system tray icon triggers "open bitcoin" openBitcoinAction->trigger(); } - } +#endif void BitcoinGUI::optionsClicked() { + if(!clientModel || !clientModel->getOptionsModel()) + return; OptionsDialog dlg; dlg.setModel(clientModel->getOptionsModel()); dlg.exec(); @@ -334,21 +454,49 @@ void BitcoinGUI::setNumConnections(int count) void BitcoinGUI::setNumBlocks(int count) { - int initTotal = clientModel->getNumBlocksAtStartup(); - int total = clientModel->getNumBlocksOfPeers(); + // don't show / hide progressBar and it's label if we have no connection(s) to the network + if (!clientModel || clientModel->getNumConnections() == 0) + { + progressBarLabel->setVisible(false); + progressBar->setVisible(false); + + return; + } + + int nTotalBlocks = clientModel->getNumBlocksOfPeers(); QString tooltip; - if(count < total) + if(count < nTotalBlocks) { - progressBarLabel->setVisible(true); - progressBar->setVisible(true); - progressBar->setMaximum(total - initTotal); - progressBar->setValue(count - initTotal); - tooltip = tr("Downloaded %1 of %2 blocks of transaction history.").arg(count).arg(total); + int nRemainingBlocks = nTotalBlocks - count; + float nPercentageDone = count / (nTotalBlocks * 0.01f); + + if (clientModel->getStatusBarWarnings() == "") + { + progressBarLabel->setText(tr("Synchronizing with network...")); + progressBarLabel->setVisible(true); + progressBar->setFormat(tr("~%n block(s) remaining", "", nRemainingBlocks)); + progressBar->setMaximum(nTotalBlocks); + progressBar->setValue(count); + progressBar->setVisible(true); + } + else + { + progressBarLabel->setText(clientModel->getStatusBarWarnings()); + progressBarLabel->setVisible(true); + progressBar->setVisible(false); + } + tooltip = tr("Downloaded %1 of %2 blocks of transaction history (%3% done).").arg(count).arg(nTotalBlocks).arg(nPercentageDone, 0, 'f', 2); } else { - progressBarLabel->setVisible(false); + if (clientModel->getStatusBarWarnings() == "") + progressBarLabel->setVisible(false); + else + { + progressBarLabel->setText(clientModel->getStatusBarWarnings()); + progressBarLabel->setVisible(true); + } progressBar->setVisible(false); tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count); } @@ -359,7 +507,11 @@ void BitcoinGUI::setNumBlocks(int count) QString text; // Represent time from last generated block in human readable text - if(secs < 60) + if(secs <= 0) + { + // Fully up to date. Leave text empty. + } + else if(secs < 60) { text = tr("%n second(s) ago","",secs); } @@ -377,9 +529,9 @@ void BitcoinGUI::setNumBlocks(int count) } // Set icon state: spinning if catching up, tick otherwise - if(secs < 30*60) + if(secs < 90*60) { - tooltip = tr("Up to date") + QString("\n") + tooltip; + tooltip = tr("Up to date") + QString(".\n") + tooltip; labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); } else @@ -389,47 +541,58 @@ void BitcoinGUI::setNumBlocks(int count) syncIconMovie->start(); } - tooltip += QString("\n"); - tooltip += tr("Last received block was generated %1.").arg(text); + if(!text.isEmpty()) + { + tooltip += QString("\n"); + tooltip += tr("Last received block was generated %1.").arg(text); + } labelBlocksIcon->setToolTip(tooltip); progressBarLabel->setToolTip(tooltip); progressBar->setToolTip(tooltip); } -void BitcoinGUI::error(const QString &title, const QString &message) +void BitcoinGUI::error(const QString &title, const QString &message, bool modal) { // Report errors from network/worker thread - notificator->notify(Notificator::Critical, title, message); + if(modal) + { + QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok); + } else { + notificator->notify(Notificator::Critical, title, message); + } } void BitcoinGUI::changeEvent(QEvent *e) { - if (e->type() == QEvent::WindowStateChange) + QMainWindow::changeEvent(e); +#ifndef Q_WS_MAC // Ignored on Mac + if(e->type() == QEvent::WindowStateChange) { - if(clientModel->getOptionsModel()->getMinimizeToTray()) + if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray()) { - if (isMinimized()) + QWindowStateChangeEvent *wsevt = static_cast(e); + if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized()) { - hide(); + QTimer::singleShot(0, this, SLOT(hide())); e->ignore(); } - else - { - show(); - e->accept(); - } } } - QMainWindow::changeEvent(e); +#endif } void BitcoinGUI::closeEvent(QCloseEvent *event) { - if(!clientModel->getOptionsModel()->getMinimizeToTray() && - !clientModel->getOptionsModel()->getMinimizeOnClose()) + if(clientModel) { - qApp->quit(); +#ifndef Q_WS_MAC // Ignored on Mac + if(!clientModel->getOptionsModel()->getMinimizeToTray() && + !clientModel->getOptionsModel()->getMinimizeOnClose()) + { + qApp->quit(); + } +#endif } QMainWindow::closeEvent(event); } @@ -449,6 +612,8 @@ void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee) void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end) { + if(!walletModel || !clientModel) + return; TransactionTableModel *ttm = walletModel->getTransactionTableModel(); qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent) .data(Qt::EditRole).toULongLong(); @@ -522,22 +687,35 @@ void BitcoinGUI::gotoReceiveCoinsPage() void BitcoinGUI::gotoSendCoinsPage() { sendCoinsAction->setChecked(true); - if(centralWidget->currentWidget() != sendCoinsPage) - { - // Clear the current contents if we arrived from another tab - // Not necessary especially if the user is jumping between Transactions - // and Send Coins pages. - Matoking - //sendCoinsPage->clear(); - } centralWidget->setCurrentWidget(sendCoinsPage); exportAction->setEnabled(false); disconnect(exportAction, SIGNAL(triggered()), 0, 0); } +void BitcoinGUI::gotoMessagePage() +{ +#ifdef FIRST_CLASS_MESSAGING + messageAction->setChecked(true); + centralWidget->setCurrentWidget(messagePage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +#else + messagePage->show(); + messagePage->setFocus(); +#endif +} + +void BitcoinGUI::gotoMessagePage(QString addr) +{ + gotoMessagePage(); + messagePage->setAddress(addr); +} + void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event) { - // Accept only URLs + // Accept only URIs if(event->mimeData()->hasUrls()) event->acceptProposedAction(); } @@ -547,16 +725,27 @@ void BitcoinGUI::dropEvent(QDropEvent *event) if(event->mimeData()->hasUrls()) { gotoSendCoinsPage(); - QList urls = event->mimeData()->urls(); - foreach(const QUrl &url, urls) + QList uris = event->mimeData()->urls(); + foreach(const QUrl &uri, uris) { - sendCoinsPage->handleURL(&url); + sendCoinsPage->handleURI(uri.toString()); } } event->acceptProposedAction(); } +void BitcoinGUI::handleURI(QString strURI) +{ + gotoSendCoinsPage(); + sendCoinsPage->handleURI(strURI); + + if(!isActiveWindow()) + activateWindow(); + + showNormalIfMinimized(); +} + void BitcoinGUI::setEncryptionStatus(int status) { switch(status) @@ -588,6 +777,8 @@ void BitcoinGUI::setEncryptionStatus(int status) void BitcoinGUI::encryptWallet(bool status) { + if(!walletModel) + return; AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt: AskPassphraseDialog::Decrypt, this); dlg.setModel(walletModel); @@ -596,6 +787,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); @@ -605,6 +807,8 @@ void BitcoinGUI::changePassphrase() void BitcoinGUI::unlockWallet() { + if(!walletModel) + return; // Unlock wallet when requested by wallet model if(walletModel->getEncryptionStatus() == WalletModel::Locked) { @@ -613,3 +817,11 @@ void BitcoinGUI::unlockWallet() dlg.exec(); } } + +void BitcoinGUI::showNormalIfMinimized() +{ + if(!isVisible()) // Show, if hidden + show(); + if(isMinimized()) // Unminimize, if minimized + showNormal(); +}