/**
* Copyright 2013 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.action;
import org.multibit.controller.bitcoin.BitcoinController;
import org.multibit.file.FileHandler;
import org.multibit.message.Message;
import org.multibit.message.MessageManager;
import org.multibit.model.bitcoin.WalletData;
import org.multibit.viewsystem.swing.MultiBitFrame;
import org.multibit.viewsystem.swing.view.panels.HelpContentsPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.List;
/**
* This {@link Action} closes the active wallet.
*/
public class CloseWalletAction extends MultiBitSubmitAction {
private static final Logger log = LoggerFactory.getLogger(CloseWalletAction.class);
private static final long serialVersionUID = 1923933460523457765L;
private MultiBitFrame mainFrame;
private static final int RECREATE_ALL_VIEWS_WAIT_TIME = 500; // ms
/**
* Creates a new {@link CloseWalletAction}.
*/
public CloseWalletAction(BitcoinController bitcoinController, ImageIcon icon, MultiBitFrame mainFrame) {
super(bitcoinController, "closeWalletAction.text", "closeWalletAction.tooltip", "closeWalletAction.mnemonicKey", icon);
this.mainFrame = mainFrame;
putValue(SHORT_DESCRIPTION, HelpContentsPanel.createTooltipTextForMenuItem(controller.getLocaliser().getString("closeWalletAction.tooltip")));
}
/**
* Close the active wallet.
*/
@Override
public void actionPerformed(ActionEvent e) {
if (abort()) {
return;
}
boolean successfullyClosedWallet = false;
String walletToCloseFilename = "";
try {
if (mainFrame != null) {
if (EventQueue.isDispatchThread()) {
mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}
});
}
}
// Close the wallet.
WalletData perWalletModelData = this.bitcoinController.getModel().getActivePerWalletModelData();
walletToCloseFilename = perWalletModelData.getWalletFilename();
// Unhook it from the PeerGroup.
super.bitcoinController.getMultiBitService().getPeerGroup().removeWallet(perWalletModelData.getWallet());
// Save it.
FileHandler fileHandler = new FileHandler(super.bitcoinController);
fileHandler.savePerWalletModelData(perWalletModelData, true);
// Work out which wallet to select after the wallet is removed.
String activeWalletFilename = perWalletModelData.getWalletFilename();
List<WalletData> perWalletModelDataList = this.bitcoinController.getModel().getPerWalletModelDataList();
int numberOfOpenWalletsBefore = perWalletModelDataList.size();
int positionInList = -1;
for (int i = 0; i < numberOfOpenWalletsBefore; i++) {
if (activeWalletFilename.equals(perWalletModelDataList.get(i).getWalletFilename())) {
positionInList = i;
break;
}
}
// By default select the first wallet.
int newWalletToSelect = 0;
if (numberOfOpenWalletsBefore > 1) {
// If removing the last, then select the new last one.
if (positionInList == numberOfOpenWalletsBefore - 1) {
newWalletToSelect = numberOfOpenWalletsBefore - 2;
} else {
// Select the same position in the list
newWalletToSelect = positionInList;
}
} else {
// One wallet open before. None after.
}
// Remove it from the model.
this.bitcoinController.getModel().remove(perWalletModelData);
// Set the new Wallet to be the active wallet.
if (!this.bitcoinController.getModel().getPerWalletModelDataList().isEmpty()) {
WalletData firstPerWalletModelData = this.bitcoinController.getModel().getPerWalletModelDataList().get(newWalletToSelect);
this.bitcoinController.getModel().setActiveWalletByFilename(firstPerWalletModelData.getWalletFilename());
} else {
// No wallets are selected.
// Clear all the views.
}
successfullyClosedWallet = true;
} finally {
controller.fireRecreateAllViews(true);
// Wait a while for the UI to reinitialise and then set the status message
// Give the user a message that wallet is closed.
final String finalWalletToCloseFilename = walletToCloseFilename;
final boolean finalSuccessfullyClosedWallet = successfullyClosedWallet;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (finalSuccessfullyClosedWallet) {
try {
Thread.sleep(RECREATE_ALL_VIEWS_WAIT_TIME);
} catch (InterruptedException e1) {
log.error("Unexpected thread interruption", e1);
}
Message closeMessage = new Message(controller.getLocaliser().getString("multiBit.closedWallet", new Object[]{finalWalletToCloseFilename}));
MessageManager.INSTANCE.addMessage(closeMessage);
}
// Reset wait cursor
if (mainFrame != null) {
mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
});
}
}
}