mirror of
https://github.com/AskDavis/Casinotest.git
synced 2026-01-07 21:29:47 -08:00
Initial commit.
This commit is contained in:
30
src/qt/aboutdialog.cpp
Normal file
30
src/qt/aboutdialog.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "aboutdialog.h"
|
||||
#include "ui_aboutdialog.h"
|
||||
#include "clientmodel.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
AboutDialog::AboutDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AboutDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
void AboutDialog::setModel(ClientModel *model)
|
||||
{
|
||||
if(model)
|
||||
{
|
||||
ui->versionLabel->setText(model->formatFullVersion());
|
||||
}
|
||||
}
|
||||
|
||||
AboutDialog::~AboutDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AboutDialog::on_buttonBox_accepted()
|
||||
{
|
||||
close();
|
||||
}
|
||||
28
src/qt/aboutdialog.h
Normal file
28
src/qt/aboutdialog.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef ABOUTDIALOG_H
|
||||
#define ABOUTDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class AboutDialog;
|
||||
}
|
||||
class ClientModel;
|
||||
|
||||
/** "About" dialog box */
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AboutDialog(QWidget *parent = 0);
|
||||
~AboutDialog();
|
||||
|
||||
void setModel(ClientModel *model);
|
||||
private:
|
||||
Ui::AboutDialog *ui;
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
};
|
||||
|
||||
#endif // ABOUTDIALOG_H
|
||||
374
src/qt/addressbookpage.cpp
Normal file
374
src/qt/addressbookpage.cpp
Normal file
@@ -0,0 +1,374 @@
|
||||
#include "addressbookpage.h"
|
||||
#include "ui_addressbookpage.h"
|
||||
|
||||
#include "addresstablemodel.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "bitcoingui.h"
|
||||
#include "editaddressdialog.h"
|
||||
#include "csvmodelwriter.h"
|
||||
#include "guiutil.h"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QClipboard>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
|
||||
#ifdef USE_QRCODE
|
||||
#include "qrcodedialog.h"
|
||||
#endif
|
||||
|
||||
AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AddressBookPage),
|
||||
model(0),
|
||||
optionsModel(0),
|
||||
mode(mode),
|
||||
tab(tab)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
#ifdef Q_WS_MAC // Icons on push buttons are very uncommon on Mac
|
||||
ui->newAddressButton->setIcon(QIcon());
|
||||
ui->copyToClipboard->setIcon(QIcon());
|
||||
ui->deleteButton->setIcon(QIcon());
|
||||
#endif
|
||||
|
||||
#ifndef USE_QRCODE
|
||||
ui->showQRCode->setVisible(false);
|
||||
#endif
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case ForSending:
|
||||
connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
|
||||
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
ui->tableView->setFocus();
|
||||
break;
|
||||
case ForEditing:
|
||||
ui->buttonBox->setVisible(false);
|
||||
break;
|
||||
}
|
||||
switch(tab)
|
||||
{
|
||||
case SendingTab:
|
||||
ui->labelExplanation->setVisible(false);
|
||||
ui->deleteButton->setVisible(true);
|
||||
ui->signMessage->setVisible(false);
|
||||
break;
|
||||
case ReceivingTab:
|
||||
ui->deleteButton->setVisible(false);
|
||||
ui->signMessage->setVisible(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Context menu actions
|
||||
QAction *copyLabelAction = new QAction(tr("Copy &Label"), this);
|
||||
QAction *copyAddressAction = new QAction(ui->copyToClipboard->text(), this);
|
||||
QAction *editAction = new QAction(tr("&Edit"), this);
|
||||
QAction *showQRCodeAction = new QAction(ui->showQRCode->text(), this);
|
||||
QAction *signMessageAction = new QAction(ui->signMessage->text(), this);
|
||||
QAction *verifyMessageAction = new QAction(ui->verifyMessage->text(), this);
|
||||
deleteAction = new QAction(ui->deleteButton->text(), this);
|
||||
|
||||
// Build context menu
|
||||
contextMenu = new QMenu();
|
||||
contextMenu->addAction(copyAddressAction);
|
||||
contextMenu->addAction(copyLabelAction);
|
||||
contextMenu->addAction(editAction);
|
||||
if(tab == SendingTab)
|
||||
contextMenu->addAction(deleteAction);
|
||||
contextMenu->addSeparator();
|
||||
contextMenu->addAction(showQRCodeAction);
|
||||
if(tab == ReceivingTab)
|
||||
contextMenu->addAction(signMessageAction);
|
||||
else if(tab == SendingTab)
|
||||
contextMenu->addAction(verifyMessageAction);
|
||||
|
||||
// Connect signals for context menu actions
|
||||
connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyToClipboard_clicked()));
|
||||
connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
|
||||
connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
|
||||
connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked()));
|
||||
connect(showQRCodeAction, SIGNAL(triggered()), this, SLOT(on_showQRCode_clicked()));
|
||||
connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked()));
|
||||
connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(on_verifyMessage_clicked()));
|
||||
|
||||
connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
|
||||
|
||||
// Pass through accept action from button box
|
||||
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
}
|
||||
|
||||
AddressBookPage::~AddressBookPage()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AddressBookPage::setModel(AddressTableModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
if(!model)
|
||||
return;
|
||||
|
||||
proxyModel = new QSortFilterProxyModel(this);
|
||||
proxyModel->setSourceModel(model);
|
||||
proxyModel->setDynamicSortFilter(true);
|
||||
proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
switch(tab)
|
||||
{
|
||||
case ReceivingTab:
|
||||
// Receive filter
|
||||
proxyModel->setFilterRole(AddressTableModel::TypeRole);
|
||||
proxyModel->setFilterFixedString(AddressTableModel::Receive);
|
||||
break;
|
||||
case SendingTab:
|
||||
// Send filter
|
||||
proxyModel->setFilterRole(AddressTableModel::TypeRole);
|
||||
proxyModel->setFilterFixedString(AddressTableModel::Send);
|
||||
break;
|
||||
}
|
||||
ui->tableView->setModel(proxyModel);
|
||||
ui->tableView->sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
// Set column widths
|
||||
ui->tableView->horizontalHeader()->resizeSection(
|
||||
AddressTableModel::Address, 320);
|
||||
ui->tableView->horizontalHeader()->setResizeMode(
|
||||
AddressTableModel::Label, QHeaderView::Stretch);
|
||||
|
||||
connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||
this, SLOT(selectionChanged()));
|
||||
|
||||
// Select row for newly created address
|
||||
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
this, SLOT(selectNewAddress(QModelIndex,int,int)));
|
||||
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
void AddressBookPage::setOptionsModel(OptionsModel *optionsModel)
|
||||
{
|
||||
this->optionsModel = optionsModel;
|
||||
}
|
||||
|
||||
void AddressBookPage::on_copyToClipboard_clicked()
|
||||
{
|
||||
GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);
|
||||
}
|
||||
|
||||
void AddressBookPage::onCopyLabelAction()
|
||||
{
|
||||
GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label);
|
||||
}
|
||||
|
||||
void AddressBookPage::onEditAction()
|
||||
{
|
||||
if(!ui->tableView->selectionModel())
|
||||
return;
|
||||
QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();
|
||||
if(indexes.isEmpty())
|
||||
return;
|
||||
|
||||
EditAddressDialog dlg(
|
||||
tab == SendingTab ?
|
||||
EditAddressDialog::EditSendingAddress :
|
||||
EditAddressDialog::EditReceivingAddress);
|
||||
dlg.setModel(model);
|
||||
QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
|
||||
dlg.loadRow(origIndex.row());
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void AddressBookPage::on_signMessage_clicked()
|
||||
{
|
||||
QTableView *table = ui->tableView;
|
||||
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
|
||||
QString addr;
|
||||
|
||||
foreach (QModelIndex index, indexes)
|
||||
{
|
||||
QVariant address = index.data();
|
||||
addr = address.toString();
|
||||
}
|
||||
|
||||
emit signMessage(addr);
|
||||
}
|
||||
|
||||
void AddressBookPage::on_verifyMessage_clicked()
|
||||
{
|
||||
QTableView *table = ui->tableView;
|
||||
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
|
||||
QString addr;
|
||||
|
||||
foreach (QModelIndex index, indexes)
|
||||
{
|
||||
QVariant address = index.data();
|
||||
addr = address.toString();
|
||||
}
|
||||
|
||||
emit verifyMessage(addr);
|
||||
}
|
||||
|
||||
void AddressBookPage::on_newAddressButton_clicked()
|
||||
{
|
||||
if(!model)
|
||||
return;
|
||||
EditAddressDialog dlg(
|
||||
tab == SendingTab ?
|
||||
EditAddressDialog::NewSendingAddress :
|
||||
EditAddressDialog::NewReceivingAddress, this);
|
||||
dlg.setModel(model);
|
||||
if(dlg.exec())
|
||||
{
|
||||
newAddressToSelect = dlg.getAddress();
|
||||
}
|
||||
}
|
||||
|
||||
void AddressBookPage::on_deleteButton_clicked()
|
||||
{
|
||||
QTableView *table = ui->tableView;
|
||||
if(!table->selectionModel())
|
||||
return;
|
||||
QModelIndexList indexes = table->selectionModel()->selectedRows();
|
||||
if(!indexes.isEmpty())
|
||||
{
|
||||
table->model()->removeRow(indexes.at(0).row());
|
||||
}
|
||||
}
|
||||
|
||||
void AddressBookPage::selectionChanged()
|
||||
{
|
||||
// Set button states based on selected tab and selection
|
||||
QTableView *table = ui->tableView;
|
||||
if(!table->selectionModel())
|
||||
return;
|
||||
|
||||
if(table->selectionModel()->hasSelection())
|
||||
{
|
||||
switch(tab)
|
||||
{
|
||||
case SendingTab:
|
||||
// In sending tab, allow deletion of selection
|
||||
ui->deleteButton->setEnabled(true);
|
||||
ui->deleteButton->setVisible(true);
|
||||
deleteAction->setEnabled(true);
|
||||
ui->signMessage->setEnabled(false);
|
||||
ui->signMessage->setVisible(false);
|
||||
ui->verifyMessage->setEnabled(true);
|
||||
ui->verifyMessage->setVisible(true);
|
||||
break;
|
||||
case ReceivingTab:
|
||||
// Deleting receiving addresses, however, is not allowed
|
||||
ui->deleteButton->setEnabled(false);
|
||||
ui->deleteButton->setVisible(false);
|
||||
deleteAction->setEnabled(false);
|
||||
ui->signMessage->setEnabled(true);
|
||||
ui->signMessage->setVisible(true);
|
||||
ui->verifyMessage->setEnabled(false);
|
||||
ui->verifyMessage->setVisible(false);
|
||||
break;
|
||||
}
|
||||
ui->copyToClipboard->setEnabled(true);
|
||||
ui->showQRCode->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->deleteButton->setEnabled(false);
|
||||
ui->showQRCode->setEnabled(false);
|
||||
ui->copyToClipboard->setEnabled(false);
|
||||
ui->signMessage->setEnabled(false);
|
||||
ui->verifyMessage->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AddressBookPage::done(int retval)
|
||||
{
|
||||
QTableView *table = ui->tableView;
|
||||
if(!table->selectionModel() || !table->model())
|
||||
return;
|
||||
// When this is a tab/widget and not a model dialog, ignore "done"
|
||||
if(mode == ForEditing)
|
||||
return;
|
||||
|
||||
// Figure out which address was selected, and return it
|
||||
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
|
||||
|
||||
foreach (QModelIndex index, indexes)
|
||||
{
|
||||
QVariant address = table->model()->data(index);
|
||||
returnValue = address.toString();
|
||||
}
|
||||
|
||||
if(returnValue.isEmpty())
|
||||
{
|
||||
// If no address entry selected, return rejected
|
||||
retval = Rejected;
|
||||
}
|
||||
|
||||
QDialog::done(retval);
|
||||
}
|
||||
|
||||
void AddressBookPage::exportClicked()
|
||||
{
|
||||
// CSV is currently the only supported format
|
||||
QString filename = GUIUtil::getSaveFileName(
|
||||
this,
|
||||
tr("Export Address Book Data"), QString(),
|
||||
tr("Comma separated file (*.csv)"));
|
||||
|
||||
if (filename.isNull()) return;
|
||||
|
||||
CSVModelWriter writer(filename);
|
||||
|
||||
// name, column, role
|
||||
writer.setModel(proxyModel);
|
||||
writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole);
|
||||
writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole);
|
||||
|
||||
if(!writer.write())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename),
|
||||
QMessageBox::Abort, QMessageBox::Abort);
|
||||
}
|
||||
}
|
||||
|
||||
void AddressBookPage::on_showQRCode_clicked()
|
||||
{
|
||||
#ifdef USE_QRCODE
|
||||
QTableView *table = ui->tableView;
|
||||
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
|
||||
|
||||
foreach (QModelIndex index, indexes)
|
||||
{
|
||||
QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString();
|
||||
|
||||
QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this);
|
||||
if(optionsModel)
|
||||
dialog->setModel(optionsModel);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AddressBookPage::contextualMenu(const QPoint &point)
|
||||
{
|
||||
QModelIndex index = ui->tableView->indexAt(point);
|
||||
if(index.isValid())
|
||||
{
|
||||
contextMenu->exec(QCursor::pos());
|
||||
}
|
||||
}
|
||||
|
||||
void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int end)
|
||||
{
|
||||
QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
|
||||
if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
|
||||
{
|
||||
// Select row of newly created address, once
|
||||
ui->tableView->setFocus();
|
||||
ui->tableView->selectRow(idx.row());
|
||||
newAddressToSelect.clear();
|
||||
}
|
||||
}
|
||||
85
src/qt/addressbookpage.h
Normal file
85
src/qt/addressbookpage.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef ADDRESSBOOKPAGE_H
|
||||
#define ADDRESSBOOKPAGE_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class AddressBookPage;
|
||||
}
|
||||
class AddressTableModel;
|
||||
class OptionsModel;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTableView;
|
||||
class QItemSelection;
|
||||
class QSortFilterProxyModel;
|
||||
class QMenu;
|
||||
class QModelIndex;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/** Widget that shows a list of sending or receiving addresses.
|
||||
*/
|
||||
class AddressBookPage : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Tabs {
|
||||
SendingTab = 0,
|
||||
ReceivingTab = 1
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
ForSending, /**< Open address book to pick address for sending */
|
||||
ForEditing /**< Open address book for editing */
|
||||
};
|
||||
|
||||
explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent = 0);
|
||||
~AddressBookPage();
|
||||
|
||||
void setModel(AddressTableModel *model);
|
||||
void setOptionsModel(OptionsModel *optionsModel);
|
||||
const QString &getReturnValue() const { return returnValue; }
|
||||
|
||||
public slots:
|
||||
void done(int retval);
|
||||
void exportClicked();
|
||||
|
||||
private:
|
||||
Ui::AddressBookPage *ui;
|
||||
AddressTableModel *model;
|
||||
OptionsModel *optionsModel;
|
||||
Mode mode;
|
||||
Tabs tab;
|
||||
QString returnValue;
|
||||
QSortFilterProxyModel *proxyModel;
|
||||
QMenu *contextMenu;
|
||||
QAction *deleteAction;
|
||||
QString newAddressToSelect;
|
||||
|
||||
private slots:
|
||||
void on_deleteButton_clicked();
|
||||
void on_newAddressButton_clicked();
|
||||
/** Copy address of currently selected address entry to clipboard */
|
||||
void on_copyToClipboard_clicked();
|
||||
void on_signMessage_clicked();
|
||||
void on_verifyMessage_clicked();
|
||||
void selectionChanged();
|
||||
void on_showQRCode_clicked();
|
||||
/** Spawn contextual menu (right mouse menu) for address book entry */
|
||||
void contextualMenu(const QPoint &point);
|
||||
|
||||
/** Copy label of currently selected address entry to clipboard */
|
||||
void onCopyLabelAction();
|
||||
/** Edit currently selected address entry */
|
||||
void onEditAction();
|
||||
|
||||
/** New entry/entries were added to address table */
|
||||
void selectNewAddress(const QModelIndex &parent, int begin, int end);
|
||||
|
||||
signals:
|
||||
void signMessage(QString addr);
|
||||
void verifyMessage(QString addr);
|
||||
};
|
||||
|
||||
#endif // ADDRESSBOOKDIALOG_H
|
||||
406
src/qt/addresstablemodel.cpp
Normal file
406
src/qt/addresstablemodel.cpp
Normal file
@@ -0,0 +1,406 @@
|
||||
#include "addresstablemodel.h"
|
||||
#include "guiutil.h"
|
||||
#include "walletmodel.h"
|
||||
|
||||
#include "wallet.h"
|
||||
#include "base58.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QColor>
|
||||
|
||||
const QString AddressTableModel::Send = "S";
|
||||
const QString AddressTableModel::Receive = "R";
|
||||
|
||||
struct AddressTableEntry
|
||||
{
|
||||
enum Type {
|
||||
Sending,
|
||||
Receiving
|
||||
};
|
||||
|
||||
Type type;
|
||||
QString label;
|
||||
QString address;
|
||||
|
||||
AddressTableEntry() {}
|
||||
AddressTableEntry(Type type, const QString &label, const QString &address):
|
||||
type(type), label(label), address(address) {}
|
||||
};
|
||||
|
||||
struct AddressTableEntryLessThan
|
||||
{
|
||||
bool operator()(const AddressTableEntry &a, const AddressTableEntry &b) const
|
||||
{
|
||||
return a.address < b.address;
|
||||
}
|
||||
bool operator()(const AddressTableEntry &a, const QString &b) const
|
||||
{
|
||||
return a.address < b;
|
||||
}
|
||||
bool operator()(const QString &a, const AddressTableEntry &b) const
|
||||
{
|
||||
return a < b.address;
|
||||
}
|
||||
};
|
||||
|
||||
// Private implementation
|
||||
class AddressTablePriv
|
||||
{
|
||||
public:
|
||||
CWallet *wallet;
|
||||
QList<AddressTableEntry> cachedAddressTable;
|
||||
AddressTableModel *parent;
|
||||
|
||||
AddressTablePriv(CWallet *wallet, AddressTableModel *parent):
|
||||
wallet(wallet), parent(parent) {}
|
||||
|
||||
void refreshAddressTable()
|
||||
{
|
||||
cachedAddressTable.clear();
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, std::string)& item, wallet->mapAddressBook)
|
||||
{
|
||||
const CBitcoinAddress& address = item.first;
|
||||
const std::string& strName = item.second;
|
||||
bool fMine = IsMine(*wallet, address.Get());
|
||||
cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
|
||||
QString::fromStdString(strName),
|
||||
QString::fromStdString(address.ToString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateEntry(const QString &address, const QString &label, bool isMine, int status)
|
||||
{
|
||||
// Find address / label in model
|
||||
QList<AddressTableEntry>::iterator lower = qLowerBound(
|
||||
cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
|
||||
QList<AddressTableEntry>::iterator upper = qUpperBound(
|
||||
cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
|
||||
int lowerIndex = (lower - cachedAddressTable.begin());
|
||||
int upperIndex = (upper - cachedAddressTable.begin());
|
||||
bool inModel = (lower != upper);
|
||||
AddressTableEntry::Type newEntryType = isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending;
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case CT_NEW:
|
||||
if(inModel)
|
||||
{
|
||||
OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_NOW, but entry is already in model\n");
|
||||
break;
|
||||
}
|
||||
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
|
||||
cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address));
|
||||
parent->endInsertRows();
|
||||
break;
|
||||
case CT_UPDATED:
|
||||
if(!inModel)
|
||||
{
|
||||
OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_UPDATED, but entry is not in model\n");
|
||||
break;
|
||||
}
|
||||
lower->type = newEntryType;
|
||||
lower->label = label;
|
||||
parent->emitDataChanged(lowerIndex);
|
||||
break;
|
||||
case CT_DELETED:
|
||||
if(!inModel)
|
||||
{
|
||||
OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_DELETED, but entry is not in model\n");
|
||||
break;
|
||||
}
|
||||
parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
|
||||
cachedAddressTable.erase(lower, upper);
|
||||
parent->endRemoveRows();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
return cachedAddressTable.size();
|
||||
}
|
||||
|
||||
AddressTableEntry *index(int idx)
|
||||
{
|
||||
if(idx >= 0 && idx < cachedAddressTable.size())
|
||||
{
|
||||
return &cachedAddressTable[idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) :
|
||||
QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0)
|
||||
{
|
||||
columns << tr("Label") << tr("Address");
|
||||
priv = new AddressTablePriv(wallet, this);
|
||||
priv->refreshAddressTable();
|
||||
}
|
||||
|
||||
AddressTableModel::~AddressTableModel()
|
||||
{
|
||||
delete priv;
|
||||
}
|
||||
|
||||
int AddressTableModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return priv->size();
|
||||
}
|
||||
|
||||
int AddressTableModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return columns.length();
|
||||
}
|
||||
|
||||
QVariant AddressTableModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
|
||||
|
||||
if(role == Qt::DisplayRole || role == Qt::EditRole)
|
||||
{
|
||||
switch(index.column())
|
||||
{
|
||||
case Label:
|
||||
if(rec->label.isEmpty() && role == Qt::DisplayRole)
|
||||
{
|
||||
return tr("(no label)");
|
||||
}
|
||||
else
|
||||
{
|
||||
return rec->label;
|
||||
}
|
||||
case Address:
|
||||
return rec->address;
|
||||
}
|
||||
}
|
||||
else if (role == Qt::FontRole)
|
||||
{
|
||||
QFont font;
|
||||
if(index.column() == Address)
|
||||
{
|
||||
font = GUIUtil::bitcoinAddressFont();
|
||||
}
|
||||
return font;
|
||||
}
|
||||
else if (role == TypeRole)
|
||||
{
|
||||
switch(rec->type)
|
||||
{
|
||||
case AddressTableEntry::Sending:
|
||||
return Send;
|
||||
case AddressTableEntry::Receiving:
|
||||
return Receive;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role)
|
||||
{
|
||||
if(!index.isValid())
|
||||
return false;
|
||||
AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
|
||||
|
||||
editStatus = OK;
|
||||
|
||||
if(role == Qt::EditRole)
|
||||
{
|
||||
switch(index.column())
|
||||
{
|
||||
case Label:
|
||||
wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get(), value.toString().toStdString());
|
||||
rec->label = value.toString();
|
||||
break;
|
||||
case Address:
|
||||
// Refuse to set invalid address, set error status and return false
|
||||
if(!walletModel->validateAddress(value.toString()))
|
||||
{
|
||||
editStatus = INVALID_ADDRESS;
|
||||
return false;
|
||||
}
|
||||
// Double-check that we're not overwriting a receiving address
|
||||
if(rec->type == AddressTableEntry::Sending)
|
||||
{
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
// Remove old entry
|
||||
wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
|
||||
// Add new entry with new address
|
||||
wallet->SetAddressBookName(CBitcoinAddress(value.toString().toStdString()).Get(), rec->label.toStdString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if(orientation == Qt::Horizontal)
|
||||
{
|
||||
if(role == Qt::DisplayRole)
|
||||
{
|
||||
return columns[section];
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return 0;
|
||||
AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
|
||||
|
||||
Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
// Can edit address and label for sending addresses,
|
||||
// and only label for receiving addresses.
|
||||
if(rec->type == AddressTableEntry::Sending ||
|
||||
(rec->type == AddressTableEntry::Receiving && index.column()==Label))
|
||||
{
|
||||
retval |= Qt::ItemIsEditable;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
AddressTableEntry *data = priv->index(row);
|
||||
if(data)
|
||||
{
|
||||
return createIndex(row, column, priv->index(row));
|
||||
}
|
||||
else
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
}
|
||||
|
||||
void AddressTableModel::updateEntry(const QString &address, const QString &label, bool isMine, int status)
|
||||
{
|
||||
// Update address book model from Bitcoin core
|
||||
priv->updateEntry(address, label, isMine, status);
|
||||
}
|
||||
|
||||
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address)
|
||||
{
|
||||
std::string strLabel = label.toStdString();
|
||||
std::string strAddress = address.toStdString();
|
||||
|
||||
editStatus = OK;
|
||||
|
||||
if(type == Send)
|
||||
{
|
||||
if(!walletModel->validateAddress(address))
|
||||
{
|
||||
editStatus = INVALID_ADDRESS;
|
||||
return QString();
|
||||
}
|
||||
// Check for duplicate addresses
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
if(wallet->mapAddressBook.count(CBitcoinAddress(strAddress).Get()))
|
||||
{
|
||||
editStatus = DUPLICATE_ADDRESS;
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type == Receive)
|
||||
{
|
||||
// Generate a new address to associate with given label
|
||||
WalletModel::UnlockContext ctx(walletModel->requestUnlock());
|
||||
if(!ctx.isValid())
|
||||
{
|
||||
// Unlock wallet failed or was cancelled
|
||||
editStatus = WALLET_UNLOCK_FAILURE;
|
||||
return QString();
|
||||
}
|
||||
CPubKey newKey;
|
||||
if(!wallet->GetKeyFromPool(newKey, true))
|
||||
{
|
||||
editStatus = KEY_GENERATION_FAILURE;
|
||||
return QString();
|
||||
}
|
||||
strAddress = CBitcoinAddress(newKey.GetID()).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
// Add entry
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->SetAddressBookName(CBitcoinAddress(strAddress).Get(), strLabel);
|
||||
}
|
||||
return QString::fromStdString(strAddress);
|
||||
}
|
||||
|
||||
bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent)
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
AddressTableEntry *rec = priv->index(row);
|
||||
if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving)
|
||||
{
|
||||
// Can only remove one row at a time, and cannot remove rows not in model.
|
||||
// Also refuse to remove receiving addresses.
|
||||
return false;
|
||||
}
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->DelAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Look up label for address in address book, if not found return empty string.
|
||||
*/
|
||||
QString AddressTableModel::labelForAddress(const QString &address) const
|
||||
{
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
CBitcoinAddress address_parsed(address.toStdString());
|
||||
std::map<CTxDestination, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed.Get());
|
||||
if (mi != wallet->mapAddressBook.end())
|
||||
{
|
||||
return QString::fromStdString(mi->second);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
int AddressTableModel::lookupAddress(const QString &address) const
|
||||
{
|
||||
QModelIndexList lst = match(index(0, Address, QModelIndex()),
|
||||
Qt::EditRole, address, 1, Qt::MatchExactly);
|
||||
if(lst.isEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lst.at(0).row();
|
||||
}
|
||||
}
|
||||
|
||||
void AddressTableModel::emitDataChanged(int idx)
|
||||
{
|
||||
emit dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
|
||||
}
|
||||
91
src/qt/addresstablemodel.h
Normal file
91
src/qt/addresstablemodel.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef ADDRESSTABLEMODEL_H
|
||||
#define ADDRESSTABLEMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include <QStringList>
|
||||
|
||||
class AddressTablePriv;
|
||||
class CWallet;
|
||||
class WalletModel;
|
||||
|
||||
/**
|
||||
Qt model of the address book in the core. This allows views to access and modify the address book.
|
||||
*/
|
||||
class AddressTableModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0);
|
||||
~AddressTableModel();
|
||||
|
||||
enum ColumnIndex {
|
||||
Label = 0, /**< User specified label */
|
||||
Address = 1 /**< Bitcoin address */
|
||||
};
|
||||
|
||||
enum RoleIndex {
|
||||
TypeRole = Qt::UserRole /**< Type of address (#Send or #Receive) */
|
||||
};
|
||||
|
||||
/** Return status of edit/insert operation */
|
||||
enum EditStatus {
|
||||
OK,
|
||||
INVALID_ADDRESS, /**< Unparseable address */
|
||||
DUPLICATE_ADDRESS, /**< Address already in address book */
|
||||
WALLET_UNLOCK_FAILURE, /**< Wallet could not be unlocked to create new receiving address */
|
||||
KEY_GENERATION_FAILURE /**< Generating a new public key for a receiving address failed */
|
||||
};
|
||||
|
||||
static const QString Send; /**< Specifies send address */
|
||||
static const QString Receive; /**< Specifies receive address */
|
||||
|
||||
/** @name Methods overridden from QAbstractTableModel
|
||||
@{*/
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
bool setData(const QModelIndex & index, const QVariant & value, int role);
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex & parent) const;
|
||||
bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex());
|
||||
Qt::ItemFlags flags(const QModelIndex & index) const;
|
||||
/*@}*/
|
||||
|
||||
/* Add an address to the model.
|
||||
Returns the added address on success, and an empty string otherwise.
|
||||
*/
|
||||
QString addRow(const QString &type, const QString &label, const QString &address);
|
||||
|
||||
/* Look up label for address in address book, if not found return empty string.
|
||||
*/
|
||||
QString labelForAddress(const QString &address) const;
|
||||
|
||||
/* Look up row index of an address in the model.
|
||||
Return -1 if not found.
|
||||
*/
|
||||
int lookupAddress(const QString &address) const;
|
||||
|
||||
EditStatus getEditStatus() const { return editStatus; }
|
||||
|
||||
private:
|
||||
WalletModel *walletModel;
|
||||
CWallet *wallet;
|
||||
AddressTablePriv *priv;
|
||||
QStringList columns;
|
||||
EditStatus editStatus;
|
||||
|
||||
/** Notify listeners that data changed. */
|
||||
void emitDataChanged(int index);
|
||||
|
||||
signals:
|
||||
void defaultAddressChanged(const QString &address);
|
||||
|
||||
public slots:
|
||||
/* Update address list from core.
|
||||
*/
|
||||
void updateEntry(const QString &address, const QString &label, bool isMine, int status);
|
||||
|
||||
friend class AddressTablePriv;
|
||||
};
|
||||
|
||||
#endif // ADDRESSTABLEMODEL_H
|
||||
239
src/qt/askpassphrasedialog.cpp
Normal file
239
src/qt/askpassphrasedialog.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
#include "askpassphrasedialog.h"
|
||||
#include "ui_askpassphrasedialog.h"
|
||||
|
||||
#include "guiconstants.h"
|
||||
#include "walletmodel.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QKeyEvent>
|
||||
|
||||
AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AskPassphraseDialog),
|
||||
mode(mode),
|
||||
model(0),
|
||||
fCapsLock(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
|
||||
ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
|
||||
ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);
|
||||
|
||||
// Setup Caps Lock detection.
|
||||
ui->passEdit1->installEventFilter(this);
|
||||
ui->passEdit2->installEventFilter(this);
|
||||
ui->passEdit3->installEventFilter(this);
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case Encrypt: // Ask passphrase x2
|
||||
ui->passLabel1->hide();
|
||||
ui->passEdit1->hide();
|
||||
ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>."));
|
||||
setWindowTitle(tr("Encrypt wallet"));
|
||||
break;
|
||||
case Unlock: // Ask passphrase
|
||||
ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
|
||||
ui->passLabel2->hide();
|
||||
ui->passEdit2->hide();
|
||||
ui->passLabel3->hide();
|
||||
ui->passEdit3->hide();
|
||||
setWindowTitle(tr("Unlock wallet"));
|
||||
break;
|
||||
case Decrypt: // Ask passphrase
|
||||
ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet."));
|
||||
ui->passLabel2->hide();
|
||||
ui->passEdit2->hide();
|
||||
ui->passLabel3->hide();
|
||||
ui->passEdit3->hide();
|
||||
setWindowTitle(tr("Decrypt wallet"));
|
||||
break;
|
||||
case ChangePass: // Ask old passphrase + new passphrase x2
|
||||
setWindowTitle(tr("Change passphrase"));
|
||||
ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet."));
|
||||
break;
|
||||
}
|
||||
|
||||
textChanged();
|
||||
connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
|
||||
connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
|
||||
connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
|
||||
}
|
||||
|
||||
AskPassphraseDialog::~AskPassphraseDialog()
|
||||
{
|
||||
// Attempt to overwrite text so that they do not linger around in memory
|
||||
ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size()));
|
||||
ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size()));
|
||||
ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size()));
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AskPassphraseDialog::setModel(WalletModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
}
|
||||
|
||||
void AskPassphraseDialog::accept()
|
||||
{
|
||||
SecureString oldpass, newpass1, newpass2;
|
||||
if(!model)
|
||||
return;
|
||||
oldpass.reserve(MAX_PASSPHRASE_SIZE);
|
||||
newpass1.reserve(MAX_PASSPHRASE_SIZE);
|
||||
newpass2.reserve(MAX_PASSPHRASE_SIZE);
|
||||
// TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
|
||||
// Alternately, find a way to make this input mlock()'d to begin with.
|
||||
oldpass.assign(ui->passEdit1->text().toStdString().c_str());
|
||||
newpass1.assign(ui->passEdit2->text().toStdString().c_str());
|
||||
newpass2.assign(ui->passEdit3->text().toStdString().c_str());
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case Encrypt: {
|
||||
if(newpass1.empty() || newpass2.empty())
|
||||
{
|
||||
// Cannot encrypt with empty passphrase
|
||||
break;
|
||||
}
|
||||
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
|
||||
tr("WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR CASINOCOINS</b>!\nAre you sure you wish to encrypt your wallet?"),
|
||||
QMessageBox::Yes|QMessageBox::Cancel,
|
||||
QMessageBox::Cancel);
|
||||
if(retval == QMessageBox::Yes)
|
||||
{
|
||||
if(newpass1 == newpass2)
|
||||
{
|
||||
if(model->setWalletEncrypted(true, newpass1))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Wallet encrypted"),
|
||||
tr("CasinoCoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your casinocoins from being stolen by malware infecting your computer."));
|
||||
QApplication::quit();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wallet encryption failed"),
|
||||
tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
|
||||
}
|
||||
QDialog::accept(); // Success
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wallet encryption failed"),
|
||||
tr("The supplied passphrases do not match."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QDialog::reject(); // Cancelled
|
||||
}
|
||||
} break;
|
||||
case Unlock:
|
||||
if(!model->setWalletLocked(false, oldpass))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wallet unlock failed"),
|
||||
tr("The passphrase entered for the wallet decryption was incorrect."));
|
||||
}
|
||||
else
|
||||
{
|
||||
QDialog::accept(); // Success
|
||||
}
|
||||
break;
|
||||
case Decrypt:
|
||||
if(!model->setWalletEncrypted(false, oldpass))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wallet decryption failed"),
|
||||
tr("The passphrase entered for the wallet decryption was incorrect."));
|
||||
}
|
||||
else
|
||||
{
|
||||
QDialog::accept(); // Success
|
||||
}
|
||||
break;
|
||||
case ChangePass:
|
||||
if(newpass1 == newpass2)
|
||||
{
|
||||
if(model->changePassphrase(oldpass, newpass1))
|
||||
{
|
||||
QMessageBox::information(this, tr("Wallet encrypted"),
|
||||
tr("Wallet passphrase was successfully changed."));
|
||||
QDialog::accept(); // Success
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wallet encryption failed"),
|
||||
tr("The passphrase entered for the wallet decryption was incorrect."));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wallet encryption failed"),
|
||||
tr("The supplied passphrases do not match."));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AskPassphraseDialog::textChanged()
|
||||
{
|
||||
// Validate input, set Ok button to enabled when accepable
|
||||
bool acceptable = false;
|
||||
switch(mode)
|
||||
{
|
||||
case Encrypt: // New passphrase x2
|
||||
acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
|
||||
break;
|
||||
case Unlock: // Old passphrase x1
|
||||
case Decrypt:
|
||||
acceptable = !ui->passEdit1->text().isEmpty();
|
||||
break;
|
||||
case ChangePass: // Old passphrase x1, new passphrase x2
|
||||
acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
|
||||
break;
|
||||
}
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
|
||||
}
|
||||
|
||||
bool AskPassphraseDialog::event(QEvent *event)
|
||||
{
|
||||
// Detect Caps Lock key press.
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
|
||||
if (ke->key() == Qt::Key_CapsLock) {
|
||||
fCapsLock = !fCapsLock;
|
||||
}
|
||||
if (fCapsLock) {
|
||||
ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
|
||||
} else {
|
||||
ui->capsLabel->clear();
|
||||
}
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
bool AskPassphraseDialog::eventFilter(QObject *, QEvent *event)
|
||||
{
|
||||
/* Detect Caps Lock.
|
||||
* There is no good OS-independent way to check a key state in Qt, but we
|
||||
* can detect Caps Lock by checking for the following condition:
|
||||
* Shift key is down and the result is a lower case character, or
|
||||
* Shift key is not down and the result is an upper case character.
|
||||
*/
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
|
||||
QString str = ke->text();
|
||||
if (str.length() != 0) {
|
||||
const QChar *psz = str.unicode();
|
||||
bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
|
||||
if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) {
|
||||
fCapsLock = true;
|
||||
ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
|
||||
} else if (psz->isLetter()) {
|
||||
fCapsLock = false;
|
||||
ui->capsLabel->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
45
src/qt/askpassphrasedialog.h
Normal file
45
src/qt/askpassphrasedialog.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef ASKPASSPHRASEDIALOG_H
|
||||
#define ASKPASSPHRASEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class AskPassphraseDialog;
|
||||
}
|
||||
|
||||
class WalletModel;
|
||||
|
||||
/** Multifunctional dialog to ask for passphrases. Used for encryption, unlocking, and changing the passphrase.
|
||||
*/
|
||||
class AskPassphraseDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Mode {
|
||||
Encrypt, /**< Ask passphrase twice and encrypt */
|
||||
Unlock, /**< Ask passphrase and unlock */
|
||||
ChangePass, /**< Ask old passphrase + new passphrase twice */
|
||||
Decrypt /**< Ask passphrase and decrypt wallet */
|
||||
};
|
||||
|
||||
explicit AskPassphraseDialog(Mode mode, QWidget *parent = 0);
|
||||
~AskPassphraseDialog();
|
||||
|
||||
void accept();
|
||||
|
||||
void setModel(WalletModel *model);
|
||||
|
||||
private:
|
||||
Ui::AskPassphraseDialog *ui;
|
||||
Mode mode;
|
||||
WalletModel *model;
|
||||
bool fCapsLock;
|
||||
|
||||
private slots:
|
||||
void textChanged();
|
||||
bool event(QEvent *event);
|
||||
bool eventFilter(QObject *, QEvent *event);
|
||||
};
|
||||
|
||||
#endif // ASKPASSPHRASEDIALOG_H
|
||||
316
src/qt/bitcoin.cpp
Normal file
316
src/qt/bitcoin.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* W.J. van der Laan 2011-2012
|
||||
*/
|
||||
#include "bitcoingui.h"
|
||||
#include "clientmodel.h"
|
||||
#include "walletmodel.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "guiutil.h"
|
||||
#include "guiconstants.h"
|
||||
|
||||
#include "init.h"
|
||||
#include "ui_interface.h"
|
||||
#include "qtipcserver.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QTextCodec>
|
||||
#include <QLocale>
|
||||
#include <QTranslator>
|
||||
#include <QSplashScreen>
|
||||
#include <QLibraryInfo>
|
||||
|
||||
#include <boost/interprocess/ipc/message_queue.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
|
||||
#define _BITCOIN_QT_PLUGINS_INCLUDED
|
||||
#define __INSURE__
|
||||
#include <QtPlugin>
|
||||
Q_IMPORT_PLUGIN(qcncodecs)
|
||||
Q_IMPORT_PLUGIN(qjpcodecs)
|
||||
Q_IMPORT_PLUGIN(qtwcodecs)
|
||||
Q_IMPORT_PLUGIN(qkrcodecs)
|
||||
Q_IMPORT_PLUGIN(qtaccessiblewidgets)
|
||||
#endif
|
||||
|
||||
// Need a global reference for the notifications to find the GUI
|
||||
static BitcoinGUI *guiref;
|
||||
static QSplashScreen *splashref;
|
||||
|
||||
static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
|
||||
{
|
||||
// Message from network thread
|
||||
if(guiref)
|
||||
{
|
||||
bool modal = (style & CClientUIInterface::MODAL);
|
||||
// in case of modal message, use blocking connection to wait for user to click OK
|
||||
QMetaObject::invokeMethod(guiref, "error",
|
||||
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(caption)),
|
||||
Q_ARG(QString, QString::fromStdString(message)),
|
||||
Q_ARG(bool, modal));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s: %s\n", caption.c_str(), message.c_str());
|
||||
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
|
||||
{
|
||||
if(!guiref)
|
||||
return false;
|
||||
if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon)
|
||||
return true;
|
||||
bool payFee = false;
|
||||
|
||||
QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(),
|
||||
Q_ARG(qint64, nFeeRequired),
|
||||
Q_ARG(bool*, &payFee));
|
||||
|
||||
return payFee;
|
||||
}
|
||||
|
||||
static void ThreadSafeHandleURI(const std::string& strURI)
|
||||
{
|
||||
if(!guiref)
|
||||
return;
|
||||
|
||||
QMetaObject::invokeMethod(guiref, "handleURI", GUIUtil::blockingGUIThreadConnection(),
|
||||
Q_ARG(QString, QString::fromStdString(strURI)));
|
||||
}
|
||||
|
||||
static void InitMessage(const std::string &message)
|
||||
{
|
||||
if(splashref)
|
||||
{
|
||||
splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200));
|
||||
QApplication::instance()->processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
static void QueueShutdown()
|
||||
{
|
||||
QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
/*
|
||||
Translate string to current locale using Qt.
|
||||
*/
|
||||
static std::string Translate(const char* psz)
|
||||
{
|
||||
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
|
||||
}
|
||||
|
||||
/* Handle runaway exceptions. Shows a message box with the problem and quits the program.
|
||||
*/
|
||||
static void handleRunawayException(std::exception *e)
|
||||
{
|
||||
PrintExceptionContinue(e, "Runaway exception");
|
||||
QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occured. CasinoCoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifndef BITCOIN_QT_TEST
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// TODO: implement URI support on the Mac.
|
||||
#if !defined(MAC_OSX)
|
||||
// Do this early as we don't want to bother initializing if we are just calling IPC
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (boost::algorithm::istarts_with(argv[i], "casinocoin:"))
|
||||
{
|
||||
const char *strURI = argv[i];
|
||||
try {
|
||||
boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME);
|
||||
if (mq.try_send(strURI, strlen(strURI), 0))
|
||||
// if URI could be sent to the message queue exit here
|
||||
exit(0);
|
||||
else
|
||||
// if URI could not be sent to the message queue do a normal Bitcoin-Qt startup
|
||||
break;
|
||||
}
|
||||
catch (boost::interprocess::interprocess_exception &ex) {
|
||||
// don't log the "file not found" exception, because that's normal for
|
||||
// the first start of the first instance
|
||||
if (ex.get_error_code() != boost::interprocess::not_found_error)
|
||||
{
|
||||
printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Internal string conversion is all UTF-8
|
||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
|
||||
|
||||
Q_INIT_RESOURCE(bitcoin);
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// Install global event filter that makes sure that long tooltips can be word-wrapped
|
||||
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
|
||||
|
||||
// Command-line options take precedence:
|
||||
ParseParameters(argc, argv);
|
||||
|
||||
// ... then bitcoin.conf:
|
||||
if (!boost::filesystem::is_directory(GetDataDir(false)))
|
||||
{
|
||||
fprintf(stderr, "Error: Specified directory does not exist\n");
|
||||
return 1;
|
||||
}
|
||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||
|
||||
// Application identification (must be set before OptionsModel is initialized,
|
||||
// as it is used to locate QSettings)
|
||||
app.setOrganizationName("CasinoCoin");
|
||||
app.setOrganizationDomain("casinocoin.org");
|
||||
if(GetBoolArg("-testnet")) // Separate UI settings for testnet
|
||||
app.setApplicationName("CasinoCoin-Qt-testnet");
|
||||
else
|
||||
app.setApplicationName("CasinoCoin-Qt");
|
||||
|
||||
// ... then GUI settings:
|
||||
OptionsModel optionsModel;
|
||||
|
||||
// Get desired locale (e.g. "de_DE") from command line or use system locale
|
||||
QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
|
||||
QString lang = lang_territory;
|
||||
// Convert to "de" only by truncating "_DE"
|
||||
lang.truncate(lang_territory.lastIndexOf('_'));
|
||||
|
||||
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
|
||||
// Load language files for configured locale:
|
||||
// - First load the translator for the base language, without territory
|
||||
// - Then load the more specific locale translator
|
||||
|
||||
// Load e.g. qt_de.qm
|
||||
if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
|
||||
app.installTranslator(&qtTranslatorBase);
|
||||
|
||||
// Load e.g. qt_de_DE.qm
|
||||
if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
|
||||
app.installTranslator(&qtTranslator);
|
||||
|
||||
// Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
|
||||
if (translatorBase.load(lang, ":/translations/"))
|
||||
app.installTranslator(&translatorBase);
|
||||
|
||||
// Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
|
||||
if (translator.load(lang_territory, ":/translations/"))
|
||||
app.installTranslator(&translator);
|
||||
|
||||
// Subscribe to global signals from core
|
||||
uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
|
||||
uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee);
|
||||
uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI);
|
||||
uiInterface.InitMessage.connect(InitMessage);
|
||||
uiInterface.QueueShutdown.connect(QueueShutdown);
|
||||
uiInterface.Translate.connect(Translate);
|
||||
|
||||
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
|
||||
// but before showing splash screen.
|
||||
if (mapArgs.count("-?") || mapArgs.count("--help"))
|
||||
{
|
||||
GUIUtil::HelpMessageBox help;
|
||||
help.showOrPrint();
|
||||
return 1;
|
||||
}
|
||||
|
||||
QSplashScreen splash(QPixmap(":/images/splash"), 0);
|
||||
if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
|
||||
{
|
||||
splash.show();
|
||||
splash.setAutoFillBackground(true);
|
||||
splashref = &splash;
|
||||
}
|
||||
|
||||
app.processEvents();
|
||||
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
|
||||
try
|
||||
{
|
||||
// Regenerate startup link, to fix links to old versions
|
||||
if (GUIUtil::GetStartOnSystemStartup())
|
||||
GUIUtil::SetStartOnSystemStartup(true);
|
||||
|
||||
BitcoinGUI window;
|
||||
guiref = &window;
|
||||
if(AppInit2())
|
||||
{
|
||||
{
|
||||
// Put this in a block, so that the Model objects are cleaned up before
|
||||
// calling Shutdown().
|
||||
|
||||
optionsModel.Upgrade(); // Must be done after AppInit2
|
||||
|
||||
if (splashref)
|
||||
splash.finish(&window);
|
||||
|
||||
ClientModel clientModel(&optionsModel);
|
||||
WalletModel walletModel(pwalletMain, &optionsModel);
|
||||
|
||||
window.setClientModel(&clientModel);
|
||||
window.setWalletModel(&walletModel);
|
||||
|
||||
// If -min option passed, start window minimized.
|
||||
if(GetBoolArg("-min"))
|
||||
{
|
||||
window.showMinimized();
|
||||
}
|
||||
else
|
||||
{
|
||||
window.show();
|
||||
}
|
||||
// TODO: implement URI support on the Mac.
|
||||
#if !defined(MAC_OSX)
|
||||
|
||||
// Place this here as guiref has to be defined if we dont want to lose URIs
|
||||
ipcInit();
|
||||
|
||||
// Check for URI in argv
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (boost::algorithm::istarts_with(argv[i], "casinocoin:"))
|
||||
{
|
||||
const char *strURI = argv[i];
|
||||
try {
|
||||
boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME);
|
||||
mq.try_send(strURI, strlen(strURI), 0);
|
||||
}
|
||||
catch (boost::interprocess::interprocess_exception &ex) {
|
||||
printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
app.exec();
|
||||
|
||||
window.hide();
|
||||
window.setClientModel(0);
|
||||
window.setWalletModel(0);
|
||||
guiref = 0;
|
||||
}
|
||||
// Shutdown the core and it's threads, but don't exit Bitcoin-Qt here
|
||||
Shutdown(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
handleRunawayException(&e);
|
||||
} catch (...) {
|
||||
handleRunawayException(NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // BITCOIN_QT_TEST
|
||||
89
src/qt/bitcoin.qrc
Normal file
89
src/qt/bitcoin.qrc
Normal file
@@ -0,0 +1,89 @@
|
||||
<RCC>
|
||||
<qresource prefix="/icons">
|
||||
<file alias="bitcoin">res/icons/bitcoin.png</file>
|
||||
<file alias="address-book">res/icons/address-book.png</file>
|
||||
<file alias="quit">res/icons/quit.png</file>
|
||||
<file alias="send">res/icons/send.png</file>
|
||||
<file alias="toolbar">res/icons/toolbar.png</file>
|
||||
<file alias="connect_0">res/icons/connect0_16.png</file>
|
||||
<file alias="connect_1">res/icons/connect1_16.png</file>
|
||||
<file alias="connect_2">res/icons/connect2_16.png</file>
|
||||
<file alias="connect_3">res/icons/connect3_16.png</file>
|
||||
<file alias="connect_4">res/icons/connect4_16.png</file>
|
||||
<file alias="transaction_0">res/icons/transaction0.png</file>
|
||||
<file alias="transaction_confirmed">res/icons/transaction2.png</file>
|
||||
<file alias="transaction_1">res/icons/clock1.png</file>
|
||||
<file alias="transaction_2">res/icons/clock2.png</file>
|
||||
<file alias="transaction_3">res/icons/clock3.png</file>
|
||||
<file alias="transaction_4">res/icons/clock4.png</file>
|
||||
<file alias="transaction_5">res/icons/clock5.png</file>
|
||||
<file alias="options">res/icons/configure.png</file>
|
||||
<file alias="receiving_addresses">res/icons/receive.png</file>
|
||||
<file alias="editpaste">res/icons/editpaste.png</file>
|
||||
<file alias="editcopy">res/icons/editcopy.png</file>
|
||||
<file alias="add">res/icons/add.png</file>
|
||||
<file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file>
|
||||
<file alias="toolbar_testnet">res/icons/toolbar_testnet.png</file>
|
||||
<file alias="edit">res/icons/edit.png</file>
|
||||
<file alias="history">res/icons/history.png</file>
|
||||
<file alias="overview">res/icons/overview.png</file>
|
||||
<file alias="export">res/icons/export.png</file>
|
||||
<file alias="synced">res/icons/synced.png</file>
|
||||
<file alias="remove">res/icons/remove.png</file>
|
||||
<file alias="tx_input">res/icons/tx_input.png</file>
|
||||
<file alias="tx_output">res/icons/tx_output.png</file>
|
||||
<file alias="tx_inout">res/icons/tx_inout.png</file>
|
||||
<file alias="tx_mined">res/icons/tx_mined.png</file>
|
||||
<file alias="lock_closed">res/icons/lock_closed.png</file>
|
||||
<file alias="lock_open">res/icons/lock_open.png</file>
|
||||
<file alias="key">res/icons/key.png</file>
|
||||
<file alias="filesave">res/icons/filesave.png</file>
|
||||
<file alias="qrcode">res/icons/qrcode.png</file>
|
||||
<file alias="debugwindow">res/icons/debugwindow.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/images">
|
||||
<file alias="about">res/images/about.png</file>
|
||||
<file alias="splash">res/images/splash2.jpg</file>
|
||||
<file alias="backg">res/images/wallet.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/movies">
|
||||
<file alias="update_spinner">res/movies/update_spinner.mng</file>
|
||||
</qresource>
|
||||
<qresource prefix="/translations">
|
||||
<file alias="bg">locale/bitcoin_bg.qm</file>
|
||||
<file alias="ca_ES">locale/bitcoin_ca_ES.qm</file>
|
||||
<file alias="cs">locale/bitcoin_cs.qm</file>
|
||||
<file alias="da">locale/bitcoin_da.qm</file>
|
||||
<file alias="de">locale/bitcoin_de.qm</file>
|
||||
<file alias="el_GR">locale/bitcoin_el_GR.qm</file>
|
||||
<file alias="en">locale/bitcoin_en.qm</file>
|
||||
<file alias="es">locale/bitcoin_es.qm</file>
|
||||
<file alias="es_CL">locale/bitcoin_es_CL.qm</file>
|
||||
<file alias="et">locale/bitcoin_et.qm</file>
|
||||
<file alias="eu_ES">locale/bitcoin_eu_ES.qm</file>
|
||||
<file alias="fa">locale/bitcoin_fa.qm</file>
|
||||
<file alias="fa_IR">locale/bitcoin_fa_IR.qm</file>
|
||||
<file alias="fi">locale/bitcoin_fi.qm</file>
|
||||
<file alias="fr">locale/bitcoin_fr.qm</file>
|
||||
<file alias="fr_CA">locale/bitcoin_fr_CA.qm</file>
|
||||
<file alias="he">locale/bitcoin_he.qm</file>
|
||||
<file alias="hr">locale/bitcoin_hr.qm</file>
|
||||
<file alias="hu">locale/bitcoin_hu.qm</file>
|
||||
<file alias="it">locale/bitcoin_it.qm</file>
|
||||
<file alias="lt">locale/bitcoin_lt.qm</file>
|
||||
<file alias="nb">locale/bitcoin_nb.qm</file>
|
||||
<file alias="nl">locale/bitcoin_nl.qm</file>
|
||||
<file alias="pl">locale/bitcoin_pl.qm</file>
|
||||
<file alias="pt_BR">locale/bitcoin_pt_BR.qm</file>
|
||||
<file alias="pt_PT">locale/bitcoin_pt_PT.qm</file>
|
||||
<file alias="ro_RO">locale/bitcoin_ro_RO.qm</file>
|
||||
<file alias="ru">locale/bitcoin_ru.qm</file>
|
||||
<file alias="sk">locale/bitcoin_sk.qm</file>
|
||||
<file alias="sr">locale/bitcoin_sr.qm</file>
|
||||
<file alias="sv">locale/bitcoin_sv.qm</file>
|
||||
<file alias="tr">locale/bitcoin_tr.qm</file>
|
||||
<file alias="uk">locale/bitcoin_uk.qm</file>
|
||||
<file alias="zh_CN">locale/bitcoin_zh_CN.qm</file>
|
||||
<file alias="zh_TW">locale/bitcoin_zh_TW.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
77
src/qt/bitcoinaddressvalidator.cpp
Normal file
77
src/qt/bitcoinaddressvalidator.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "bitcoinaddressvalidator.h"
|
||||
|
||||
/* Base58 characters are:
|
||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
This is:
|
||||
- All numbers except for '0'
|
||||
- All uppercase letters except for 'I' and 'O'
|
||||
- All lowercase letters except for 'l'
|
||||
|
||||
User friendly Base58 input can map
|
||||
- 'l' and 'I' to '1'
|
||||
- '0' and 'O' to 'o'
|
||||
*/
|
||||
|
||||
BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) :
|
||||
QValidator(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const
|
||||
{
|
||||
// Correction
|
||||
for(int idx=0; idx<input.size();)
|
||||
{
|
||||
bool removeChar = false;
|
||||
QChar ch = input.at(idx);
|
||||
// Corrections made are very conservative on purpose, to avoid
|
||||
// users unexpectedly getting away with typos that would normally
|
||||
// be detected, and thus sending to the wrong address.
|
||||
switch(ch.unicode())
|
||||
{
|
||||
// Qt categorizes these as "Other_Format" not "Separator_Space"
|
||||
case 0x200B: // ZERO WIDTH SPACE
|
||||
case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
|
||||
removeChar = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Remove whitespace
|
||||
if(ch.isSpace())
|
||||
removeChar = true;
|
||||
// To next character
|
||||
if(removeChar)
|
||||
input.remove(idx, 1);
|
||||
else
|
||||
++idx;
|
||||
}
|
||||
|
||||
// Validation
|
||||
QValidator::State state = QValidator::Acceptable;
|
||||
for(int idx=0; idx<input.size(); ++idx)
|
||||
{
|
||||
int ch = input.at(idx).unicode();
|
||||
|
||||
if(((ch >= '0' && ch<='9') ||
|
||||
(ch >= 'a' && ch<='z') ||
|
||||
(ch >= 'A' && ch<='Z')) &&
|
||||
ch != 'l' && ch != 'I' && ch != '0' && ch != 'O')
|
||||
{
|
||||
// Alphanumeric and not a 'forbidden' character
|
||||
}
|
||||
else
|
||||
{
|
||||
state = QValidator::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
// Empty address is "intermediate" input
|
||||
if(input.isEmpty())
|
||||
{
|
||||
state = QValidator::Intermediate;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
24
src/qt/bitcoinaddressvalidator.h
Normal file
24
src/qt/bitcoinaddressvalidator.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef BITCOINADDRESSVALIDATOR_H
|
||||
#define BITCOINADDRESSVALIDATOR_H
|
||||
|
||||
#include <QRegExpValidator>
|
||||
|
||||
/** Base48 entry widget validator.
|
||||
Corrects near-miss characters and refuses characters that are no part of base48.
|
||||
*/
|
||||
class BitcoinAddressValidator : public QValidator
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BitcoinAddressValidator(QObject *parent = 0);
|
||||
|
||||
State validate(QString &input, int &pos) const;
|
||||
|
||||
static const int MaxAddressLength = 35;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // BITCOINADDRESSVALIDATOR_H
|
||||
168
src/qt/bitcoinamountfield.cpp
Normal file
168
src/qt/bitcoinamountfield.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
#include "bitcoinamountfield.h"
|
||||
#include "qvaluecombobox.h"
|
||||
#include "bitcoinunits.h"
|
||||
|
||||
#include "guiconstants.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QRegExpValidator>
|
||||
#include <QHBoxLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QApplication>
|
||||
#include <qmath.h>
|
||||
|
||||
BitcoinAmountField::BitcoinAmountField(QWidget *parent):
|
||||
QWidget(parent), amount(0), currentUnit(-1)
|
||||
{
|
||||
amount = new QDoubleSpinBox(this);
|
||||
amount->setLocale(QLocale::c());
|
||||
amount->setDecimals(8);
|
||||
amount->installEventFilter(this);
|
||||
amount->setMaximumWidth(170);
|
||||
amount->setSingleStep(0.001);
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->addWidget(amount);
|
||||
unit = new QValueComboBox(this);
|
||||
unit->setModel(new BitcoinUnits(this));
|
||||
layout->addWidget(unit);
|
||||
layout->addStretch(1);
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
setFocusPolicy(Qt::TabFocus);
|
||||
setFocusProxy(amount);
|
||||
|
||||
// If one if the widgets changes, the combined content changes as well
|
||||
connect(amount, SIGNAL(valueChanged(QString)), this, SIGNAL(textChanged()));
|
||||
connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int)));
|
||||
|
||||
// Set default based on configuration
|
||||
unitChanged(unit->currentIndex());
|
||||
}
|
||||
|
||||
void BitcoinAmountField::setText(const QString &text)
|
||||
{
|
||||
if (text.isEmpty())
|
||||
amount->clear();
|
||||
else
|
||||
amount->setValue(text.toDouble());
|
||||
}
|
||||
|
||||
void BitcoinAmountField::clear()
|
||||
{
|
||||
amount->clear();
|
||||
unit->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
bool BitcoinAmountField::validate()
|
||||
{
|
||||
bool valid = true;
|
||||
if (amount->value() == 0.0)
|
||||
valid = false;
|
||||
if (valid && !BitcoinUnits::parse(currentUnit, text(), 0))
|
||||
valid = false;
|
||||
|
||||
setValid(valid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
void BitcoinAmountField::setValid(bool valid)
|
||||
{
|
||||
if (valid)
|
||||
amount->setStyleSheet("");
|
||||
else
|
||||
amount->setStyleSheet(STYLE_INVALID);
|
||||
}
|
||||
|
||||
QString BitcoinAmountField::text() const
|
||||
{
|
||||
if (amount->text().isEmpty())
|
||||
return QString();
|
||||
else
|
||||
return amount->text();
|
||||
}
|
||||
|
||||
bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::FocusIn)
|
||||
{
|
||||
// Clear invalid flag on focus
|
||||
setValid(true);
|
||||
}
|
||||
else if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
|
||||
{
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
if (keyEvent->key() == Qt::Key_Comma)
|
||||
{
|
||||
// Translate a comma into a period
|
||||
QKeyEvent periodKeyEvent(event->type(), Qt::Key_Period, keyEvent->modifiers(), ".", keyEvent->isAutoRepeat(), keyEvent->count());
|
||||
qApp->sendEvent(object, &periodKeyEvent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(object, event);
|
||||
}
|
||||
|
||||
QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
|
||||
{
|
||||
QWidget::setTabOrder(prev, amount);
|
||||
return amount;
|
||||
}
|
||||
|
||||
qint64 BitcoinAmountField::value(bool *valid_out) const
|
||||
{
|
||||
qint64 val_out = 0;
|
||||
bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
|
||||
if(valid_out)
|
||||
{
|
||||
*valid_out = valid;
|
||||
}
|
||||
return val_out;
|
||||
}
|
||||
|
||||
void BitcoinAmountField::setValue(qint64 value)
|
||||
{
|
||||
setText(BitcoinUnits::format(currentUnit, value));
|
||||
}
|
||||
|
||||
void BitcoinAmountField::unitChanged(int idx)
|
||||
{
|
||||
// Use description tooltip for current unit for the combobox
|
||||
unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
|
||||
|
||||
// Determine new unit ID
|
||||
int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt();
|
||||
|
||||
// Parse current value and convert to new unit
|
||||
bool valid = false;
|
||||
qint64 currentValue = value(&valid);
|
||||
|
||||
currentUnit = newUnit;
|
||||
|
||||
// Set max length after retrieving the value, to prevent truncation
|
||||
amount->setDecimals(BitcoinUnits::decimals(currentUnit));
|
||||
amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
|
||||
|
||||
if(valid)
|
||||
{
|
||||
// If value was valid, re-place it in the widget with the new unit
|
||||
setValue(currentValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If current value is invalid, just clear field
|
||||
setText("");
|
||||
}
|
||||
setValid(true);
|
||||
}
|
||||
|
||||
void BitcoinAmountField::setDisplayUnit(int newUnit)
|
||||
{
|
||||
unit->setValue(newUnit);
|
||||
}
|
||||
60
src/qt/bitcoinamountfield.h
Normal file
60
src/qt/bitcoinamountfield.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef BITCOINFIELD_H
|
||||
#define BITCOINFIELD_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDoubleSpinBox;
|
||||
class QValueComboBox;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/** Widget for entering bitcoin amounts.
|
||||
*/
|
||||
class BitcoinAmountField: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY textChanged USER true)
|
||||
public:
|
||||
explicit BitcoinAmountField(QWidget *parent = 0);
|
||||
|
||||
qint64 value(bool *valid=0) const;
|
||||
void setValue(qint64 value);
|
||||
|
||||
/** Mark current value as invalid in UI. */
|
||||
void setValid(bool valid);
|
||||
/** Perform input validation, mark field as invalid if entered value is not valid. */
|
||||
bool validate();
|
||||
|
||||
/** Change unit used to display amount. */
|
||||
void setDisplayUnit(int unit);
|
||||
|
||||
/** Make field empty and ready for new input. */
|
||||
void clear();
|
||||
|
||||
/** Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907),
|
||||
in these cases we have to set it up manually.
|
||||
*/
|
||||
QWidget *setupTabChain(QWidget *prev);
|
||||
|
||||
signals:
|
||||
void textChanged();
|
||||
|
||||
protected:
|
||||
/** Intercept focus-in event and ',' keypresses */
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
private:
|
||||
QDoubleSpinBox *amount;
|
||||
QValueComboBox *unit;
|
||||
int currentUnit;
|
||||
|
||||
void setText(const QString &text);
|
||||
QString text() const;
|
||||
|
||||
private slots:
|
||||
void unitChanged(int idx);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // BITCOINFIELD_H
|
||||
919
src/qt/bitcoingui.cpp
Normal file
919
src/qt/bitcoingui.cpp
Normal file
@@ -0,0 +1,919 @@
|
||||
/*
|
||||
* Qt4 bitcoin GUI.
|
||||
*
|
||||
* W.J. van der Laan 2011-2012
|
||||
* The Bitcoin Developers 2011-2012
|
||||
* The CasinoCoin Developers 201-2013
|
||||
*/
|
||||
#include "bitcoingui.h"
|
||||
#include "transactiontablemodel.h"
|
||||
#include "addressbookpage.h"
|
||||
#include "sendcoinsdialog.h"
|
||||
#include "signverifymessagedialog.h"
|
||||
#include "optionsdialog.h"
|
||||
#include "aboutdialog.h"
|
||||
#include "clientmodel.h"
|
||||
#include "walletmodel.h"
|
||||
#include "editaddressdialog.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "transactiondescdialog.h"
|
||||
#include "addresstablemodel.h"
|
||||
#include "transactionview.h"
|
||||
#include "overviewpage.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "guiconstants.h"
|
||||
#include "askpassphrasedialog.h"
|
||||
#include "notificator.h"
|
||||
#include "guiutil.h"
|
||||
#include "rpcconsole.h"
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
#include "macdockiconhandler.h"
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QMenuBar>
|
||||
#include <QMenu>
|
||||
#include <QIcon>
|
||||
#include <QTabWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QToolBar>
|
||||
#include <QStatusBar>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressBar>
|
||||
#include <QStackedWidget>
|
||||
#include <QDateTime>
|
||||
#include <QMovie>
|
||||
#include <QFileDialog>
|
||||
#include <QDesktopServices>
|
||||
#include <QTimer>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QUrl>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
BitcoinGUI::BitcoinGUI(QWidget *parent):
|
||||
QMainWindow(parent),
|
||||
clientModel(0),
|
||||
walletModel(0),
|
||||
encryptWalletAction(0),
|
||||
changePassphraseAction(0),
|
||||
aboutQtAction(0),
|
||||
trayIcon(0),
|
||||
notificator(0),
|
||||
rpcConsole(0)
|
||||
{
|
||||
resize(850, 550);
|
||||
setWindowTitle(tr("CasinoCoin") + " - " + tr("Wallet"));
|
||||
#ifndef Q_WS_MAC
|
||||
qApp->setWindowIcon(QIcon(":icons/bitcoin"));
|
||||
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();
|
||||
|
||||
// Create application menu bar
|
||||
createMenuBar();
|
||||
|
||||
// Create the toolbars
|
||||
createToolBars();
|
||||
|
||||
// Create the tray icon (or setup the dock icon)
|
||||
createTrayIcon();
|
||||
|
||||
// Create tabs
|
||||
overviewPage = new OverviewPage();
|
||||
|
||||
transactionsPage = new QWidget(this);
|
||||
QVBoxLayout *vbox = new QVBoxLayout();
|
||||
transactionView = new TransactionView(this);
|
||||
vbox->addWidget(transactionView);
|
||||
transactionsPage->setLayout(vbox);
|
||||
|
||||
addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab);
|
||||
|
||||
receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab);
|
||||
|
||||
sendCoinsPage = new SendCoinsDialog(this);
|
||||
|
||||
signVerifyMessageDialog = new SignVerifyMessageDialog(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(signVerifyMessageDialog);
|
||||
#endif
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
// Create status bar
|
||||
statusBar();
|
||||
|
||||
// Status bar notification icons
|
||||
QFrame *frameBlocks = new QFrame();
|
||||
frameBlocks->setContentsMargins(0,0,0,0);
|
||||
frameBlocks->setMinimumWidth(73);
|
||||
frameBlocks->setMaximumWidth(73);
|
||||
QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
|
||||
frameBlocksLayout->setContentsMargins(3,0,3,0);
|
||||
frameBlocksLayout->setSpacing(3);
|
||||
labelEncryptionIcon = new QLabel();
|
||||
labelConnectionsIcon = new QLabel();
|
||||
labelBlocksIcon = new QLabel();
|
||||
frameBlocksLayout->addStretch();
|
||||
frameBlocksLayout->addWidget(labelEncryptionIcon);
|
||||
frameBlocksLayout->addStretch();
|
||||
frameBlocksLayout->addWidget(labelConnectionsIcon);
|
||||
frameBlocksLayout->addStretch();
|
||||
frameBlocksLayout->addWidget(labelBlocksIcon);
|
||||
frameBlocksLayout->addStretch();
|
||||
|
||||
// Progress bar and label for blocks download
|
||||
progressBarLabel = new QLabel();
|
||||
progressBarLabel->setVisible(false);
|
||||
progressBar = new QProgressBar();
|
||||
progressBar->setAlignment(Qt::AlignCenter);
|
||||
progressBar->setVisible(false);
|
||||
|
||||
statusBar()->addWidget(progressBarLabel);
|
||||
statusBar()->addWidget(progressBar);
|
||||
statusBar()->addPermanentWidget(frameBlocks);
|
||||
|
||||
syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
|
||||
|
||||
// Clicking on a transaction on the overview page simply sends you to transaction history page
|
||||
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage()));
|
||||
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
|
||||
|
||||
// Doubleclicking on a transaction on the transaction history page shows details
|
||||
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
|
||||
|
||||
rpcConsole = new RPCConsole(this);
|
||||
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
|
||||
|
||||
// Clicking on "Verify Message" in the address book sends you to the verify message tab
|
||||
connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString)));
|
||||
// Clicking on "Sign Message" in the receive coins page sends you to the sign message tab
|
||||
connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString)));
|
||||
|
||||
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);
|
||||
|
||||
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 CasinoCoin address"));
|
||||
sendCoinsAction->setCheckable(true);
|
||||
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
|
||||
tabGroup->addAction(sendCoinsAction);
|
||||
|
||||
signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
|
||||
signMessageAction->setToolTip(tr("Sign a message to prove you own a Bitcoin address"));
|
||||
tabGroup->addAction(signMessageAction);
|
||||
|
||||
verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
|
||||
verifyMessageAction->setToolTip(tr("Verify a message to ensure it was signed with a specified Bitcoin address"));
|
||||
tabGroup->addAction(verifyMessageAction);
|
||||
|
||||
#ifdef FIRST_CLASS_MESSAGING
|
||||
firstClassMessagingAction = new QAction(QIcon(":/icons/edit"), tr("S&ignatures"), this);
|
||||
firstClassMessagingAction->setToolTip(signMessageAction->toolTip() + QString(". / ") + verifyMessageAction->toolTip() + QString("."));
|
||||
firstClassMessagingAction->setCheckable(true);
|
||||
tabGroup->addAction(firstClassMessagingAction);
|
||||
#endif
|
||||
|
||||
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(signMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
|
||||
connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
|
||||
#ifdef FIRST_CLASS_MESSAGING
|
||||
connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||
// Always start with the sign message tab for FIRST_CLASS_MESSAGING
|
||||
connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
|
||||
#endif
|
||||
|
||||
quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
|
||||
quitAction->setToolTip(tr("Quit application"));
|
||||
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
|
||||
quitAction->setMenuRole(QAction::QuitRole);
|
||||
aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About CasinoCoin"), this);
|
||||
aboutAction->setToolTip(tr("Show information about CasinoCoin"));
|
||||
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 CasinoCoin"));
|
||||
optionsAction->setMenuRole(QAction::PreferencesRole);
|
||||
toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("Show/Hide &CasinoCoin"), this);
|
||||
toggleHideAction->setToolTip(tr("Show or hide the CasinoCoin window"));
|
||||
exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
|
||||
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"));
|
||||
openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this);
|
||||
openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console"));
|
||||
|
||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
|
||||
connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
|
||||
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
|
||||
connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
|
||||
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(signMessageAction);
|
||||
file->addAction(verifyMessageAction);
|
||||
#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(openRPCConsoleAction);
|
||||
help->addSeparator();
|
||||
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(firstClassMessagingAction);
|
||||
#endif
|
||||
|
||||
QToolBar *toolbar2 = addToolBar(tr("Actions toolbar"));
|
||||
toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
toolbar2->addAction(exportAction);
|
||||
}
|
||||
|
||||
void BitcoinGUI::setClientModel(ClientModel *clientModel)
|
||||
{
|
||||
this->clientModel = clientModel;
|
||||
if(clientModel)
|
||||
{
|
||||
// Replace some strings and icons, when using the testnet
|
||||
if(clientModel->isTestNet())
|
||||
{
|
||||
setWindowTitle(windowTitle() + QString(" ") + tr("[testnet]"));
|
||||
#ifndef Q_WS_MAC
|
||||
qApp->setWindowIcon(QIcon(":icons/bitcoin_testnet"));
|
||||
setWindowIcon(QIcon(":icons/bitcoin_testnet"));
|
||||
#else
|
||||
MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet"));
|
||||
#endif
|
||||
if(trayIcon)
|
||||
{
|
||||
trayIcon->setToolTip(tr("CasinoCoin client") + QString(" ") + tr("[testnet]"));
|
||||
trayIcon->setIcon(QIcon(":/icons/toolbar_testnet"));
|
||||
toggleHideAction->setIcon(QIcon(":/icons/toolbar_testnet"));
|
||||
}
|
||||
|
||||
aboutAction->setIcon(QIcon(":/icons/toolbar_testnet"));
|
||||
}
|
||||
|
||||
// Keep up to date with client
|
||||
setNumConnections(clientModel->getNumConnections());
|
||||
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
|
||||
|
||||
setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers());
|
||||
connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int)));
|
||||
|
||||
// Report errors from network/worker thread
|
||||
connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool)));
|
||||
|
||||
rpcConsole->setClientModel(clientModel);
|
||||
addressBookPage->setOptionsModel(clientModel->getOptionsModel());
|
||||
receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
|
||||
}
|
||||
}
|
||||
|
||||
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)));
|
||||
|
||||
// Put transaction list in tabs
|
||||
transactionView->setModel(walletModel);
|
||||
|
||||
overviewPage->setModel(walletModel);
|
||||
addressBookPage->setModel(walletModel->getAddressTableModel());
|
||||
receiveCoinsPage->setModel(walletModel->getAddressTableModel());
|
||||
sendCoinsPage->setModel(walletModel);
|
||||
signVerifyMessageDialog->setModel(walletModel);
|
||||
|
||||
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)));
|
||||
|
||||
// Ask for passphrase if needed
|
||||
connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
|
||||
}
|
||||
}
|
||||
|
||||
void BitcoinGUI::createTrayIcon()
|
||||
{
|
||||
QMenu *trayIconMenu;
|
||||
#ifndef Q_WS_MAC
|
||||
trayIcon = new QSystemTrayIcon(this);
|
||||
trayIconMenu = new QMenu(this);
|
||||
trayIcon->setContextMenu(trayIconMenu);
|
||||
trayIcon->setToolTip(tr("CasinoCoin 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();
|
||||
trayIconMenu = dockIconHandler->dockMenu();
|
||||
#endif
|
||||
|
||||
// Configuration of the tray icon (or dock icon) icon menu
|
||||
trayIconMenu->addAction(toggleHideAction);
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(sendCoinsAction);
|
||||
trayIconMenu->addAction(receiveCoinsAction);
|
||||
#ifndef FIRST_CLASS_MESSAGING
|
||||
trayIconMenu->addSeparator();
|
||||
#endif
|
||||
trayIconMenu->addAction(signMessageAction);
|
||||
trayIconMenu->addAction(verifyMessageAction);
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(optionsAction);
|
||||
trayIconMenu->addAction(openRPCConsoleAction);
|
||||
#ifndef Q_WS_MAC // This is built-in on Mac
|
||||
trayIconMenu->addSeparator();
|
||||
trayIconMenu->addAction(quitAction);
|
||||
#endif
|
||||
|
||||
notificator = new Notificator(qApp->applicationName(), trayIcon);
|
||||
}
|
||||
|
||||
#ifndef Q_WS_MAC
|
||||
void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||
{
|
||||
if(reason == QSystemTrayIcon::Trigger)
|
||||
{
|
||||
// Click on system tray icon triggers "show/hide CasinoCoin"
|
||||
toggleHideAction->trigger();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void BitcoinGUI::optionsClicked()
|
||||
{
|
||||
if(!clientModel || !clientModel->getOptionsModel())
|
||||
return;
|
||||
OptionsDialog dlg;
|
||||
dlg.setModel(clientModel->getOptionsModel());
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void BitcoinGUI::aboutClicked()
|
||||
{
|
||||
AboutDialog dlg;
|
||||
dlg.setModel(clientModel);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void BitcoinGUI::setNumConnections(int count)
|
||||
{
|
||||
QString icon;
|
||||
switch(count)
|
||||
{
|
||||
case 0: icon = ":/icons/connect_0"; break;
|
||||
case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
|
||||
case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
|
||||
case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
|
||||
default: icon = ":/icons/connect_4"; break;
|
||||
}
|
||||
labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
|
||||
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to CasinoCoin network", "", count));
|
||||
}
|
||||
|
||||
void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
QString tooltip;
|
||||
|
||||
if(count < nTotalBlocks)
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
tooltip = tr("Current difficulty is %1.").arg(clientModel->GetDifficulty()) + QString("<br>") + tooltip;
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QDateTime lastBlockDate = clientModel->getLastBlockDate();
|
||||
int secs = lastBlockDate.secsTo(now);
|
||||
QString text;
|
||||
|
||||
// Represent time from last generated block in human readable text
|
||||
if(secs <= 0)
|
||||
{
|
||||
// Fully up to date. Leave text empty.
|
||||
}
|
||||
else if(secs < 60)
|
||||
{
|
||||
text = tr("%n second(s) ago","",secs);
|
||||
}
|
||||
else if(secs < 60*60)
|
||||
{
|
||||
text = tr("%n minute(s) ago","",secs/60);
|
||||
}
|
||||
else if(secs < 24*60*60)
|
||||
{
|
||||
text = tr("%n hour(s) ago","",secs/(60*60));
|
||||
}
|
||||
else
|
||||
{
|
||||
text = tr("%n day(s) ago","",secs/(60*60*24));
|
||||
}
|
||||
|
||||
// Set icon state: spinning if catching up, tick otherwise
|
||||
if(secs < 90*60 && count >= nTotalBlocks)
|
||||
{
|
||||
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
|
||||
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
||||
|
||||
overviewPage->showOutOfSyncWarning(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
|
||||
labelBlocksIcon->setMovie(syncIconMovie);
|
||||
syncIconMovie->start();
|
||||
|
||||
overviewPage->showOutOfSyncWarning(true);
|
||||
}
|
||||
|
||||
if(!text.isEmpty())
|
||||
{
|
||||
tooltip += QString("<br>");
|
||||
tooltip += tr("Last received block was generated %1.").arg(text);
|
||||
}
|
||||
|
||||
// Don't word-wrap this (fixed-width) tooltip
|
||||
tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
|
||||
|
||||
labelBlocksIcon->setToolTip(tooltip);
|
||||
progressBarLabel->setToolTip(tooltip);
|
||||
progressBar->setToolTip(tooltip);
|
||||
}
|
||||
|
||||
void BitcoinGUI::error(const QString &title, const QString &message, bool modal)
|
||||
{
|
||||
// Report errors from network/worker thread
|
||||
if(modal)
|
||||
{
|
||||
QMessageBox::critical(this, title, message, QMessageBox::Ok, QMessageBox::Ok);
|
||||
} else {
|
||||
notificator->notify(Notificator::Critical, title, message);
|
||||
}
|
||||
}
|
||||
|
||||
void BitcoinGUI::changeEvent(QEvent *e)
|
||||
{
|
||||
QMainWindow::changeEvent(e);
|
||||
#ifndef Q_WS_MAC // Ignored on Mac
|
||||
if(e->type() == QEvent::WindowStateChange)
|
||||
{
|
||||
if(clientModel && clientModel->getOptionsModel()->getMinimizeToTray())
|
||||
{
|
||||
QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
|
||||
if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
|
||||
{
|
||||
QTimer::singleShot(0, this, SLOT(hide()));
|
||||
e->ignore();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BitcoinGUI::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if(clientModel)
|
||||
{
|
||||
#ifndef Q_WS_MAC // Ignored on Mac
|
||||
if(!clientModel->getOptionsModel()->getMinimizeToTray() &&
|
||||
!clientModel->getOptionsModel()->getMinimizeOnClose())
|
||||
{
|
||||
qApp->quit();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
|
||||
{
|
||||
QString strMessage =
|
||||
tr("This transaction is over the size limit. You can still send it for a fee of %1, "
|
||||
"which goes to the nodes that process your transaction and helps to support the network. "
|
||||
"Do you want to pay the fee?").arg(
|
||||
BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired));
|
||||
QMessageBox::StandardButton retval = QMessageBox::question(
|
||||
this, tr("Confirm transaction fee"), strMessage,
|
||||
QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes);
|
||||
*payFee = (retval == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
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();
|
||||
if(!clientModel->inInitialBlockDownload())
|
||||
{
|
||||
// On new transaction, make an info balloon
|
||||
// Unless the initial block download is in progress, to prevent balloon-spam
|
||||
QString date = ttm->index(start, TransactionTableModel::Date, parent)
|
||||
.data().toString();
|
||||
QString type = ttm->index(start, TransactionTableModel::Type, parent)
|
||||
.data().toString();
|
||||
QString address = ttm->index(start, TransactionTableModel::ToAddress, parent)
|
||||
.data().toString();
|
||||
QIcon icon = qvariant_cast<QIcon>(ttm->index(start,
|
||||
TransactionTableModel::ToAddress, parent)
|
||||
.data(Qt::DecorationRole));
|
||||
|
||||
notificator->notify(Notificator::Information,
|
||||
(amount)<0 ? tr("Sent transaction") :
|
||||
tr("Incoming transaction"),
|
||||
tr("Date: %1\n"
|
||||
"Amount: %2\n"
|
||||
"Type: %3\n"
|
||||
"Address: %4\n")
|
||||
.arg(date)
|
||||
.arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true))
|
||||
.arg(type)
|
||||
.arg(address), icon);
|
||||
}
|
||||
}
|
||||
|
||||
void BitcoinGUI::gotoOverviewPage()
|
||||
{
|
||||
overviewAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(overviewPage);
|
||||
|
||||
exportAction->setEnabled(false);
|
||||
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
|
||||
}
|
||||
|
||||
void BitcoinGUI::gotoHistoryPage()
|
||||
{
|
||||
historyAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(transactionsPage);
|
||||
|
||||
exportAction->setEnabled(true);
|
||||
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
|
||||
connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked()));
|
||||
}
|
||||
|
||||
void BitcoinGUI::gotoAddressBookPage()
|
||||
{
|
||||
addressBookAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(addressBookPage);
|
||||
|
||||
exportAction->setEnabled(true);
|
||||
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
|
||||
connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked()));
|
||||
}
|
||||
|
||||
void BitcoinGUI::gotoReceiveCoinsPage()
|
||||
{
|
||||
receiveCoinsAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(receiveCoinsPage);
|
||||
|
||||
exportAction->setEnabled(true);
|
||||
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
|
||||
connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked()));
|
||||
}
|
||||
|
||||
void BitcoinGUI::gotoSendCoinsPage()
|
||||
{
|
||||
sendCoinsAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(sendCoinsPage);
|
||||
|
||||
exportAction->setEnabled(false);
|
||||
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
|
||||
}
|
||||
|
||||
void BitcoinGUI::gotoSignMessageTab(QString addr)
|
||||
{
|
||||
#ifdef FIRST_CLASS_MESSAGING
|
||||
firstClassMessagingAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(signVerifyMessageDialog);
|
||||
|
||||
exportAction->setEnabled(false);
|
||||
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
|
||||
|
||||
signVerifyMessageDialog->showTab_SM(false);
|
||||
#else
|
||||
// call show() in showTab_SM()
|
||||
signVerifyMessageDialog->showTab_SM(true);
|
||||
#endif
|
||||
|
||||
if(!addr.isEmpty())
|
||||
signVerifyMessageDialog->setAddress_SM(addr);
|
||||
}
|
||||
|
||||
void BitcoinGUI::gotoVerifyMessageTab(QString addr)
|
||||
{
|
||||
#ifdef FIRST_CLASS_MESSAGING
|
||||
firstClassMessagingAction->setChecked(true);
|
||||
centralWidget->setCurrentWidget(signVerifyMessageDialog);
|
||||
|
||||
exportAction->setEnabled(false);
|
||||
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
|
||||
|
||||
signVerifyMessageDialog->showTab_VM(false);
|
||||
#else
|
||||
// call show() in showTab_VM()
|
||||
signVerifyMessageDialog->showTab_VM(true);
|
||||
#endif
|
||||
|
||||
if(!addr.isEmpty())
|
||||
signVerifyMessageDialog->setAddress_VM(addr);
|
||||
}
|
||||
|
||||
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
// Accept only URIs
|
||||
if(event->mimeData()->hasUrls())
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void BitcoinGUI::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if(event->mimeData()->hasUrls())
|
||||
{
|
||||
int nValidUrisFound = 0;
|
||||
QList<QUrl> uris = event->mimeData()->urls();
|
||||
foreach(const QUrl &uri, uris)
|
||||
{
|
||||
if (sendCoinsPage->handleURI(uri.toString()))
|
||||
nValidUrisFound++;
|
||||
}
|
||||
|
||||
// if valid URIs were found
|
||||
if (nValidUrisFound)
|
||||
gotoSendCoinsPage();
|
||||
else
|
||||
notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid CasinoCoin address or malformed URI parameters."));
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void BitcoinGUI::handleURI(QString strURI)
|
||||
{
|
||||
// URI has to be valid
|
||||
if (sendCoinsPage->handleURI(strURI))
|
||||
{
|
||||
showNormalIfMinimized();
|
||||
gotoSendCoinsPage();
|
||||
}
|
||||
else
|
||||
notificator->notify(Notificator::Warning, tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid CasinoCoin address or malformed URI parameters."));
|
||||
}
|
||||
|
||||
void BitcoinGUI::setEncryptionStatus(int status)
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
case WalletModel::Unencrypted:
|
||||
labelEncryptionIcon->hide();
|
||||
encryptWalletAction->setChecked(false);
|
||||
changePassphraseAction->setEnabled(false);
|
||||
encryptWalletAction->setEnabled(true);
|
||||
break;
|
||||
case WalletModel::Unlocked:
|
||||
labelEncryptionIcon->show();
|
||||
labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
|
||||
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
|
||||
encryptWalletAction->setChecked(true);
|
||||
changePassphraseAction->setEnabled(true);
|
||||
encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
|
||||
break;
|
||||
case WalletModel::Locked:
|
||||
labelEncryptionIcon->show();
|
||||
labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
|
||||
labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
|
||||
encryptWalletAction->setChecked(true);
|
||||
changePassphraseAction->setEnabled(true);
|
||||
encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BitcoinGUI::encryptWallet(bool status)
|
||||
{
|
||||
if(!walletModel)
|
||||
return;
|
||||
AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
|
||||
AskPassphraseDialog::Decrypt, this);
|
||||
dlg.setModel(walletModel);
|
||||
dlg.exec();
|
||||
|
||||
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);
|
||||
dlg.setModel(walletModel);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void BitcoinGUI::unlockWallet()
|
||||
{
|
||||
if(!walletModel)
|
||||
return;
|
||||
// Unlock wallet when requested by wallet model
|
||||
if(walletModel->getEncryptionStatus() == WalletModel::Locked)
|
||||
{
|
||||
AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
|
||||
dlg.setModel(walletModel);
|
||||
dlg.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
||||
{
|
||||
// activateWindow() (sometimes) helps with keyboard focus on Windows
|
||||
if (isHidden())
|
||||
{
|
||||
show();
|
||||
activateWindow();
|
||||
}
|
||||
else if (isMinimized())
|
||||
{
|
||||
showNormal();
|
||||
activateWindow();
|
||||
}
|
||||
else if (GUIUtil::isObscured(this))
|
||||
{
|
||||
raise();
|
||||
activateWindow();
|
||||
}
|
||||
else if(fToggleHidden)
|
||||
hide();
|
||||
}
|
||||
|
||||
void BitcoinGUI::toggleHidden()
|
||||
{
|
||||
showNormalIfMinimized(true);
|
||||
}
|
||||
180
src/qt/bitcoingui.h
Normal file
180
src/qt/bitcoingui.h
Normal file
@@ -0,0 +1,180 @@
|
||||
#ifndef BITCOINGUI_H
|
||||
#define BITCOINGUI_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
class TransactionTableModel;
|
||||
class ClientModel;
|
||||
class WalletModel;
|
||||
class TransactionView;
|
||||
class OverviewPage;
|
||||
class AddressBookPage;
|
||||
class SendCoinsDialog;
|
||||
class SignVerifyMessageDialog;
|
||||
class Notificator;
|
||||
class RPCConsole;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QTableView;
|
||||
class QAbstractItemModel;
|
||||
class QModelIndex;
|
||||
class QProgressBar;
|
||||
class QStackedWidget;
|
||||
class QUrl;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/**
|
||||
Bitcoin GUI main class. This class represents the main window of the Bitcoin UI. It communicates with both the client and
|
||||
wallet models to give the user an up-to-date view of the current core state.
|
||||
*/
|
||||
class BitcoinGUI : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BitcoinGUI(QWidget *parent = 0);
|
||||
~BitcoinGUI();
|
||||
|
||||
/** Set the client model.
|
||||
The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic.
|
||||
*/
|
||||
void setClientModel(ClientModel *clientModel);
|
||||
/** Set the wallet model.
|
||||
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
||||
functionality.
|
||||
*/
|
||||
void setWalletModel(WalletModel *walletModel);
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
|
||||
private:
|
||||
ClientModel *clientModel;
|
||||
WalletModel *walletModel;
|
||||
|
||||
QStackedWidget *centralWidget;
|
||||
|
||||
OverviewPage *overviewPage;
|
||||
QWidget *transactionsPage;
|
||||
AddressBookPage *addressBookPage;
|
||||
AddressBookPage *receiveCoinsPage;
|
||||
SendCoinsDialog *sendCoinsPage;
|
||||
SignVerifyMessageDialog *signVerifyMessageDialog;
|
||||
|
||||
QLabel *labelEncryptionIcon;
|
||||
QLabel *labelConnectionsIcon;
|
||||
QLabel *labelBlocksIcon;
|
||||
QLabel *progressBarLabel;
|
||||
QProgressBar *progressBar;
|
||||
|
||||
QMenuBar *appMenuBar;
|
||||
QAction *overviewAction;
|
||||
QAction *historyAction;
|
||||
QAction *quitAction;
|
||||
QAction *sendCoinsAction;
|
||||
QAction *addressBookAction;
|
||||
QAction *signMessageAction;
|
||||
QAction *verifyMessageAction;
|
||||
QAction *firstClassMessagingAction;
|
||||
QAction *aboutAction;
|
||||
QAction *receiveCoinsAction;
|
||||
QAction *optionsAction;
|
||||
QAction *toggleHideAction;
|
||||
QAction *exportAction;
|
||||
QAction *encryptWalletAction;
|
||||
QAction *backupWalletAction;
|
||||
QAction *changePassphraseAction;
|
||||
QAction *aboutQtAction;
|
||||
QAction *openRPCConsoleAction;
|
||||
|
||||
QSystemTrayIcon *trayIcon;
|
||||
Notificator *notificator;
|
||||
TransactionView *transactionView;
|
||||
RPCConsole *rpcConsole;
|
||||
|
||||
QMovie *syncIconMovie;
|
||||
|
||||
/** Create the main UI actions. */
|
||||
void createActions();
|
||||
/** Create the menu bar and submenus. */
|
||||
void createMenuBar();
|
||||
/** Create the toolbars */
|
||||
void createToolBars();
|
||||
/** Create system tray (notification) icon */
|
||||
void createTrayIcon();
|
||||
|
||||
public slots:
|
||||
/** Set number of connections shown in the UI */
|
||||
void setNumConnections(int count);
|
||||
/** Set number of blocks shown in the UI */
|
||||
void setNumBlocks(int count, int countOfPeers);
|
||||
/** Set the encryption status as shown in the UI.
|
||||
@param[in] status current encryption status
|
||||
@see WalletModel::EncryptionStatus
|
||||
*/
|
||||
void setEncryptionStatus(int status);
|
||||
|
||||
/** Notify the user of an error in the network or transaction handling code. */
|
||||
void error(const QString &title, const QString &message, bool modal);
|
||||
/** Asks the user whether to pay the transaction fee or to cancel the transaction.
|
||||
It is currently not possible to pass a return value to another thread through
|
||||
BlockingQueuedConnection, so an indirected pointer is used.
|
||||
http://bugreports.qt.nokia.com/browse/QTBUG-10440
|
||||
|
||||
@param[in] nFeeRequired the required fee
|
||||
@param[out] payFee true to pay the fee, false to not pay the fee
|
||||
*/
|
||||
void askFee(qint64 nFeeRequired, bool *payFee);
|
||||
void handleURI(QString strURI);
|
||||
|
||||
private slots:
|
||||
/** Switch to overview (home) page */
|
||||
void gotoOverviewPage();
|
||||
/** Switch to history (transactions) page */
|
||||
void gotoHistoryPage();
|
||||
/** Switch to address book page */
|
||||
void gotoAddressBookPage();
|
||||
/** Switch to receive coins page */
|
||||
void gotoReceiveCoinsPage();
|
||||
/** Switch to send coins page */
|
||||
void gotoSendCoinsPage();
|
||||
|
||||
/** Show Sign/Verify Message dialog and switch to sign message tab */
|
||||
void gotoSignMessageTab(QString addr = "");
|
||||
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
||||
void gotoVerifyMessageTab(QString addr = "");
|
||||
|
||||
/** Show configuration dialog */
|
||||
void optionsClicked();
|
||||
/** Show about dialog */
|
||||
void aboutClicked();
|
||||
#ifndef Q_WS_MAC
|
||||
/** Handle tray icon clicked */
|
||||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
#endif
|
||||
/** Show incoming transaction notification for new transactions.
|
||||
|
||||
The new items are those between start and end inclusive, under the given parent item.
|
||||
*/
|
||||
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 */
|
||||
void unlockWallet();
|
||||
|
||||
/** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
|
||||
void showNormalIfMinimized(bool fToggleHidden = false);
|
||||
/** simply calls showNormalIfMinimized(true) for use in SLOT() macro */
|
||||
void toggleHidden();
|
||||
};
|
||||
|
||||
#endif
|
||||
148
src/qt/bitcoinstrings.cpp
Normal file
148
src/qt/bitcoinstrings.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include <QtGlobal>
|
||||
// Automatically generated by extract_strings.py
|
||||
#ifdef __GNUC__
|
||||
#define UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
static const char UNUSED *bitcoin_strings[] = {
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"%s, you must set a rpcpassword in the configuration file:\n"
|
||||
" %s\n"
|
||||
"It is recommended you use the following random password:\n"
|
||||
"rpcuser=casinocoinrpc\n"
|
||||
"rpcpassword=%s\n"
|
||||
"(you do not need to remember this password)\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions.\n"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:"
|
||||
"@STRENGTH)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Cannot obtain a lock on data directory %s. CasinoCoin is probably already "
|
||||
"running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Detach block and address databases. Increases shutdown time (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: The transaction was rejected. This might happen if some of the coins "
|
||||
"in your wallet were already spent, such as if you used a copy of wallet.dat "
|
||||
"and coins were spent in the copy but not marked as spent here."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Error: This transaction requires a transaction fee of at least %s because of "
|
||||
"its amount, complexity, or use of recently received funds "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Execute command when the best block changes (%s in cmd is replaced by block "
|
||||
"hash)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Number of seconds to keep misbehaving peers from reconnecting (default: "
|
||||
"86400)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Unable to bind to %s on this computer. CasinoCoin is probably already running."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: -paytxfee is set very high. This is the transaction fee you will "
|
||||
"pay if you send a transaction."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"Warning: Please check that your computer's date and time are correct. If "
|
||||
"your clock is wrong CasinoCoin will not work properly."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"You must set rpcpassword=<password> in the configuration file:\n"
|
||||
"%s\n"
|
||||
"If the file does not exist, create it with owner-readable-only file "
|
||||
"permissions."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", ""
|
||||
"\n"
|
||||
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1 if no -proxy or -connect)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "An error occured while setting up the RPC port %i for listening: %s"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Bind to given address. Use [host]:port notation for IPv6"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "CasinoCoin version"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "CasinoCoin"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot downgrade wallet"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot initialize keypool"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks proxy"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of CasinoCoin"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction "),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Error: could not start node"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using DNS lookup (default: 1 unless -connect)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using internet relay chat (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -tor address: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "List commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 9332)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 9333 or testnet: 19333)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4, IPv6 or Tor)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Output extra debugging information. Implies all other -debug* options"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Output extra network debugging information"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Select the version of socks proxy to use (4-5, default: 5)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or casinocoind"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to debugger"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (default: 25)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set database disk log size in megabytes (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: casinocoin.conf)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: casinocoind.pid)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %d, %s)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown -socks proxy version requested: %i"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Upgrade wallet to latest format"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 0)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default: 1 when listening)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use proxy to reach tor hidden services (default: same as -proxy)"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart CasinoCoin to complete"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low"),
|
||||
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: this version is obsolete, upgrade required"),
|
||||
};
|
||||
181
src/qt/bitcoinunits.cpp
Normal file
181
src/qt/bitcoinunits.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
#include "bitcoinunits.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
BitcoinUnits::BitcoinUnits(QObject *parent):
|
||||
QAbstractListModel(parent),
|
||||
unitlist(availableUnits())
|
||||
{
|
||||
}
|
||||
|
||||
QList<BitcoinUnits::Unit> BitcoinUnits::availableUnits()
|
||||
{
|
||||
QList<BitcoinUnits::Unit> unitlist;
|
||||
unitlist.append(BTC);
|
||||
unitlist.append(mBTC);
|
||||
unitlist.append(uBTC);
|
||||
return unitlist;
|
||||
}
|
||||
|
||||
bool BitcoinUnits::valid(int unit)
|
||||
{
|
||||
switch(unit)
|
||||
{
|
||||
case BTC:
|
||||
case mBTC:
|
||||
case uBTC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString BitcoinUnits::name(int unit)
|
||||
{
|
||||
switch(unit)
|
||||
{
|
||||
case BTC: return QString("CSC");
|
||||
case mBTC: return QString("mCSC");
|
||||
case uBTC: return QString::fromUtf8("μCSC");
|
||||
default: return QString("???");
|
||||
}
|
||||
}
|
||||
|
||||
QString BitcoinUnits::description(int unit)
|
||||
{
|
||||
switch(unit)
|
||||
{
|
||||
case BTC: return QString("CasinoCoins");
|
||||
case mBTC: return QString("Milli-CasinoCoins (1 / 1,000)");
|
||||
case uBTC: return QString("Micro-CasinoCoins (1 / 1,000,000)");
|
||||
default: return QString("???");
|
||||
}
|
||||
}
|
||||
|
||||
qint64 BitcoinUnits::factor(int unit)
|
||||
{
|
||||
switch(unit)
|
||||
{
|
||||
case BTC: return 100000000;
|
||||
case mBTC: return 100000;
|
||||
case uBTC: return 100;
|
||||
default: return 100000000;
|
||||
}
|
||||
}
|
||||
|
||||
int BitcoinUnits::amountDigits(int unit)
|
||||
{
|
||||
switch(unit)
|
||||
{
|
||||
case BTC: return 8; // 21,000,000 (# digits, without commas)
|
||||
case mBTC: return 11; // 21,000,000,000
|
||||
case uBTC: return 14; // 21,000,000,000,000
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int BitcoinUnits::decimals(int unit)
|
||||
{
|
||||
switch(unit)
|
||||
{
|
||||
case BTC: return 8;
|
||||
case mBTC: return 5;
|
||||
case uBTC: return 2;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
QString BitcoinUnits::format(int unit, qint64 n, bool fPlus)
|
||||
{
|
||||
// Note: not using straight sprintf here because we do NOT want
|
||||
// localized number formatting.
|
||||
if(!valid(unit))
|
||||
return QString(); // Refuse to format invalid unit
|
||||
qint64 coin = factor(unit);
|
||||
int num_decimals = decimals(unit);
|
||||
qint64 n_abs = (n > 0 ? n : -n);
|
||||
qint64 quotient = n_abs / coin;
|
||||
qint64 remainder = n_abs % coin;
|
||||
QString quotient_str = QString::number(quotient);
|
||||
QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
|
||||
|
||||
// Right-trim excess 0's after the decimal point
|
||||
int nTrim = 0;
|
||||
for (int i = remainder_str.size()-1; i>=2 && (remainder_str.at(i) == '0'); --i)
|
||||
++nTrim;
|
||||
remainder_str.chop(nTrim);
|
||||
|
||||
if (n < 0)
|
||||
quotient_str.insert(0, '-');
|
||||
else if (fPlus && n > 0)
|
||||
quotient_str.insert(0, '+');
|
||||
return quotient_str + QString(".") + remainder_str;
|
||||
}
|
||||
|
||||
QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign)
|
||||
{
|
||||
return format(unit, amount, plussign) + QString(" ") + name(unit);
|
||||
}
|
||||
|
||||
bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out)
|
||||
{
|
||||
if(!valid(unit) || value.isEmpty())
|
||||
return false; // Refuse to parse invalid unit or empty string
|
||||
int num_decimals = decimals(unit);
|
||||
QStringList parts = value.split(".");
|
||||
|
||||
if(parts.size() > 2)
|
||||
{
|
||||
return false; // More than one dot
|
||||
}
|
||||
QString whole = parts[0];
|
||||
QString decimals;
|
||||
|
||||
if(parts.size() > 1)
|
||||
{
|
||||
decimals = parts[1];
|
||||
}
|
||||
if(decimals.size() > num_decimals)
|
||||
{
|
||||
return false; // Exceeds max precision
|
||||
}
|
||||
bool ok = false;
|
||||
QString str = whole + decimals.leftJustified(num_decimals, '0');
|
||||
|
||||
if(str.size() > 18)
|
||||
{
|
||||
return false; // Longer numbers will exceed 63 bits
|
||||
}
|
||||
qint64 retvalue = str.toLongLong(&ok);
|
||||
if(val_out)
|
||||
{
|
||||
*val_out = retvalue;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
int BitcoinUnits::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return unitlist.size();
|
||||
}
|
||||
|
||||
QVariant BitcoinUnits::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
int row = index.row();
|
||||
if(row >= 0 && row < unitlist.size())
|
||||
{
|
||||
Unit unit = unitlist.at(row);
|
||||
switch(role)
|
||||
{
|
||||
case Qt::EditRole:
|
||||
case Qt::DisplayRole:
|
||||
return QVariant(name(unit));
|
||||
case Qt::ToolTipRole:
|
||||
return QVariant(description(unit));
|
||||
case UnitRole:
|
||||
return QVariant(static_cast<int>(unit));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
66
src/qt/bitcoinunits.h
Normal file
66
src/qt/bitcoinunits.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef BITCOINUNITS_H
|
||||
#define BITCOINUNITS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
/** Bitcoin unit definitions. Encapsulates parsing and formatting
|
||||
and serves as list model for dropdown selection boxes.
|
||||
*/
|
||||
class BitcoinUnits: public QAbstractListModel
|
||||
{
|
||||
public:
|
||||
explicit BitcoinUnits(QObject *parent);
|
||||
|
||||
/** Bitcoin units.
|
||||
@note Source: https://en.bitcoin.it/wiki/Units . Please add only sensible ones
|
||||
*/
|
||||
enum Unit
|
||||
{
|
||||
BTC,
|
||||
mBTC,
|
||||
uBTC
|
||||
};
|
||||
|
||||
//! @name Static API
|
||||
//! Unit conversion and formatting
|
||||
///@{
|
||||
|
||||
//! Get list of units, for dropdown box
|
||||
static QList<Unit> availableUnits();
|
||||
//! Is unit ID valid?
|
||||
static bool valid(int unit);
|
||||
//! Short name
|
||||
static QString name(int unit);
|
||||
//! Longer description
|
||||
static QString description(int unit);
|
||||
//! Number of Satoshis (1e-8) per unit
|
||||
static qint64 factor(int unit);
|
||||
//! Number of amount digits (to represent max number of coins)
|
||||
static int amountDigits(int unit);
|
||||
//! Number of decimals left
|
||||
static int decimals(int unit);
|
||||
//! Format as string
|
||||
static QString format(int unit, qint64 amount, bool plussign=false);
|
||||
//! Format as string (with unit)
|
||||
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false);
|
||||
//! Parse string to coin amount
|
||||
static bool parse(int unit, const QString &value, qint64 *val_out);
|
||||
///@}
|
||||
|
||||
//! @name AbstractListModel implementation
|
||||
//! List model for unit dropdown selection box.
|
||||
///@{
|
||||
enum RoleIndex {
|
||||
/** Unit identifier */
|
||||
UnitRole = Qt::UserRole
|
||||
};
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
///@}
|
||||
private:
|
||||
QList<BitcoinUnits::Unit> unitlist;
|
||||
};
|
||||
typedef BitcoinUnits::Unit BitcoinUnit;
|
||||
|
||||
#endif // BITCOINUNITS_H
|
||||
209
src/qt/clientmodel.cpp
Normal file
209
src/qt/clientmodel.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#include "clientmodel.h"
|
||||
#include "guiconstants.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "addresstablemodel.h"
|
||||
#include "transactiontablemodel.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "init.h" // for pwalletMain
|
||||
#include "ui_interface.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
|
||||
static const int64 nClientStartupTime = GetTime();
|
||||
|
||||
ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
|
||||
QObject(parent), optionsModel(optionsModel),
|
||||
cachedNumBlocks(0), cachedNumBlocksOfPeers(0), cachedHashrate(0), pollTimer(0)
|
||||
{
|
||||
numBlocksAtStartup = -1;
|
||||
|
||||
pollTimer = new QTimer(this);
|
||||
pollTimer->setInterval(MODEL_UPDATE_DELAY);
|
||||
pollTimer->start();
|
||||
connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
|
||||
|
||||
subscribeToCoreSignals();
|
||||
}
|
||||
|
||||
ClientModel::~ClientModel()
|
||||
{
|
||||
unsubscribeFromCoreSignals();
|
||||
}
|
||||
|
||||
int ClientModel::getNumConnections() const
|
||||
{
|
||||
return vNodes.size();
|
||||
}
|
||||
|
||||
int ClientModel::getNumBlocks() const
|
||||
{
|
||||
return nBestHeight;
|
||||
}
|
||||
|
||||
int ClientModel::getNumBlocksAtStartup()
|
||||
{
|
||||
if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks();
|
||||
return numBlocksAtStartup;
|
||||
}
|
||||
|
||||
int ClientModel::getHashrate() const
|
||||
{
|
||||
if (GetTimeMillis() - nHPSTimerStart > 8000)
|
||||
return (boost::int64_t)0;
|
||||
return (boost::int64_t)dHashesPerSec;
|
||||
}
|
||||
|
||||
// CasinoCoin: copied from bitcoinrpc.cpp.
|
||||
double ClientModel::GetDifficulty() const
|
||||
{
|
||||
// Floating point number that is a multiple of the minimum difficulty,
|
||||
// minimum difficulty = 1.0.
|
||||
|
||||
if (pindexBest == NULL)
|
||||
return 1.0;
|
||||
int nShift = (pindexBest->nBits >> 24) & 0xff;
|
||||
|
||||
double dDiff =
|
||||
(double)0x0000ffff / (double)(pindexBest->nBits & 0x00ffffff);
|
||||
|
||||
while (nShift < 29)
|
||||
{
|
||||
dDiff *= 256.0;
|
||||
nShift++;
|
||||
}
|
||||
while (nShift > 29)
|
||||
{
|
||||
dDiff /= 256.0;
|
||||
nShift--;
|
||||
}
|
||||
|
||||
return dDiff;
|
||||
}
|
||||
|
||||
QDateTime ClientModel::getLastBlockDate() const
|
||||
{
|
||||
return QDateTime::fromTime_t(pindexBest->GetBlockTime());
|
||||
}
|
||||
|
||||
void ClientModel::updateTimer()
|
||||
{
|
||||
// Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
|
||||
// Periodically check and update with a timer.
|
||||
int newNumBlocks = getNumBlocks();
|
||||
int newNumBlocksOfPeers = getNumBlocksOfPeers();
|
||||
|
||||
if(cachedNumBlocks != newNumBlocks || cachedNumBlocksOfPeers != newNumBlocksOfPeers)
|
||||
emit numBlocksChanged(newNumBlocks, newNumBlocksOfPeers);
|
||||
|
||||
cachedNumBlocks = newNumBlocks;
|
||||
cachedNumBlocksOfPeers = newNumBlocksOfPeers;
|
||||
}
|
||||
|
||||
void ClientModel::updateNumConnections(int numConnections)
|
||||
{
|
||||
emit numConnectionsChanged(numConnections);
|
||||
}
|
||||
|
||||
void ClientModel::updateAlert(const QString &hash, int status)
|
||||
{
|
||||
// Show error message notification for new alert
|
||||
if(status == CT_NEW)
|
||||
{
|
||||
uint256 hash_256;
|
||||
hash_256.SetHex(hash.toStdString());
|
||||
CAlert alert = CAlert::getAlertByHash(hash_256);
|
||||
if(!alert.IsNull())
|
||||
{
|
||||
emit error(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false);
|
||||
}
|
||||
}
|
||||
|
||||
// Emit a numBlocksChanged when the status message changes,
|
||||
// so that the view recomputes and updates the status bar.
|
||||
emit numBlocksChanged(getNumBlocks(), getNumBlocksOfPeers());
|
||||
}
|
||||
|
||||
bool ClientModel::isTestNet() const
|
||||
{
|
||||
return fTestNet;
|
||||
}
|
||||
|
||||
bool ClientModel::inInitialBlockDownload() const
|
||||
{
|
||||
return IsInitialBlockDownload();
|
||||
}
|
||||
|
||||
int ClientModel::getNumBlocksOfPeers() const
|
||||
{
|
||||
return GetNumBlocksOfPeers();
|
||||
}
|
||||
|
||||
QString ClientModel::getStatusBarWarnings() const
|
||||
{
|
||||
return QString::fromStdString(GetWarnings("statusbar"));
|
||||
}
|
||||
|
||||
OptionsModel *ClientModel::getOptionsModel()
|
||||
{
|
||||
return optionsModel;
|
||||
}
|
||||
|
||||
QString ClientModel::formatFullVersion() const
|
||||
{
|
||||
return QString::fromStdString(FormatFullVersion());
|
||||
}
|
||||
|
||||
QString ClientModel::formatBuildDate() const
|
||||
{
|
||||
return QString::fromStdString(CLIENT_DATE);
|
||||
}
|
||||
|
||||
QString ClientModel::clientName() const
|
||||
{
|
||||
return QString::fromStdString(CLIENT_NAME);
|
||||
}
|
||||
|
||||
QString ClientModel::formatClientStartupTime() const
|
||||
{
|
||||
return QDateTime::fromTime_t(nClientStartupTime).toString();
|
||||
}
|
||||
|
||||
// Handlers for core signals
|
||||
static void NotifyBlocksChanged(ClientModel *clientmodel)
|
||||
{
|
||||
// This notification is too frequent. Don't trigger a signal.
|
||||
// Don't remove it, though, as it might be useful later.
|
||||
}
|
||||
|
||||
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
|
||||
{
|
||||
// Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections);
|
||||
QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
|
||||
Q_ARG(int, newNumConnections));
|
||||
}
|
||||
|
||||
static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
|
||||
{
|
||||
OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status);
|
||||
QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
|
||||
Q_ARG(QString, QString::fromStdString(hash.GetHex())),
|
||||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
void ClientModel::subscribeToCoreSignals()
|
||||
{
|
||||
// Connect signals to client
|
||||
uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this));
|
||||
uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
|
||||
uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
|
||||
}
|
||||
|
||||
void ClientModel::unsubscribeFromCoreSignals()
|
||||
{
|
||||
// Disconnect signals from client
|
||||
uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this));
|
||||
uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
|
||||
uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
|
||||
}
|
||||
75
src/qt/clientmodel.h
Normal file
75
src/qt/clientmodel.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef CLIENTMODEL_H
|
||||
#define CLIENTMODEL_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class OptionsModel;
|
||||
class AddressTableModel;
|
||||
class TransactionTableModel;
|
||||
class CWallet;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDateTime;
|
||||
class QTimer;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/** Model for Bitcoin network client. */
|
||||
class ClientModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0);
|
||||
~ClientModel();
|
||||
|
||||
OptionsModel *getOptionsModel();
|
||||
|
||||
int getNumConnections() const;
|
||||
int getNumBlocks() const;
|
||||
int getNumBlocksAtStartup();
|
||||
|
||||
int getHashrate() const;
|
||||
double GetDifficulty() const;
|
||||
|
||||
QDateTime getLastBlockDate() const;
|
||||
|
||||
//! Return true if client connected to testnet
|
||||
bool isTestNet() const;
|
||||
//! Return true if core is doing initial block download
|
||||
bool inInitialBlockDownload() const;
|
||||
//! Return conservative estimate of total number of blocks, or 0 if unknown
|
||||
int getNumBlocksOfPeers() const;
|
||||
//! Return warnings to be displayed in status bar
|
||||
QString getStatusBarWarnings() const;
|
||||
|
||||
QString formatFullVersion() const;
|
||||
QString formatBuildDate() const;
|
||||
QString clientName() const;
|
||||
QString formatClientStartupTime() const;
|
||||
|
||||
private:
|
||||
OptionsModel *optionsModel;
|
||||
|
||||
int cachedNumBlocks;
|
||||
int cachedNumBlocksOfPeers;
|
||||
int cachedHashrate;
|
||||
|
||||
int numBlocksAtStartup;
|
||||
|
||||
QTimer *pollTimer;
|
||||
|
||||
void subscribeToCoreSignals();
|
||||
void unsubscribeFromCoreSignals();
|
||||
signals:
|
||||
void numConnectionsChanged(int count);
|
||||
void numBlocksChanged(int count, int countOfPeers);
|
||||
|
||||
//! Asynchronous error notification
|
||||
void error(const QString &title, const QString &message, bool modal);
|
||||
|
||||
public slots:
|
||||
void updateTimer();
|
||||
void updateNumConnections(int numConnections);
|
||||
void updateAlert(const QString &hash, int status);
|
||||
};
|
||||
|
||||
#endif // CLIENTMODEL_H
|
||||
88
src/qt/csvmodelwriter.cpp
Normal file
88
src/qt/csvmodelwriter.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include "csvmodelwriter.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) :
|
||||
QObject(parent),
|
||||
filename(filename), model(0)
|
||||
{
|
||||
}
|
||||
|
||||
void CSVModelWriter::setModel(const QAbstractItemModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
}
|
||||
|
||||
void CSVModelWriter::addColumn(const QString &title, int column, int role)
|
||||
{
|
||||
Column col;
|
||||
col.title = title;
|
||||
col.column = column;
|
||||
col.role = role;
|
||||
|
||||
columns.append(col);
|
||||
}
|
||||
|
||||
static void writeValue(QTextStream &f, const QString &value)
|
||||
{
|
||||
QString escaped = value;
|
||||
escaped.replace('"', "\"\"");
|
||||
f << "\"" << escaped << "\"";
|
||||
}
|
||||
|
||||
static void writeSep(QTextStream &f)
|
||||
{
|
||||
f << ",";
|
||||
}
|
||||
|
||||
static void writeNewline(QTextStream &f)
|
||||
{
|
||||
f << "\n";
|
||||
}
|
||||
|
||||
bool CSVModelWriter::write()
|
||||
{
|
||||
QFile file(filename);
|
||||
if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
return false;
|
||||
QTextStream out(&file);
|
||||
|
||||
int numRows = 0;
|
||||
if(model)
|
||||
{
|
||||
numRows = model->rowCount();
|
||||
}
|
||||
|
||||
// Header row
|
||||
for(int i=0; i<columns.size(); ++i)
|
||||
{
|
||||
if(i!=0)
|
||||
{
|
||||
writeSep(out);
|
||||
}
|
||||
writeValue(out, columns[i].title);
|
||||
}
|
||||
writeNewline(out);
|
||||
|
||||
// Data rows
|
||||
for(int j=0; j<numRows; ++j)
|
||||
{
|
||||
for(int i=0; i<columns.size(); ++i)
|
||||
{
|
||||
if(i!=0)
|
||||
{
|
||||
writeSep(out);
|
||||
}
|
||||
QVariant data = model->index(j, columns[i].column).data(columns[i].role);
|
||||
writeValue(out, data.toString());
|
||||
}
|
||||
writeNewline(out);
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
return file.error() == QFile::NoError;
|
||||
}
|
||||
|
||||
46
src/qt/csvmodelwriter.h
Normal file
46
src/qt/csvmodelwriter.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef CSVMODELWRITER_H
|
||||
#define CSVMODELWRITER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAbstractItemModel;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/** Export a Qt table model to a CSV file. This is useful for analyzing or post-processing the data in
|
||||
a spreadsheet.
|
||||
*/
|
||||
class CSVModelWriter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CSVModelWriter(const QString &filename, QObject *parent = 0);
|
||||
|
||||
void setModel(const QAbstractItemModel *model);
|
||||
void addColumn(const QString &title, int column, int role=Qt::EditRole);
|
||||
|
||||
/** Perform export of the model to CSV.
|
||||
@returns true on success, false otherwise
|
||||
*/
|
||||
bool write();
|
||||
|
||||
private:
|
||||
QString filename;
|
||||
const QAbstractItemModel *model;
|
||||
|
||||
struct Column
|
||||
{
|
||||
QString title;
|
||||
int column;
|
||||
int role;
|
||||
};
|
||||
QList<Column> columns;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // CSVMODELWRITER_H
|
||||
128
src/qt/editaddressdialog.cpp
Normal file
128
src/qt/editaddressdialog.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "editaddressdialog.h"
|
||||
#include "ui_editaddressdialog.h"
|
||||
#include "addresstablemodel.h"
|
||||
#include "guiutil.h"
|
||||
|
||||
#include <QDataWidgetMapper>
|
||||
#include <QMessageBox>
|
||||
|
||||
EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::EditAddressDialog), mapper(0), mode(mode), model(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
GUIUtil::setupAddressWidget(ui->addressEdit, this);
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case NewReceivingAddress:
|
||||
setWindowTitle(tr("New receiving address"));
|
||||
ui->addressEdit->setEnabled(false);
|
||||
break;
|
||||
case NewSendingAddress:
|
||||
setWindowTitle(tr("New sending address"));
|
||||
break;
|
||||
case EditReceivingAddress:
|
||||
setWindowTitle(tr("Edit receiving address"));
|
||||
ui->addressEdit->setDisabled(true);
|
||||
break;
|
||||
case EditSendingAddress:
|
||||
setWindowTitle(tr("Edit sending address"));
|
||||
break;
|
||||
}
|
||||
|
||||
mapper = new QDataWidgetMapper(this);
|
||||
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
||||
}
|
||||
|
||||
EditAddressDialog::~EditAddressDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void EditAddressDialog::setModel(AddressTableModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
mapper->setModel(model);
|
||||
mapper->addMapping(ui->labelEdit, AddressTableModel::Label);
|
||||
mapper->addMapping(ui->addressEdit, AddressTableModel::Address);
|
||||
}
|
||||
|
||||
void EditAddressDialog::loadRow(int row)
|
||||
{
|
||||
mapper->setCurrentIndex(row);
|
||||
}
|
||||
|
||||
bool EditAddressDialog::saveCurrentRow()
|
||||
{
|
||||
if(!model)
|
||||
return false;
|
||||
switch(mode)
|
||||
{
|
||||
case NewReceivingAddress:
|
||||
case NewSendingAddress:
|
||||
address = model->addRow(
|
||||
mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive,
|
||||
ui->labelEdit->text(),
|
||||
ui->addressEdit->text());
|
||||
break;
|
||||
case EditReceivingAddress:
|
||||
case EditSendingAddress:
|
||||
if(mapper->submit())
|
||||
{
|
||||
address = ui->addressEdit->text();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return !address.isEmpty();
|
||||
}
|
||||
|
||||
void EditAddressDialog::accept()
|
||||
{
|
||||
if(!model)
|
||||
return;
|
||||
if(!saveCurrentRow())
|
||||
{
|
||||
switch(model->getEditStatus())
|
||||
{
|
||||
case AddressTableModel::DUPLICATE_ADDRESS:
|
||||
QMessageBox::warning(this, windowTitle(),
|
||||
tr("The entered address \"%1\" is already in the address book.").arg(ui->addressEdit->text()),
|
||||
QMessageBox::Ok, QMessageBox::Ok);
|
||||
break;
|
||||
case AddressTableModel::INVALID_ADDRESS:
|
||||
QMessageBox::warning(this, windowTitle(),
|
||||
tr("The entered address \"%1\" is not a valid CasinoCoin address.").arg(ui->addressEdit->text()),
|
||||
QMessageBox::Ok, QMessageBox::Ok);
|
||||
return;
|
||||
case AddressTableModel::WALLET_UNLOCK_FAILURE:
|
||||
QMessageBox::critical(this, windowTitle(),
|
||||
tr("Could not unlock wallet."),
|
||||
QMessageBox::Ok, QMessageBox::Ok);
|
||||
return;
|
||||
case AddressTableModel::KEY_GENERATION_FAILURE:
|
||||
QMessageBox::critical(this, windowTitle(),
|
||||
tr("New key generation failed."),
|
||||
QMessageBox::Ok, QMessageBox::Ok);
|
||||
return;
|
||||
case AddressTableModel::OK:
|
||||
// Failed with unknown reason. Just reject.
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
QString EditAddressDialog::getAddress() const
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
void EditAddressDialog::setAddress(const QString &address)
|
||||
{
|
||||
this->address = address;
|
||||
ui->addressEdit->setText(address);
|
||||
}
|
||||
50
src/qt/editaddressdialog.h
Normal file
50
src/qt/editaddressdialog.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef EDITADDRESSDIALOG_H
|
||||
#define EDITADDRESSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDataWidgetMapper;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Ui {
|
||||
class EditAddressDialog;
|
||||
}
|
||||
class AddressTableModel;
|
||||
|
||||
/** Dialog for editing an address and associated information.
|
||||
*/
|
||||
class EditAddressDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Mode {
|
||||
NewReceivingAddress,
|
||||
NewSendingAddress,
|
||||
EditReceivingAddress,
|
||||
EditSendingAddress
|
||||
};
|
||||
|
||||
explicit EditAddressDialog(Mode mode, QWidget *parent = 0);
|
||||
~EditAddressDialog();
|
||||
|
||||
void setModel(AddressTableModel *model);
|
||||
void loadRow(int row);
|
||||
|
||||
void accept();
|
||||
|
||||
QString getAddress() const;
|
||||
void setAddress(const QString &address);
|
||||
private:
|
||||
bool saveCurrentRow();
|
||||
|
||||
Ui::EditAddressDialog *ui;
|
||||
QDataWidgetMapper *mapper;
|
||||
Mode mode;
|
||||
AddressTableModel *model;
|
||||
|
||||
QString address;
|
||||
};
|
||||
|
||||
#endif // EDITADDRESSDIALOG_H
|
||||
183
src/qt/forms/aboutdialog.ui
Normal file
183
src/qt/forms/aboutdialog.ui
Normal file
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AboutDialog</class>
|
||||
<widget class="QDialog" name="AboutDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>593</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About CasinoCoin</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Ignored">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><b>CasinoCoin</b> version</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="versionLabel">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0.3.666-beta</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>
|
||||
Copyright © 2009-2012 Bitcoin Developers
|
||||
Copyright © 2011-2012 Litecoin Developers
|
||||
Copyright © 2013 CasinoCoin Developers
|
||||
|
||||
This is experimental software.
|
||||
|
||||
Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard.
|
||||
|
||||
Official forum: http://forum.casinoco.in
|
||||
</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AboutDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>360</x>
|
||||
<y>308</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AboutDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>428</x>
|
||||
<y>308</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
175
src/qt/forms/addressbookpage.ui
Normal file
175
src/qt/forms/addressbookpage.ui
Normal file
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AddressBookPage</class>
|
||||
<widget class="QWidget" name="AddressBookPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>760</width>
|
||||
<height>380</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Address Book</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelExplanation">
|
||||
<property name="text">
|
||||
<string>These are your CasinoCoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="tableView">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Double-click to edit address or label</string>
|
||||
</property>
|
||||
<property name="tabKeyNavigation">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="newAddressButton">
|
||||
<property name="toolTip">
|
||||
<string>Create a new address</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&New Address</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/add</normaloff>:/icons/add</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="copyToClipboard">
|
||||
<property name="toolTip">
|
||||
<string>Copy the currently selected address to the system clipboard</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Copy Address</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="showQRCode">
|
||||
<property name="text">
|
||||
<string>Show &QR Code</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/qrcode</normaloff>:/icons/qrcode</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="signMessage">
|
||||
<property name="toolTip">
|
||||
<string>Sign a message to prove you own a Bitcoin address</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Sign Message</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/edit</normaloff>:/icons/edit</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="verifyMessage">
|
||||
<property name="toolTip">
|
||||
<string>Verify a message to ensure it was signed with a specified Bitcoin address</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Verify Message</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/transaction_0</normaloff>:/icons/transaction_0</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteButton">
|
||||
<property name="toolTip">
|
||||
<string>Delete the currently selected address from the list. Only sending addresses can be deleted.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Delete</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
151
src/qt/forms/askpassphrasedialog.ui
Normal file
151
src/qt/forms/askpassphrasedialog.ui
Normal file
@@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AskPassphraseDialog</class>
|
||||
<widget class="QDialog" name="AskPassphraseDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>598</width>
|
||||
<height>198</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>550</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Passphrase Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="warningLabel">
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="passLabel1">
|
||||
<property name="text">
|
||||
<string>Enter passphrase</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="passEdit1">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="passLabel2">
|
||||
<property name="text">
|
||||
<string>New passphrase</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="passEdit2">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="passLabel3">
|
||||
<property name="text">
|
||||
<string>Repeat new passphrase</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="passEdit3">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="capsLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AskPassphraseDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AskPassphraseDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
105
src/qt/forms/editaddressdialog.ui
Normal file
105
src/qt/forms/editaddressdialog.ui
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditAddressDialog</class>
|
||||
<widget class="QDialog" name="EditAddressDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>457</width>
|
||||
<height>126</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Edit Address</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>&Label</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>labelEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="labelEdit">
|
||||
<property name="toolTip">
|
||||
<string>The label associated with this address book entry</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>&Address</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>addressEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="addressEdit">
|
||||
<property name="toolTip">
|
||||
<string>The address associated with this address book entry. This can only be modified for sending addresses.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>EditAddressDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>EditAddressDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
466
src/qt/forms/optionsdialog.ui
Normal file
466
src/qt/forms/optionsdialog.ui
Normal file
@@ -0,0 +1,466 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OptionsDialog</class>
|
||||
<widget class="QDialog" name="OptionsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>540</width>
|
||||
<height>380</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::North</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabMain">
|
||||
<attribute name="title">
|
||||
<string>&Main</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Main">
|
||||
<item>
|
||||
<widget class="QLabel" name="transactionFeeInfoLabel">
|
||||
<property name="text">
|
||||
<string>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_Main">
|
||||
<item>
|
||||
<widget class="QLabel" name="transactionFeeLabel">
|
||||
<property name="text">
|
||||
<string>Pay transaction &fee</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>transactionFee</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="BitcoinAmountField" name="transactionFee"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_Main">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="bitcoinAtStartup">
|
||||
<property name="toolTip">
|
||||
<string>Automatically start CasinoCoin after logging in to the system.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Start CasinoCoin on system login</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="detachDatabases">
|
||||
<property name="toolTip">
|
||||
<string>Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Detach databases at shutdown</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Main">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabNetwork">
|
||||
<attribute name="title">
|
||||
<string>&Network</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Network">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mapPortUpnp">
|
||||
<property name="toolTip">
|
||||
<string>Automatically open the CasinoCoin client port on the router. This only works when your router supports UPnP and it is enabled.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Map port using &UPnP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="connectSocks">
|
||||
<property name="toolTip">
|
||||
<string>Connect to the CasinoCoin network through a SOCKS proxy (e.g. when connecting through Tor).</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Connect through SOCKS proxy:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_Network">
|
||||
<item>
|
||||
<widget class="QLabel" name="proxyIpLabel">
|
||||
<property name="text">
|
||||
<string>Proxy &IP:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>proxyIp</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="proxyIp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>IP address of the proxy (e.g. 127.0.0.1)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="proxyPortLabel">
|
||||
<property name="text">
|
||||
<string>&Port:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>proxyPort</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="proxyPort">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>55</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Port of the proxy (e.g. 9050)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="socksVersionLabel">
|
||||
<property name="text">
|
||||
<string>SOCKS &Version:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>socksVersion</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValueComboBox" name="socksVersion">
|
||||
<property name="toolTip">
|
||||
<string>SOCKS version of the proxy (e.g. 5)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_Network">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Network">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabWindow">
|
||||
<attribute name="title">
|
||||
<string>&Window</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Window">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="minimizeToTray">
|
||||
<property name="toolTip">
|
||||
<string>Show only a tray icon after minimizing the window.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Minimize to the tray instead of the taskbar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="minimizeOnClose">
|
||||
<property name="toolTip">
|
||||
<string>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>M&inimize on close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Window">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabDisplay">
|
||||
<attribute name="title">
|
||||
<string>&Display</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_Display">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1_Display">
|
||||
<item>
|
||||
<widget class="QLabel" name="langLabel">
|
||||
<property name="text">
|
||||
<string>User Interface &language:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lang</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValueComboBox" name="lang">
|
||||
<property name="toolTip">
|
||||
<string>The user interface language can be set here. This setting will take effect after restarting CasinoCoin.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2_Display">
|
||||
<item>
|
||||
<widget class="QLabel" name="unitLabel">
|
||||
<property name="text">
|
||||
<string>&Unit to show amounts in:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>unit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValueComboBox" name="unit">
|
||||
<property name="toolTip">
|
||||
<string>Choose the default subdivision unit to show in the interface and when sending coins.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="displayAddresses">
|
||||
<property name="toolTip">
|
||||
<string>Whether to show CasinoCoin addresses in the transaction list or not.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Display addresses in transaction list</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_Display">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_Buttons">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="okButton">
|
||||
<property name="text">
|
||||
<string>&OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="text">
|
||||
<string>&Cancel</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="applyButton">
|
||||
<property name="text">
|
||||
<string>&Apply</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BitcoinAmountField</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>bitcoinamountfield.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QValueComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>qvaluecombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QValidatedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>qvalidatedlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
320
src/qt/forms/overviewpage.ui
Normal file
320
src/qt/forms/overviewpage.ui
Normal file
@@ -0,0 +1,320 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OverviewPage</class>
|
||||
<widget class="QWidget" name="OverviewPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>573</width>
|
||||
<height>342</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Wallet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelWalletStatus">
|
||||
<property name="toolTip">
|
||||
<string>The displayed information may be out of date. Your wallet automatically synchronizes with the CasinoCoin network after a connection is established, but this process has not completed yet.</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel { color: red; }</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">(out of sync)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Balance:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="labelBalance">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Your current balance</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0 CSC</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Unconfirmed:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="labelUnconfirmed">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Total of transactions that have yet to be confirmed, and do not yet count toward the current balance</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0 CSC</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Number of transactions:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="labelNumTransactions">
|
||||
<property name="toolTip">
|
||||
<string>Total number of transactions in wallet</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelImmatureText">
|
||||
<property name="text">
|
||||
<string>Immature:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="labelImmature">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Mined balance that has not yet matured</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">0 CSC</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../bitcoin.qrc">:/images/backg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>-2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string><b>Recent transactions</b></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelTransactionsStatus">
|
||||
<property name="toolTip">
|
||||
<string>The displayed information may be out of date. Your wallet automatically synchronizes with the CasinoCoin network after a connection is established, but this process has not completed yet.</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel { color: red; }</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">(out of sync)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListView" name="listTransactions">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QListView { background: transparent; }</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
212
src/qt/forms/qrcodedialog.ui
Normal file
212
src/qt/forms/qrcodedialog.ui
Normal file
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QRCodeDialog</class>
|
||||
<widget class="QDialog" name="QRCodeDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>340</width>
|
||||
<height>530</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>QR Code Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblQRCode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="outUri">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="tabChangesFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkReqPayment">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Request Payment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblLabel">
|
||||
<property name="text">
|
||||
<string>Label:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lnLabel</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lnLabel"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblMessage">
|
||||
<property name="text">
|
||||
<string>Message:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lnMessage</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lnMessage"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblAmount">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Amount:</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lnReqAmount</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="BitcoinAmountField" name="lnReqAmount">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSaveAs">
|
||||
<property name="text">
|
||||
<string>&Save As...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BitcoinAmountField</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>bitcoinamountfield.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>chkReqPayment</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>lnReqAmount</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>92</x>
|
||||
<y>285</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>98</x>
|
||||
<y>311</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
436
src/qt/forms/rpcconsole.ui
Normal file
436
src/qt/forms/rpcconsole.ui
Normal file
@@ -0,0 +1,436 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RPCConsole</class>
|
||||
<widget class="QDialog" name="RPCConsole">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>740</width>
|
||||
<height>450</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>CasinoCoin - Debug window</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_info">
|
||||
<attribute name="title">
|
||||
<string>&Information</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bitcoin Core</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Client name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="clientName">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Client version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="clientVersion">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Using OpenSSL version</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="openSSLVersion">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Startup time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="startupTime">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Network</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Number of connections</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="numberOfConnections">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>On testnet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QCheckBox" name="isTestNet">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Block chain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Current number of blocks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLabel" name="numberOfBlocks">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Estimated total blocks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLabel" name="totalBlocks">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Last block time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QLabel" name="lastBlockTime">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N/A</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="labelDebugLogfile">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Debug logfile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QPushButton" name="openDebugLogfileButton">
|
||||
<property name="toolTip">
|
||||
<string>Open the CasinoCoin debug logfile from the current data directory. This can take a few seconds for large logfiles.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Open</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QLabel" name="labelCLOptions">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Command-line options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QPushButton" name="showCLOptionsButton">
|
||||
<property name="toolTip">
|
||||
<string>Show the CasinoCoin-Qt help message to get a list with possible CasinoCoin command-line options.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Show</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_console">
|
||||
<attribute name="title">
|
||||
<string>&Console</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="messagesWidget">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="tabKeyNavigation" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="columnCount" stdset="0">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string notr="true">></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Clear console</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string notr="true">Ctrl+L</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
175
src/qt/forms/sendcoinsdialog.ui
Normal file
175
src/qt/forms/sendcoinsdialog.ui
Normal file
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SendCoinsDialog</class>
|
||||
<widget class="QDialog" name="SendCoinsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>686</width>
|
||||
<height>217</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Send Coins</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>666</width>
|
||||
<height>165</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="entries">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="toolTip">
|
||||
<string>Send to multiple recipients at once</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Add Recipient</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/add</normaloff>:/icons/add</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove all transaction fields</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear &All</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||
</property>
|
||||
<property name="autoRepeatDelay">
|
||||
<number>300</number>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Balance:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelBalance">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>123.456 CSC</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sendButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Confirm the send action</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Send</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/send</normaloff>:/icons/send</iconset>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
169
src/qt/forms/sendcoinsentry.ui
Normal file
169
src/qt/forms/sendcoinsentry.ui
Normal file
@@ -0,0 +1,169 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SendCoinsEntry</class>
|
||||
<widget class="QFrame" name="SendCoinsEntry">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>729</width>
|
||||
<height>136</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="spacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>A&mount:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>payAmount</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Pay &To:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>payTo</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="BitcoinAmountField" name="payAmount"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="addAsLabel">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Enter a label for this address to add it to your address book</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>&Label:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>addAsLabel</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="payToLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="payTo">
|
||||
<property name="toolTip">
|
||||
<string>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>34</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="addressBookButton">
|
||||
<property name="toolTip">
|
||||
<string>Choose address from address book</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+A</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pasteButton">
|
||||
<property name="toolTip">
|
||||
<string>Paste address from clipboard</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+P</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="deleteButton">
|
||||
<property name="toolTip">
|
||||
<string>Remove this recipient</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BitcoinAmountField</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>bitcoinamountfield.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QValidatedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>qvalidatedlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
386
src/qt/forms/signverifymessagedialog.ui
Normal file
386
src/qt/forms/signverifymessagedialog.ui
Normal file
@@ -0,0 +1,386 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SignVerifyMessageDialog</class>
|
||||
<widget class="QDialog" name="SignVerifyMessageDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>700</width>
|
||||
<height>380</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Signatures - Sign / Verify a Message</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabSignMessage">
|
||||
<attribute name="title">
|
||||
<string>&Sign Message</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_SM">
|
||||
<item>
|
||||
<widget class="QLabel" name="infoLabel_SM">
|
||||
<property name="text">
|
||||
<string>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1_SM">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="addressIn_SM">
|
||||
<property name="toolTip">
|
||||
<string>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>34</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addressBookButton_SM">
|
||||
<property name="toolTip">
|
||||
<string>Choose an address from the address book</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+A</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pasteButton_SM">
|
||||
<property name="toolTip">
|
||||
<string>Paste address from clipboard</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+P</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="messageIn_SM">
|
||||
<property name="toolTip">
|
||||
<string>Enter the message you want to sign here</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2_SM">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="signatureOut_SM">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="copySignatureButton_SM">
|
||||
<property name="toolTip">
|
||||
<string>Copy the current signature to the system clipboard</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3_SM">
|
||||
<item>
|
||||
<widget class="QPushButton" name="signMessageButton_SM">
|
||||
<property name="toolTip">
|
||||
<string>Sign the message to prove you own this Bitcoin address</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Sign Message</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/edit</normaloff>:/icons/edit</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearButton_SM">
|
||||
<property name="toolTip">
|
||||
<string>Reset all sign message fields</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear &All</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_1_SM">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="statusLabel_SM">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2_SM">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabVerifyMessage">
|
||||
<attribute name="title">
|
||||
<string>&Verify Message</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_VM">
|
||||
<item>
|
||||
<widget class="QLabel" name="infoLabel_VM">
|
||||
<property name="text">
|
||||
<string>Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack.</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1_VM">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="addressIn_VM">
|
||||
<property name="toolTip">
|
||||
<string>The address the message was signed with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>34</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addressBookButton_VM">
|
||||
<property name="toolTip">
|
||||
<string>Choose an address from the address book</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Alt+A</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="messageIn_VM"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QValidatedLineEdit" name="signatureIn_VM"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2_VM">
|
||||
<item>
|
||||
<widget class="QPushButton" name="verifyMessageButton_VM">
|
||||
<property name="toolTip">
|
||||
<string>Verify the message to ensure it was signed with the specified Bitcoin address</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Verify Message</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/transaction_0</normaloff>:/icons/transaction_0</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearButton_VM">
|
||||
<property name="toolTip">
|
||||
<string>Reset all verify message fields</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear &All</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../bitcoin.qrc">
|
||||
<normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_1_VM">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="statusLabel_VM">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2_VM">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QValidatedLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>qvalidatedlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../bitcoin.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
74
src/qt/forms/transactiondescdialog.ui
Normal file
74
src/qt/forms/transactiondescdialog.ui
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TransactionDescDialog</class>
|
||||
<widget class="QDialog" name="TransactionDescDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>620</width>
|
||||
<height>250</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Transaction details</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="detailText">
|
||||
<property name="toolTip">
|
||||
<string>This pane shows a detailed description of the transaction</string>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>TransactionDescDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>TransactionDescDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
34
src/qt/guiconstants.h
Normal file
34
src/qt/guiconstants.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef GUICONSTANTS_H
|
||||
#define GUICONSTANTS_H
|
||||
|
||||
/* Milliseconds between model updates */
|
||||
static const int MODEL_UPDATE_DELAY = 500;
|
||||
|
||||
/* AskPassphraseDialog -- Maximum passphrase length */
|
||||
static const int MAX_PASSPHRASE_SIZE = 1024;
|
||||
|
||||
/* BitcoinGUI -- Size of icons in status bar */
|
||||
static const int STATUSBAR_ICONSIZE = 16;
|
||||
|
||||
/* Invalid field background style */
|
||||
#define STYLE_INVALID "background:#FF8080"
|
||||
|
||||
/* Transaction list -- unconfirmed transaction */
|
||||
#define COLOR_UNCONFIRMED QColor(128, 128, 128)
|
||||
/* Transaction list -- negative amount */
|
||||
#define COLOR_NEGATIVE QColor(255, 0, 0)
|
||||
/* Transaction list -- bare address (without label) */
|
||||
#define COLOR_BAREADDRESS QColor(140, 140, 140)
|
||||
|
||||
/* Tooltips longer than this (in characters) are converted into rich text,
|
||||
so that they can be word-wrapped.
|
||||
*/
|
||||
static const int TOOLTIP_WRAP_THRESHOLD = 80;
|
||||
|
||||
/* Maximum allowed URI length */
|
||||
static const int MAX_URI_LENGTH = 255;
|
||||
|
||||
/* QRCodeDialog -- size of exported QR Code image */
|
||||
#define EXPORT_IMAGE_SIZE 256
|
||||
|
||||
#endif // GUICONSTANTS_H
|
||||
463
src/qt/guiutil.cpp
Normal file
463
src/qt/guiutil.cpp
Normal file
@@ -0,0 +1,463 @@
|
||||
#include "guiutil.h"
|
||||
#include "bitcoinaddressvalidator.h"
|
||||
#include "walletmodel.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "util.h"
|
||||
#include "init.h"
|
||||
#include "base58.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
#include <QDoubleValidator>
|
||||
#include <QFont>
|
||||
#include <QLineEdit>
|
||||
#include <QUrl>
|
||||
#include <QTextDocument> // For Qt::escape
|
||||
#include <QAbstractItemView>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QFileDialog>
|
||||
#include <QDesktopServices>
|
||||
#include <QThread>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#ifdef _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#endif
|
||||
#define _WIN32_IE 0x0501
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include "shlwapi.h"
|
||||
#include "shlobj.h"
|
||||
#include "shellapi.h"
|
||||
#endif
|
||||
|
||||
namespace GUIUtil {
|
||||
|
||||
QString dateTimeStr(const QDateTime &date)
|
||||
{
|
||||
return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm");
|
||||
}
|
||||
|
||||
QString dateTimeStr(qint64 nTime)
|
||||
{
|
||||
return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
|
||||
}
|
||||
|
||||
QFont bitcoinAddressFont()
|
||||
{
|
||||
QFont font("Monospace");
|
||||
font.setStyleHint(QFont::TypeWriter);
|
||||
return font;
|
||||
}
|
||||
|
||||
void setupAddressWidget(QLineEdit *widget, QWidget *parent)
|
||||
{
|
||||
widget->setMaxLength(BitcoinAddressValidator::MaxAddressLength);
|
||||
widget->setValidator(new BitcoinAddressValidator(parent));
|
||||
widget->setFont(bitcoinAddressFont());
|
||||
}
|
||||
|
||||
void setupAmountWidget(QLineEdit *widget, QWidget *parent)
|
||||
{
|
||||
QDoubleValidator *amountValidator = new QDoubleValidator(parent);
|
||||
amountValidator->setDecimals(8);
|
||||
amountValidator->setBottom(0.0);
|
||||
widget->setValidator(amountValidator);
|
||||
widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
|
||||
{
|
||||
if(uri.scheme() != QString("casinocoin"))
|
||||
return false;
|
||||
|
||||
// check if the address is valid
|
||||
CBitcoinAddress addressFromUri(uri.path().toStdString());
|
||||
if (!addressFromUri.IsValid())
|
||||
return false;
|
||||
|
||||
SendCoinsRecipient rv;
|
||||
rv.address = uri.path();
|
||||
rv.amount = 0;
|
||||
QList<QPair<QString, QString> > items = uri.queryItems();
|
||||
for (QList<QPair<QString, QString> >::iterator i = items.begin(); i != items.end(); i++)
|
||||
{
|
||||
bool fShouldReturnFalse = false;
|
||||
if (i->first.startsWith("req-"))
|
||||
{
|
||||
i->first.remove(0, 4);
|
||||
fShouldReturnFalse = true;
|
||||
}
|
||||
|
||||
if (i->first == "label")
|
||||
{
|
||||
rv.label = i->second;
|
||||
fShouldReturnFalse = false;
|
||||
}
|
||||
else if (i->first == "amount")
|
||||
{
|
||||
if(!i->second.isEmpty())
|
||||
{
|
||||
if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fShouldReturnFalse = false;
|
||||
}
|
||||
|
||||
if (fShouldReturnFalse)
|
||||
return false;
|
||||
}
|
||||
if(out)
|
||||
{
|
||||
*out = rv;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseBitcoinURI(QString uri, SendCoinsRecipient *out)
|
||||
{
|
||||
// Convert casinocoin:// to casinocoin:
|
||||
//
|
||||
// Cannot handle this later, because casinocoin:// will cause Qt to see the part after // as host,
|
||||
// which will lowercase it (and thus invalidate the address).
|
||||
if(uri.startsWith("casinocoin://"))
|
||||
{
|
||||
uri.replace(0, 11, "casinocoin:");
|
||||
}
|
||||
QUrl uriInstance(uri);
|
||||
return parseBitcoinURI(uriInstance, out);
|
||||
}
|
||||
|
||||
QString HtmlEscape(const QString& str, bool fMultiLine)
|
||||
{
|
||||
QString escaped = Qt::escape(str);
|
||||
if(fMultiLine)
|
||||
{
|
||||
escaped = escaped.replace("\n", "<br>\n");
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
QString HtmlEscape(const std::string& str, bool fMultiLine)
|
||||
{
|
||||
return HtmlEscape(QString::fromStdString(str), fMultiLine);
|
||||
}
|
||||
|
||||
void copyEntryData(QAbstractItemView *view, int column, int role)
|
||||
{
|
||||
if(!view || !view->selectionModel())
|
||||
return;
|
||||
QModelIndexList selection = view->selectionModel()->selectedRows(column);
|
||||
|
||||
if(!selection.isEmpty())
|
||||
{
|
||||
// Copy first item
|
||||
QApplication::clipboard()->setText(selection.at(0).data(role).toString());
|
||||
}
|
||||
}
|
||||
|
||||
QString getSaveFileName(QWidget *parent, const QString &caption,
|
||||
const QString &dir,
|
||||
const QString &filter,
|
||||
QString *selectedSuffixOut)
|
||||
{
|
||||
QString selectedFilter;
|
||||
QString myDir;
|
||||
if(dir.isEmpty()) // Default to user documents location
|
||||
{
|
||||
myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
myDir = dir;
|
||||
}
|
||||
QString result = QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter);
|
||||
|
||||
/* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
|
||||
QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
|
||||
QString selectedSuffix;
|
||||
if(filter_re.exactMatch(selectedFilter))
|
||||
{
|
||||
selectedSuffix = filter_re.cap(1);
|
||||
}
|
||||
|
||||
/* Add suffix if needed */
|
||||
QFileInfo info(result);
|
||||
if(!result.isEmpty())
|
||||
{
|
||||
if(info.suffix().isEmpty() && !selectedSuffix.isEmpty())
|
||||
{
|
||||
/* No suffix specified, add selected suffix */
|
||||
if(!result.endsWith("."))
|
||||
result.append(".");
|
||||
result.append(selectedSuffix);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return selected suffix if asked to */
|
||||
if(selectedSuffixOut)
|
||||
{
|
||||
*selectedSuffixOut = selectedSuffix;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Qt::ConnectionType blockingGUIThreadConnection()
|
||||
{
|
||||
if(QThread::currentThread() != QCoreApplication::instance()->thread())
|
||||
{
|
||||
return Qt::BlockingQueuedConnection;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Qt::DirectConnection;
|
||||
}
|
||||
}
|
||||
|
||||
bool checkPoint(const QPoint &p, const QWidget *w)
|
||||
{
|
||||
QWidget *atW = qApp->widgetAt(w->mapToGlobal(p));
|
||||
if (!atW) return false;
|
||||
return atW->topLevelWidget() == w;
|
||||
}
|
||||
|
||||
bool isObscured(QWidget *w)
|
||||
{
|
||||
return !(checkPoint(QPoint(0, 0), w)
|
||||
&& checkPoint(QPoint(w->width() - 1, 0), w)
|
||||
&& checkPoint(QPoint(0, w->height() - 1), w)
|
||||
&& checkPoint(QPoint(w->width() - 1, w->height() - 1), w)
|
||||
&& checkPoint(QPoint(w->width() / 2, w->height() / 2), w));
|
||||
}
|
||||
|
||||
void openDebugLogfile()
|
||||
{
|
||||
boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
|
||||
|
||||
/* Open debug.log with the associated application */
|
||||
if (boost::filesystem::exists(pathDebug))
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string())));
|
||||
}
|
||||
|
||||
ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) :
|
||||
QObject(parent), size_threshold(size_threshold)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
|
||||
{
|
||||
if(evt->type() == QEvent::ToolTipChange)
|
||||
{
|
||||
QWidget *widget = static_cast<QWidget*>(obj);
|
||||
QString tooltip = widget->toolTip();
|
||||
if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt/>") && !Qt::mightBeRichText(tooltip))
|
||||
{
|
||||
// Prefix <qt/> to make sure Qt detects this as rich text
|
||||
// Escape the current message as HTML and replace \n by <br>
|
||||
tooltip = "<qt/>" + HtmlEscape(tooltip, true);
|
||||
widget->setToolTip(tooltip);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, evt);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
boost::filesystem::path static StartupShortcutPath()
|
||||
{
|
||||
return GetSpecialFolderPath(CSIDL_STARTUP) / "CasinoCoin.lnk";
|
||||
}
|
||||
|
||||
bool GetStartOnSystemStartup()
|
||||
{
|
||||
// check for CasinoCoin.lnk
|
||||
return boost::filesystem::exists(StartupShortcutPath());
|
||||
}
|
||||
|
||||
bool SetStartOnSystemStartup(bool fAutoStart)
|
||||
{
|
||||
// If the shortcut exists already, remove it for updating
|
||||
boost::filesystem::remove(StartupShortcutPath());
|
||||
|
||||
if (fAutoStart)
|
||||
{
|
||||
CoInitialize(NULL);
|
||||
|
||||
// Get a pointer to the IShellLink interface.
|
||||
IShellLink* psl = NULL;
|
||||
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
|
||||
CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||
reinterpret_cast<void**>(&psl));
|
||||
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
// Get the current executable path
|
||||
TCHAR pszExePath[MAX_PATH];
|
||||
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
|
||||
|
||||
TCHAR pszArgs[5] = TEXT("-min");
|
||||
|
||||
// Set the path to the shortcut target
|
||||
psl->SetPath(pszExePath);
|
||||
PathRemoveFileSpec(pszExePath);
|
||||
psl->SetWorkingDirectory(pszExePath);
|
||||
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
|
||||
psl->SetArguments(pszArgs);
|
||||
|
||||
// Query IShellLink for the IPersistFile interface for
|
||||
// saving the shortcut in persistent storage.
|
||||
IPersistFile* ppf = NULL;
|
||||
hres = psl->QueryInterface(IID_IPersistFile,
|
||||
reinterpret_cast<void**>(&ppf));
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
WCHAR pwsz[MAX_PATH];
|
||||
// Ensure that the string is ANSI.
|
||||
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH);
|
||||
// Save the link by calling IPersistFile::Save.
|
||||
hres = ppf->Save(pwsz, TRUE);
|
||||
ppf->Release();
|
||||
psl->Release();
|
||||
CoUninitialize();
|
||||
return true;
|
||||
}
|
||||
psl->Release();
|
||||
}
|
||||
CoUninitialize();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(LINUX)
|
||||
|
||||
// Follow the Desktop Application Autostart Spec:
|
||||
// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
|
||||
|
||||
boost::filesystem::path static GetAutostartDir()
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
char* pszConfigHome = getenv("XDG_CONFIG_HOME");
|
||||
if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
|
||||
char* pszHome = getenv("HOME");
|
||||
if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
|
||||
return fs::path();
|
||||
}
|
||||
|
||||
boost::filesystem::path static GetAutostartFilePath()
|
||||
{
|
||||
return GetAutostartDir() / "casinocoin.desktop";
|
||||
}
|
||||
|
||||
bool GetStartOnSystemStartup()
|
||||
{
|
||||
boost::filesystem::ifstream optionFile(GetAutostartFilePath());
|
||||
if (!optionFile.good())
|
||||
return false;
|
||||
// Scan through file for "Hidden=true":
|
||||
std::string line;
|
||||
while (!optionFile.eof())
|
||||
{
|
||||
getline(optionFile, line);
|
||||
if (line.find("Hidden") != std::string::npos &&
|
||||
line.find("true") != std::string::npos)
|
||||
return false;
|
||||
}
|
||||
optionFile.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetStartOnSystemStartup(bool fAutoStart)
|
||||
{
|
||||
if (!fAutoStart)
|
||||
boost::filesystem::remove(GetAutostartFilePath());
|
||||
else
|
||||
{
|
||||
char pszExePath[MAX_PATH+1];
|
||||
memset(pszExePath, 0, sizeof(pszExePath));
|
||||
if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1)
|
||||
return false;
|
||||
|
||||
boost::filesystem::create_directories(GetAutostartDir());
|
||||
|
||||
boost::filesystem::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out|std::ios_base::trunc);
|
||||
if (!optionFile.good())
|
||||
return false;
|
||||
// Write a casinocoin.desktop file to the autostart directory:
|
||||
optionFile << "[Desktop Entry]\n";
|
||||
optionFile << "Type=Application\n";
|
||||
optionFile << "Name=CasinoCoin\n";
|
||||
optionFile << "Exec=" << pszExePath << " -min\n";
|
||||
optionFile << "Terminal=false\n";
|
||||
optionFile << "Hidden=false\n";
|
||||
optionFile.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
|
||||
// TODO: OSX startup stuff; see:
|
||||
// https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
|
||||
|
||||
bool GetStartOnSystemStartup() { return false; }
|
||||
bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
|
||||
|
||||
#endif
|
||||
|
||||
HelpMessageBox::HelpMessageBox(QWidget *parent) :
|
||||
QMessageBox(parent)
|
||||
{
|
||||
header = tr("CasinoCoin-Qt") + " " + tr("version") + " " +
|
||||
QString::fromStdString(FormatFullVersion()) + "\n\n" +
|
||||
tr("Usage:") + "\n" +
|
||||
" casinocoin-qt [" + tr("command-line options") + "] " + "\n";
|
||||
|
||||
coreOptions = QString::fromStdString(HelpMessage());
|
||||
|
||||
uiOptions = tr("UI options") + ":\n" +
|
||||
" -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
|
||||
" -min " + tr("Start minimized") + "\n" +
|
||||
" -splash " + tr("Show splash screen on startup (default: 1)") + "\n";
|
||||
|
||||
setWindowTitle(tr("CasinoCoin-Qt"));
|
||||
setTextFormat(Qt::PlainText);
|
||||
// setMinimumWidth is ignored for QMessageBox so put in nonbreaking spaces to make it wider.
|
||||
setText(header + QString(QChar(0x2003)).repeated(50));
|
||||
setDetailedText(coreOptions + "\n" + uiOptions);
|
||||
}
|
||||
|
||||
void HelpMessageBox::printToConsole()
|
||||
{
|
||||
// On other operating systems, the expected action is to print the message to the console.
|
||||
QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions;
|
||||
fprintf(stderr, "%s", strUsage.toStdString().c_str());
|
||||
}
|
||||
|
||||
void HelpMessageBox::showOrPrint()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
// On windows, show a message box, as there is no stderr/stdout in windowed applications
|
||||
exec();
|
||||
#else
|
||||
// On other operating systems, print help text to console
|
||||
printToConsole();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace GUIUtil
|
||||
|
||||
120
src/qt/guiutil.h
Normal file
120
src/qt/guiutil.h
Normal file
@@ -0,0 +1,120 @@
|
||||
#ifndef GUIUTIL_H
|
||||
#define GUIUTIL_H
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
#include <QMessageBox>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFont;
|
||||
class QLineEdit;
|
||||
class QWidget;
|
||||
class QDateTime;
|
||||
class QUrl;
|
||||
class QAbstractItemView;
|
||||
QT_END_NAMESPACE
|
||||
class SendCoinsRecipient;
|
||||
|
||||
/** Utility functions used by the CasinoCoin Qt UI.
|
||||
*/
|
||||
namespace GUIUtil
|
||||
{
|
||||
// Create human-readable string from date
|
||||
QString dateTimeStr(const QDateTime &datetime);
|
||||
QString dateTimeStr(qint64 nTime);
|
||||
|
||||
// Render CasinoCoin addresses in monospace font
|
||||
QFont bitcoinAddressFont();
|
||||
|
||||
// Set up widgets for address and amounts
|
||||
void setupAddressWidget(QLineEdit *widget, QWidget *parent);
|
||||
void setupAmountWidget(QLineEdit *widget, QWidget *parent);
|
||||
|
||||
// Parse "casinocoin:" URI into recipient object, return true on succesful parsing
|
||||
// See Bitcoin URI definition discussion here: https://bitcointalk.org/index.php?topic=33490.0
|
||||
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out);
|
||||
bool parseBitcoinURI(QString uri, SendCoinsRecipient *out);
|
||||
|
||||
// HTML escaping for rich text controls
|
||||
QString HtmlEscape(const QString& str, bool fMultiLine=false);
|
||||
QString HtmlEscape(const std::string& str, bool fMultiLine=false);
|
||||
|
||||
/** Copy a field of the currently selected entry of a view to the clipboard. Does nothing if nothing
|
||||
is selected.
|
||||
@param[in] column Data column to extract from the model
|
||||
@param[in] role Data role to extract from the model
|
||||
@see TransactionView::copyLabel, TransactionView::copyAmount, TransactionView::copyAddress
|
||||
*/
|
||||
void copyEntryData(QAbstractItemView *view, int column, int role=Qt::EditRole);
|
||||
|
||||
/** Get save file name, mimics QFileDialog::getSaveFileName, except that it appends a default suffix
|
||||
when no suffix is provided by the user.
|
||||
|
||||
@param[in] parent Parent window (or 0)
|
||||
@param[in] caption Window caption (or empty, for default)
|
||||
@param[in] dir Starting directory (or empty, to default to documents directory)
|
||||
@param[in] filter Filter specification such as "Comma Separated Files (*.csv)"
|
||||
@param[out] selectedSuffixOut Pointer to return the suffix (file type) that was selected (or 0).
|
||||
Can be useful when choosing the save file format based on suffix.
|
||||
*/
|
||||
QString getSaveFileName(QWidget *parent=0, const QString &caption=QString(),
|
||||
const QString &dir=QString(), const QString &filter=QString(),
|
||||
QString *selectedSuffixOut=0);
|
||||
|
||||
/** Get connection type to call object slot in GUI thread with invokeMethod. The call will be blocking.
|
||||
|
||||
@returns If called from the GUI thread, return a Qt::DirectConnection.
|
||||
If called from another thread, return a Qt::BlockingQueuedConnection.
|
||||
*/
|
||||
Qt::ConnectionType blockingGUIThreadConnection();
|
||||
|
||||
// Determine whether a widget is hidden behind other windows
|
||||
bool isObscured(QWidget *w);
|
||||
|
||||
// Open debug.log
|
||||
void openDebugLogfile();
|
||||
|
||||
/** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text
|
||||
representation if needed. This assures that Qt can word-wrap long tooltip messages.
|
||||
Tooltips longer than the provided size threshold (in characters) are wrapped.
|
||||
*/
|
||||
class ToolTipToRichTextFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = 0);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *evt);
|
||||
|
||||
private:
|
||||
int size_threshold;
|
||||
};
|
||||
|
||||
bool GetStartOnSystemStartup();
|
||||
bool SetStartOnSystemStartup(bool fAutoStart);
|
||||
|
||||
/** Help message for CasinoCoin-Qt, shown with --help. */
|
||||
class HelpMessageBox : public QMessageBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HelpMessageBox(QWidget *parent = 0);
|
||||
|
||||
/** Show message box or print help message to standard output, based on operating system. */
|
||||
void showOrPrint();
|
||||
|
||||
/** Print help message to console */
|
||||
void printToConsole();
|
||||
|
||||
private:
|
||||
QString header;
|
||||
QString coreOptions;
|
||||
QString uiOptions;
|
||||
};
|
||||
|
||||
} // namespace GUIUtil
|
||||
|
||||
#endif // GUIUTIL_H
|
||||
2500
src/qt/locale/bitcoin_bg.ts
Normal file
2500
src/qt/locale/bitcoin_bg.ts
Normal file
File diff suppressed because it is too large
Load Diff
2499
src/qt/locale/bitcoin_ca_ES.ts
Normal file
2499
src/qt/locale/bitcoin_ca_ES.ts
Normal file
File diff suppressed because it is too large
Load Diff
2520
src/qt/locale/bitcoin_cs.ts
Normal file
2520
src/qt/locale/bitcoin_cs.ts
Normal file
File diff suppressed because it is too large
Load Diff
2532
src/qt/locale/bitcoin_da.ts
Normal file
2532
src/qt/locale/bitcoin_da.ts
Normal file
File diff suppressed because it is too large
Load Diff
2518
src/qt/locale/bitcoin_de.ts
Normal file
2518
src/qt/locale/bitcoin_de.ts
Normal file
File diff suppressed because it is too large
Load Diff
2521
src/qt/locale/bitcoin_el_GR.ts
Normal file
2521
src/qt/locale/bitcoin_el_GR.ts
Normal file
File diff suppressed because it is too large
Load Diff
2086
src/qt/locale/bitcoin_en.ts
Normal file
2086
src/qt/locale/bitcoin_en.ts
Normal file
File diff suppressed because it is too large
Load Diff
2540
src/qt/locale/bitcoin_es.ts
Normal file
2540
src/qt/locale/bitcoin_es.ts
Normal file
File diff suppressed because it is too large
Load Diff
2538
src/qt/locale/bitcoin_es_CL.ts
Normal file
2538
src/qt/locale/bitcoin_es_CL.ts
Normal file
File diff suppressed because it is too large
Load Diff
2499
src/qt/locale/bitcoin_et.ts
Normal file
2499
src/qt/locale/bitcoin_et.ts
Normal file
File diff suppressed because it is too large
Load Diff
2499
src/qt/locale/bitcoin_eu_ES.ts
Normal file
2499
src/qt/locale/bitcoin_eu_ES.ts
Normal file
File diff suppressed because it is too large
Load Diff
2512
src/qt/locale/bitcoin_fa.ts
Normal file
2512
src/qt/locale/bitcoin_fa.ts
Normal file
File diff suppressed because it is too large
Load Diff
2499
src/qt/locale/bitcoin_fa_IR.ts
Normal file
2499
src/qt/locale/bitcoin_fa_IR.ts
Normal file
File diff suppressed because it is too large
Load Diff
2520
src/qt/locale/bitcoin_fi.ts
Normal file
2520
src/qt/locale/bitcoin_fi.ts
Normal file
File diff suppressed because it is too large
Load Diff
2520
src/qt/locale/bitcoin_fr.ts
Normal file
2520
src/qt/locale/bitcoin_fr.ts
Normal file
File diff suppressed because it is too large
Load Diff
2499
src/qt/locale/bitcoin_fr_CA.ts
Normal file
2499
src/qt/locale/bitcoin_fr_CA.ts
Normal file
File diff suppressed because it is too large
Load Diff
2517
src/qt/locale/bitcoin_he.ts
Normal file
2517
src/qt/locale/bitcoin_he.ts
Normal file
File diff suppressed because it is too large
Load Diff
2510
src/qt/locale/bitcoin_hr.ts
Normal file
2510
src/qt/locale/bitcoin_hr.ts
Normal file
File diff suppressed because it is too large
Load Diff
2534
src/qt/locale/bitcoin_hu.ts
Normal file
2534
src/qt/locale/bitcoin_hu.ts
Normal file
File diff suppressed because it is too large
Load Diff
2540
src/qt/locale/bitcoin_it.ts
Normal file
2540
src/qt/locale/bitcoin_it.ts
Normal file
File diff suppressed because it is too large
Load Diff
2510
src/qt/locale/bitcoin_lt.ts
Normal file
2510
src/qt/locale/bitcoin_lt.ts
Normal file
File diff suppressed because it is too large
Load Diff
2521
src/qt/locale/bitcoin_nb.ts
Normal file
2521
src/qt/locale/bitcoin_nb.ts
Normal file
File diff suppressed because it is too large
Load Diff
2546
src/qt/locale/bitcoin_nl.ts
Normal file
2546
src/qt/locale/bitcoin_nl.ts
Normal file
File diff suppressed because it is too large
Load Diff
2517
src/qt/locale/bitcoin_pl.ts
Normal file
2517
src/qt/locale/bitcoin_pl.ts
Normal file
File diff suppressed because it is too large
Load Diff
2537
src/qt/locale/bitcoin_pt_BR.ts
Normal file
2537
src/qt/locale/bitcoin_pt_BR.ts
Normal file
File diff suppressed because it is too large
Load Diff
2518
src/qt/locale/bitcoin_pt_PT.ts
Normal file
2518
src/qt/locale/bitcoin_pt_PT.ts
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/qt/locale/bitcoin_ro_RO.ts
Normal file
2500
src/qt/locale/bitcoin_ro_RO.ts
Normal file
File diff suppressed because it is too large
Load Diff
2521
src/qt/locale/bitcoin_ru.ts
Normal file
2521
src/qt/locale/bitcoin_ru.ts
Normal file
File diff suppressed because it is too large
Load Diff
2503
src/qt/locale/bitcoin_sk.ts
Normal file
2503
src/qt/locale/bitcoin_sk.ts
Normal file
File diff suppressed because it is too large
Load Diff
2500
src/qt/locale/bitcoin_sr.ts
Normal file
2500
src/qt/locale/bitcoin_sr.ts
Normal file
File diff suppressed because it is too large
Load Diff
2520
src/qt/locale/bitcoin_sv.ts
Normal file
2520
src/qt/locale/bitcoin_sv.ts
Normal file
File diff suppressed because it is too large
Load Diff
2520
src/qt/locale/bitcoin_tr.ts
Normal file
2520
src/qt/locale/bitcoin_tr.ts
Normal file
File diff suppressed because it is too large
Load Diff
2540
src/qt/locale/bitcoin_uk.ts
Normal file
2540
src/qt/locale/bitcoin_uk.ts
Normal file
File diff suppressed because it is too large
Load Diff
2547
src/qt/locale/bitcoin_zh_CN.ts
Normal file
2547
src/qt/locale/bitcoin_zh_CN.ts
Normal file
File diff suppressed because it is too large
Load Diff
2541
src/qt/locale/bitcoin_zh_TW.ts
Normal file
2541
src/qt/locale/bitcoin_zh_TW.ts
Normal file
File diff suppressed because it is too large
Load Diff
45
src/qt/macdockiconhandler.h
Normal file
45
src/qt/macdockiconhandler.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef MACDOCKICONHANDLER_H
|
||||
#define MACDOCKICONHANDLER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class QMenu;
|
||||
class QIcon;
|
||||
class QWidget;
|
||||
class objc_object;
|
||||
|
||||
#ifdef __OBJC__
|
||||
@class DockIconClickEventHandler;
|
||||
#else
|
||||
class DockIconClickEventHandler;
|
||||
#endif
|
||||
|
||||
/** Macintosh-specific dock icon handler.
|
||||
*/
|
||||
class MacDockIconHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~MacDockIconHandler();
|
||||
|
||||
QMenu *dockMenu();
|
||||
void setIcon(const QIcon &icon);
|
||||
|
||||
static MacDockIconHandler *instance();
|
||||
|
||||
void handleDockIconClickEvent();
|
||||
|
||||
signals:
|
||||
void dockIconClicked();
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
MacDockIconHandler();
|
||||
|
||||
DockIconClickEventHandler *m_dockIconClickEventHandler;
|
||||
QWidget *m_dummyWidget;
|
||||
QMenu *m_dockMenu;
|
||||
};
|
||||
|
||||
#endif // MACDOCKICONCLICKHANDLER_H
|
||||
99
src/qt/macdockiconhandler.mm
Normal file
99
src/qt/macdockiconhandler.mm
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
#include "macdockiconhandler.h"
|
||||
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
extern void qt_mac_set_dock_menu(QMenu*);
|
||||
|
||||
#undef slots
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
@interface DockIconClickEventHandler : NSObject
|
||||
{
|
||||
MacDockIconHandler* dockIconHandler;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation DockIconClickEventHandler
|
||||
|
||||
- (id)initWithDockIconHandler:(MacDockIconHandler *)aDockIconHandler
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
dockIconHandler = aDockIconHandler;
|
||||
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
andSelector:@selector(handleDockClickEvent:withReplyEvent:)
|
||||
forEventClass:kCoreEventClass
|
||||
andEventID:kAEReopenApplication];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
Q_UNUSED(replyEvent)
|
||||
|
||||
if (dockIconHandler)
|
||||
dockIconHandler->handleDockIconClickEvent();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
MacDockIconHandler::MacDockIconHandler() : QObject()
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
this->m_dockIconClickEventHandler = [[DockIconClickEventHandler alloc] initWithDockIconHandler:this];
|
||||
|
||||
this->m_dummyWidget = new QWidget();
|
||||
this->m_dockMenu = new QMenu(this->m_dummyWidget);
|
||||
qt_mac_set_dock_menu(this->m_dockMenu);
|
||||
[pool release];
|
||||
}
|
||||
|
||||
MacDockIconHandler::~MacDockIconHandler()
|
||||
{
|
||||
[this->m_dockIconClickEventHandler release];
|
||||
delete this->m_dummyWidget;
|
||||
}
|
||||
|
||||
QMenu *MacDockIconHandler::dockMenu()
|
||||
{
|
||||
return this->m_dockMenu;
|
||||
}
|
||||
|
||||
void MacDockIconHandler::setIcon(const QIcon &icon)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSImage *image;
|
||||
if (icon.isNull())
|
||||
image = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
|
||||
else {
|
||||
QSize size = icon.actualSize(QSize(128, 128));
|
||||
QPixmap pixmap = icon.pixmap(size);
|
||||
CGImageRef cgImage = pixmap.toMacCGImageRef();
|
||||
image = [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize];
|
||||
CFRelease(cgImage);
|
||||
}
|
||||
|
||||
[NSApp setApplicationIconImage:image];
|
||||
[image release];
|
||||
[pool release];
|
||||
}
|
||||
|
||||
MacDockIconHandler *MacDockIconHandler::instance()
|
||||
{
|
||||
static MacDockIconHandler *s_instance = NULL;
|
||||
if (!s_instance)
|
||||
s_instance = new MacDockIconHandler();
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void MacDockIconHandler::handleDockIconClickEvent()
|
||||
{
|
||||
emit this->dockIconClicked();
|
||||
}
|
||||
36
src/qt/monitoreddatamapper.cpp
Normal file
36
src/qt/monitoreddatamapper.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "monitoreddatamapper.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMetaObject>
|
||||
#include <QMetaProperty>
|
||||
|
||||
MonitoredDataMapper::MonitoredDataMapper(QObject *parent) :
|
||||
QDataWidgetMapper(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MonitoredDataMapper::addMapping(QWidget *widget, int section)
|
||||
{
|
||||
QDataWidgetMapper::addMapping(widget, section);
|
||||
addChangeMonitor(widget);
|
||||
}
|
||||
|
||||
void MonitoredDataMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName)
|
||||
{
|
||||
QDataWidgetMapper::addMapping(widget, section, propertyName);
|
||||
addChangeMonitor(widget);
|
||||
}
|
||||
|
||||
void MonitoredDataMapper::addChangeMonitor(QWidget *widget)
|
||||
{
|
||||
// Watch user property of widget for changes, and connect
|
||||
// the signal to our viewModified signal.
|
||||
QMetaProperty prop = widget->metaObject()->userProperty();
|
||||
int signal = prop.notifySignalIndex();
|
||||
int method = this->metaObject()->indexOfMethod("viewModified()");
|
||||
if(signal != -1 && method != -1)
|
||||
{
|
||||
QMetaObject::connect(widget, signal, this, method);
|
||||
}
|
||||
}
|
||||
31
src/qt/monitoreddatamapper.h
Normal file
31
src/qt/monitoreddatamapper.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef MONITOREDDATAMAPPER_H
|
||||
#define MONITOREDDATAMAPPER_H
|
||||
|
||||
#include <QDataWidgetMapper>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/** Data to Widget mapper that watches for edits and notifies listeners when a field is edited.
|
||||
This can be used, for example, to enable a commit/apply button in a configuration dialog.
|
||||
*/
|
||||
class MonitoredDataMapper : public QDataWidgetMapper
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MonitoredDataMapper(QObject *parent=0);
|
||||
|
||||
void addMapping(QWidget *widget, int section);
|
||||
void addMapping(QWidget *widget, int section, const QByteArray &propertyName);
|
||||
private:
|
||||
void addChangeMonitor(QWidget *widget);
|
||||
|
||||
signals:
|
||||
void viewModified();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // MONITOREDDATAMAPPER_H
|
||||
302
src/qt/notificator.cpp
Normal file
302
src/qt/notificator.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
#include "notificator.h"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
#include <QIcon>
|
||||
#include <QApplication>
|
||||
#include <QStyle>
|
||||
#include <QByteArray>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QMessageBox>
|
||||
#include <QTemporaryFile>
|
||||
#include <QImageWriter>
|
||||
|
||||
#ifdef USE_DBUS
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
extern bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret);
|
||||
#endif
|
||||
|
||||
// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128
|
||||
const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128;
|
||||
|
||||
Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, QWidget *parent):
|
||||
QObject(parent),
|
||||
parent(parent),
|
||||
programName(programName),
|
||||
mode(None),
|
||||
trayIcon(trayicon)
|
||||
#ifdef USE_DBUS
|
||||
,interface(0)
|
||||
#endif
|
||||
{
|
||||
if(trayicon && trayicon->supportsMessages())
|
||||
{
|
||||
mode = QSystemTray;
|
||||
}
|
||||
#ifdef USE_DBUS
|
||||
interface = new QDBusInterface("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications", "org.freedesktop.Notifications");
|
||||
if(interface->isValid())
|
||||
{
|
||||
mode = Freedesktop;
|
||||
}
|
||||
#endif
|
||||
#ifdef Q_WS_MAC
|
||||
// Check if Growl is installed (based on Qt's tray icon implementation)
|
||||
CFURLRef cfurl;
|
||||
OSStatus status = LSGetApplicationForInfo(kLSUnknownType, kLSUnknownCreator, CFSTR("growlTicket"), kLSRolesAll, 0, &cfurl);
|
||||
if (status != kLSApplicationNotFoundErr) {
|
||||
CFBundleRef bundle = CFBundleCreate(0, cfurl);
|
||||
if (CFStringCompare(CFBundleGetIdentifier(bundle), CFSTR("com.Growl.GrowlHelperApp"), kCFCompareCaseInsensitive | kCFCompareBackwards) == kCFCompareEqualTo) {
|
||||
if (CFStringHasSuffix(CFURLGetString(cfurl), CFSTR("/Growl.app/")))
|
||||
mode = Growl13;
|
||||
else
|
||||
mode = Growl12;
|
||||
}
|
||||
CFRelease(cfurl);
|
||||
CFRelease(bundle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Notificator::~Notificator()
|
||||
{
|
||||
#ifdef USE_DBUS
|
||||
delete interface;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_DBUS
|
||||
|
||||
// Loosely based on http://www.qtcentre.org/archive/index.php/t-25879.html
|
||||
class FreedesktopImage
|
||||
{
|
||||
public:
|
||||
FreedesktopImage() {}
|
||||
FreedesktopImage(const QImage &img);
|
||||
|
||||
static int metaType();
|
||||
|
||||
// Image to variant that can be marshaled over DBus
|
||||
static QVariant toVariant(const QImage &img);
|
||||
|
||||
private:
|
||||
int width, height, stride;
|
||||
bool hasAlpha;
|
||||
int channels;
|
||||
int bitsPerSample;
|
||||
QByteArray image;
|
||||
|
||||
friend QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i);
|
||||
friend const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(FreedesktopImage);
|
||||
|
||||
// Image configuration settings
|
||||
const int CHANNELS = 4;
|
||||
const int BYTES_PER_PIXEL = 4;
|
||||
const int BITS_PER_SAMPLE = 8;
|
||||
|
||||
FreedesktopImage::FreedesktopImage(const QImage &img):
|
||||
width(img.width()),
|
||||
height(img.height()),
|
||||
stride(img.width() * BYTES_PER_PIXEL),
|
||||
hasAlpha(true),
|
||||
channels(CHANNELS),
|
||||
bitsPerSample(BITS_PER_SAMPLE)
|
||||
{
|
||||
// Convert 00xAARRGGBB to RGBA bytewise (endian-independent) format
|
||||
QImage tmp = img.convertToFormat(QImage::Format_ARGB32);
|
||||
const uint32_t *data = reinterpret_cast<const uint32_t*>(tmp.constBits());
|
||||
|
||||
unsigned int num_pixels = width * height;
|
||||
image.resize(num_pixels * BYTES_PER_PIXEL);
|
||||
|
||||
for(unsigned int ptr = 0; ptr < num_pixels; ++ptr)
|
||||
{
|
||||
image[ptr*BYTES_PER_PIXEL+0] = data[ptr] >> 16; // R
|
||||
image[ptr*BYTES_PER_PIXEL+1] = data[ptr] >> 8; // G
|
||||
image[ptr*BYTES_PER_PIXEL+2] = data[ptr]; // B
|
||||
image[ptr*BYTES_PER_PIXEL+3] = data[ptr] >> 24; // A
|
||||
}
|
||||
}
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i)
|
||||
{
|
||||
a.beginStructure();
|
||||
a << i.width << i.height << i.stride << i.hasAlpha << i.bitsPerSample << i.channels << i.image;
|
||||
a.endStructure();
|
||||
return a;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i)
|
||||
{
|
||||
a.beginStructure();
|
||||
a >> i.width >> i.height >> i.stride >> i.hasAlpha >> i.bitsPerSample >> i.channels >> i.image;
|
||||
a.endStructure();
|
||||
return a;
|
||||
}
|
||||
|
||||
int FreedesktopImage::metaType()
|
||||
{
|
||||
return qDBusRegisterMetaType<FreedesktopImage>();
|
||||
}
|
||||
|
||||
QVariant FreedesktopImage::toVariant(const QImage &img)
|
||||
{
|
||||
FreedesktopImage fimg(img);
|
||||
return QVariant(FreedesktopImage::metaType(), &fimg);
|
||||
}
|
||||
|
||||
void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
|
||||
{
|
||||
Q_UNUSED(cls);
|
||||
// Arguments for DBus call:
|
||||
QList<QVariant> args;
|
||||
|
||||
// Program Name:
|
||||
args.append(programName);
|
||||
|
||||
// Unique ID of this notification type:
|
||||
args.append(0U);
|
||||
|
||||
// Application Icon, empty string
|
||||
args.append(QString());
|
||||
|
||||
// Summary
|
||||
args.append(title);
|
||||
|
||||
// Body
|
||||
args.append(text);
|
||||
|
||||
// Actions (none, actions are deprecated)
|
||||
QStringList actions;
|
||||
args.append(actions);
|
||||
|
||||
// Hints
|
||||
QVariantMap hints;
|
||||
|
||||
// If no icon specified, set icon based on class
|
||||
QIcon tmpicon;
|
||||
if(icon.isNull())
|
||||
{
|
||||
QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion;
|
||||
switch(cls)
|
||||
{
|
||||
case Information: sicon = QStyle::SP_MessageBoxInformation; break;
|
||||
case Warning: sicon = QStyle::SP_MessageBoxWarning; break;
|
||||
case Critical: sicon = QStyle::SP_MessageBoxCritical; break;
|
||||
default: break;
|
||||
}
|
||||
tmpicon = QApplication::style()->standardIcon(sicon);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpicon = icon;
|
||||
}
|
||||
hints["icon_data"] = FreedesktopImage::toVariant(tmpicon.pixmap(FREEDESKTOP_NOTIFICATION_ICON_SIZE).toImage());
|
||||
args.append(hints);
|
||||
|
||||
// Timeout (in msec)
|
||||
args.append(millisTimeout);
|
||||
|
||||
// "Fire and forget"
|
||||
interface->callWithArgumentList(QDBus::NoBlock, "Notify", args);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Notificator::notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
|
||||
{
|
||||
Q_UNUSED(icon);
|
||||
QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon;
|
||||
switch(cls) // Set icon based on class
|
||||
{
|
||||
case Information: sicon = QSystemTrayIcon::Information; break;
|
||||
case Warning: sicon = QSystemTrayIcon::Warning; break;
|
||||
case Critical: sicon = QSystemTrayIcon::Critical; break;
|
||||
}
|
||||
trayIcon->showMessage(title, text, sicon, millisTimeout);
|
||||
}
|
||||
|
||||
// Based on Qt's tray icon implementation
|
||||
#ifdef Q_WS_MAC
|
||||
void Notificator::notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon)
|
||||
{
|
||||
const QString script(
|
||||
"tell application \"%5\"\n"
|
||||
" set the allNotificationsList to {\"Notification\"}\n" // -- Make a list of all the notification types (all)
|
||||
" set the enabledNotificationsList to {\"Notification\"}\n" // -- Make a list of the notifications (enabled)
|
||||
" register as application \"%1\" all notifications allNotificationsList default notifications enabledNotificationsList\n" // -- Register our script with Growl
|
||||
" notify with name \"Notification\" title \"%2\" description \"%3\" application name \"%1\"%4\n" // -- Send a Notification
|
||||
"end tell"
|
||||
);
|
||||
|
||||
QString notificationApp(QApplication::applicationName());
|
||||
if (notificationApp.isEmpty())
|
||||
notificationApp = "Application";
|
||||
|
||||
QPixmap notificationIconPixmap;
|
||||
if (icon.isNull()) { // If no icon specified, set icon based on class
|
||||
QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion;
|
||||
switch (cls)
|
||||
{
|
||||
case Information: sicon = QStyle::SP_MessageBoxInformation; break;
|
||||
case Warning: sicon = QStyle::SP_MessageBoxWarning; break;
|
||||
case Critical: sicon = QStyle::SP_MessageBoxCritical; break;
|
||||
}
|
||||
notificationIconPixmap = QApplication::style()->standardPixmap(sicon);
|
||||
}
|
||||
else {
|
||||
QSize size = icon.actualSize(QSize(48, 48));
|
||||
notificationIconPixmap = icon.pixmap(size);
|
||||
}
|
||||
|
||||
QString notificationIcon;
|
||||
QTemporaryFile notificationIconFile;
|
||||
if (!notificationIconPixmap.isNull() && notificationIconFile.open()) {
|
||||
QImageWriter writer(¬ificationIconFile, "PNG");
|
||||
if (writer.write(notificationIconPixmap.toImage()))
|
||||
notificationIcon = QString(" image from location \"file://%1\"").arg(notificationIconFile.fileName());
|
||||
}
|
||||
|
||||
QString quotedTitle(title), quotedText(text);
|
||||
quotedTitle.replace("\\", "\\\\").replace("\"", "\\");
|
||||
quotedText.replace("\\", "\\\\").replace("\"", "\\");
|
||||
QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp");
|
||||
qt_mac_execute_apple_script(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
#ifdef USE_DBUS
|
||||
case Freedesktop:
|
||||
notifyDBus(cls, title, text, icon, millisTimeout);
|
||||
break;
|
||||
#endif
|
||||
case QSystemTray:
|
||||
notifySystray(cls, title, text, icon, millisTimeout);
|
||||
break;
|
||||
#ifdef Q_WS_MAC
|
||||
case Growl12:
|
||||
case Growl13:
|
||||
notifyGrowl(cls, title, text, icon);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
if(cls == Critical)
|
||||
{
|
||||
// Fall back to old fashioned popup dialog if critical and no other notification available
|
||||
QMessageBox::critical(parent, title, text, QMessageBox::Ok, QMessageBox::Ok);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
69
src/qt/notificator.h
Normal file
69
src/qt/notificator.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef NOTIFICATOR_H
|
||||
#define NOTIFICATOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QIcon>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSystemTrayIcon;
|
||||
#ifdef USE_DBUS
|
||||
class QDBusInterface;
|
||||
#endif
|
||||
QT_END_NAMESPACE
|
||||
|
||||
/** Cross-platform desktop notification client. */
|
||||
class Notificator: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** Create a new notificator.
|
||||
@note Ownership of trayIcon is not transferred to this object.
|
||||
*/
|
||||
Notificator(const QString &programName=QString(), QSystemTrayIcon *trayIcon=0, QWidget *parent=0);
|
||||
~Notificator();
|
||||
|
||||
// Message class
|
||||
enum Class
|
||||
{
|
||||
Information, /**< Informational message */
|
||||
Warning, /**< Notify user of potential problem */
|
||||
Critical /**< An error occured */
|
||||
};
|
||||
|
||||
public slots:
|
||||
|
||||
/** Show notification message.
|
||||
@param[in] cls general message class
|
||||
@param[in] title title shown with message
|
||||
@param[in] text message content
|
||||
@param[in] icon optional icon to show with message
|
||||
@param[in] millisTimeout notification timeout in milliseconds (defaults to 10 seconds)
|
||||
@note Platform implementations are free to ignore any of the provided fields except for \a text.
|
||||
*/
|
||||
void notify(Class cls, const QString &title, const QString &text,
|
||||
const QIcon &icon = QIcon(), int millisTimeout = 10000);
|
||||
|
||||
private:
|
||||
QWidget *parent;
|
||||
enum Mode {
|
||||
None, /**< Ignore informational notifications, and show a modal pop-up dialog for Critical notifications. */
|
||||
Freedesktop, /**< Use DBus org.freedesktop.Notifications */
|
||||
QSystemTray, /**< Use QSystemTray::showMessage */
|
||||
Growl12, /**< Use the Growl 1.2 notification system (Mac only) */
|
||||
Growl13 /**< Use the Growl 1.3 notification system (Mac only) */
|
||||
};
|
||||
QString programName;
|
||||
Mode mode;
|
||||
QSystemTrayIcon *trayIcon;
|
||||
#ifdef USE_DBUS
|
||||
QDBusInterface *interface;
|
||||
|
||||
void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
|
||||
#endif
|
||||
void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
|
||||
#ifdef Q_WS_MAC
|
||||
void notifyGrowl(Class cls, const QString &title, const QString &text, const QIcon &icon);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // NOTIFICATOR_H
|
||||
241
src/qt/optionsdialog.cpp
Normal file
241
src/qt/optionsdialog.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
#include "optionsdialog.h"
|
||||
#include "ui_optionsdialog.h"
|
||||
|
||||
#include "bitcoinamountfield.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "monitoreddatamapper.h"
|
||||
#include "netbase.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "qvalidatedlineedit.h"
|
||||
#include "qvaluecombobox.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QIntValidator>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRegExp>
|
||||
#include <QRegExpValidator>
|
||||
#include <QTabWidget>
|
||||
#include <QWidget>
|
||||
|
||||
OptionsDialog::OptionsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::OptionsDialog),
|
||||
model(0),
|
||||
mapper(0),
|
||||
fRestartWarningDisplayed_Proxy(false),
|
||||
fRestartWarningDisplayed_Lang(false),
|
||||
fProxyIpValid(true)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
/* Network elements init */
|
||||
#ifndef USE_UPNP
|
||||
ui->mapPortUpnp->setEnabled(false);
|
||||
#endif
|
||||
|
||||
ui->socksVersion->setEnabled(false);
|
||||
ui->socksVersion->addItem("5", 5);
|
||||
ui->socksVersion->addItem("4", 4);
|
||||
ui->socksVersion->setCurrentIndex(0);
|
||||
|
||||
ui->proxyIp->setEnabled(false);
|
||||
ui->proxyPort->setEnabled(false);
|
||||
ui->proxyPort->setValidator(new QIntValidator(0, 65535, this));
|
||||
|
||||
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->socksVersion, SLOT(setEnabled(bool)));
|
||||
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
|
||||
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
|
||||
|
||||
ui->proxyIp->installEventFilter(this);
|
||||
|
||||
/* Window elements init */
|
||||
#ifdef Q_WS_MAC
|
||||
ui->tabWindow->setVisible(false);
|
||||
#endif
|
||||
|
||||
/* Display elements init */
|
||||
QDir translations(":translations");
|
||||
ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
|
||||
foreach(const QString &langStr, translations.entryList())
|
||||
{
|
||||
QLocale locale(langStr);
|
||||
|
||||
/** check if the locale name consists of 2 parts (language_country) */
|
||||
if(langStr.contains("_"))
|
||||
{
|
||||
#if QT_VERSION >= 0x040800
|
||||
/** display language strings as "native language - native country (locale name)", e.g. "Deutsch - Deutschland (de)" */
|
||||
ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") + locale.nativeCountryName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
||||
#else
|
||||
/** display language strings as "language - country (locale name)", e.g. "German - Germany (de)" */
|
||||
ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" - ") + QLocale::countryToString(locale.country()) + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if QT_VERSION >= 0x040800
|
||||
/** display language strings as "native language (locale name)", e.g. "Deutsch (de)" */
|
||||
ui->lang->addItem(locale.nativeLanguageName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
||||
#else
|
||||
/** display language strings as "language (locale name)", e.g. "German (de)" */
|
||||
ui->lang->addItem(QLocale::languageToString(locale.language()) + QString(" (") + langStr + QString(")"), QVariant(langStr));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ui->unit->setModel(new BitcoinUnits(this));
|
||||
|
||||
connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning_Proxy()));
|
||||
connect(ui->lang, SIGNAL(activated(int)), this, SLOT(showRestartWarning_Lang()));
|
||||
|
||||
/* Widget-to-option mapper */
|
||||
mapper = new MonitoredDataMapper(this);
|
||||
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
||||
mapper->setOrientation(Qt::Vertical);
|
||||
|
||||
/* enable save buttons when data modified */
|
||||
connect(mapper, SIGNAL(viewModified()), this, SLOT(enableSaveButtons()));
|
||||
/* disable save buttons when new data loaded */
|
||||
connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(disableSaveButtons()));
|
||||
/* disable/enable save buttons when proxy IP is invalid/valid */
|
||||
connect(this, SIGNAL(proxyIpValid(bool)), this, SLOT(setSaveButtonState(bool)));
|
||||
}
|
||||
|
||||
OptionsDialog::~OptionsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void OptionsDialog::setModel(OptionsModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
|
||||
if(model)
|
||||
{
|
||||
connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
|
||||
mapper->setModel(model);
|
||||
setMapper();
|
||||
mapper->toFirst();
|
||||
}
|
||||
|
||||
// update the display unit, to not use the default ("BTC")
|
||||
updateDisplayUnit();
|
||||
}
|
||||
|
||||
void OptionsDialog::setMapper()
|
||||
{
|
||||
/* Main */
|
||||
mapper->addMapping(ui->transactionFee, OptionsModel::Fee);
|
||||
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
|
||||
mapper->addMapping(ui->detachDatabases, OptionsModel::DetachDatabases);
|
||||
|
||||
/* Network */
|
||||
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
|
||||
mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
|
||||
mapper->addMapping(ui->socksVersion, OptionsModel::ProxySocksVersion);
|
||||
mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
|
||||
mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);
|
||||
|
||||
/* Window */
|
||||
#ifndef Q_WS_MAC
|
||||
mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
|
||||
mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose);
|
||||
#endif
|
||||
|
||||
/* Display */
|
||||
mapper->addMapping(ui->lang, OptionsModel::Language);
|
||||
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
|
||||
mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses);
|
||||
}
|
||||
|
||||
void OptionsDialog::enableSaveButtons()
|
||||
{
|
||||
// prevent enabling of the save buttons when data modified, if there is an invalid proxy address present
|
||||
if(fProxyIpValid)
|
||||
setSaveButtonState(true);
|
||||
}
|
||||
|
||||
void OptionsDialog::disableSaveButtons()
|
||||
{
|
||||
setSaveButtonState(false);
|
||||
}
|
||||
|
||||
void OptionsDialog::setSaveButtonState(bool fState)
|
||||
{
|
||||
ui->applyButton->setEnabled(fState);
|
||||
ui->okButton->setEnabled(fState);
|
||||
}
|
||||
|
||||
void OptionsDialog::on_okButton_clicked()
|
||||
{
|
||||
mapper->submit();
|
||||
accept();
|
||||
}
|
||||
|
||||
void OptionsDialog::on_cancelButton_clicked()
|
||||
{
|
||||
reject();
|
||||
}
|
||||
|
||||
void OptionsDialog::on_applyButton_clicked()
|
||||
{
|
||||
mapper->submit();
|
||||
ui->applyButton->setEnabled(false);
|
||||
}
|
||||
|
||||
void OptionsDialog::showRestartWarning_Proxy()
|
||||
{
|
||||
if(!fRestartWarningDisplayed_Proxy)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting CasinoCoin."), QMessageBox::Ok);
|
||||
fRestartWarningDisplayed_Proxy = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsDialog::showRestartWarning_Lang()
|
||||
{
|
||||
if(!fRestartWarningDisplayed_Lang)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting CasinoCoin."), QMessageBox::Ok);
|
||||
fRestartWarningDisplayed_Lang = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OptionsDialog::updateDisplayUnit()
|
||||
{
|
||||
if(model)
|
||||
{
|
||||
// Update transactionFee with the current unit
|
||||
ui->transactionFee->setDisplayUnit(model->getDisplayUnit());
|
||||
}
|
||||
}
|
||||
|
||||
bool OptionsDialog::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
if(object == ui->proxyIp && event->type() == QEvent::FocusOut)
|
||||
{
|
||||
// Check proxyIP for a valid IPv4/IPv6 address
|
||||
CService addr;
|
||||
if(!LookupNumeric(ui->proxyIp->text().toStdString().c_str(), addr))
|
||||
{
|
||||
ui->proxyIp->setValid(false);
|
||||
fProxyIpValid = false;
|
||||
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
|
||||
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
|
||||
emit proxyIpValid(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
fProxyIpValid = true;
|
||||
ui->statusLabel->clear();
|
||||
emit proxyIpValid(true);
|
||||
}
|
||||
}
|
||||
return QDialog::eventFilter(object, event);
|
||||
}
|
||||
54
src/qt/optionsdialog.h
Normal file
54
src/qt/optionsdialog.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef OPTIONSDIALOG_H
|
||||
#define OPTIONSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class OptionsDialog;
|
||||
}
|
||||
class OptionsModel;
|
||||
class MonitoredDataMapper;
|
||||
|
||||
/** Preferences dialog. */
|
||||
class OptionsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OptionsDialog(QWidget *parent = 0);
|
||||
~OptionsDialog();
|
||||
|
||||
void setModel(OptionsModel *model);
|
||||
void setMapper();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event);
|
||||
|
||||
private slots:
|
||||
/* enable apply button and OK button */
|
||||
void enableSaveButtons();
|
||||
/* disable apply button and OK button */
|
||||
void disableSaveButtons();
|
||||
/* set apply button and OK button state (enabled / disabled) */
|
||||
void setSaveButtonState(bool fState);
|
||||
void on_okButton_clicked();
|
||||
void on_cancelButton_clicked();
|
||||
void on_applyButton_clicked();
|
||||
|
||||
void showRestartWarning_Proxy();
|
||||
void showRestartWarning_Lang();
|
||||
void updateDisplayUnit();
|
||||
|
||||
signals:
|
||||
void proxyIpValid(bool fValid);
|
||||
|
||||
private:
|
||||
Ui::OptionsDialog *ui;
|
||||
OptionsModel *model;
|
||||
MonitoredDataMapper *mapper;
|
||||
bool fRestartWarningDisplayed_Proxy;
|
||||
bool fRestartWarningDisplayed_Lang;
|
||||
bool fProxyIpValid;
|
||||
};
|
||||
|
||||
#endif // OPTIONSDIALOG_H
|
||||
284
src/qt/optionsmodel.cpp
Normal file
284
src/qt/optionsmodel.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
#include "optionsmodel.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include <QSettings>
|
||||
|
||||
#include "init.h"
|
||||
#include "walletdb.h"
|
||||
#include "guiutil.h"
|
||||
|
||||
OptionsModel::OptionsModel(QObject *parent) :
|
||||
QAbstractListModel(parent)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
bool static ApplyProxySettings()
|
||||
{
|
||||
QSettings settings;
|
||||
CService addrProxy(settings.value("addrProxy", "127.0.0.1:9050").toString().toStdString());
|
||||
int nSocksVersion(settings.value("nSocksVersion", 5).toInt());
|
||||
if (!settings.value("fUseProxy", false).toBool()) {
|
||||
addrProxy = CService();
|
||||
nSocksVersion = 0;
|
||||
return false;
|
||||
}
|
||||
if (nSocksVersion && !addrProxy.IsValid())
|
||||
return false;
|
||||
if (!IsLimited(NET_IPV4))
|
||||
SetProxy(NET_IPV4, addrProxy, nSocksVersion);
|
||||
if (nSocksVersion > 4) {
|
||||
#ifdef USE_IPV6
|
||||
if (!IsLimited(NET_IPV6))
|
||||
SetProxy(NET_IPV6, addrProxy, nSocksVersion);
|
||||
#endif
|
||||
SetNameProxy(addrProxy, nSocksVersion);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OptionsModel::Init()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
// These are Qt-only settings:
|
||||
nDisplayUnit = settings.value("nDisplayUnit", BitcoinUnits::BTC).toInt();
|
||||
bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool();
|
||||
fMinimizeToTray = settings.value("fMinimizeToTray", false).toBool();
|
||||
fMinimizeOnClose = settings.value("fMinimizeOnClose", false).toBool();
|
||||
nTransactionFee = settings.value("nTransactionFee").toLongLong();
|
||||
language = settings.value("language", "").toString();
|
||||
|
||||
// These are shared with core Bitcoin; we want
|
||||
// command-line options to override the GUI settings:
|
||||
if (settings.contains("fUseUPnP"))
|
||||
SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool());
|
||||
if (settings.contains("addrProxy") && settings.value("fUseProxy").toBool())
|
||||
SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString());
|
||||
if (settings.contains("nSocksVersion") && settings.value("fUseProxy").toBool())
|
||||
SoftSetArg("-socks", settings.value("nSocksVersion").toString().toStdString());
|
||||
if (settings.contains("detachDB"))
|
||||
SoftSetBoolArg("-detachdb", settings.value("detachDB").toBool());
|
||||
if (!language.isEmpty())
|
||||
SoftSetArg("-lang", language.toStdString());
|
||||
}
|
||||
|
||||
bool OptionsModel::Upgrade()
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
if (settings.contains("bImportFinished"))
|
||||
return false; // Already upgraded
|
||||
|
||||
settings.setValue("bImportFinished", true);
|
||||
|
||||
// Move settings from old wallet.dat (if any):
|
||||
CWalletDB walletdb("wallet.dat");
|
||||
|
||||
QList<QString> intOptions;
|
||||
intOptions << "nDisplayUnit" << "nTransactionFee";
|
||||
foreach(QString key, intOptions)
|
||||
{
|
||||
int value = 0;
|
||||
if (walletdb.ReadSetting(key.toStdString(), value))
|
||||
{
|
||||
settings.setValue(key, value);
|
||||
walletdb.EraseSetting(key.toStdString());
|
||||
}
|
||||
}
|
||||
QList<QString> boolOptions;
|
||||
boolOptions << "bDisplayAddresses" << "fMinimizeToTray" << "fMinimizeOnClose" << "fUseProxy" << "fUseUPnP";
|
||||
foreach(QString key, boolOptions)
|
||||
{
|
||||
bool value = false;
|
||||
if (walletdb.ReadSetting(key.toStdString(), value))
|
||||
{
|
||||
settings.setValue(key, value);
|
||||
walletdb.EraseSetting(key.toStdString());
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
CAddress addrProxyAddress;
|
||||
if (walletdb.ReadSetting("addrProxy", addrProxyAddress))
|
||||
{
|
||||
settings.setValue("addrProxy", addrProxyAddress.ToStringIPPort().c_str());
|
||||
walletdb.EraseSetting("addrProxy");
|
||||
}
|
||||
}
|
||||
catch (std::ios_base::failure &e)
|
||||
{
|
||||
// 0.6.0rc1 saved this as a CService, which causes failure when parsing as a CAddress
|
||||
CService addrProxy;
|
||||
if (walletdb.ReadSetting("addrProxy", addrProxy))
|
||||
{
|
||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
||||
walletdb.EraseSetting("addrProxy");
|
||||
}
|
||||
}
|
||||
ApplyProxySettings();
|
||||
Init();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int OptionsModel::rowCount(const QModelIndex & parent) const
|
||||
{
|
||||
return OptionIDRowCount;
|
||||
}
|
||||
|
||||
QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
||||
{
|
||||
if(role == Qt::EditRole)
|
||||
{
|
||||
QSettings settings;
|
||||
switch(index.row())
|
||||
{
|
||||
case StartAtStartup:
|
||||
return QVariant(GUIUtil::GetStartOnSystemStartup());
|
||||
case MinimizeToTray:
|
||||
return QVariant(fMinimizeToTray);
|
||||
case MapPortUPnP:
|
||||
return settings.value("fUseUPnP", GetBoolArg("-upnp", true));
|
||||
case MinimizeOnClose:
|
||||
return QVariant(fMinimizeOnClose);
|
||||
case ProxyUse:
|
||||
return settings.value("fUseProxy", false);
|
||||
case ProxyIP: {
|
||||
CService addrProxy;
|
||||
if (GetProxy(NET_IPV4, addrProxy))
|
||||
return QVariant(QString::fromStdString(addrProxy.ToStringIP()));
|
||||
else
|
||||
return QVariant(QString::fromStdString("127.0.0.1"));
|
||||
}
|
||||
case ProxyPort: {
|
||||
CService addrProxy;
|
||||
if (GetProxy(NET_IPV4, addrProxy))
|
||||
return QVariant(addrProxy.GetPort());
|
||||
else
|
||||
return 9050;
|
||||
}
|
||||
case ProxySocksVersion:
|
||||
return settings.value("nSocksVersion", 5);
|
||||
case Fee:
|
||||
return QVariant(nTransactionFee);
|
||||
case DisplayUnit:
|
||||
return QVariant(nDisplayUnit);
|
||||
case DisplayAddresses:
|
||||
return QVariant(bDisplayAddresses);
|
||||
case DetachDatabases:
|
||||
return QVariant(bitdb.GetDetach());
|
||||
case Language:
|
||||
return settings.value("language", "");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
|
||||
{
|
||||
bool successful = true; /* set to false on parse error */
|
||||
if(role == Qt::EditRole)
|
||||
{
|
||||
QSettings settings;
|
||||
switch(index.row())
|
||||
{
|
||||
case StartAtStartup:
|
||||
successful = GUIUtil::SetStartOnSystemStartup(value.toBool());
|
||||
break;
|
||||
case MinimizeToTray:
|
||||
fMinimizeToTray = value.toBool();
|
||||
settings.setValue("fMinimizeToTray", fMinimizeToTray);
|
||||
break;
|
||||
case MapPortUPnP:
|
||||
fUseUPnP = value.toBool();
|
||||
settings.setValue("fUseUPnP", fUseUPnP);
|
||||
MapPort();
|
||||
break;
|
||||
case MinimizeOnClose:
|
||||
fMinimizeOnClose = value.toBool();
|
||||
settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
|
||||
break;
|
||||
case ProxyUse:
|
||||
settings.setValue("fUseProxy", value.toBool());
|
||||
ApplyProxySettings();
|
||||
break;
|
||||
case ProxyIP:
|
||||
{
|
||||
CService addrProxy("127.0.0.1", 9050);
|
||||
GetProxy(NET_IPV4, addrProxy);
|
||||
CNetAddr addr(value.toString().toStdString());
|
||||
addrProxy.SetIP(addr);
|
||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
||||
successful = ApplyProxySettings();
|
||||
}
|
||||
break;
|
||||
case ProxyPort:
|
||||
{
|
||||
CService addrProxy("127.0.0.1", 9050);
|
||||
GetProxy(NET_IPV4, addrProxy);
|
||||
addrProxy.SetPort(value.toInt());
|
||||
settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str());
|
||||
successful = ApplyProxySettings();
|
||||
}
|
||||
break;
|
||||
case ProxySocksVersion:
|
||||
settings.setValue("nSocksVersion", value.toInt());
|
||||
ApplyProxySettings();
|
||||
break;
|
||||
case Fee:
|
||||
nTransactionFee = value.toLongLong();
|
||||
settings.setValue("nTransactionFee", nTransactionFee);
|
||||
break;
|
||||
case DisplayUnit:
|
||||
nDisplayUnit = value.toInt();
|
||||
settings.setValue("nDisplayUnit", nDisplayUnit);
|
||||
emit displayUnitChanged(nDisplayUnit);
|
||||
break;
|
||||
case DisplayAddresses:
|
||||
bDisplayAddresses = value.toBool();
|
||||
settings.setValue("bDisplayAddresses", bDisplayAddresses);
|
||||
break;
|
||||
case DetachDatabases: {
|
||||
bool fDetachDB = value.toBool();
|
||||
bitdb.SetDetach(fDetachDB);
|
||||
settings.setValue("detachDB", fDetachDB);
|
||||
}
|
||||
break;
|
||||
case Language:
|
||||
settings.setValue("language", value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
emit dataChanged(index, index);
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
qint64 OptionsModel::getTransactionFee()
|
||||
{
|
||||
return nTransactionFee;
|
||||
}
|
||||
|
||||
bool OptionsModel::getMinimizeToTray()
|
||||
{
|
||||
return fMinimizeToTray;
|
||||
}
|
||||
|
||||
bool OptionsModel::getMinimizeOnClose()
|
||||
{
|
||||
return fMinimizeOnClose;
|
||||
}
|
||||
|
||||
int OptionsModel::getDisplayUnit()
|
||||
{
|
||||
return nDisplayUnit;
|
||||
}
|
||||
|
||||
bool OptionsModel::getDisplayAddresses()
|
||||
{
|
||||
return bDisplayAddresses;
|
||||
}
|
||||
64
src/qt/optionsmodel.h
Normal file
64
src/qt/optionsmodel.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef OPTIONSMODEL_H
|
||||
#define OPTIONSMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
/** Interface from Qt to configuration data structure for Bitcoin client.
|
||||
To Qt, the options are presented as a list with the different options
|
||||
laid out vertically.
|
||||
This can be changed to a tree once the settings become sufficiently
|
||||
complex.
|
||||
*/
|
||||
class OptionsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OptionsModel(QObject *parent = 0);
|
||||
|
||||
enum OptionID {
|
||||
StartAtStartup, // bool
|
||||
MinimizeToTray, // bool
|
||||
MapPortUPnP, // bool
|
||||
MinimizeOnClose, // bool
|
||||
ProxyUse, // bool
|
||||
ProxyIP, // QString
|
||||
ProxyPort, // int
|
||||
ProxySocksVersion, // int
|
||||
Fee, // qint64
|
||||
DisplayUnit, // BitcoinUnits::Unit
|
||||
DisplayAddresses, // bool
|
||||
DetachDatabases, // bool
|
||||
Language, // QString
|
||||
OptionIDRowCount,
|
||||
};
|
||||
|
||||
void Init();
|
||||
|
||||
/* Migrate settings from wallet.dat after app initialization */
|
||||
bool Upgrade(); /* returns true if settings upgraded */
|
||||
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
|
||||
|
||||
/* Explicit getters */
|
||||
qint64 getTransactionFee();
|
||||
bool getMinimizeToTray();
|
||||
bool getMinimizeOnClose();
|
||||
int getDisplayUnit();
|
||||
bool getDisplayAddresses();
|
||||
QString getLanguage() { return language; }
|
||||
|
||||
private:
|
||||
int nDisplayUnit;
|
||||
bool bDisplayAddresses;
|
||||
bool fMinimizeToTray;
|
||||
bool fMinimizeOnClose;
|
||||
QString language;
|
||||
|
||||
signals:
|
||||
void displayUnitChanged(int unit);
|
||||
};
|
||||
|
||||
#endif // OPTIONSMODEL_H
|
||||
200
src/qt/overviewpage.cpp
Normal file
200
src/qt/overviewpage.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
#include "overviewpage.h"
|
||||
#include "ui_overviewpage.h"
|
||||
|
||||
#include "walletmodel.h"
|
||||
#include "bitcoinunits.h"
|
||||
#include "optionsmodel.h"
|
||||
#include "transactiontablemodel.h"
|
||||
#include "transactionfilterproxy.h"
|
||||
#include "guiutil.h"
|
||||
#include "guiconstants.h"
|
||||
|
||||
#include <QAbstractItemDelegate>
|
||||
#include <QPainter>
|
||||
|
||||
#define DECORATION_SIZE 64
|
||||
#define NUM_ITEMS 3
|
||||
|
||||
class TxViewDelegate : public QAbstractItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index ) const
|
||||
{
|
||||
painter->save();
|
||||
|
||||
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
|
||||
QRect mainRect = option.rect;
|
||||
QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
|
||||
int xspace = DECORATION_SIZE + 8;
|
||||
int ypad = 6;
|
||||
int halfheight = (mainRect.height() - 2*ypad)/2;
|
||||
QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
|
||||
QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
|
||||
icon.paint(painter, decorationRect);
|
||||
|
||||
QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
|
||||
QString address = index.data(Qt::DisplayRole).toString();
|
||||
qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
|
||||
bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
|
||||
QVariant value = index.data(Qt::ForegroundRole);
|
||||
QColor foreground = option.palette.color(QPalette::Text);
|
||||
if(qVariantCanConvert<QColor>(value))
|
||||
{
|
||||
foreground = qvariant_cast<QColor>(value);
|
||||
}
|
||||
|
||||
painter->setPen(foreground);
|
||||
painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address);
|
||||
|
||||
if(amount < 0)
|
||||
{
|
||||
foreground = COLOR_NEGATIVE;
|
||||
}
|
||||
else if(!confirmed)
|
||||
{
|
||||
foreground = COLOR_UNCONFIRMED;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreground = option.palette.color(QPalette::Text);
|
||||
}
|
||||
painter->setPen(foreground);
|
||||
QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true);
|
||||
if(!confirmed)
|
||||
{
|
||||
amountText = QString("[") + amountText + QString("]");
|
||||
}
|
||||
painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);
|
||||
|
||||
painter->setPen(option.palette.color(QPalette::Text));
|
||||
painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
return QSize(DECORATION_SIZE, DECORATION_SIZE);
|
||||
}
|
||||
|
||||
int unit;
|
||||
|
||||
};
|
||||
#include "overviewpage.moc"
|
||||
|
||||
OverviewPage::OverviewPage(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::OverviewPage),
|
||||
currentBalance(-1),
|
||||
currentUnconfirmedBalance(-1),
|
||||
currentImmatureBalance(-1),
|
||||
txdelegate(new TxViewDelegate()),
|
||||
filter(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// Recent transactions
|
||||
ui->listTransactions->setItemDelegate(txdelegate);
|
||||
ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
|
||||
ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
|
||||
ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
|
||||
connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));
|
||||
|
||||
// init "out of sync" warning labels
|
||||
ui->labelWalletStatus->setText("(" + tr("Out of sync") + ")");
|
||||
ui->labelTransactionsStatus->setText("(" + tr("Out of sync") + ")");
|
||||
|
||||
// start with displaying the "out of sync" warnings
|
||||
showOutOfSyncWarning(true);
|
||||
}
|
||||
|
||||
void OverviewPage::handleTransactionClicked(const QModelIndex &index)
|
||||
{
|
||||
if(filter)
|
||||
emit transactionClicked(filter->mapToSource(index));
|
||||
}
|
||||
|
||||
OverviewPage::~OverviewPage()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
|
||||
{
|
||||
int unit = model->getOptionsModel()->getDisplayUnit();
|
||||
currentBalance = balance;
|
||||
currentUnconfirmedBalance = unconfirmedBalance;
|
||||
currentImmatureBalance = immatureBalance;
|
||||
ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
|
||||
ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
|
||||
ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
|
||||
|
||||
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
|
||||
// for the non-mining users
|
||||
bool showImmature = immatureBalance != 0;
|
||||
ui->labelImmature->setVisible(showImmature);
|
||||
ui->labelImmatureText->setVisible(showImmature);
|
||||
}
|
||||
|
||||
void OverviewPage::setNumTransactions(int count)
|
||||
{
|
||||
ui->labelNumTransactions->setText(QLocale::system().toString(count));
|
||||
}
|
||||
|
||||
void OverviewPage::setModel(WalletModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
// Set up transaction list
|
||||
filter = new TransactionFilterProxy();
|
||||
filter->setSourceModel(model->getTransactionTableModel());
|
||||
filter->setLimit(NUM_ITEMS);
|
||||
filter->setDynamicSortFilter(true);
|
||||
filter->setSortRole(Qt::EditRole);
|
||||
filter->sort(TransactionTableModel::Status, Qt::DescendingOrder);
|
||||
|
||||
ui->listTransactions->setModel(filter);
|
||||
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
|
||||
|
||||
// Keep up to date with wallet
|
||||
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
|
||||
connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
|
||||
|
||||
setNumTransactions(model->getNumTransactions());
|
||||
connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));
|
||||
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
}
|
||||
|
||||
// update the display unit, to not use the default ("CSC")
|
||||
updateDisplayUnit();
|
||||
}
|
||||
|
||||
void OverviewPage::updateDisplayUnit()
|
||||
{
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
if(currentBalance != -1)
|
||||
setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance);
|
||||
|
||||
// Update txdelegate->unit with the current unit
|
||||
txdelegate->unit = model->getOptionsModel()->getDisplayUnit();
|
||||
|
||||
ui->listTransactions->update();
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewPage::showOutOfSyncWarning(bool fShow)
|
||||
{
|
||||
ui->labelWalletStatus->setVisible(fShow);
|
||||
ui->labelTransactionsStatus->setVisible(fShow);
|
||||
}
|
||||
51
src/qt/overviewpage.h
Normal file
51
src/qt/overviewpage.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef OVERVIEWPAGE_H
|
||||
#define OVERVIEWPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QModelIndex;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Ui {
|
||||
class OverviewPage;
|
||||
}
|
||||
class WalletModel;
|
||||
class TxViewDelegate;
|
||||
class TransactionFilterProxy;
|
||||
|
||||
/** Overview ("home") page widget */
|
||||
class OverviewPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OverviewPage(QWidget *parent = 0);
|
||||
~OverviewPage();
|
||||
|
||||
void setModel(WalletModel *model);
|
||||
void showOutOfSyncWarning(bool fShow);
|
||||
|
||||
public slots:
|
||||
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
|
||||
void setNumTransactions(int count);
|
||||
|
||||
signals:
|
||||
void transactionClicked(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
Ui::OverviewPage *ui;
|
||||
WalletModel *model;
|
||||
qint64 currentBalance;
|
||||
qint64 currentUnconfirmedBalance;
|
||||
qint64 currentImmatureBalance;
|
||||
|
||||
TxViewDelegate *txdelegate;
|
||||
TransactionFilterProxy *filter;
|
||||
|
||||
private slots:
|
||||
void updateDisplayUnit();
|
||||
void handleTransactionClicked(const QModelIndex &index);
|
||||
};
|
||||
|
||||
#endif // OVERVIEWPAGE_H
|
||||
171
src/qt/qrcodedialog.cpp
Normal file
171
src/qt/qrcodedialog.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include "qrcodedialog.h"
|
||||
#include "ui_qrcodedialog.h"
|
||||
|
||||
#include "bitcoinunits.h"
|
||||
#include "guiconstants.h"
|
||||
#include "guiutil.h"
|
||||
#include "optionsmodel.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QUrl>
|
||||
|
||||
#include <qrencode.h>
|
||||
|
||||
QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::QRCodeDialog),
|
||||
model(0),
|
||||
address(addr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowTitle(QString("%1").arg(address));
|
||||
|
||||
ui->chkReqPayment->setVisible(enableReq);
|
||||
ui->lblAmount->setVisible(enableReq);
|
||||
ui->lnReqAmount->setVisible(enableReq);
|
||||
|
||||
ui->lnLabel->setText(label);
|
||||
|
||||
ui->btnSaveAs->setEnabled(false);
|
||||
|
||||
genCode();
|
||||
}
|
||||
|
||||
QRCodeDialog::~QRCodeDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void QRCodeDialog::setModel(OptionsModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
|
||||
if (model)
|
||||
connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
|
||||
// update the display unit, to not use the default ("BTC")
|
||||
updateDisplayUnit();
|
||||
}
|
||||
|
||||
void QRCodeDialog::genCode()
|
||||
{
|
||||
QString uri = getURI();
|
||||
|
||||
if (uri != "")
|
||||
{
|
||||
ui->lblQRCode->setText("");
|
||||
|
||||
QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
|
||||
if (!code)
|
||||
{
|
||||
ui->lblQRCode->setText(tr("Error encoding URI into QR Code."));
|
||||
return;
|
||||
}
|
||||
myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32);
|
||||
myImage.fill(0xffffff);
|
||||
unsigned char *p = code->data;
|
||||
for (int y = 0; y < code->width; y++)
|
||||
{
|
||||
for (int x = 0; x < code->width; x++)
|
||||
{
|
||||
myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff));
|
||||
p++;
|
||||
}
|
||||
}
|
||||
QRcode_free(code);
|
||||
|
||||
ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300));
|
||||
|
||||
ui->outUri->setPlainText(uri);
|
||||
}
|
||||
}
|
||||
|
||||
QString QRCodeDialog::getURI()
|
||||
{
|
||||
QString ret = QString("casinocoin:%1").arg(address);
|
||||
int paramCount = 0;
|
||||
|
||||
ui->outUri->clear();
|
||||
|
||||
if (ui->chkReqPayment->isChecked())
|
||||
{
|
||||
if (ui->lnReqAmount->validate())
|
||||
{
|
||||
// even if we allow a non BTC unit input in lnReqAmount, we generate the URI with BTC as unit (as defined in BIP21)
|
||||
ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, ui->lnReqAmount->value()));
|
||||
paramCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->btnSaveAs->setEnabled(false);
|
||||
ui->lblQRCode->setText(tr("The entered amount is invalid, please check."));
|
||||
return QString("");
|
||||
}
|
||||
}
|
||||
|
||||
if (!ui->lnLabel->text().isEmpty())
|
||||
{
|
||||
QString lbl(QUrl::toPercentEncoding(ui->lnLabel->text()));
|
||||
ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl);
|
||||
paramCount++;
|
||||
}
|
||||
|
||||
if (!ui->lnMessage->text().isEmpty())
|
||||
{
|
||||
QString msg(QUrl::toPercentEncoding(ui->lnMessage->text()));
|
||||
ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg);
|
||||
paramCount++;
|
||||
}
|
||||
|
||||
// limit URI length to prevent a DoS against the QR-Code dialog
|
||||
if (ret.length() > MAX_URI_LENGTH)
|
||||
{
|
||||
ui->btnSaveAs->setEnabled(false);
|
||||
ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
|
||||
return QString("");
|
||||
}
|
||||
|
||||
ui->btnSaveAs->setEnabled(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_lnReqAmount_textChanged()
|
||||
{
|
||||
genCode();
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_lnLabel_textChanged()
|
||||
{
|
||||
genCode();
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_lnMessage_textChanged()
|
||||
{
|
||||
genCode();
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_btnSaveAs_clicked()
|
||||
{
|
||||
QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)"));
|
||||
if (!fn.isEmpty())
|
||||
myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn);
|
||||
}
|
||||
|
||||
void QRCodeDialog::on_chkReqPayment_toggled(bool fChecked)
|
||||
{
|
||||
if (!fChecked)
|
||||
// if chkReqPayment is not active, don't display lnReqAmount as invalid
|
||||
ui->lnReqAmount->setValid(true);
|
||||
|
||||
genCode();
|
||||
}
|
||||
|
||||
void QRCodeDialog::updateDisplayUnit()
|
||||
{
|
||||
if (model)
|
||||
{
|
||||
// Update lnReqAmount with the current unit
|
||||
ui->lnReqAmount->setDisplayUnit(model->getDisplayUnit());
|
||||
}
|
||||
}
|
||||
41
src/qt/qrcodedialog.h
Normal file
41
src/qt/qrcodedialog.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef QRCODEDIALOG_H
|
||||
#define QRCODEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QImage>
|
||||
|
||||
namespace Ui {
|
||||
class QRCodeDialog;
|
||||
}
|
||||
class OptionsModel;
|
||||
|
||||
class QRCodeDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent = 0);
|
||||
~QRCodeDialog();
|
||||
|
||||
void setModel(OptionsModel *model);
|
||||
|
||||
private slots:
|
||||
void on_lnReqAmount_textChanged();
|
||||
void on_lnLabel_textChanged();
|
||||
void on_lnMessage_textChanged();
|
||||
void on_btnSaveAs_clicked();
|
||||
void on_chkReqPayment_toggled(bool fChecked);
|
||||
|
||||
void updateDisplayUnit();
|
||||
|
||||
private:
|
||||
Ui::QRCodeDialog *ui;
|
||||
OptionsModel *model;
|
||||
QString address;
|
||||
QImage myImage;
|
||||
|
||||
void genCode();
|
||||
QString getURI();
|
||||
};
|
||||
|
||||
#endif // QRCODEDIALOG_H
|
||||
124
src/qt/qtipcserver.cpp
Normal file
124
src/qt/qtipcserver.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#if defined(WIN32) && BOOST_VERSION == 104900
|
||||
#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME
|
||||
#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME
|
||||
#endif
|
||||
|
||||
#include "qtipcserver.h"
|
||||
#include "guiconstants.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/interprocess/ipc/message_queue.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if defined(WIN32) && (!defined(BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME) || !defined(BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME) || BOOST_VERSION < 104900)
|
||||
#warning Compiling without BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME and BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME uncommented in boost/interprocess/detail/tmp_dir_helpers.hpp or using a boost version before 1.49 may have unintended results see svn.boost.org/trac/boost/ticket/5392
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::interprocess;
|
||||
using namespace boost::posix_time;
|
||||
|
||||
static void ipcThread2(void* pArg);
|
||||
|
||||
#ifdef MAC_OSX
|
||||
// URI handling not implemented on OSX yet
|
||||
|
||||
void ipcInit() { }
|
||||
|
||||
#else
|
||||
|
||||
static void ipcThread(void* pArg)
|
||||
{
|
||||
IMPLEMENT_RANDOMIZE_STACK(ipcThread(pArg));
|
||||
|
||||
// Make this thread recognisable as the GUI-IPC thread
|
||||
RenameThread("bitcoin-gui-ipc");
|
||||
|
||||
try
|
||||
{
|
||||
ipcThread2(pArg);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "ipcThread()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "ipcThread()");
|
||||
}
|
||||
printf("ipcThread exited\n");
|
||||
}
|
||||
|
||||
static void ipcThread2(void* pArg)
|
||||
{
|
||||
printf("ipcThread started\n");
|
||||
|
||||
message_queue* mq = (message_queue*)pArg;
|
||||
char buffer[MAX_URI_LENGTH + 1] = "";
|
||||
size_t nSize = 0;
|
||||
unsigned int nPriority = 0;
|
||||
|
||||
loop
|
||||
{
|
||||
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100);
|
||||
if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
|
||||
{
|
||||
uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
if (fShutdown)
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove message queue
|
||||
message_queue::remove(BITCOINURI_QUEUE_NAME);
|
||||
// Cleanup allocated memory
|
||||
delete mq;
|
||||
}
|
||||
|
||||
void ipcInit()
|
||||
{
|
||||
message_queue* mq = NULL;
|
||||
char buffer[MAX_URI_LENGTH + 1] = "";
|
||||
size_t nSize = 0;
|
||||
unsigned int nPriority = 0;
|
||||
|
||||
try {
|
||||
mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
|
||||
|
||||
// Make sure we don't lose any casinocoin: URIs
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1);
|
||||
if (mq->timed_receive(&buffer, sizeof(buffer), nSize, nPriority, d))
|
||||
{
|
||||
uiInterface.ThreadSafeHandleURI(std::string(buffer, nSize));
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Make sure only one casinocoin instance is listening
|
||||
message_queue::remove(BITCOINURI_QUEUE_NAME);
|
||||
delete mq;
|
||||
|
||||
mq = new message_queue(open_or_create, BITCOINURI_QUEUE_NAME, 2, MAX_URI_LENGTH);
|
||||
}
|
||||
catch (interprocess_exception &ex) {
|
||||
printf("ipcInit() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CreateThread(ipcThread, mq))
|
||||
{
|
||||
delete mq;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
9
src/qt/qtipcserver.h
Normal file
9
src/qt/qtipcserver.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef QTIPCSERVER_H
|
||||
#define QTIPCSERVER_H
|
||||
|
||||
// Define Bitcoin-Qt message queue name
|
||||
#define BITCOINURI_QUEUE_NAME "BitcoinURI"
|
||||
|
||||
void ipcInit();
|
||||
|
||||
#endif // QTIPCSERVER_H
|
||||
45
src/qt/qvalidatedlineedit.cpp
Normal file
45
src/qt/qvalidatedlineedit.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "qvalidatedlineedit.h"
|
||||
|
||||
#include "guiconstants.h"
|
||||
|
||||
QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) :
|
||||
QLineEdit(parent), valid(true)
|
||||
{
|
||||
connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid()));
|
||||
}
|
||||
|
||||
void QValidatedLineEdit::setValid(bool valid)
|
||||
{
|
||||
if(valid == this->valid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(valid)
|
||||
{
|
||||
setStyleSheet("");
|
||||
}
|
||||
else
|
||||
{
|
||||
setStyleSheet(STYLE_INVALID);
|
||||
}
|
||||
this->valid = valid;
|
||||
}
|
||||
|
||||
void QValidatedLineEdit::focusInEvent(QFocusEvent *evt)
|
||||
{
|
||||
// Clear invalid flag on focus
|
||||
setValid(true);
|
||||
QLineEdit::focusInEvent(evt);
|
||||
}
|
||||
|
||||
void QValidatedLineEdit::markValid()
|
||||
{
|
||||
setValid(true);
|
||||
}
|
||||
|
||||
void QValidatedLineEdit::clear()
|
||||
{
|
||||
setValid(true);
|
||||
QLineEdit::clear();
|
||||
}
|
||||
29
src/qt/qvalidatedlineedit.h
Normal file
29
src/qt/qvalidatedlineedit.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef QVALIDATEDLINEEDIT_H
|
||||
#define QVALIDATEDLINEEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
/** Line edit that can be marked as "invalid" to show input validation feedback. When marked as invalid,
|
||||
it will get a red background until it is focused.
|
||||
*/
|
||||
class QValidatedLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QValidatedLineEdit(QWidget *parent = 0);
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent *evt);
|
||||
|
||||
private:
|
||||
bool valid;
|
||||
|
||||
public slots:
|
||||
void setValid(bool valid);
|
||||
|
||||
private slots:
|
||||
void markValid();
|
||||
};
|
||||
|
||||
#endif // QVALIDATEDLINEEDIT_H
|
||||
27
src/qt/qvaluecombobox.cpp
Normal file
27
src/qt/qvaluecombobox.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "qvaluecombobox.h"
|
||||
|
||||
QValueComboBox::QValueComboBox(QWidget *parent) :
|
||||
QComboBox(parent), role(Qt::UserRole)
|
||||
{
|
||||
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(handleSelectionChanged(int)));
|
||||
}
|
||||
|
||||
QVariant QValueComboBox::value() const
|
||||
{
|
||||
return itemData(currentIndex(), role);
|
||||
}
|
||||
|
||||
void QValueComboBox::setValue(const QVariant &value)
|
||||
{
|
||||
setCurrentIndex(findData(value, role));
|
||||
}
|
||||
|
||||
void QValueComboBox::setRole(int role)
|
||||
{
|
||||
this->role = role;
|
||||
}
|
||||
|
||||
void QValueComboBox::handleSelectionChanged(int idx)
|
||||
{
|
||||
emit valueChanged();
|
||||
}
|
||||
33
src/qt/qvaluecombobox.h
Normal file
33
src/qt/qvaluecombobox.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef QVALUECOMBOBOX_H
|
||||
#define QVALUECOMBOBOX_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QVariant>
|
||||
|
||||
/* QComboBox that can be used with QDataWidgetMapper to select ordinal values from a model. */
|
||||
class QValueComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true)
|
||||
public:
|
||||
explicit QValueComboBox(QWidget *parent = 0);
|
||||
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
/** Specify model role to use as ordinal value (defaults to Qt::UserRole) */
|
||||
void setRole(int role);
|
||||
|
||||
signals:
|
||||
void valueChanged();
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
int role;
|
||||
|
||||
private slots:
|
||||
void handleSelectionChanged(int idx);
|
||||
};
|
||||
|
||||
#endif // QVALUECOMBOBOX_H
|
||||
1
src/qt/res/bitcoin-qt.rc
Normal file
1
src/qt/res/bitcoin-qt.rc
Normal file
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico"
|
||||
BIN
src/qt/res/icons/add.png
Normal file
BIN
src/qt/res/icons/add.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/qt/res/icons/address-book.png
Normal file
BIN
src/qt/res/icons/address-book.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/qt/res/icons/bitcoin.icns
Normal file
BIN
src/qt/res/icons/bitcoin.icns
Normal file
Binary file not shown.
BIN
src/qt/res/icons/bitcoin.ico
Normal file
BIN
src/qt/res/icons/bitcoin.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 345 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user