2011-07-07 17:33:15 +02:00
# include "addressbookpage.h"
# include "ui_addressbookpage.h"
# include "addresstablemodel.h"
2012-06-24 18:28:05 +02:00
# include "optionsmodel.h"
2011-12-23 16:14:57 +01:00
# include "bitcoingui.h"
2011-07-07 17:33:15 +02:00
# include "editaddressdialog.h"
2011-07-09 10:53:55 +02:00
# include "csvmodelwriter.h"
2011-12-04 18:01:53 +01:00
# include "guiutil.h"
2011-07-07 17:33:15 +02:00
2013-01-23 21:51:02 +01:00
# ifdef USE_QRCODE
# include "qrcodedialog.h"
# endif
2011-07-07 17:33:15 +02:00
# include <QSortFilterProxyModel>
# include <QClipboard>
2011-07-09 10:53:55 +02:00
# include <QMessageBox>
2011-12-04 18:01:53 +01:00
# include <QMenu>
2011-07-07 17:33:15 +02:00
AddressBookPage : : AddressBookPage ( Mode mode , Tabs tab , QWidget * parent ) :
QDialog ( parent ) ,
ui ( new Ui : : AddressBookPage ) ,
model ( 0 ) ,
2012-06-24 18:28:05 +02:00
optionsModel ( 0 ) ,
2011-07-07 17:33:15 +02:00
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 ( ) ) ;
ui - > verifyMessage - > setIcon ( QIcon ( ) ) ;
ui - > signMessage - > setIcon ( QIcon ( ) ) ;
2013-04-12 12:24:41 +02:00
ui - > exportButton - > setIcon ( QIcon ( ) ) ;
2011-10-07 13:21:45 +02:00
# endif
2011-11-10 15:20:17 +01:00
# ifndef USE_QRCODE
ui - > showQRCode - > setVisible ( false ) ;
# endif
2011-07-07 17:33:15 +02:00
switch ( mode )
{
case ForSending :
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-04-12 12:24:41 +02:00
ui - > exportButton - > hide ( ) ;
2011-07-07 17:33:15 +02:00
break ;
case ForEditing :
2012-04-01 13:22:13 +02:00
ui - > buttonBox - > setVisible ( false ) ;
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 ) ;
2012-04-01 13:22:13 +02:00
ui - > signMessage - > setVisible ( false ) ;
2011-07-07 17:33:15 +02:00
break ;
case ReceivingTab :
2013-04-02 12:08:13 +02:00
ui - > labelExplanation - > setText ( tr ( " These are your Bitcoin 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. " ) ) ;
ui - > deleteAddress - > setVisible ( false ) ;
2012-04-01 13:22:13 +02:00
ui - > signMessage - > setVisible ( true ) ;
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-04-02 12:08:13 +02:00
QAction * copyAddressAction = new QAction ( ui - > copyAddress - > text ( ) , 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-01-25 18:46:53 +01:00
QAction * sendCoinsAction = new QAction ( tr ( " Send &Coins " ) , this ) ;
2012-05-04 17:56:29 +02:00
QAction * showQRCodeAction = new QAction ( ui - > showQRCode - > text ( ) , this ) ;
QAction * signMessageAction = new QAction ( ui - > signMessage - > text ( ) , this ) ;
2012-06-15 09:48:26 +02:00
QAction * verifyMessageAction = new QAction ( ui - > verifyMessage - > text ( ) , 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 ( ) ;
2013-01-25 18:46:53 +01:00
if ( tab = = SendingTab )
contextMenu - > addAction ( sendCoinsAction ) ;
2013-01-10 08:52:39 +01:00
# ifdef USE_QRCODE
2012-05-04 17:56:29 +02:00
contextMenu - > addAction ( showQRCodeAction ) ;
2013-01-10 08:52:39 +01:00
# endif
2012-05-04 17:56:29 +02:00
if ( tab = = ReceivingTab )
contextMenu - > addAction ( signMessageAction ) ;
2012-06-15 09:48:26 +02:00
else if ( tab = = SendingTab )
contextMenu - > addAction ( verifyMessageAction ) ;
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 ( ) ) ) ;
connect ( sendCoinsAction , SIGNAL ( triggered ( ) ) , this , SLOT ( onSendCoinsAction ( ) ) ) ;
2012-05-04 17:56:29 +02:00
connect ( showQRCodeAction , SIGNAL ( triggered ( ) ) , this , SLOT ( on_showQRCode_clicked ( ) ) ) ;
connect ( signMessageAction , SIGNAL ( triggered ( ) ) , this , SLOT ( on_signMessage_clicked ( ) ) ) ;
2012-06-15 09:48:26 +02:00
connect ( verifyMessageAction , SIGNAL ( triggered ( ) ) , this , SLOT ( on_verifyMessage_clicked ( ) ) ) ;
2011-12-04 18:01:53 +01:00
connect ( ui - > tableView , SIGNAL ( customContextMenuRequested ( QPoint ) ) , this , SLOT ( contextualMenu ( QPoint ) ) ) ;
// Pass through accept action from button box
2011-07-07 18:25:27 +02:00
connect ( ui - > buttonBox , SIGNAL ( accepted ( ) ) , 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-04-02 12:08:13 +02:00
ui - > tableView - > horizontalHeader ( ) - > setResizeMode ( AddressTableModel : : Label , QHeaderView : : Stretch ) ;
ui - > tableView - > horizontalHeader ( ) - > setResizeMode ( AddressTableModel : : Address , QHeaderView : : ResizeToContents ) ;
2011-07-07 17:33:15 +02:00
connect ( ui - > tableView - > selectionModel ( ) , SIGNAL ( selectionChanged ( QItemSelection , QItemSelection ) ) ,
this , SLOT ( selectionChanged ( ) ) ) ;
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 ( ) ;
}
2012-06-24 18:28:05 +02:00
void AddressBookPage : : setOptionsModel ( OptionsModel * optionsModel )
{
this - > optionsModel = optionsModel ;
}
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 ( )
{
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 (
tab = = SendingTab ?
EditAddressDialog : : EditSendingAddress :
EditAddressDialog : : EditReceivingAddress ) ;
dlg . setModel ( model ) ;
QModelIndex origIndex = proxyModel - > mapToSource ( indexes . at ( 0 ) ) ;
dlg . loadRow ( origIndex . row ( ) ) ;
dlg . exec ( ) ;
2011-07-07 17:33:15 +02:00
}
2011-12-23 16:14:57 +01:00
void AddressBookPage : : on_signMessage_clicked ( )
{
QTableView * table = ui - > tableView ;
QModelIndexList indexes = table - > selectionModel ( ) - > selectedRows ( AddressTableModel : : Address ) ;
foreach ( QModelIndex index , indexes )
{
2013-01-10 08:52:39 +01:00
QString address = index . data ( ) . toString ( ) ;
emit signMessage ( address ) ;
2011-12-23 16:14:57 +01:00
}
2012-06-15 09:48:26 +02:00
}
void AddressBookPage : : on_verifyMessage_clicked ( )
{
QTableView * table = ui - > tableView ;
QModelIndexList indexes = table - > selectionModel ( ) - > selectedRows ( AddressTableModel : : Address ) ;
foreach ( QModelIndex index , indexes )
{
2013-01-10 08:52:39 +01:00
QString address = index . data ( ) . toString ( ) ;
emit verifyMessage ( address ) ;
2012-06-15 09:48:26 +02:00
}
2011-12-23 16:14:57 +01:00
}
2013-04-02 12:08:13 +02:00
void AddressBookPage : : onSendCoinsAction ( )
2013-01-25 18:46:53 +01:00
{
QTableView * table = ui - > tableView ;
QModelIndexList indexes = table - > selectionModel ( ) - > selectedRows ( AddressTableModel : : Address ) ;
foreach ( QModelIndex index , indexes )
{
QString address = index . data ( ) . toString ( ) ;
emit sendCoins ( address ) ;
}
}
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 (
tab = = SendingTab ?
EditAddressDialog : : NewSendingAddress :
2012-05-06 22:41:35 +02:00
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-12-23 16:14:57 +01:00
ui - > signMessage - > setEnabled ( false ) ;
2012-04-01 13:22:13 +02:00
ui - > signMessage - > setVisible ( false ) ;
2012-06-15 09:48:26 +02:00
ui - > verifyMessage - > setEnabled ( true ) ;
ui - > verifyMessage - > setVisible ( 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-12-23 16:14:57 +01:00
ui - > signMessage - > setEnabled ( true ) ;
2012-04-01 13:22:13 +02:00
ui - > signMessage - > setVisible ( true ) ;
2012-06-15 09:48:26 +02:00
ui - > verifyMessage - > setEnabled ( false ) ;
ui - > verifyMessage - > setVisible ( false ) ;
2011-07-07 17:33:15 +02:00
break ;
}
2013-04-02 12:08:13 +02:00
ui - > copyAddress - > setEnabled ( true ) ;
2011-11-10 15:20:17 +01:00
ui - > showQRCode - > setEnabled ( true ) ;
2011-07-07 17:33:15 +02:00
}
else
{
2013-04-02 12:08:13 +02:00
ui - > deleteAddress - > setEnabled ( false ) ;
2011-11-10 15:20:17 +01:00
ui - > showQRCode - > setEnabled ( false ) ;
2013-04-02 12:08:13 +02:00
ui - > copyAddress - > setEnabled ( false ) ;
2011-12-23 16:14:57 +01:00
ui - > signMessage - > setEnabled ( false ) ;
2012-06-15 09:48:26 +02:00
ui - > verifyMessage - > 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 17:33:15 +02:00
// When this is a tab/widget and not a model dialog, ignore "done"
if ( mode = = ForEditing )
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
2012-02-15 14:47:08 +01:00
QString filename = GUIUtil : : getSaveFileName (
2011-07-09 10:53:55 +02:00
this ,
2012-02-15 14:47:08 +01:00
tr ( " Export Address Book Data " ) , QString ( ) ,
2011-07-09 10:53:55 +02:00
tr ( " Comma separated file (*.csv) " ) ) ;
2011-07-15 02:11:11 +02:00
if ( filename . isNull ( ) ) return ;
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 ) ;
if ( ! writer . write ( ) )
{
QMessageBox : : critical ( this , tr ( " Error exporting " ) , tr ( " Could not write to file %1. " ) . arg ( filename ) ,
QMessageBox : : Abort , QMessageBox : : Abort ) ;
}
}
2011-11-10 15:20:17 +01:00
void AddressBookPage : : on_showQRCode_clicked ( )
{
# ifdef USE_QRCODE
QTableView * table = ui - > tableView ;
QModelIndexList indexes = table - > selectionModel ( ) - > selectedRows ( AddressTableModel : : Address ) ;
foreach ( QModelIndex index , indexes )
{
2013-01-10 08:52:39 +01:00
QString address = index . data ( ) . toString ( ) ;
QString label = index . sibling ( index . row ( ) , 0 ) . data ( Qt : : EditRole ) . toString ( ) ;
2011-11-10 15:20:17 +01:00
2012-04-11 23:05:22 +02:00
QRCodeDialog * dialog = new QRCodeDialog ( address , label , tab = = ReceivingTab , this ) ;
2013-01-10 08:52:39 +01:00
dialog - > setModel ( optionsModel ) ;
2012-02-27 12:55:04 +01:00
dialog - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
2012-04-11 14:21:15 +02:00
dialog - > show ( ) ;
2011-11-10 15:20:17 +01:00
}
# endif
}
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 ( ) ;
}
}