<commit_before>/* 
 * SparkBit
 *
 * Copyright 2011-2014 multibit.org
 * Copyright 2014 Coin Sciences Ltd
 *
 * 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 com.google.bitcoin.core.Transaction;
//import com.google.bitcoin.core.TransactionConfidence;
//import com.google.bitcoin.core.TransactionConfidence.ConfidenceType;
//import org.multibit.viewsystem.CoinSparks.CSAssetsDBDialog;
import com.google.common.eventbus.Subscribe;
import org.sparkbit.SparkBit;
import org.multibit.controller.Controller;
import org.multibit.controller.bitcoin.BitcoinController;
//import org.multibit.exchange.CurrencyConverter;
//import org.multibit.exchange.CurrencyConverterListener;
//import org.multibit.exchange.ExchangeRate;
//import org.multibit.model.bitcoin.WalletTableData;
import org.multibit.model.core.CoreModel;
import org.multibit.utils.DateUtils;
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.UpdateTransactionsTimerTask;
//import org.multibit.viewsystem.swing.WalletTableModel;
import org.multibit.viewsystem.swing.action.ExportTransactionsSubmitAction;
import org.multibit.viewsystem.swing.action.HelpContextAction;
import org.multibit.viewsystem.swing.action.ShowTransactionDetailsAction;
import org.multibit.viewsystem.swing.action.CSAddAssetManuallyAction;
import org.multibit.viewsystem.swing.view.components.FontSizer;
import org.multibit.viewsystem.swing.view.components.HelpButton;
import org.multibit.viewsystem.swing.view.components.MultiBitButton;
import org.multibit.viewsystem.swing.view.components.MultiBitLabel;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.*;
import javax.swing.text.*;
import java.awt.*;

import java.math.BigDecimal;
import java.math.BigInteger;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
//import java.util.List;
//import java.util.Timer;
/* CoinSpark START */
import org.coinspark.wallet.CSAsset;
//import org.coinspark.wallet.CSAssetDatabase;
import org.multibit.viewsystem.swing.WalletAssetTableModel;
import org.multibit.model.bitcoin.WalletAssetTableData;
//import org.multibit.viewsystem.swing.view.panels.CSAssetDetailPanel;
import javax.swing.border.Border;
import org.coinspark.wallet.CSEvent;
import org.coinspark.wallet.CSEventBus;
import org.coinspark.wallet.CSEventType;

import com.google.bitcoin.core.Wallet;
import org.coinspark.wallet.CSBalance;
import org.multibit.viewsystem.swing.action.CSRefreshAssetAction;
import org.multibit.viewsystem.swing.action.CSDeleteAssetAction;
import org.multibit.viewsystem.swing.view.components.CSCustomFontDefaultTableCellRenderer;
import org.multibit.viewsystem.swing.view.components.CSTruncatedTooltipDefaultTableCellRenderer; 

import java.awt.event.*;
import org.multibit.utils.CSMiscUtils;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;

/* CoinSpark END */

// We don't need to implement CurrencyConverterListener
public class CSShowAssetsPanel extends JPanel implements Viewable {

    private static final long serialVersionUID = 1005108897887842662L;

    private final Controller controller;
    private final BitcoinController bitcoinController;
    
    private MultiBitFrame mainFrame;

    private JTable table;
    private WalletAssetTableModel assetTableModel;
    private Wallet previousWallet;

    private TableRowSorter<TableModel> rowSorter;

    private static final String SPACER = "   "; // 3 spaces
    
    private static final int STATUS_WIDTH_DELTA = 6;

    private static final int TABLE_BORDER = 3;

    private static final int MINIMUM_ICON_HEIGHT = 16;
    
    public static final int HEIGHT_DELTA = 3;

    public static final String PROGRESS_0_ICON_FILE = "/images/circleProgress0.png";
    private static final String PROGRESS_1_ICON_FILE = "/images/circleProgress1.png";
    private static final String PROGRESS_2_ICON_FILE = "/images/circleProgress2.png";
    private static final String PROGRESS_3_ICON_FILE = "/images/circleProgress3.png";
    private static final String PROGRESS_4_ICON_FILE = "/images/circleProgress4.png";
    private static final String PROGRESS_5_ICON_FILE = "/images/circleProgress5.png";
    private static final String RTL_PROGRESS_1_ICON_FILE = "/images/circleProgress1.png";
    private static final String RTL_PROGRESS_2_ICON_FILE = "/images/circleProgress2.png";
    private static final String RTL_PROGRESS_3_ICON_FILE = "/images/circleProgress3.png";
    private static final String RTL_PROGRESS_4_ICON_FILE = "/images/circleProgress4.png";
    private static final String RTL_PROGRESS_5_ICON_FILE = "/images/circleProgress5.png";
    private static final String TICK_ICON_FILE = "/images/tick.png";
    private static final String PICKAXE_ICON_FILE = "/images/pickaxe.png";
    private static final String SMALL_EXCLAMATION_MARK_ICON_FILE = "/images/smallExclamationMark.png";

