package org.ripple.power.ui.btc;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.WindowConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;
import org.ripple.power.txns.btc.Address;
import org.ripple.power.txns.btc.BTCLoader;
import org.ripple.power.txns.btc.BlockStoreException;
import org.ripple.power.ui.UIRes;
import org.ripple.power.ui.table.AddressTable;
import org.ripple.power.ui.view.ButtonPane;
import org.ripple.power.ui.view.log.ErrorLog;
public class SendAddressDialog extends JDialog implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final Class<?>[] columnClasses = { String.class,
String.class };
private static final String[] columnNames = { "Name", "Address" };
private static final int[] columnTypes = { AddressTable.NAME,
AddressTable.ADDRESS };
private final AddressTableModel tableModel;
private final AddressTable table;
private final JScrollPane scrollPane;
public SendAddressDialog(JDialog parent) {
super(parent, "Send Addresses", Dialog.ModalityType.DOCUMENT_MODAL);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
tableModel = new AddressTableModel(columnNames, columnClasses);
table = new AddressTable(tableModel, columnTypes);
table.setRowSorter(new TableRowSorter<>(tableModel));
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
scrollPane = new JScrollPane(table);
JPanel tablePane = new JPanel();
tablePane.setBackground(Color.WHITE);
tablePane.add(Box.createGlue());
tablePane.add(scrollPane);
tablePane.add(Box.createGlue());
JPanel buttonPane = new ButtonPane(this, 10, new String[] { "New",
"new" }, new String[] { "Copy", "copy" }, new String[] {
"Edit", "edit" }, new String[] { "Delete", "delete" },
new String[] { "Done", "done" });
buttonPane.setBackground(Color.white);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
contentPane.setOpaque(true);
contentPane.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
contentPane.setBackground(Color.WHITE);
contentPane.add(tablePane);
contentPane.add(buttonPane);
setContentPane(contentPane);
}
public static void showDialog(JDialog parent) {
try {
JDialog dialog = new SendAddressDialog(parent);
dialog.pack();
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
} catch (Exception exc) {
ErrorLog.get().logException("Exception while displaying dialog", exc);
}
}
@Override
public void actionPerformed(ActionEvent ae) {
try {
String action = ae.getActionCommand();
if (action.equals("done")) {
setVisible(false);
dispose();
} else if (action.equals("new")) {
editAddress(null, -1);
} else {
int row = table.getSelectedRow();
if (row < 0) {
UIRes.showErrorMessage(this,"Error", "No entry selected");
} else {
row = table.convertRowIndexToModel(row);
Address addr = BTCLoader.addresses.get(row);
switch (action) {
case "copy":
StringSelection sel = new StringSelection(
addr.toString());
Clipboard cb = Toolkit.getDefaultToolkit()
.getSystemClipboard();
cb.setContents(sel, null);
break;
case "edit":
editAddress(addr, row);
break;
case "delete":
BTCLoader.addresses.remove(row);
BTCLoader.blockStore.deleteAddress(addr);
tableModel.fireTableDataChanged();
break;
}
}
}
} catch (BlockStoreException exc) {
ErrorLog.get().logException("Unable to update blockStore database", exc);
} catch (Exception exc) {
ErrorLog.get().logException("Exception while processing action event",
exc);
}
}
private void editAddress(Address address, int row)
throws BlockStoreException {
Address addr = address;
while (true) {
addr = AddressEditDialog.showDialog(this, addr, true);
if (addr == null)
break;
String label = addr.getLabel();
boolean valid = true;
synchronized (BTCLoader.lock) {
for (Address chkAddr : BTCLoader.addresses) {
if (chkAddr.equals(address))
continue;
if (chkAddr.getLabel().compareToIgnoreCase(label) == 0) {
UIRes.showErrorMessage(this,"Error",
"Duplicate name specified");
valid = false;
break;
}
}
if (valid) {
if (row >= 0) {
BTCLoader.addresses.remove(row);
}
boolean added = false;
for (int i = 0; i < BTCLoader.addresses.size(); i++) {
Address chkAddr = BTCLoader.addresses.get(i);
if (chkAddr.getLabel().compareToIgnoreCase(label) > 0) {
BTCLoader.addresses.add(i, addr);
added = true;
break;
}
}
if (!added) {
BTCLoader.addresses.add(addr);
}
}
}
if (valid) {
if (row >= 0)
BTCLoader.blockStore.setAddressLabel(addr);
else
BTCLoader.blockStore.storeAddress(addr);
tableModel.fireTableDataChanged();
break;
}
}
}
private class AddressTableModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = 1L;
private String[] columnNames;
private Class<?>[] columnClasses;
public AddressTableModel(String[] columnNames, Class<?>[] columnClasses) {
super();
if (columnNames.length != columnClasses.length) {
throw new IllegalArgumentException(
"Number of names not same as number of classes");
}
this.columnNames = columnNames;
this.columnClasses = columnClasses;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Class<?> getColumnClass(int column) {
return columnClasses[column];
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public int getRowCount() {
return BTCLoader.addresses.size();
}
@Override
public Object getValueAt(int row, int column) {
if (row >= BTCLoader.addresses.size()){
throw new IndexOutOfBoundsException("Table row " + row
+ " is not valid");
}
Object value;
Address addr = BTCLoader.addresses.get(row);
switch (column) {
case 0:
value = addr.getLabel();
break;
case 1:
value = addr.toString();
break;
default:
throw new IndexOutOfBoundsException("Table column " + column
+ " is not valid");
}
return value;
}
}
}