/**
* Copyright 2011 multibit.org
*
* Licensed under the MIT license (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://opensource.org/licenses/mit-license.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.multibit.viewsystem.swing.view.panels;
import org.multibit.controller.bitcoin.BitcoinController;
import org.multibit.exchange.CurrencyConverter;
import org.multibit.exchange.CurrencyConverterResult;
import org.multibit.model.bitcoin.BitcoinModel;
import org.multibit.model.bitcoin.WalletAddressBookData;
import org.multibit.model.bitcoin.WalletInfoData;
import org.multibit.model.core.CoreModel;
import org.multibit.utils.ImageLoader;
import org.multibit.viewsystem.DisplayHint;
import org.multibit.viewsystem.View;
import org.multibit.viewsystem.Viewable;
import org.multibit.viewsystem.swing.ColorAndFontConstants;
import org.multibit.viewsystem.swing.MultiBitFrame;
import org.multibit.viewsystem.swing.action.*;
import org.multibit.viewsystem.swing.view.components.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.ArrayList;
public class ReceiveBitcoinPanel extends AbstractTradePanel implements Viewable {
static final Logger log = LoggerFactory.getLogger(ReceiveBitcoinPanel.class);
private static final long serialVersionUID = -2065108865497842662L;
private CreateNewReceivingAddressAction createNewReceivingAddressAction;
public ReceiveBitcoinPanel(BitcoinController bitcoinController, MultiBitFrame mainFrame) {
super(mainFrame, bitcoinController);
}
@Override
protected boolean isReceiveBitcoin() {
return true;
}
@Override
protected Action getCreateNewAddressAction() {
createNewReceivingAddressAction = new CreateNewReceivingAddressAction(super.bitcoinController, mainFrame, this);
return createNewReceivingAddressAction;
}
@Override
protected Action getDeleteAddressAction() {
// Return a delete sending address action - it gets turned into a stent
return new DeleteSendingAddressAction(super.bitcoinController, mainFrame, null);
}
@Override
public String getAddressConstant() {
return BitcoinModel.RECEIVE_ADDRESS;
}
@Override
public String getLabelConstant() {
return BitcoinModel.RECEIVE_LABEL;
}
@Override
public String getAmountConstant() {
return BitcoinModel.RECEIVE_AMOUNT;
}
/**
* method for concrete impls to populate the localisation map
*/
@Override
protected void populateLocalisationMap() {
localisationKeyConstantToKeyMap.put(ADDRESSES_TITLE, "receiveBitcoinPanel.receivingAddressesTitle");
localisationKeyConstantToKeyMap.put(CREATE_NEW_TOOLTIP, "createOrEditAddressAction.createReceiving.tooltip");
}
@Override
protected JPanel createFormPanel(JPanel formPanel, GridBagConstraints constraints) {
formPanel.setBackground(ColorAndFontConstants.VERY_LIGHT_BACKGROUND_COLOR);
JPanel buttonPanel = new JPanel();
FlowLayout flowLayout = new FlowLayout();
flowLayout.setAlignment(FlowLayout.LEADING);
buttonPanel.setLayout(flowLayout);
formPanel.setLayout(new GridBagLayout());
JPanel filler1 = new JPanel();
filler1.setOpaque(false);
// create stents and forcers
createFormPanelStentsAndForcers(formPanel, constraints);
MultiBitLabel addressLabel = new MultiBitLabel(controller.getLocaliser().getString("receiveBitcoinPanel.addressLabel"));
addressLabel.setToolTipText(HelpContentsPanel.createTooltipText(controller.getLocaliser().getString("receiveBitcoinPanel.addressLabel.tooltip")));
addressLabel.setBorder(BorderFactory.createMatteBorder((int) (TEXTFIELD_VERTICAL_DELTA * 0.5), 0, (int) (TEXTFIELD_VERTICAL_DELTA * 0.5), 0, ColorAndFontConstants.VERY_LIGHT_BACKGROUND_COLOR));
addressLabel.setHorizontalAlignment(JLabel.TRAILING);
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 0;
constraints.gridy = 1;
constraints.weightx = 1;
constraints.weighty = 0.2;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_END;
formPanel.add(addressLabel, constraints);
FontMetrics fontMetric = getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont());
int longFieldWidth = fontMetric.stringWidth(MultiBitFrame.EXAMPLE_LONG_FIELD_TEXT);
addressTextField = new MultiBitTextField("", 24, controller);
//addressTextField = new MultiBitTextArea("", 24, 1, controller);
addressTextField.setEditable(false);
addressTextField.setOpaque(false);
Insets insets = addressTextField.getBorder().getBorderInsets(addressTextField);
addressTextField.setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right));
addressTextField.setMinimumSize(new Dimension(longFieldWidth, getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont()).getHeight()));
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 2;
constraints.gridy = 1;
constraints.weightx = 0.1;
constraints.weighty = 0.2;
constraints.gridwidth = 3;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_START;
formPanel.add(addressTextField, constraints);
ImageIcon copyIcon = ImageLoader.createImageIcon(ImageLoader.COPY_ICON_FILE);
CopyReceiveAddressAction copyAddressAction = new CopyReceiveAddressAction(controller, this, copyIcon);
MultiBitButton copyAddressButton = new MultiBitButton(copyAddressAction, controller);
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 6;
constraints.gridy = 1;
constraints.weightx = 1;
constraints.gridwidth = 1;
constraints.anchor = GridBagConstraints.LINE_START;
formPanel.add(copyAddressButton, constraints);
JPanel pasteButtonStent = MultiBitTitledPanel.createStent((int) copyAddressButton.getPreferredSize().getWidth(), (int) copyAddressButton.getPreferredSize().getHeight());
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 8;
constraints.gridy = 1;
constraints.weightx = 10.0;
constraints.weighty = 0.2;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_START;
formPanel.add(pasteButtonStent, constraints);
MultiBitLabel labelLabel = new MultiBitLabel(controller.getLocaliser().getString("receiveBitcoinPanel.labelLabel"));
labelLabel.setToolTipText(HelpContentsPanel.createTooltipText(controller.getLocaliser().getString("receiveBitcoinPanel.labelLabel.tooltip")));
labelLabel.setHorizontalAlignment(JLabel.TRAILING);
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 0;
constraints.gridy = 3;
constraints.weightx = 0.1;
constraints.weighty = 1.0;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_END;
formPanel.add(labelLabel, constraints);
JTextField aTextField = new JTextField();
labelTextArea = new MultiBitTextArea("", AbstractTradePanel.PREFERRED_NUMBER_OF_LABEL_ROWS, 20, controller);
labelTextArea.setBorder(aTextField.getBorder());
labelTextArea.addKeyListener(new QRCodeKeyListener());
final JScrollPane labelScrollPane = new JScrollPane(labelTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
labelScrollPane.setOpaque(true);
labelScrollPane.setBackground(ColorAndFontConstants.VERY_LIGHT_BACKGROUND_COLOR);
labelScrollPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
labelScrollPane.getViewport().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (labelScrollPane.getVerticalScrollBar().isVisible()) {
labelScrollPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
} else {
labelScrollPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
}
}
});
labelScrollPane.setMinimumSize(new Dimension(longFieldWidth, getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont())
.getHeight() * AbstractTradePanel.PREFERRED_NUMBER_OF_LABEL_ROWS + TEXTFIELD_VERTICAL_DELTA));
labelScrollPane.setMinimumSize(new Dimension(longFieldWidth, getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont())
.getHeight() * AbstractTradePanel.PREFERRED_NUMBER_OF_LABEL_ROWS + TEXTFIELD_VERTICAL_DELTA + 6));
labelScrollPane.setPreferredSize(new Dimension(longFieldWidth, getFontMetrics(FontSizer.INSTANCE.getAdjustedDefaultFont())
.getHeight() * AbstractTradePanel.PREFERRED_NUMBER_OF_LABEL_ROWS + TEXTFIELD_VERTICAL_DELTA + 6));
labelScrollPane.getHorizontalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);
labelScrollPane.getVerticalScrollBar().setUnitIncrement(CoreModel.SCROLL_INCREMENT);
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 2;
constraints.gridy = 3;
constraints.weightx = 0.6;
constraints.weighty = 1.0;
constraints.gridwidth = 4;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_START;
formPanel.add(labelScrollPane, constraints);
MultiBitLabel amountLabel = new MultiBitLabel(controller.getLocaliser().getString("receiveBitcoinPanel.amountLabel"));
amountLabel.setToolTipText(HelpContentsPanel.createTooltipText(controller.getLocaliser().getString("receiveBitcoinPanel.amountLabel.tooltip")));
amountLabel.setHorizontalAlignment(JLabel.TRAILING);
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 0;
constraints.gridy = 5;
constraints.weightx = 0.1;
constraints.weighty = 0.2;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_END;
formPanel.add(amountLabel, constraints);
JPanel amountPanel = createAmountPanel();
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 2;
constraints.gridy = 5;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.weightx = 0.1;
constraints.weighty = 0.20;
constraints.anchor = GridBagConstraints.LINE_START;
formPanel.add(amountPanel, constraints);
notificationLabel = new MultiBitLabel("");
notificationLabel.setForeground(Color.RED);
//notificationLabel.setBorder(BorderFactory.createLineBorder(Color.GREEN));
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 2;
constraints.gridy = 6;
constraints.gridwidth = 8;
constraints.gridheight = 3;
constraints.weightx = 0.1;
constraints.weighty = 0.1;
constraints.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING;
formPanel.add(notificationLabel, constraints);
Action helpAction;
if (ComponentOrientation.LEFT_TO_RIGHT == ComponentOrientation.getOrientation(controller.getLocaliser().getLocale())) {
helpAction = new HelpContextAction(controller, ImageLoader.HELP_CONTENTS_BIG_ICON_FILE,
"multiBitFrame.helpMenuText", "multiBitFrame.helpMenuTooltip", "multiBitFrame.helpMenuText",
HelpContentsPanel.HELP_RECEIVING_URL);
} else {
helpAction = new HelpContextAction(controller, ImageLoader.HELP_CONTENTS_BIG_RTL_ICON_FILE,
"multiBitFrame.helpMenuText", "multiBitFrame.helpMenuTooltip", "multiBitFrame.helpMenuText",
HelpContentsPanel.HELP_RECEIVING_URL);
}
HelpButton helpButton = new HelpButton(helpAction, controller);
helpButton.setText("");
String tooltipText = HelpContentsPanel.createMultilineTooltipText(new String[]{controller.getLocaliser().getString("receiveBitcoinPanel.helpLabel1.message"),
controller.getLocaliser().getString("receiveBitcoinPanel.helpLabel2.message"), controller.getLocaliser().getString("receiveBitcoinPanel.helpLabel3.message"),
"\n", controller.getLocaliser().getString("multiBitFrame.helpMenuTooltip")});
helpButton.setToolTipText(tooltipText);
helpButton.setHorizontalAlignment(SwingConstants.LEADING);
helpButton.setBorder(BorderFactory.createEmptyBorder(0, HELP_BUTTON_INDENT, HELP_BUTTON_INDENT, HELP_BUTTON_INDENT));
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 0;
constraints.gridy = 8;
constraints.weightx = 1;
constraints.weighty = 0.3;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.BELOW_BASELINE_LEADING;
formPanel.add(helpButton, constraints);
SendBitcoinConfirmAction sendBitcoinConfirmAction = new SendBitcoinConfirmAction(super.bitcoinController, mainFrame, this);
MultiBitButton notUsedSendButton = new MultiBitButton(sendBitcoinConfirmAction, controller);
JPanel sendButtonStent = MultiBitTitledPanel.createStent((int) notUsedSendButton.getPreferredSize().getWidth(), (int) notUsedSendButton.getPreferredSize().getHeight());
constraints.fill = GridBagConstraints.BOTH;
constraints.gridx = 6;
constraints.gridy = 5;
constraints.weightx = 0.1;
constraints.weighty = 0.1;
constraints.gridwidth = 3;
constraints.gridheight = 1;
constraints.anchor = GridBagConstraints.LINE_START;
formPanel.add(sendButtonStent, constraints);
Action sidePanelAction = new MoreOrLessAction(controller, this);
sidePanelButton = new MultiBitButton(sidePanelAction, controller);
sidePanelButton.setBorder(BorderFactory.createEmptyBorder());
sidePanelButton.setBorderPainted(false);
sidePanelButton.setFocusPainted(false);
sidePanelButton.setContentAreaFilled(false);
displaySidePanel();
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 3;
constraints.gridy = 3;
constraints.weightx = 0.1;
constraints.weighty = 0.3;
constraints.gridwidth = 8;
constraints.gridheight = 3;
constraints.anchor = GridBagConstraints.BASELINE_TRAILING;
formPanel.add(sidePanelButton, constraints);
labelTextArea.setToolTipText(null);
labelTextArea.setEditable(true);
labelTextArea.setEnabled(true);
amountBTCTextField.setToolTipText(null);
amountBTCTextField.setEditable(true);
amountBTCTextField.setEnabled(true);
return formPanel;
}
public String getReceiveAddress() {
if (addressTextField != null) {
return addressTextField.getText();
} else {
return "";
}
}
@Override
public void loadForm() {
// get the current address, label and amount from the model
String address = this.bitcoinController.getModel().getActiveWalletPreference(BitcoinModel.RECEIVE_ADDRESS);
String label = this.bitcoinController.getModel().getActiveWalletPreference(BitcoinModel.RECEIVE_LABEL);
String amountNotLocalised = this.bitcoinController.getModel().getActiveWalletPreference(BitcoinModel.RECEIVE_AMOUNT);
if (amountBTCTextField != null) {
CurrencyConverterResult converterResult = CurrencyConverter.INSTANCE.parseToBTCNotLocalised(amountNotLocalised);
if (converterResult.isBtcMoneyValid()) {
parsedAmountBTC = converterResult.getBtcMoney();
String amountLocalised = CurrencyConverter.INSTANCE.getBTCAsLocalisedString(converterResult.getBtcMoney());
amountBTCTextField.setText(amountLocalised);
if (notificationLabel != null) {
notificationLabel.setText("");
}
} else {
parsedAmountBTC = null;
amountBTCTextField.setText("");
if (notificationLabel != null) {
notificationLabel.setText(converterResult.getBtcMessage());
}
}
}
// if the currently stored address is missing or is not in this wallet,
// pick
// the address book's first receiving address
boolean pickFirstReceivingAddress = false;
if (address == null || address.equals("")) {
pickFirstReceivingAddress = true;
} else {
WalletInfoData addressBook = this.bitcoinController.getModel().getActiveWalletWalletInfo();
if (addressBook != null) {
if (!addressBook.containsReceivingAddress(address)) {
pickFirstReceivingAddress = true;
}
}
}
if (pickFirstReceivingAddress) {
WalletInfoData addressBook = this.bitcoinController.getModel().getActiveWalletWalletInfo();
if (addressBook != null) {
ArrayList<WalletAddressBookData> receivingAddresses = addressBook.getReceivingAddresses();
if (receivingAddresses != null) {
if (receivingAddresses.iterator().hasNext()) {
WalletAddressBookData addressBookData = receivingAddresses.iterator().next();
if (addressBookData != null) {
address = addressBookData.getAddress();
label = addressBookData.getLabel();
this.bitcoinController.getModel().setActiveWalletPreference(BitcoinModel.RECEIVE_ADDRESS, address);
this.bitcoinController.getModel().setActiveWalletPreference(BitcoinModel.RECEIVE_LABEL, label);
}
}
}
}
}
if (address != null) {
addressTextField.setText(address);
}
if (label != null) {
labelTextArea.setText(label);
}
}
@Override
public void displayView(DisplayHint displayHint) {
super.displayView(displayHint);
if (DisplayHint.WALLET_TRANSACTIONS_HAVE_CHANGED == displayHint) {
return;
}
JTextField aTextField = new JTextField();
labelTextArea.setBorder(aTextField.getBorder());
titleLabel.setText(controller.getLocaliser().getString("receiveBitcoinPanel.receivingAddressesTitle"));
titleLabel.setToolTipText(null);
}
@Override
public Icon getViewIcon() {
return ImageLoader.createImageIcon(ImageLoader.RECEIVE_BITCOIN_ICON_FILE);
}
@Override
public String getViewTitle() {
return controller.getLocaliser().getString("receiveBitcoinAction.textShort");
}
@Override
public String getViewTooltip() {
return controller.getLocaliser().getString("receiveBitcoinAction.tooltip");
}
@Override
public View getViewId() {
return View.RECEIVE_BITCOIN_VIEW;
}
public CreateNewReceivingAddressAction getCreateNewReceivingAddressAction() {
return createNewReceivingAddressAction;
}
@Override
public void checkDeleteSendingEnabled() {
// Not used on receive bitcoin panel.
}
}