    private ListSelectionModel listSelectionModel;
    private int selectedRow = -1;
    
    private Action addAssetManuallyAction;
    private MultiBitButton addAssetManuallyButton;
    private Action refreshAssetAction;
    private MultiBitButton refreshAssetButton;
    private Action deleteAssetAction;
    private MultiBitButton deleteAssetButton;
    
//    private Action showTransactionDetailsAction;
//    private MultiBitButton showTransactionsButton;
//    
//    private Action exportTransactionsSubmitAction;
//    private MultiBitButton exportTransactionsButton;

//    public static final int UPDATE_TRANSACTIONS_DELAY_TIME = 1000; // milliseconds
    
    private JScrollPane scrollPane;
    
    private CSAssetDetailPanel assetDetailPanel;
    
    private boolean viewIsVisible;
    
    /**
     * Timer used to condense multiple updates
     */
    //private static Timer updateTransactionsTimer;
    //private static UpdateTransactionsTimerTask updateTransactionsTimerTask;
    
    class JComponentTableCellRenderer implements TableCellRenderer {
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
		boolean hasFocus, int row, int column) {
	    return (JComponent) value;
	}
    }

    public CSShowAssetsPanel(BitcoinController bitcoinController, MultiBitFrame mainFrame) {
        this.bitcoinController = bitcoinController;
        this.controller = this.bitcoinController;
        this.mainFrame = mainFrame;

//        updateTransactionsTimerTask = new UpdateTransactionsTimerTask(controller, this, mainFrame);
//        updateTransactionsTimer = new Timer();
//        updateTransactionsTimer.scheduleAtFixedRate(updateTransactionsTimerTask, UPDATE_TRANSACTIONS_DELAY_TIME, UPDATE_TRANSACTIONS_DELAY_TIME);
               
        initUI();

        applyComponentOrientation(ComponentOrientation.getOrientation(controller.getLocaliser().getLocale()));
        
//        CurrencyConverter.INSTANCE.addCurrencyConverterListener(this);
	
	// Register ourselves as a listener the CSEventBus
	CSEventBus.INSTANCE.registerAsyncSubscriber(this);
    }

    @Subscribe
    public void listen(CSEvent event) throws Exception {
	// Ignore, don't update table etc. unless view is selected tab pane.
	if (!this.viewIsVisible) return;
	
	// We want to preserve selection
	final int selectedRow = table.getSelectedRow(); // display, not model index
	final int selectedColumn = table.getSelectedColumn(); // display, not model index
	final boolean selectionExists = (selectedColumn!=-1 && selectedRow!=-1);
	final int selectedAssetID = (selectionExists) ? assetTableModel.getAssetIDAtRow(rowSorter.convertRowIndexToModel(selectedRow)) : -1;
//	System.out.println("selected cell row " + selectedRow + ", col " + selectedColumn + "  where asset ID = " + selectedAssetID);
	//log.debug("Received CSEvent: Type=" + event.getType() + " , info=" + event.getInfo());
	Object o = event.getInfo();
	
	CSEventType t = event.getType();
	
	if (t == CSEventType.BALANCE_VALID) {
	    CSBalance bal = (CSBalance) o;
	    if (bal != null) {
		o = (Integer) bal.getAssetID();  // the integer is used later
	    }
	}
	
	if (t == CSEventType.ASSET_VALIDATION_STARTED
		|| t == CSEventType.ASSET_VALIDATION_COMPLETED
		|| t == CSEventType.ASSET_UPDATED
		|| t == CSEventType.BALANCE_VALID) {
	    
	    
	    
	    // We know o should be an Integer, but if BALANCE_VALID, we have already computed the value.
	    final int changedAssetID = (int)o;

	    SwingUtilities.invokeLater(new Runnable() {
		@Override
		public void run() {
//		    assetTableModel.fireTableDataChanged();

		    // row is the model row index, not display row indexdue to sorting
		    int changedRow = assetTableModel.getRowForAssetID(changedAssetID);
		    if (changedRow != -1) {
			// Note: if changedRow is -1, the header column becomes corrupted, with visibility icon becoming text label.
			assetTableModel.fireTableRowsUpdated(changedRow, changedRow);
		    }
		    assetDetailPanel.updateView();
		    assetDetailPanel.revalidate();
		}
	    });
	} else if (t == CSEventType.ASSET_DELETED<commit_msg>Fix a bug where changes to an asset's visibility would not trigger checkbox to update.<commit_after>/* 
 * SparkBit
 *
 * Copyright 2011-2014 multibit.org
 * Copyright 2014 Coin Sciences Ltd
 *
 * 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 com.google.bitcoin.core.Transaction;
//import com.google.bitcoin.core.TransactionConfidence;
//import com.google.bitcoin.core.TransactionConfidence.ConfidenceType;
//import org.multibit.viewsystem.CoinSparks.CSAssetsDBDialog;
import com.google.common.eventbus.Subscribe;
import org.sparkbit.SparkBit;
import org.multibit.controller.Controller;
import org.multibit.controller.bitcoin.BitcoinController;
//import org.multibit.exchange.CurrencyConverter;
//import org.multibit.exchange.CurrencyConverterListener;
//import org.multibit.exchange.ExchangeRate;
//import org.multibit.model.bitcoin.WalletTableData;
import org.multibit.model.core.CoreModel;
import org.multibit.utils.DateUtils;
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.UpdateTransactionsTimerTask;
//import org.multibit.viewsystem.swing.WalletTableModel;
import org.multibit.viewsystem.swing.action.ExportTransactionsSubmitAction;
import org.multibit.viewsystem.swing.action.HelpContextAction;
import org.multibit.viewsystem.swing.action.ShowTransactionDetailsAction;
import org.multibit.viewsystem.swing.action.CSAddAssetManuallyAction;
import org.multibit.viewsystem.swing.view.components.FontSizer;
import org.multibit.viewsystem.swing.view.components.HelpButton;
import org.multibit.viewsystem.swing.view.components.MultiBitButton;
import org.multibit.viewsystem.swing.view.components.MultiBitLabel;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.*;
import javax.swing.text.*;
import java.awt.*;

import java.math.BigDecimal;
import java.math.BigInteger;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
//import java.util.List;
//import java.util.Timer;
/* CoinSpark START */
import org.coinspark.wallet.CSAsset;
//import org.coinspark.wallet.CSAssetDatabase;
import org.multibit.viewsystem.swing.WalletAssetTableModel;
import org.multibit.model.bitcoin.WalletAssetTableData;
//import org.multibit.viewsystem.swing.view.panels.CSAssetDetailPanel;
import javax.swing.border.Border;
import org.coinspark.wallet.CSEvent;
import org.coinspark.wallet.CSEventBus;
import org.coinspark.wallet.CSEventType;

import com.google.bitcoin.core.Wallet;
import org.coinspark.wallet.CSBalance;
import org.multibit.viewsystem.swing.action.CSRefreshAssetAction;
import org.multibit.viewsystem.swing.action.CSDeleteAssetAction;
import org.multibit.viewsystem.swing.view.components.CSCustomFontDefaultTableCellRenderer;
import org.multibit.viewsystem.swing.view.components.CSTruncatedTooltipDefaultTableCellRenderer; 

import java.awt.event.*;
import org.multibit.utils.CSMiscUtils;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;

/* CoinSpark END */

// We don't need to implement CurrencyConverterListener
public class CSShowAssetsPanel extends JPanel implements Viewable {

    private static final long serialVersionUID = 1005108897887842662L;

    private final Controller controller;
    private final BitcoinController bitcoinController;
    
    private MultiBitFrame mainFrame;

    private JTable table;
    private WalletAssetTableModel assetTableModel;
    private Wallet previousWallet;

    private TableRowSorter<TableModel> rowSorter;

    private static final String SPACER = "   "; // 3 spaces
    
    private static final int STATUS_WIDTH_DELTA = 6;

    private static final int TABLE_BORDER = 3;

    private static final int MINIMUM_ICON_HEIGHT = 16;
    
    public static final int HEIGHT_DELTA = 3;

    public static final String PROGRESS_0_ICON_FILE = "/images/circleProgress0.png";
    private static final String PROGRESS_1_ICON_FILE = "/images/circleProgress1.png";
    private static final String PROGRESS_2_ICON_FILE = "/images/circleProgress2.png";
    private static final String PROGRESS_3_ICON_FILE = "/images/circleProgress3.png";
    private static final String PROGRESS_4_ICON_FILE = "/images/circleProgress4.png";
    private static final String PROGRESS_5_ICON_FILE = "/images/circleProgress5.png";
    private static final String RTL_PROGRESS_1_ICON_FILE = "/images/circleProgress1.png";
    private static final String RTL_PROGRESS_2_ICON_FILE = "/images/circleProgress2.png";
    private static final String RTL_PROGRESS_3_ICON_FILE = "/images/circleProgress3.png";
    private static final String RTL_PROGRESS_4_ICON_FILE = "/images/circleProgress4.png";
    private static final String RTL_PROGRESS_5_ICON_FILE = "/images/circleProgress5.png";
    private static final String TICK_ICON_FILE = "/images/tick.png";
    private static final String PICKAXE_ICON_FILE = "/images/pickaxe.png";
    private static final String SMALL_EXCLAMATION_MARK_ICON_FILE = "/images/smallExclamationMark.png";

    private ListSelectionModel listSelectionModel;
    private int selectedRow = -1;
    
    private Action addAssetManuallyAction;
    private MultiBitButton addAssetManuallyButton;
    private Action refreshAssetAction;
    private MultiBitButton refreshAssetButton;
    private Action deleteAssetAction;
    private MultiBitButton deleteAssetButton;
    
//    private Action showTransactionDetailsAction;
//    private MultiBitButton showTransactionsButton;
//    
//    private Action exportTransactionsSubmitAction;
//    private MultiBitButton exportTransactionsButton;

//    public static final int UPDATE_TRANSACTIONS_DELAY_TIME = 1000; // milliseconds
    
    private JScrollPane scrollPane;
    
    private CSAssetDetailPanel assetDetailPanel;
    
    private boolean viewIsVisible;
    
    /**
     * Timer used to condense multiple updates
     */
    //private static Timer updateTransactionsTimer;
    //private static UpdateTransactionsTimerTask updateTransactionsTimerTask;
    
    class JComponentTableCellRenderer implements TableCellRenderer {
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
		boolean hasFocus, int row, int column) {
	    return (JComponent) value;
	}
    }

    public CSShowAssetsPanel(BitcoinController bitcoinController, MultiBitFrame mainFrame) {
        this.bitcoinController = bitcoinController;
        this.controller = this.bitcoinController;
        this.mainFrame = mainFrame;

//        updateTransactionsTimerTask = new UpdateTransactionsTimerTask(controller, this, mainFrame);
//        updateTransactionsTimer = new Timer();
//        updateTransactionsTimer.scheduleAtFixedRate(updateTransactionsTimerTask, UPDATE_TRANSACTIONS_DELAY_TIME, UPDATE_TRANSACTIONS_DELAY_TIME);
               
        initUI();

        applyComponentOrientation(ComponentOrientation.getOrientation(controller.getLocaliser().getLocale()));
        
//        CurrencyConverter.INSTANCE.addCurrencyConverterListener(this);
	
	// Register ourselves as a listener the CSEventBus
	CSEventBus.INSTANCE.registerAsyncSubscriber(this);
    }

    @Subscribe
    public void listen(CSEvent event) throws Exception {
	// Ignore, don't update table etc. unless view is selected tab pane.
	if (!this.viewIsVisible) return;
	
	// We want to preserve selection
	final int selectedRow = table.getSelectedRow(); // display, not model index
	final int selectedColumn = table.getSelectedColumn(); // display, not model index
	final boolean selectionExists = (selectedColumn!=-1 && selectedRow!=-1);
	final int selectedAssetID = (selectionExists) ? assetTableModel.getAssetIDAtRow(rowSorter.convertRowIndexToModel(selectedRow)) : -1;
//	System.out.println("selected cell row " + selectedRow + ", col " + selectedColumn + "  where asset ID = " + selectedAssetID);
	//log.debug("Received CSEvent: Type=" + event.getType() + " , info=" + event.getInfo());
	Object o = event.getInfo();
	
	CSEventType t = event.getType();
	
	if (t == CSEventType.BALANCE_VALID) {
	    CSBalance bal = (CSBalance) o;
	    if (bal != null) {
		o = (Integer) bal.getAssetID();  // the integer is used later
	    }
	}
	
	if (t == CSEventType.ASSET_VALIDATION_STARTED
		|| t == CSEventType.ASSET_VALIDATION_COMPLETED
		|| t == CSEventType.ASSET_UPDATED
		|| t == CSEventType.ASSET_VISIBILITY_CHANGED
		|| t == CSEventType.BALANCE_VALID) {
	    
	    
	    
	    // We know o should be an Integer, but if BALANCE_VALID, we have already computed the value.
	    final int changedAssetID = (int)o;

	    SwingUtilities.invokeLater(new Runnable() {
		@Override
		public void run() {
//		    assetTableModel.fireTableDataChanged();

		    // row is the model row index, not display row indexdue to sorting
		    int changedRow = assetTableModel.getRowForAssetID(changedAssetID);
		    if (changedRow != -1) {
			// Note: if changedRow is -1, the header column becomes corrupted, with visibility icon becoming text label.
			assetTableModel.fireTableRowsUpdated(changedRow, changedRow);
		    }
		    assetDetailPanel.updateView();
		    assetDetailPanel.revalidate();
		}
	    });
	} else if (t == CSEventType.ASSET_DELETED
{'fraction_non_alphanumeric': 0.08694130586941305, 'fraction_numerical': 0.006899310068993101, 'mean_word_length': 4.551762420205384, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5015139', 'n_tokens_mistral': 5979, 'n_tokens_neox': 5750, 'n_words': 1353}