2014-12-17 02:47:57 +01:00
// Copyright (c) 2011-2013 The Bitcoin Core developers
2014-12-13 05:09:33 +01:00
// Distributed under the MIT software license, see the accompanying
2013-11-04 16:20:43 +01:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2013-05-28 01:55:01 +02:00
# if defined(HAVE_CONFIG_H)
2014-06-23 20:04:24 +02:00
# include "config/bitcoin-config.h"
2013-05-28 01:55:01 +02:00
# endif
2011-07-07 17:33:15 +02:00
# include "addressbookpage.h"
# include "ui_addressbookpage.h"
# include "addresstablemodel.h"
2011-12-23 16:14:57 +01:00
# include "bitcoingui.h"
2011-07-09 10:53:55 +02:00
# include "csvmodelwriter.h"
2013-04-13 07:13:08 +02:00
# include "editaddressdialog.h"
2011-12-04 18:01:53 +01:00
# include "guiutil.h"
2014-11-06 20:55:52 +01:00
# include "scicon.h"
2011-07-07 17:33:15 +02:00
2013-04-13 07:13:08 +02:00
# include <QIcon>
2011-12-04 18:01:53 +01:00
# include <QMenu>
2013-04-13 07:13:08 +02:00
# include <QMessageBox>
# include <QSortFilterProxyModel>
2011-07-07 17:33:15 +02:00
AddressBookPage : : AddressBookPage ( Mode mode , Tabs tab , QWidget * parent ) :
QDialog ( parent ) ,
ui ( new Ui : : AddressBookPage ) ,
model ( 0 ) ,
mode ( mode ) ,
tab ( tab )
{
ui - > setupUi ( this ) ;
2011-10-07 13:21:45 +02:00
2012-09-21 19:06:53 +02:00
# ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
2013-04-09 21:11:16 +02:00
ui - > newAddress - > setIcon ( QIcon ( ) ) ;
ui - > copyAddress - > setIcon ( QIcon ( ) ) ;
ui - > deleteAddress - > setIcon ( QIcon ( ) ) ;
2013-04-12 12:24:41 +02:00
ui - > exportButton - > setIcon ( QIcon ( ) ) ;
2014-11-06 20:55:52 +01:00
# else
ui - > newAddress - > setIcon ( SingleColorIcon ( " :/icons/add " ) ) ;
ui - > copyAddress - > setIcon ( SingleColorIcon ( " :/icons/editcopy " ) ) ;
ui - > deleteAddress - > setIcon ( SingleColorIcon ( " :/icons/remove " ) ) ;
ui - > exportButton - > setIcon ( SingleColorIcon ( " :/icons/export " ) ) ;
2011-10-07 13:21:45 +02:00
# endif
2011-07-07 17:33:15 +02:00
switch ( mode )
{
2013-10-16 15:14:26 +02:00
case ForSelection :
switch ( tab )
{
case SendingTab : setWindowTitle ( tr ( " Choose the address to send coins to " ) ) ; break ;
case ReceivingTab : setWindowTitle ( tr ( " Choose the address to receive coins with " ) ) ; break ;
}
2011-07-07 18:25:27 +02:00
connect ( ui - > tableView , SIGNAL ( doubleClicked ( QModelIndex ) ) , this , SLOT ( accept ( ) ) ) ;
ui - > tableView - > setEditTriggers ( QAbstractItemView : : NoEditTriggers ) ;
2011-07-07 17:33:15 +02:00
ui - > tableView - > setFocus ( ) ;
2013-10-18 19:42:40 +02:00
ui - > closeButton - > setText ( tr ( " C&hoose " ) ) ;
2013-04-12 12:24:41 +02:00
ui - > exportButton - > hide ( ) ;
2011-07-07 17:33:15 +02:00
break ;
case ForEditing :
2013-10-16 15:14:26 +02:00
switch ( tab )
{
case SendingTab : setWindowTitle ( tr ( " Sending addresses " ) ) ; break ;
case ReceivingTab : setWindowTitle ( tr ( " Receiving addresses " ) ) ; break ;
}
2011-07-07 17:33:15 +02:00
break ;
}
switch ( tab )
{
case SendingTab :
2013-04-02 12:08:13 +02:00
ui - > labelExplanation - > setText ( tr ( " These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins. " ) ) ;
ui - > deleteAddress - > setVisible ( true ) ;
2011-07-07 17:33:15 +02:00
break ;
case ReceivingTab :
2013-10-16 15:14:26 +02:00
ui - > labelExplanation - > setText ( tr ( " These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction. " ) ) ;
2013-04-02 12:08:13 +02:00
ui - > deleteAddress - > setVisible ( false ) ;
2011-07-07 17:33:15 +02:00
break ;
}
2011-07-07 18:25:27 +02:00
2011-12-04 18:01:53 +01:00
// Context menu actions
2013-10-25 14:19:44 +02:00
QAction * copyAddressAction = new QAction ( tr ( " &Copy Address " ) , this ) ;
2013-01-10 08:52:39 +01:00
QAction * copyLabelAction = new QAction ( tr ( " Copy &Label " ) , this ) ;
2012-05-04 17:56:29 +02:00
QAction * editAction = new QAction ( tr ( " &Edit " ) , this ) ;
2013-04-02 12:08:13 +02:00
deleteAction = new QAction ( ui - > deleteAddress - > text ( ) , this ) ;
2011-12-04 18:01:53 +01:00
2012-05-04 17:56:29 +02:00
// Build context menu
2011-12-04 18:01:53 +01:00
contextMenu = new QMenu ( ) ;
contextMenu - > addAction ( copyAddressAction ) ;
contextMenu - > addAction ( copyLabelAction ) ;
contextMenu - > addAction ( editAction ) ;
2012-05-04 17:56:29 +02:00
if ( tab = = SendingTab )
contextMenu - > addAction ( deleteAction ) ;
contextMenu - > addSeparator ( ) ;
2011-12-04 18:01:53 +01:00
2012-05-04 17:56:29 +02:00
// Connect signals for context menu actions
2013-04-02 12:08:13 +02:00
connect ( copyAddressAction , SIGNAL ( triggered ( ) ) , this , SLOT ( on_copyAddress_clicked ( ) ) ) ;
2011-12-04 18:01:53 +01:00
connect ( copyLabelAction , SIGNAL ( triggered ( ) ) , this , SLOT ( onCopyLabelAction ( ) ) ) ;
connect ( editAction , SIGNAL ( triggered ( ) ) , this , SLOT ( onEditAction ( ) ) ) ;
2013-04-02 12:08:13 +02:00
connect ( deleteAction , SIGNAL ( triggered ( ) ) , this , SLOT ( on_deleteAddress_clicked ( ) ) ) ;
2011-12-04 18:01:53 +01:00
connect ( ui - > tableView , SIGNAL ( customContextMenuRequested ( QPoint ) ) , this , SLOT ( contextualMenu ( QPoint ) ) ) ;
2013-10-18 19:42:40 +02:00
connect ( ui - > closeButton , SIGNAL ( clicked ( ) ) , this , SLOT ( accept ( ) ) ) ;
2011-07-07 17:33:15 +02:00
}
AddressBookPage : : ~ AddressBookPage ( )
{
delete ui ;
}
void AddressBookPage : : setModel ( AddressTableModel * model )
{
this - > model = model ;
2011-11-08 21:18:36 +01:00
if ( ! model )
return ;
2011-07-07 17:33:15 +02:00
2011-07-09 10:53:55 +02:00
proxyModel = new QSortFilterProxyModel ( this ) ;
proxyModel - > setSourceModel ( model ) ;
proxyModel - > setDynamicSortFilter ( true ) ;
2012-07-17 11:38:18 +02:00
proxyModel - > setSortCaseSensitivity ( Qt : : CaseInsensitive ) ;
proxyModel - > setFilterCaseSensitivity ( Qt : : CaseInsensitive ) ;
2011-07-07 17:33:15 +02:00
switch ( tab )
{
2011-07-09 10:53:55 +02:00
case ReceivingTab :
2011-07-07 17:33:15 +02:00
// Receive filter
2011-07-09 10:53:55 +02:00
proxyModel - > setFilterRole ( AddressTableModel : : TypeRole ) ;
proxyModel - > setFilterFixedString ( AddressTableModel : : Receive ) ;
break ;
case SendingTab :
2011-07-07 17:33:15 +02:00
// Send filter
2011-07-09 10:53:55 +02:00
proxyModel - > setFilterRole ( AddressTableModel : : TypeRole ) ;
proxyModel - > setFilterFixedString ( AddressTableModel : : Send ) ;
break ;
2011-07-07 17:33:15 +02:00
}
2011-07-09 10:53:55 +02:00
ui - > tableView - > setModel ( proxyModel ) ;
ui - > tableView - > sortByColumn ( 0 , Qt : : AscendingOrder ) ;
2011-07-07 17:33:15 +02:00
// Set column widths
2013-05-31 14:02:24 +02:00
# if QT_VERSION < 0x050000
2013-04-02 12:08:13 +02:00
ui - > tableView - > horizontalHeader ( ) - > setResizeMode ( AddressTableModel : : Label , QHeaderView : : Stretch ) ;
ui - > tableView - > horizontalHeader ( ) - > setResizeMode ( AddressTableModel : : Address , QHeaderView : : ResizeToContents ) ;
2013-05-31 14:02:24 +02:00
# else
ui - > tableView - > horizontalHeader ( ) - > setSectionResizeMode ( AddressTableModel : : Label , QHeaderView : : Stretch ) ;
ui - > tableView - > horizontalHeader ( ) - > setSectionResizeMode ( AddressTableModel : : Address , QHeaderView : : ResizeToContents ) ;
# endif
2011-07-07 17:33:15 +02:00
connect ( ui - > tableView - > selectionModel ( ) , SIGNAL ( selectionChanged ( QItemSelection , QItemSelection ) ) ,
2013-10-26 18:45:50 +02:00
this , SLOT ( selectionChanged ( ) ) ) ;
2011-07-07 17:33:15 +02:00
2012-05-06 22:41:35 +02:00
// Select row for newly created address
2013-04-02 12:08:13 +02:00
connect ( model , SIGNAL ( rowsInserted ( QModelIndex , int , int ) ) , this , SLOT ( selectNewAddress ( QModelIndex , int , int ) ) ) ;
2012-05-06 22:41:35 +02:00
2011-07-07 17:33:15 +02:00
selectionChanged ( ) ;
}
2013-04-02 12:08:13 +02:00
void AddressBookPage : : on_copyAddress_clicked ( )
2011-07-07 17:33:15 +02:00
{
2011-12-04 18:01:53 +01:00
GUIUtil : : copyEntryData ( ui - > tableView , AddressTableModel : : Address ) ;
}
2012-04-01 13:22:13 +02:00
2011-12-04 18:01:53 +01:00
void AddressBookPage : : onCopyLabelAction ( )
{
GUIUtil : : copyEntryData ( ui - > tableView , AddressTableModel : : Label ) ;
}
void AddressBookPage : : onEditAction ( )
{
2013-11-14 19:47:45 +01:00
if ( ! model )
return ;
2011-12-04 18:01:53 +01:00
if ( ! ui - > tableView - > selectionModel ( ) )
return ;
QModelIndexList indexes = ui - > tableView - > selectionModel ( ) - > selectedRows ( ) ;
if ( indexes . isEmpty ( ) )
2011-11-08 21:18:36 +01:00
return ;
2011-07-07 17:33:15 +02:00
2011-12-04 18:01:53 +01:00
EditAddressDialog dlg (
2013-11-14 19:47:45 +01:00
tab = = SendingTab ?
EditAddressDialog : : EditSendingAddress :
EditAddressDialog : : EditReceivingAddress , this ) ;
2011-12-04 18:01:53 +01:00
dlg . setModel ( model ) ;
QModelIndex origIndex = proxyModel - > mapToSource ( indexes . at ( 0 ) ) ;
dlg . loadRow ( origIndex . row ( ) ) ;
dlg . exec ( ) ;
2011-07-07 17:33:15 +02:00
}
2013-04-02 12:08:13 +02:00
void AddressBookPage : : on_newAddress_clicked ( )
2011-07-07 17:33:15 +02:00
{
2011-11-08 21:18:36 +01:00
if ( ! model )
return ;
2013-01-10 08:52:39 +01:00
2011-07-07 17:33:15 +02:00
EditAddressDialog dlg (
2013-11-14 19:47:45 +01:00
tab = = SendingTab ?
EditAddressDialog : : NewSendingAddress :
EditAddressDialog : : NewReceivingAddress , this ) ;
2011-07-07 17:33:15 +02:00
dlg . setModel ( model ) ;
2011-08-04 21:31:47 +02:00
if ( dlg . exec ( ) )
{
2012-05-06 22:41:35 +02:00
newAddressToSelect = dlg . getAddress ( ) ;
2011-08-04 21:31:47 +02:00
}
2011-07-07 17:33:15 +02:00
}
2013-04-02 12:08:13 +02:00
void AddressBookPage : : on_deleteAddress_clicked ( )
2011-07-07 17:33:15 +02:00
{
2011-11-08 21:18:36 +01:00
QTableView * table = ui - > tableView ;
if ( ! table - > selectionModel ( ) )
return ;
2013-01-10 08:52:39 +01:00
2011-07-07 17:33:15 +02:00
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
2011-11-08 21:18:36 +01:00
QTableView * table = ui - > tableView ;
if ( ! table - > selectionModel ( ) )
return ;
2011-07-07 17:33:15 +02:00
if ( table - > selectionModel ( ) - > hasSelection ( ) )
{
switch ( tab )
{
case SendingTab :
2011-12-04 18:01:53 +01:00
// In sending tab, allow deletion of selection
2013-04-02 12:08:13 +02:00
ui - > deleteAddress - > setEnabled ( true ) ;
ui - > deleteAddress - > setVisible ( true ) ;
2011-12-04 18:01:53 +01:00
deleteAction - > setEnabled ( true ) ;
2011-07-07 17:33:15 +02:00
break ;
case ReceivingTab :
2011-12-04 18:01:53 +01:00
// Deleting receiving addresses, however, is not allowed
2013-04-02 12:08:13 +02:00
ui - > deleteAddress - > setEnabled ( false ) ;
ui - > deleteAddress - > setVisible ( false ) ;
2011-12-04 18:01:53 +01:00
deleteAction - > setEnabled ( false ) ;
2011-07-07 17:33:15 +02:00
break ;
}
2013-04-02 12:08:13 +02:00
ui - > copyAddress - > setEnabled ( true ) ;
2011-07-07 17:33:15 +02:00
}
else
{
2013-04-02 12:08:13 +02:00
ui - > deleteAddress - > setEnabled ( false ) ;
ui - > copyAddress - > setEnabled ( false ) ;
2011-07-07 17:33:15 +02:00
}
}
void AddressBookPage : : done ( int retval )
{
2011-11-08 21:18:36 +01:00
QTableView * table = ui - > tableView ;
if ( ! table - > selectionModel ( ) | | ! table - > model ( ) )
return ;
2011-07-07 18:25:27 +02:00
// 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 ( ) )
{
2011-12-04 18:01:53 +01:00
// If no address entry selected, return rejected
2011-07-07 18:25:27 +02:00
retval = Rejected ;
}
2011-07-07 17:33:15 +02:00
QDialog : : done ( retval ) ;
}
2011-07-09 10:53:55 +02:00
2013-04-12 12:24:41 +02:00
void AddressBookPage : : on_exportButton_clicked ( )
2011-07-09 10:53:55 +02:00
{
// CSV is currently the only supported format
2013-11-11 22:57:25 +01:00
QString filename = GUIUtil : : getSaveFileName ( this ,
tr ( " Export Address List " ) , QString ( ) ,
tr ( " Comma separated file (*.csv) " ) , NULL ) ;
2011-07-09 10:53:55 +02:00
2013-10-26 18:45:50 +02:00
if ( filename . isNull ( ) )
return ;
2011-07-15 02:11:11 +02:00
2011-07-09 10:53:55 +02:00
CSVModelWriter writer ( filename ) ;
// name, column, role
writer . setModel ( proxyModel ) ;
writer . addColumn ( " Label " , AddressTableModel : : Label , Qt : : EditRole ) ;
writer . addColumn ( " Address " , AddressTableModel : : Address , Qt : : EditRole ) ;
2013-10-26 18:45:50 +02:00
if ( ! writer . write ( ) ) {
QMessageBox : : critical ( this , tr ( " Exporting Failed " ) ,
2014-07-14 20:22:35 +02:00
tr ( " There was an error trying to save the address list to %1. Please try again. " ) . arg ( filename ) ) ;
2011-07-09 10:53:55 +02:00
}
}
2011-11-10 15:20:17 +01:00
2011-12-04 18:01:53 +01:00
void AddressBookPage : : contextualMenu ( const QPoint & point )
{
QModelIndex index = ui - > tableView - > indexAt ( point ) ;
if ( index . isValid ( ) )
{
contextMenu - > exec ( QCursor : : pos ( ) ) ;
}
}
2012-05-06 22:41:35 +02:00
2012-12-15 11:15:19 +01:00
void AddressBookPage : : selectNewAddress ( const QModelIndex & parent , int begin , int /*end*/ )
2012-05-06 22:41:35 +02:00
{
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 ( ) ;
}
}