Coverage Report - org.homeunix.thecave.buddi.view.TransactionFrame
 
Classes in this File Line Coverage Branch Coverage Complexity
TransactionFrame
0%
0/452
0%
0/196
6
TransactionFrame$1
0%
0/3
N/A
6
TransactionFrame$10
0%
0/5
N/A
6
TransactionFrame$11
0%
0/42
0%
0/26
6
TransactionFrame$2
0%
0/32
0%
0/24
6
TransactionFrame$3
0%
0/6
0%
0/2
6
TransactionFrame$4
0%
0/8
0%
0/4
6
TransactionFrame$5
0%
0/8
0%
0/4
6
TransactionFrame$6
0%
0/6
0%
0/4
6
TransactionFrame$7
0%
0/10
0%
0/6
6
TransactionFrame$8
0%
0/10
0%
0/6
6
TransactionFrame$9
0%
0/10
0%
0/6
6
 
 1  
 /*
 2  
  * Created on May 6, 2006 by wyatt
 3  
  */
 4  
 package org.homeunix.thecave.buddi.view;
 5  
 
 6  
 import java.awt.BorderLayout;
 7  
 import java.awt.FlowLayout;
 8  
 import java.awt.GridBagConstraints;
 9  
 import java.awt.GridBagLayout;
 10  
 import java.awt.event.ActionEvent;
 11  
 import java.awt.event.ActionListener;
 12  
 import java.awt.event.ComponentAdapter;
 13  
 import java.awt.event.ComponentEvent;
 14  
 import java.awt.event.ItemEvent;
 15  
 import java.awt.event.ItemListener;
 16  
 import java.awt.event.KeyAdapter;
 17  
 import java.awt.event.KeyEvent;
 18  
 import java.awt.event.MouseAdapter;
 19  
 import java.awt.event.MouseEvent;
 20  
 import java.util.Date;
 21  
 import java.util.List;
 22  
 import java.util.logging.Level;
 23  
 import java.util.logging.Logger;
 24  
 
 25  
 import javax.swing.BorderFactory;
 26  
 import javax.swing.DefaultComboBoxModel;
 27  
 import javax.swing.Icon;
 28  
 import javax.swing.JButton;
 29  
 import javax.swing.JComboBox;
 30  
 import javax.swing.JLabel;
 31  
 import javax.swing.JOptionPane;
 32  
 import javax.swing.JPanel;
 33  
 import javax.swing.JScrollPane;
 34  
 import javax.swing.ListSelectionModel;
 35  
 import javax.swing.UIManager;
 36  
 import javax.swing.event.ListSelectionEvent;
 37  
 import javax.swing.event.ListSelectionListener;
 38  
 
 39  
 import org.homeunix.thecave.buddi.Const;
 40  
 import org.homeunix.thecave.buddi.i18n.BuddiKeys;
 41  
 import org.homeunix.thecave.buddi.i18n.keys.ButtonKeys;
 42  
 import org.homeunix.thecave.buddi.i18n.keys.TransactionClearedFilterKeys;
 43  
 import org.homeunix.thecave.buddi.i18n.keys.TransactionDateFilterKeys;
 44  
 import org.homeunix.thecave.buddi.i18n.keys.TransactionReconciledFilterKeys;
 45  
 import org.homeunix.thecave.buddi.model.Account;
 46  
 import org.homeunix.thecave.buddi.model.Document;
 47  
 import org.homeunix.thecave.buddi.model.Source;
 48  
 import org.homeunix.thecave.buddi.model.Transaction;
 49  
 import org.homeunix.thecave.buddi.model.TransactionSplit;
 50  
 import org.homeunix.thecave.buddi.model.impl.ModelFactory;
 51  
 import org.homeunix.thecave.buddi.model.impl.SplitImpl;
 52  
 import org.homeunix.thecave.buddi.model.prefs.PrefsModel;
 53  
 import org.homeunix.thecave.buddi.model.swing.TransactionListModel;
 54  
 import org.homeunix.thecave.buddi.plugin.BuddiPluginFactory;
 55  
 import org.homeunix.thecave.buddi.plugin.api.BuddiTransactionCellRendererPlugin;
 56  
 import org.homeunix.thecave.buddi.plugin.api.exception.InvalidValueException;
 57  
 import org.homeunix.thecave.buddi.plugin.api.exception.ModelException;
 58  
 import org.homeunix.thecave.buddi.plugin.api.util.TextFormatter;
 59  
 import org.homeunix.thecave.buddi.plugin.builtin.cellrenderer.DefaultTransactionCellRenderer;
 60  
 import org.homeunix.thecave.buddi.util.Formatter;
 61  
 import org.homeunix.thecave.buddi.util.InternalFormatter;
 62  
 import org.homeunix.thecave.buddi.view.menu.bars.BuddiMenuBar;
 63  
 import org.homeunix.thecave.buddi.view.panels.TransactionEditorPanel;
 64  
 import org.homeunix.thecave.buddi.view.swing.TranslatorListCellRenderer;
 65  
 import org.jdesktop.swingx.JXCollapsiblePane;
 66  
 import org.jdesktop.swingx.JXList;
 67  
 import org.jdesktop.swingx.decorator.HighlighterFactory;
 68  
 
 69  
 import ca.digitalcave.moss.application.document.DocumentChangeEvent;
 70  
 import ca.digitalcave.moss.application.document.DocumentChangeListener;
 71  
 import ca.digitalcave.moss.common.ClassLoaderFunctions;
 72  
 import ca.digitalcave.moss.common.OperatingSystemUtil;
 73  
 import ca.digitalcave.moss.swing.MossAssociatedDocumentFrame;
 74  
 import ca.digitalcave.moss.swing.MossSearchField;
 75  
 import ca.digitalcave.moss.swing.MossSearchField.SearchTextChangedEvent;
 76  
 import ca.digitalcave.moss.swing.MossSearchField.SearchTextChangedEventListener;
 77  
 
 78  0
 public class TransactionFrame extends MossAssociatedDocumentFrame implements ActionListener {
 79  
         public static final long serialVersionUID = 0;        
 80  
 
 81  
         private static final int MIN_WIDTH = 400;
 82  
         private static final int MIN_HEIGHT = 200;
 83  
 
 84  
         private final JXList list;
 85  
 
 86  
         private final TransactionEditorPanel transactionEditor;
 87  
         private final JButton recordButton;
 88  
         private final JButton clearButton;
 89  
         private final JButton deleteButton;
 90  
         private final MossSearchField searchField;
 91  
         private final JComboBox dateFilterComboBox;
 92  
         private final JComboBox clearedFilterComboBox;
 93  
         private final JComboBox reconciledFilterComboBox;
 94  
         private final JLabel overdraftCreditLimit;
 95  
 
 96  
         private final JLabel balancesLabel;
 97  
         private final JLabel sumsLabel;
 98  
         private final JLabel accountBalance;
 99  
         private final JLabel clearedBalance;
 100  
         private final JLabel reconciledBalance;
 101  
         private final JLabel clearedSum;
 102  
         private final JLabel reconciledSum;
 103  
         private final JLabel notClearedSum;
 104  
         private final JLabel notReconciledSum;
 105  
         private final JPanel totalPanel;
 106  
 
 107  
         private final TransactionListModel listModel;
 108  
 
 109  
         private final Account associatedAccount;
 110  
         private final Source associatedSource; //Only used for updating title.
 111  
         private final MainFrame parent;
 112  
 
 113  0
         private boolean disableListEvents = false;
 114  
         
 115  
         private final DocumentChangeListener listener;
 116  
 
 117  
         public TransactionFrame(MainFrame parent, Source source){
 118  0
                 super(parent, TransactionFrame.class.getName() + ((Document) parent.getDocument()).getUid() + "_" + parent.getDocument().getFile() + "_" + (source != null ? source.getFullName() : ""));
 119  0
                 this.setIconImage(ClassLoaderFunctions.getImageFromClasspath("img/BuddiFrameIcon.gif"));
 120  0
                 this.associatedSource = source;
 121  0
                 if (source instanceof Account)
 122  0
                         this.associatedAccount = (Account) source;
 123  
                 else
 124  0
                         this.associatedAccount = null;
 125  0
                 this.listModel = new TransactionListModel((Document) parent.getDocument(), source);
 126  0
                 this.parent = parent;
 127  0
                 overdraftCreditLimit = new JLabel();
 128  
 
 129  0
                 totalPanel = new JPanel(new BorderLayout());
 130  
 
 131  0
                 dateFilterComboBox = new JComboBox();
 132  0
                 clearedFilterComboBox = new JComboBox();
 133  0
                 reconciledFilterComboBox = new JComboBox();
 134  
 
 135  0
                 balancesLabel = new JLabel();
 136  0
                 sumsLabel = new JLabel();
 137  0
                 accountBalance = new JLabel();
 138  0
                 clearedBalance = new JLabel();
 139  0
                 reconciledBalance = new JLabel();
 140  0
                 clearedSum = new JLabel();
 141  0
                 notClearedSum = new JLabel();
 142  0
                 reconciledSum = new JLabel();
 143  0
                 notReconciledSum = new JLabel();
 144  
                 
 145  0
                 listener = new DocumentChangeListener(){
 146  
                         public void documentChange(DocumentChangeEvent event) {
 147  0
                                 listModel.update();
 148  0
                         }
 149  
                 };
 150  
 
 151  
                 //Set up the transaction list.  We don't set the model here, for performance reasons.
 152  
                 // We set it after we have already established the prototype value.
 153  0
                 list = new JXList(){
 154  
                         public final static long serialVersionUID = 0;
 155  
 
 156  
                         @Override
 157  
                         public String getToolTipText(MouseEvent event) {
 158  0
                                 if (!PrefsModel.getInstance().isShowTooltips())
 159  0
                                         return null;
 160  0
                                 int i = locationToIndex(event.getPoint());
 161  0
                                 if (i >= 0 && i < getModel().getSize()){
 162  0
                                         Object o = getModel().getElementAt(i);
 163  
 
 164  0
                                         if (o instanceof Transaction){
 165  0
                                                 Transaction transaction = (Transaction) o;
 166  
 
 167  0
                                                 if (transaction != null){
 168  0
                                                         StringBuilder sb = new StringBuilder();
 169  
 
 170  0
                                                         sb.append("<html>");
 171  0
                                                         sb.append(transaction.getDescription());
 172  
 
 173  0
                                                         if (transaction.getNumber() != null){
 174  0
                                                                 if (transaction.getNumber().length() > 0){
 175  0
                                                                         sb.append("<br>");
 176  0
                                                                         sb.append("#");
 177  0
                                                                         sb.append(transaction.getNumber());
 178  
                                                                 }
 179  
                                                         }
 180  
 
 181  0
                                                         sb.append("<br>");
 182  0
                                                         if (TransactionFrame.this.associatedAccount != null){
 183  0
                                                                 if (InternalFormatter.isRed(transaction, transaction.getTo().equals(TransactionFrame.this.associatedAccount)))
 184  0
                                                                         sb.append("<font color='red'>");
 185  0
                                                                 sb.append(TextFormatter.getFormattedCurrency(transaction.getAmount()));
 186  0
                                                                 if (InternalFormatter.isRed(transaction, transaction.getTo().equals(TransactionFrame.this.associatedAccount)))
 187  0
                                                                         sb.append("</font>");
 188  
                                                         }
 189  
 
 190  0
                                                         sb.append("  ");
 191  0
                                                         sb.append(transaction.getFrom().getFullName())
 192  
                                                         .append(" ")
 193  
                                                         .append(PrefsModel.getInstance().getTranslator().get(BuddiKeys.TO))
 194  
                                                         .append(" ")
 195  
                                                         .append(transaction.getTo().getFullName());
 196  
 
 197  0
                                                         if (transaction.getMemo() != null 
 198  
                                                                         && transaction.getMemo().length() > 0){
 199  0
                                                                 sb.append("<br>");
 200  0
                                                                 sb.append(transaction.getMemo());
 201  
                                                         }
 202  
 
 203  0
                                                         sb.append("</html>");
 204  
 
 205  0
                                                         return sb.toString();
 206  
                                                 }
 207  
                                         }
 208  
                                 }
 209  
 
 210  0
                                 return "";
 211  
                         }
 212  
                 };
 213  
 
 214  
 
 215  
                 //Set up the editing portion
 216  0
                 transactionEditor = new TransactionEditorPanel(this, (Document) parent.getDocument(), associatedSource, false);
 217  
 
 218  0
                 recordButton = new JButton(PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_RECORD));
 219  0
                 clearButton = new JButton(PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_CLEAR));
 220  0
                 deleteButton = new JButton(PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_DELETE));
 221  0
                 searchField = new MossSearchField(OperatingSystemUtil.isMac() ? "" : PrefsModel.getInstance().getTranslator().get(BuddiKeys.DEFAULT_SEARCH));
 222  0
         }
 223  
 
 224  
         /**
 225  
          * Opens the window, and selects the given transaction.
 226  
          * @param source
 227  
          * @param transaction
 228  
          */
 229  
         public TransactionFrame(MainFrame parent, Source source, Transaction transaction) {
 230  0
                 this(parent, source);
 231  
 
 232  
                 // Iterate backwards through the list of transacations, looking for the transaction
 233  
                 // which was just passed in.
 234  
 
 235  0
                 for (int index = this.listModel.getSize() - 1; index >= 0; --index) {
 236  0
                         Transaction transactionToCheck = (Transaction) this.listModel.getElementAt(index);
 237  0
                         if (transactionToCheck.equals(transaction)) {
 238  0
                                 list.ensureIndexIsVisible(index);
 239  0
                                 list.setSelectedIndex(index);
 240  0
                                 break;
 241  
                         }
 242  
                 }
 243  
 
 244  0
                 this.requestFocusInWindow();
 245  0
         }
 246  
 
 247  
         @Override
 248  
         public void initPostPack() {
 249  0
                 super.initPostPack();
 250  
 
 251  0
                 if (((Document) getDocument()).getBudgetCategories().size() > 0){
 252  
                         try {
 253  0
                                 list.setPrototypeCellValue(ModelFactory.createTransaction(new Date(), "Relatively long description", 12345678, ((Document) getDocument()).getBudgetCategories().get(0), ((Document) getDocument()).getBudgetCategories().get(0)));
 254  
                         }
 255  0
                         catch (InvalidValueException ive){}
 256  
                 }
 257  
 
 258  0
                 list.setModel(listModel);                
 259  0
                 list.ensureIndexIsVisible(listModel.getSize() - 1);
 260  0
         }
 261  
 
 262  
         @SuppressWarnings("unchecked")
 263  
         @Override
 264  
         public void init(){
 265  0
                 super.init();
 266  
 
 267  0
                 ((Document) getDocument()).updateAllBalances();
 268  
 
 269  0
                 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 270  0
                 BuddiTransactionCellRendererPlugin renderer = new DefaultTransactionCellRenderer();
 271  0
                 for (BuddiTransactionCellRendererPlugin r : (List<BuddiTransactionCellRendererPlugin>) BuddiPluginFactory.getPlugins(BuddiTransactionCellRendererPlugin.class)) {
 272  0
                         if (r.getClass().getCanonicalName().equals(PrefsModel.getInstance().getTransactionCellRenderer())){
 273  0
                                 renderer = r;
 274  0
                                 break;
 275  
                         }
 276  
                 }
 277  
                 
 278  0
                 renderer.setAccount(associatedAccount);
 279  0
                 list.setCellRenderer(renderer);
 280  
 
 281  0
                 recordButton.setPreferredSize(InternalFormatter.getButtonSize(recordButton));
 282  0
                 clearButton.setPreferredSize(InternalFormatter.getButtonSize(clearButton));
 283  0
                 deleteButton.setPreferredSize(InternalFormatter.getButtonSize(deleteButton));
 284  0
                 searchField.setPreferredSize(InternalFormatter.getComponentSize(searchField, 160));
 285  0
                 searchField.setMaximumSize(searchField.getPreferredSize());
 286  0
                 dateFilterComboBox.setPreferredSize(InternalFormatter.getComboBoxSize(dateFilterComboBox));
 287  0
                 clearedFilterComboBox.setPreferredSize(InternalFormatter.getComboBoxSize(clearedFilterComboBox));
 288  0
                 reconciledFilterComboBox.setPreferredSize(InternalFormatter.getComboBoxSize(reconciledFilterComboBox));
 289  
 
 290  0
                 balancesLabel.setHorizontalAlignment(JLabel.RIGHT);
 291  0
                 sumsLabel.setHorizontalAlignment(JLabel.RIGHT);
 292  0
                 accountBalance.setHorizontalAlignment(JLabel.RIGHT);
 293  0
                 clearedBalance.setHorizontalAlignment(JLabel.RIGHT);
 294  0
                 reconciledBalance.setHorizontalAlignment(JLabel.RIGHT);
 295  0
                 clearedSum.setHorizontalAlignment(JLabel.RIGHT);
 296  0
                 notClearedSum.setHorizontalAlignment(JLabel.RIGHT);
 297  0
                 reconciledSum.setHorizontalAlignment(JLabel.RIGHT);
 298  0
                 notReconciledSum.setHorizontalAlignment(JLabel.RIGHT);
 299  
 
 300  
 
 301  0
                 JPanel topRightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
 302  0
                 topRightPanel.add(clearedFilterComboBox);
 303  0
                 topRightPanel.add(reconciledFilterComboBox);
 304  0
                 topRightPanel.add(dateFilterComboBox);
 305  0
                 topRightPanel.add(searchField);
 306  
 
 307  0
                 JPanel topLeftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
 308  0
                 topLeftPanel.add(overdraftCreditLimit);
 309  
 
 310  0
                 JPanel topPanelHolder = new JPanel(new BorderLayout());
 311  
 //                topPanelHolder.add(topLeftPanel, BorderLayout.NORTH);
 312  0
                 topPanelHolder.add(topRightPanel, BorderLayout.SOUTH);
 313  
 
 314  0
                 final JXCollapsiblePane topCollapsiblePanel = new JXCollapsiblePane(new BorderLayout());
 315  0
                 topCollapsiblePanel.setCollapsed(!PrefsModel.getInstance().isSearchPaneVisible());
 316  0
                 topCollapsiblePanel.add(topPanelHolder, BorderLayout.CENTER);
 317  
 
 318  0
                 final Icon collapsed = UIManager.getIcon("Tree.collapsedIcon");
 319  0
                 final Icon expanded = UIManager.getIcon("Tree.expandedIcon");
 320  0
                 final JLabel searchCheck = new JLabel(PrefsModel.getInstance().isSearchPaneVisible() ? expanded : collapsed);
 321  0
                 searchCheck.setVerticalAlignment(JLabel.TOP);
 322  
                 //Disable the Enter key for the search field
 323  0
                 searchField.addKeyListener(new KeyAdapter(){
 324  
                         @Override
 325  
                         public void keyPressed(KeyEvent e) {
 326  0
                         if (e.getKeyCode() == KeyEvent.VK_ENTER){
 327  0
                                 e.consume();
 328  0
                                         return;
 329  
                         }
 330  
                         else
 331  0
                                 super.keyPressed(e);
 332  0
                         }
 333  
                 });
 334  0
                 searchCheck.addMouseListener(new MouseAdapter(){
 335  
                         public void mouseClicked(MouseEvent e) {
 336  0
                                 if (searchCheck.getIcon().equals(expanded))
 337  0
                                         searchCheck.setIcon(collapsed);
 338  
                                 else
 339  0
                                         searchCheck.setIcon(expanded);
 340  0
                                 boolean hide = searchCheck.getIcon().equals(collapsed);
 341  0
                                 topCollapsiblePanel.setCollapsed(hide);
 342  
 
 343  0
                                 PrefsModel.getInstance().setSearchPaneVisible(!hide);
 344  0
                         }
 345  
                 });
 346  
 
 347  0
                 JPanel spacerPanel = new JPanel(new BorderLayout());
 348  0
                 spacerPanel.add(topCollapsiblePanel, BorderLayout.NORTH);
 349  
 
 350  0
                 JPanel informationPanel = new JPanel(new GridBagLayout());
 351  0
                 GridBagConstraints gbc = new GridBagConstraints();
 352  0
                 gbc.gridy = 0;
 353  0
                 gbc.fill = GridBagConstraints.HORIZONTAL;
 354  0
                 gbc.weightx = 1;
 355  0
                 gbc.weighty = 1;
 356  0
                 gbc.ipadx = 10;
 357  
                 
 358  0
                 gbc.gridx = 0;
 359  0
                 informationPanel.add(sumsLabel, gbc);
 360  
                 
 361  0
                 gbc.gridx = 1;
 362  0
                 informationPanel.add(clearedSum, gbc);
 363  
                 
 364  0
                 gbc.gridx = 2;
 365  0
                 informationPanel.add(reconciledSum, gbc);
 366  
 
 367  
                 //Second row
 368  0
                 gbc.gridy = 1;
 369  
                 
 370  0
                 gbc.gridx = 1;
 371  0
                 informationPanel.add(notClearedSum, gbc);
 372  
                 
 373  0
                 gbc.gridx = 2;
 374  0
                 informationPanel.add(notReconciledSum, gbc);
 375  
 
 376  
                 //Third row
 377  0
                 gbc.gridy = 2;
 378  
                 
 379  0
                 gbc.gridx = 0;
 380  0
                 informationPanel.add(balancesLabel, gbc);
 381  
                 
 382  0
                 gbc.gridx = 1;
 383  0
                 informationPanel.add(clearedBalance, gbc);
 384  
                 
 385  0
                 gbc.gridx = 2;
 386  0
                 informationPanel.add(reconciledBalance, gbc);
 387  
 
 388  0
                 gbc.gridx = 3;
 389  0
                 informationPanel.add(accountBalance, gbc);
 390  
 
 391  
 
 392  
 
 393  
                 
 394  0
                 JPanel topPanel = new JPanel(new BorderLayout());
 395  0
                 topPanel.add(searchCheck, BorderLayout.WEST);
 396  0
                 topPanel.add(topLeftPanel, BorderLayout.NORTH);
 397  0
                 topPanel.add(spacerPanel, BorderLayout.CENTER);                
 398  
 
 399  
 //                JPanel informationLabelsPanel = new JPanel(new BorderLayout());
 400  
 //                informationLabelsPanel.add(sumsLabel, BorderLayout.NORTH);
 401  
 ////                informationLabelsPanel.add(new JLabel(" "));
 402  
 //                informationLabelsPanel.add(balancesLabel, BorderLayout.SOUTH);
 403  
 //
 404  
 //                JPanel accountInformationPanel = new JPanel(new BorderLayout());
 405  
 ////                accountInformationPanel.add(new JLabel(" "));
 406  
 ////                accountInformationPanel.add(new JLabel(" "));
 407  
 //                accountInformationPanel.add(accountBalance, BorderLayout.SOUTH);
 408  
 //
 409  
 //                JPanel clearedInformationPanel = new JPanel(new VerticalLayout());
 410  
 //                clearedInformationPanel.add(clearedSum);
 411  
 //                clearedInformationPanel.add(notClearedSum);
 412  
 //                clearedInformationPanel.add(clearedBalance);
 413  
 //
 414  
 //                JPanel reconciledInformationPanel = new JPanel(new VerticalLayout());
 415  
 //                reconciledInformationPanel.add(reconciledSum);
 416  
 //                reconciledInformationPanel.add(notReconciledSum);
 417  
 //                reconciledInformationPanel.add(reconciledBalance);
 418  
 //
 419  
 //                JPanel clearedReconcileInformationPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
 420  
 //                clearedReconcileInformationPanel.add(informationLabelsPanel);
 421  
 //                clearedReconcileInformationPanel.add(reconciledInformationPanel);
 422  
 //                clearedReconcileInformationPanel.add(clearedInformationPanel);
 423  
 //                clearedReconcileInformationPanel.add(accountInformationPanel);
 424  
 //                clearedReconcileInformationPanel.setAlignmentY(JLabel.TOP_ALIGNMENT);
 425  
 //                clearedReconcileInformationPanel.setAlignmentX(JLabel.TOP_ALIGNMENT);
 426  
 
 427  0
                 JPanel informationPanelHolder = new JPanel(new FlowLayout(FlowLayout.RIGHT));
 428  0
                 informationPanelHolder.add(informationPanel);
 429  
                 
 430  0
                 final JXCollapsiblePane bottomCollapsiblePanel = new JXCollapsiblePane(new BorderLayout());
 431  0
                 bottomCollapsiblePanel.setCollapsed(!PrefsModel.getInstance().isTotalPaneVisible());
 432  0
                 bottomCollapsiblePanel.add(informationPanelHolder, BorderLayout.CENTER);
 433  
 
 434  0
                 final JLabel totalCheck = new JLabel(PrefsModel.getInstance().isTotalPaneVisible() ? expanded : collapsed);
 435  0
                 totalCheck.setVerticalAlignment(JLabel.TOP);
 436  0
                 totalCheck.addMouseListener(new MouseAdapter(){
 437  
                         public void mouseClicked(MouseEvent e) {
 438  0
                                 if (totalCheck.getIcon().equals(expanded))
 439  0
                                         totalCheck.setIcon(collapsed);
 440  
                                 else
 441  0
                                         totalCheck.setIcon(expanded);
 442  0
                                 boolean hide = totalCheck.getIcon().equals(collapsed);
 443  0
                                 bottomCollapsiblePanel.setCollapsed(hide);
 444  
 
 445  0
                                 PrefsModel.getInstance().setTotalPaneVisible(!hide);
 446  0
                         }
 447  
                 });
 448  
 
 449  0
                 JPanel totalSpacerPanel = new JPanel(new BorderLayout());
 450  0
                 totalSpacerPanel.add(bottomCollapsiblePanel, BorderLayout.NORTH);
 451  
 
 452  0
                 totalPanel.add(totalCheck, BorderLayout.WEST);
 453  0
                 totalPanel.add(totalSpacerPanel, BorderLayout.CENTER);
 454  
 
 455  0
                 this.getRootPane().setDefaultButton(recordButton);
 456  
 
 457  0
                 JPanel buttonPanelRight = new JPanel(new FlowLayout(FlowLayout.RIGHT));
 458  0
                 buttonPanelRight.add(clearButton);
 459  0
                 buttonPanelRight.add(recordButton);
 460  
 
 461  0
                 JPanel buttonPanelLeft = new JPanel(new FlowLayout(FlowLayout.LEFT));
 462  0
                 buttonPanelLeft.add(deleteButton);
 463  
 
 464  0
                 JPanel buttonPanel = new JPanel(new BorderLayout());
 465  0
                 buttonPanel.add(buttonPanelRight, BorderLayout.EAST);
 466  0
                 buttonPanel.add(buttonPanelLeft, BorderLayout.WEST);
 467  
 
 468  0
                 JScrollPane listScroller = new JScrollPane(list);
 469  
 
 470  0
                 JPanel scrollPanel = new JPanel(new BorderLayout());
 471  0
                 scrollPanel.add(listScroller, BorderLayout.CENTER);
 472  0
                 scrollPanel.add(transactionEditor, BorderLayout.SOUTH);
 473  
 
 474  0
                 JPanel mainPanel = new JPanel(); 
 475  0
                 mainPanel.setLayout(new BorderLayout());
 476  0
                 mainPanel.add(scrollPanel, BorderLayout.CENTER);
 477  0
                 mainPanel.add(totalPanel, BorderLayout.SOUTH);
 478  
 
 479  0
                 this.setLayout(new BorderLayout());
 480  0
                 this.add(topPanel, BorderLayout.NORTH);
 481  0
                 this.add(mainPanel, BorderLayout.CENTER);
 482  0
                 this.add(buttonPanel, BorderLayout.SOUTH);
 483  
 
 484  
 //                this.add(mainPanel, BorderLayout.CENTER);
 485  
 
 486  0
                 recordButton.addActionListener(this);
 487  0
                 clearButton.addActionListener(this);
 488  0
                 deleteButton.addActionListener(this);
 489  
 
 490  0
                 this.addComponentListener(new ComponentAdapter(){
 491  
                         public void componentResized(ComponentEvent e) {
 492  0
                                 if (e.getComponent().getWidth() < MIN_WIDTH)
 493  0
                                         e.getComponent().setSize(MIN_WIDTH, e.getComponent().getHeight());
 494  0
                                 if (e.getComponent().getHeight() < MIN_HEIGHT)
 495  0
                                         e.getComponent().setSize(e.getComponent().getWidth(), MIN_HEIGHT);
 496  0
                         }
 497  
                 });
 498  
 
 499  0
                 list.addHighlighter(HighlighterFactory.createAlternateStriping(Const.COLOR_EVEN_ROW, Const.COLOR_ODD_ROW));
 500  
 
 501  0
                 if (OperatingSystemUtil.isMac()){
 502  0
                         listScroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
 503  
                 }
 504  
                 else {
 505  0
                         transactionEditor.setBorder(BorderFactory.createEmptyBorder(3, 0, 3, 0));
 506  
                 }
 507  
 
 508  0
                 dateFilterComboBox.setModel(new DefaultComboBoxModel(TransactionDateFilterKeys.values()));
 509  0
                 dateFilterComboBox.setRenderer(new TranslatorListCellRenderer());
 510  
 
 511  0
                 clearedFilterComboBox.setModel(new DefaultComboBoxModel(TransactionClearedFilterKeys.values()));
 512  0
                 clearedFilterComboBox.setRenderer(new TranslatorListCellRenderer());
 513  
 
 514  0
                 reconciledFilterComboBox.setModel(new DefaultComboBoxModel(TransactionReconciledFilterKeys.values()));
 515  0
                 reconciledFilterComboBox.setRenderer(new TranslatorListCellRenderer());
 516  
 
 517  0
                 dateFilterComboBox.addItemListener(new ItemListener() {
 518  
                         public void itemStateChanged(ItemEvent e) {
 519  0
                                 if (dateFilterComboBox.getSelectedItem() == null){
 520  0
                                         if (e.getItem().equals(dateFilterComboBox.getItemAt(0))){
 521  0
                                                 dateFilterComboBox.setSelectedIndex(1);
 522  
                                         }
 523  0
                                         dateFilterComboBox.setSelectedIndex(0);
 524  
                                 }
 525  0
                                 if (e.getStateChange() == ItemEvent.SELECTED) {
 526  0
                                         listModel.setDateFilter((TransactionDateFilterKeys) dateFilterComboBox.getSelectedItem());
 527  
                                 }
 528  0
                                 TransactionFrame.this.updateContent();
 529  0
                                 list.ensureIndexIsVisible(listModel.getSize() - 1);
 530  0
                         }                        
 531  
                 });
 532  0
                 clearedFilterComboBox.addItemListener(new ItemListener() {
 533  
                         public void itemStateChanged(ItemEvent e) {
 534  0
                                 if (clearedFilterComboBox.getSelectedItem() == null){
 535  0
                                         if (e.getItem().equals(clearedFilterComboBox.getItemAt(0))){
 536  0
                                                 clearedFilterComboBox.setSelectedIndex(1);
 537  
                                         }
 538  0
                                         clearedFilterComboBox.setSelectedIndex(0);
 539  
                                 }
 540  0
                                 if (e.getStateChange() == ItemEvent.SELECTED) {
 541  0
                                         listModel.setClearedFilter((TransactionClearedFilterKeys) clearedFilterComboBox.getSelectedItem());
 542  
                                 }
 543  0
                                 TransactionFrame.this.updateContent();
 544  0
                                 list.ensureIndexIsVisible(listModel.getSize() - 1);
 545  0
                         }                        
 546  
                 });
 547  0
                 reconciledFilterComboBox.addItemListener(new ItemListener() {
 548  
                         public void itemStateChanged(ItemEvent e) {
 549  0
                                 if (reconciledFilterComboBox.getSelectedItem() == null){
 550  0
                                         if (e.getItem().equals(reconciledFilterComboBox.getItemAt(0))){
 551  0
                                                 reconciledFilterComboBox.setSelectedIndex(1);
 552  
                                         }
 553  0
                                         reconciledFilterComboBox.setSelectedIndex(0);
 554  
                                 }
 555  0
                                 if (e.getStateChange() == ItemEvent.SELECTED) {
 556  0
                                         listModel.setReconciledFilter((TransactionReconciledFilterKeys) reconciledFilterComboBox.getSelectedItem());
 557  
                                 }
 558  0
                                 TransactionFrame.this.updateContent();
 559  0
                                 list.ensureIndexIsVisible(listModel.getSize() - 1);
 560  0
                         }                        
 561  
                 });
 562  
 
 563  0
                 searchField.addSearchTextChangedEventListener(new SearchTextChangedEventListener(){
 564  
                         public void searchTextChangedEventOccurred(SearchTextChangedEvent evt) {
 565  0
                                 listModel.setSearchText(searchField.getText());
 566  0
                                 TransactionFrame.this.updateContent();
 567  0
                                 list.ensureIndexIsVisible(listModel.getSize() - 1);
 568  0
                         }
 569  
                 });
 570  
 
 571  0
                 list.addListSelectionListener(new ListSelectionListener(){
 572  
                         public void valueChanged(ListSelectionEvent arg0) {
 573  0
                                 if (!arg0.getValueIsAdjusting() && !TransactionFrame.this.disableListEvents){
 574  
                                         //Check if the user has changed the selected transaction
 575  0
                                         if (transactionEditor.isChanged() 
 576  
                                                         && transactionEditor.getTransaction() != (Transaction) list.getSelectedValue()){
 577  
                                                 int ret;
 578  
 
 579  0
                                                 if (transactionEditor.isTransactionValid(TransactionFrame.this.associatedAccount)){
 580  0
                                                         String[] options = new String[2];
 581  0
                                                         options[0] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_YES);
 582  0
                                                         options[1] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_NO);
 583  
 
 584  0
                                                         ret = JOptionPane.showOptionDialog(
 585  
                                                                         null, 
 586  
                                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.TRANSACTION_CHANGED_MESSAGE), 
 587  
                                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.TRANSACTION_CHANGED_TITLE),
 588  
                                                                         JOptionPane.YES_NO_CANCEL_OPTION,
 589  
                                                                         JOptionPane.PLAIN_MESSAGE,
 590  
                                                                         null,
 591  
                                                                         options,
 592  
                                                                         options[0]);
 593  0
                                                         if (ret == JOptionPane.YES_OPTION){
 594  0
                                                                 recordButton.doClick();
 595  
                                                         }
 596  0
                                                         else if (ret == JOptionPane.NO_OPTION){
 597  0
                                                                 transactionEditor.setChanged(false);
 598  
 //                                                                list.setSelectedValue(editableTransaction.getTransaction(), true);
 599  
 //                                                                return;
 600  
                                                         }
 601  0
                                                         else if (ret == JOptionPane.CANCEL_OPTION){
 602  0
                                                                 transactionEditor.setChanged(false);
 603  0
                                                                 list.setSelectedValue(transactionEditor.getTransaction(), true);
 604  0
                                                                 transactionEditor.setChanged(true);
 605  0
                                                                 return;
 606  
                                                         }
 607  0
                                                 }
 608  
                                                 else{
 609  0
                                                         String[] options = new String[2];
 610  0
                                                         options[0] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_YES);
 611  0
                                                         options[1] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_NO);
 612  
 
 613  0
                                                         ret = JOptionPane.showOptionDialog(
 614  
                                                                         null, 
 615  
                                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.TRANSACTION_CHANGED_INVALID_MESSAGE), 
 616  
                                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.TRANSACTION_CHANGED_TITLE),
 617  
                                                                         JOptionPane.YES_NO_OPTION,
 618  
                                                                         JOptionPane.PLAIN_MESSAGE,
 619  
                                                                         null,
 620  
                                                                         options,
 621  
                                                                         options[0]);
 622  0
                                                         if (ret == JOptionPane.NO_OPTION){
 623  0
                                                                 transactionEditor.setChanged(false);
 624  
 
 625  0
                                                                 if (transactionEditor.getTransaction() == null)
 626  0
                                                                         list.clearSelection();
 627  
                                                                 else
 628  0
                                                                         list.setSelectedValue(transactionEditor.getTransaction(), true);
 629  
 
 630  0
                                                                 transactionEditor.setChanged(true);
 631  0
                                                                 return;
 632  
                                                         }
 633  0
                                                         else if (ret == JOptionPane.YES_OPTION){
 634  0
                                                                 transactionEditor.setChanged(false);
 635  
                                                         }
 636  
                                                 }
 637  
                                         }
 638  
 
 639  0
                                         if (list.getSelectedValue() instanceof Transaction) {
 640  0
                                                 Transaction t = (Transaction) list.getSelectedValue();
 641  
 
 642  0
                                                 transactionEditor.setTransaction(t, false, recordButton);
 643  
 
 644  0
                                                 Logger.getLogger(this.getClass().getName()).finest("Set transaction to " + t);
 645  0
                                         }
 646  0
                                         else if (list.getSelectedValue() == null){
 647  0
                                                 transactionEditor.setTransaction(null, false, recordButton);
 648  0
                                                 transactionEditor.updateContent();
 649  
 
 650  0
                                                 Logger.getLogger(this.getClass().getName()).finest("Set transaction to null");
 651  
                                         }
 652  
 
 653  0
                                         updateButtons();
 654  
                                 }
 655  0
                         }
 656  
                 });
 657  
 
 658  
                 //Load state of filters
 659  0
                 if (PrefsModel.getInstance().getSearchText() != null){
 660  0
                         searchField.setText(PrefsModel.getInstance().getSearchText());
 661  
                 }
 662  0
                 listModel.setSearchText(searchField.getText());
 663  0
                 TransactionFrame.this.updateContent();
 664  0
                 list.ensureIndexIsVisible(listModel.getSize() - 1);
 665  
                         
 666  0
                 if (PrefsModel.getInstance().getDateFilter() != null){
 667  
                         try {
 668  0
                                 dateFilterComboBox.setSelectedItem(TransactionDateFilterKeys.valueOf(PrefsModel.getInstance().getDateFilter()));
 669  
                         }
 670  0
                         catch (IllegalArgumentException iae){
 671  0
                                 dateFilterComboBox.setSelectedItem(TransactionDateFilterKeys.TRANSACTION_FILTER_ALL_DATES);
 672  0
                         }
 673  
                 }
 674  0
                 if (PrefsModel.getInstance().getReconciledFilter() != null){
 675  
                         try {
 676  0
                                 reconciledFilterComboBox.setSelectedItem(TransactionReconciledFilterKeys.valueOf(PrefsModel.getInstance().getReconciledFilter()));
 677  
                         }
 678  0
                         catch (IllegalArgumentException iae){
 679  0
                                 reconciledFilterComboBox.setSelectedItem(TransactionReconciledFilterKeys.TRANSACTION_FILTER_ALL_RECONCILED);
 680  0
                         }
 681  
                 }
 682  0
                 if (PrefsModel.getInstance().getClearedFilter() != null){
 683  
                         try {
 684  0
                                 clearedFilterComboBox.setSelectedItem(TransactionClearedFilterKeys.valueOf(PrefsModel.getInstance().getClearedFilter()));
 685  
                         }
 686  0
                         catch (IllegalArgumentException iae){
 687  0
                                 clearedFilterComboBox.setSelectedItem(TransactionClearedFilterKeys.TRANSACTION_FILTER_ALL_CLEARED);
 688  0
                         }
 689  
                 }
 690  
                 
 691  0
                 getDocument().addDocumentChangeListener(listener);
 692  
 
 693  0
                 String dataFile = getDocument().getFile() == null ? "" : " - " + getDocument().getFile();
 694  0
                 this.setTitle(TextFormatter.getTranslation((associatedSource == null ? BuddiKeys.ALL_TRANSACTIONS : BuddiKeys.TRANSACTIONS)) 
 695  
                                 + (associatedSource != null ? " - " + associatedSource.getFullName() : "") 
 696  
                                 + dataFile + " - " + PrefsModel.getInstance().getTranslator().get(BuddiKeys.BUDDI));
 697  0
                 this.setJMenuBar(new BuddiMenuBar(this));
 698  0
         }
 699  
 
 700  
         @Override
 701  
         public void closeWindowWithoutPrompting() {
 702  0
                 PrefsModel.getInstance().setSearchText(searchField.getText());
 703  0
                 PrefsModel.getInstance().setDateFilter(dateFilterComboBox.getSelectedItem() + "");
 704  0
                 PrefsModel.getInstance().setReconciledFilter(reconciledFilterComboBox.getSelectedItem() + "");
 705  0
                 PrefsModel.getInstance().setClearedFilter(clearedFilterComboBox.getSelectedItem() + "");
 706  
                 
 707  0
                 PrefsModel.getInstance().putWindowSize(getDocument().getFile() + (associatedSource == null ? BuddiKeys.ALL_TRANSACTIONS.toString() : associatedSource.getFullName()), this.getSize());
 708  0
                 PrefsModel.getInstance().putWindowLocation(getDocument().getFile() + (associatedSource == null ? BuddiKeys.ALL_TRANSACTIONS.toString() : associatedSource.getFullName()), this.getLocation());
 709  0
                 PrefsModel.getInstance().save();
 710  
 
 711  0
                 super.closeWindowWithoutPrompting();
 712  0
         }
 713  
 
 714  
         @Override
 715  
         public void updateContent() {
 716  0
                 super.updateContent();
 717  
 
 718  0
                 if (associatedAccount != null
 719  
                                 && associatedAccount.getOverdraftCreditLimit() > 0
 720  
                                 && ((PrefsModel.getInstance().isShowOverdraft() 
 721  
                                                 && !associatedAccount.getAccountType().isCredit())
 722  
                                                 || (PrefsModel.getInstance().isShowCreditRemaining() 
 723  
                                                                 && associatedAccount.getAccountType().isCredit()))){
 724  
                         long amountLeft;
 725  0
                         amountLeft = (associatedAccount.getOverdraftCreditLimit() + associatedAccount.getBalance());
 726  0
                         double percentLeft = ((double) amountLeft) / associatedAccount.getOverdraftCreditLimit() * 100.0;
 727  
 
 728  0
                         StringBuffer sb = new StringBuffer();
 729  0
                         sb.append("<html>");
 730  0
                         sb.append(
 731  
                                         TextFormatter.getTranslation(
 732  
                                                         (associatedAccount.getAccountType().isCredit() ? 
 733  
                                                                         BuddiKeys.AVAILABLE_CREDIT 
 734  
                                                                         : BuddiKeys.AVAILABLE_FUNDS)))
 735  
                                                                         .append(": ")
 736  
                                                                         .append(InternalFormatter.isRed(associatedAccount, amountLeft) ? "<font color='red'>" : "")
 737  
                                                                         .append(TextFormatter.getFormattedCurrency(amountLeft))
 738  
                                                                         .append(InternalFormatter.isRed(associatedAccount, (long) percentLeft) ? "</font>" : "");
 739  0
                         if (associatedAccount.getAccountType().isCredit()){
 740  0
                                 sb.append(" (")
 741  
                                 .append(Formatter.getDecimalFormat().format(percentLeft))
 742  
                                 .append("%)");
 743  
                         }
 744  0
                         if (amountLeft < 0)
 745  0
                                 sb.append("</font></html>");
 746  
 
 747  0
                         overdraftCreditLimit.setText(sb.toString());
 748  0
                         if (!associatedAccount.getAccountType().isCredit() && PrefsModel.getInstance().isShowTooltips())
 749  0
                                 overdraftCreditLimit.setToolTipText(TextFormatter.getTranslation(BuddiKeys.TOOLTIP_AVAILABLE_FUNDS));
 750  0
                         overdraftCreditLimit.setVisible(true);
 751  0
                 }
 752  
                 else {
 753  0
                         overdraftCreditLimit.setText("");
 754  0
                         overdraftCreditLimit.setToolTipText("");
 755  0
                         overdraftCreditLimit.setVisible(false);
 756  
                 }
 757  
 
 758  
                 //Update the cleared and reconciled totals at the bottom
 759  0
                 if (associatedSource != null){
 760  0
                         long clearedBalanceTotal = 0, clearedTotal = 0, notClearedTotal = 0;
 761  0
                         long reconciledBalanceTotal = 0, reconciledTotal = 0, notReconciledTotal = 0;
 762  
 
 763  0
                         if (associatedAccount != null){
 764  0
                                 clearedBalanceTotal = associatedAccount.getStartingBalance();
 765  0
                                 reconciledBalanceTotal = associatedAccount.getStartingBalance();
 766  
                         }
 767  
 
 768  0
                         for (Transaction t : listModel) {
 769  0
                                 if (!t.isDeleted()){
 770  0
                                         if (t.getFrom().equals(associatedSource)){
 771  0
                                                 if (t.isClearedFrom()){
 772  0
                                                         clearedTotal -= t.getAmount();
 773  0
                                                         clearedBalanceTotal -= t.getAmount();
 774  
                                                 }
 775  
                                                 else
 776  0
                                                         notClearedTotal -= t.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 777  
                                                 
 778  0
                                                 if (t.isReconciledFrom()){
 779  0
                                                         reconciledTotal -= t.getAmount();
 780  0
                                                         reconciledBalanceTotal -= t.getAmount();
 781  
                                                 }
 782  
                                                 else
 783  0
                                                         notReconciledTotal -= t.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 784  
                                         }
 785  0
                                         else if (t.getTo().equals(associatedSource)){
 786  0
                                                 if (t.isClearedTo()){
 787  0
                                                         clearedTotal += t.getAmount();
 788  0
                                                         clearedBalanceTotal += t.getAmount();
 789  
                                                 }
 790  
                                                 else
 791  0
                                                         notClearedTotal += t.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 792  
 
 793  0
                                                 if (t.isReconciledTo()){
 794  0
                                                         reconciledTotal += t.getAmount();
 795  0
                                                         reconciledBalanceTotal += t.getAmount();
 796  
                                                 }
 797  
                                                 else
 798  0
                                                         notReconciledTotal += t.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 799  
                                         }
 800  0
                                         else if (t.getFrom() instanceof SplitImpl){
 801  0
                                                 for (TransactionSplit split : t.getFromSplits()){
 802  0
                                                         if (split.getSource().equals(associatedSource)){
 803  0
                                                                 if (t.isClearedFrom()){
 804  0
                                                                         clearedTotal -= split.getAmount();
 805  0
                                                                         clearedBalanceTotal -= split.getAmount();
 806  
                                                                 }
 807  
                                                                 else
 808  0
                                                                         notClearedTotal -= split.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 809  
                                                                 
 810  0
                                                                 if (t.isReconciledFrom()){
 811  0
                                                                         reconciledTotal -= split.getAmount();
 812  0
                                                                         reconciledBalanceTotal -= split.getAmount();
 813  
                                                                 }
 814  
                                                                 else
 815  0
                                                                         notReconciledTotal -= split.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 816  
                                                                 
 817  
                                                         }
 818  
                                                 }
 819  
                                         }
 820  0
                                         else if (t.getTo() instanceof SplitImpl){
 821  0
                                                 for (TransactionSplit split : t.getToSplits()){
 822  0
                                                         if (split.getSource().equals(associatedSource)){
 823  0
                                                                 if (t.isClearedTo()){
 824  0
                                                                         clearedTotal += split.getAmount();
 825  0
                                                                         clearedBalanceTotal += split.getAmount();
 826  
                                                                 }
 827  
                                                                 else
 828  0
                                                                         notClearedTotal += split.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 829  
 
 830  0
                                                                 if (t.isReconciledTo()){
 831  0
                                                                         reconciledTotal += split.getAmount();
 832  0
                                                                         reconciledBalanceTotal += split.getAmount();
 833  
                                                                 }
 834  
                                                                 else
 835  0
                                                                         notReconciledTotal += split.getAmount(); //(t.getAmount() * (t.isInflow() ? 1 : -1));
 836  
                                                         }
 837  
                                                 }
 838  
                                         }
 839  
                                         else {
 840  0
                                                 Logger.getLogger(this.getClass().getName()).severe("Neither TO nor FROM equals the associated source.  The value of TO is " + t.getTo().getFullName() + " and the value of FROM is " + t.getFrom().getFullName() + ", and associatedSource is " + associatedSource);
 841  
                                         }
 842  
                                 }
 843  
                         }
 844  
 
 845  0
                         clearedBalance.setText("<html>" + TextFormatter.getTranslation(BuddiKeys.BALANCE_OF_TRANSACTIONS_CLEARED) + " " + TextFormatter.getFormattedCurrency(clearedBalanceTotal) + "</html>");
 846  0
                         clearedSum.setText("<html>" + TextFormatter.getTranslation(BuddiKeys.SUM_OF_TRANSACTIONS_CLEARED) + " " + TextFormatter.getFormattedCurrency(clearedTotal) + "</html>");
 847  0
                         notClearedSum.setText("<html>" + TextFormatter.getTranslation(BuddiKeys.SUM_OF_TRANSACTIONS_NOT_CLEARED) + " " + TextFormatter.getFormattedCurrency(notClearedTotal) + "</html>");
 848  
                         
 849  0
                         reconciledBalance.setText("<html>" + TextFormatter.getTranslation(BuddiKeys.BALANCE_OF_TRANSACTIONS_RECONCILED) + " " + TextFormatter.getFormattedCurrency(reconciledBalanceTotal) + "</html>");
 850  0
                         reconciledSum.setText("<html>" + TextFormatter.getTranslation(BuddiKeys.SUM_OF_TRANSACTIONS_RECONCILED) + " " + TextFormatter.getFormattedCurrency(reconciledTotal) + "</html>");
 851  0
                         notReconciledSum.setText("<html>" + TextFormatter.getTranslation(BuddiKeys.SUM_OF_TRANSACTIONS_NOT_RECONCILED) + " " + TextFormatter.getFormattedCurrency(notReconciledTotal) + "</html>");                        
 852  
                 }
 853  
 
 854  
 
 855  
                 //Set visibility of totals
 856  
 
 857  
                 //Labels
 858  0
                 boolean accountNotFiltered = associatedAccount != null && !listModel.isListFiltered(); 
 859  0
                 boolean listFiltered = listModel.isListFiltered();
 860  0
                 boolean clearedOrReconciled = PrefsModel.getInstance().isShowCleared() || PrefsModel.getInstance().isShowReconciled();
 861  
                 
 862  0
                 if (associatedAccount != null)
 863  0
                         accountBalance.setText("<html><b>" + (clearedOrReconciled ? TextFormatter.getTranslation(BuddiKeys.BALANCE_OF_ACCOUNT) : "") + " " + TextFormatter.getFormattedCurrency(associatedAccount.getBalance()) + "</b></html>");
 864  
                 
 865  
                 //Labels
 866  0
                 if (listFiltered)
 867  0
                         sumsLabel.setText("<html><b>" + TextFormatter.getTranslation(BuddiKeys.FILTERED_SUM_LABEL) + "</b></html>");
 868  
                 else
 869  0
                         sumsLabel.setText("<html><b>" + TextFormatter.getTranslation(BuddiKeys.SUM_LABEL) + "</b></html>");
 870  0
                 balancesLabel.setText("<html><b>" + TextFormatter.getTranslation((clearedOrReconciled ? BuddiKeys.BALANCES_LABEL : BuddiKeys.BALANCE_LABEL)) + "</b></html>");
 871  
 
 872  0
                 balancesLabel.setVisible(accountNotFiltered);
 873  0
                 sumsLabel.setVisible(PrefsModel.getInstance().isShowCleared() || PrefsModel.getInstance().isShowReconciled());
 874  
                 
 875  
                 //Account
 876  0
                 accountBalance.setVisible(accountNotFiltered);
 877  
 
 878  
                 //Reconciled
 879  0
                 reconciledBalance.setVisible(accountNotFiltered && PrefsModel.getInstance().isShowReconciled());
 880  0
                 reconciledSum.setVisible(PrefsModel.getInstance().isShowReconciled());
 881  0
                 notReconciledSum.setVisible(PrefsModel.getInstance().isShowReconciled());
 882  
 
 883  
                 //Cleared
 884  0
                 clearedBalance.setVisible(accountNotFiltered && PrefsModel.getInstance().isShowCleared());
 885  0
                 clearedSum.setVisible(PrefsModel.getInstance().isShowCleared());
 886  0
                 notClearedSum.setVisible(PrefsModel.getInstance().isShowCleared());
 887  
 
 888  
                 //Everything
 889  0
                 totalPanel.setVisible(accountNotFiltered || PrefsModel.getInstance().isShowCleared() || PrefsModel.getInstance().isShowReconciled());
 890  
 
 891  
                 //Set visibility of filters
 892  0
                 clearedFilterComboBox.setVisible(PrefsModel.getInstance().isShowCleared());
 893  0
                 reconciledFilterComboBox.setVisible(PrefsModel.getInstance().isShowReconciled());
 894  
 
 895  0
                 this.repaint();
 896  0
         }
 897  
 
 898  
         public void updateButtons(){
 899  0
                 super.updateButtons();
 900  
 
 901  0
                 if (transactionEditor == null 
 902  
                                 || transactionEditor.getTransaction() == null){
 903  0
                         recordButton.setText(PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_RECORD));
 904  0
                         clearButton.setText(PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_CLEAR));
 905  0
                         deleteButton.setEnabled(false);
 906  
                 }
 907  
                 else{
 908  0
                         recordButton.setText(PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_UPDATE));
 909  0
                         clearButton.setText(PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_NEW));
 910  0
                         deleteButton.setEnabled(true);
 911  
                 }
 912  
                 
 913  0
                 if (list.getSelectedValue() instanceof Transaction){
 914  0
                         if (((Transaction) list.getSelectedValue()).isDeleted())
 915  0
                                 deleteButton.setText(TextFormatter.getTranslation(ButtonKeys.BUTTON_UNDELETE));
 916  
                         else
 917  0
                                 deleteButton.setText(TextFormatter.getTranslation(ButtonKeys.BUTTON_DELETE));
 918  
                 }
 919  0
         }
 920  
 
 921  
         public void actionPerformed(ActionEvent e) {
 922  0
                 if (e.getSource().equals(recordButton)){
 923  0
                         if (!transactionEditor.isTransactionValid(this.associatedSource)){
 924  0
                                 String[] options = new String[1];
 925  0
                                 options[0] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_OK);
 926  
 
 927  0
                                 JOptionPane.showOptionDialog(
 928  
                                                 TransactionFrame.this,
 929  
                                                 PrefsModel.getInstance().getTranslator().get(BuddiKeys.RECORD_BUTTON_ERROR),
 930  
                                                 PrefsModel.getInstance().getTranslator().get(BuddiKeys.ERROR),
 931  
                                                 JOptionPane.DEFAULT_OPTION,
 932  
                                                 JOptionPane.ERROR_MESSAGE,
 933  
                                                 null,
 934  
                                                 options,
 935  
                                                 options[0]
 936  
                                 );
 937  0
                                 return;
 938  
                         }
 939  
 
 940  
                         //Don't fire updates for a while
 941  0
                         getDocument().startBatchChange();
 942  
 
 943  
                         Transaction t;
 944  
                         boolean isUpdate;
 945  
 
 946  0
                         if (recordButton.getText().equals(TextFormatter.getTranslation(ButtonKeys.BUTTON_UPDATE)))
 947  0
                                 isUpdate = true;
 948  0
                         else if (recordButton.getText().equals(TextFormatter.getTranslation(ButtonKeys.BUTTON_RECORD)))
 949  0
                                 isUpdate = false;
 950  
                         else {
 951  0
                                 Logger.getLogger(this.getClass().getName()).warning("Unknown record button state: " + recordButton.getText());
 952  0
                                 return;
 953  
                         }
 954  
 
 955  0
                         if (isUpdate && transactionEditor.isDangerouslyChanged()) {
 956  0
                                 String[] options = new String[2];
 957  0
                                 options[0] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_CREATE_NEW_TRANSACTION);
 958  0
                                 options[1] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_OVERWRITE_TRANSACTON);
 959  
 
 960  0
                                 int ret = JOptionPane.showOptionDialog(
 961  
                                                 null, 
 962  
                                                 PrefsModel.getInstance().getTranslator().get(BuddiKeys.MESSAGE_CHANGE_EXISTING_TRANSACTION),
 963  
                                                 PrefsModel.getInstance().getTranslator().get(BuddiKeys.MESSAGE_CHANGE_EXISTING_TRANSACTION_TITLE),
 964  
                                                 JOptionPane.YES_NO_OPTION,
 965  
                                                 JOptionPane.WARNING_MESSAGE,
 966  
                                                 null,
 967  
                                                 options,
 968  
                                                 options[0]);
 969  
 
 970  0
                                 if (ret == JOptionPane.YES_OPTION){ // create new transaction
 971  0
                                         isUpdate = false;
 972  
                                 } // else continue with update
 973  
                         }
 974  
 
 975  
                         try {
 976  0
                                 if(isUpdate) {
 977  0
                                         t = transactionEditor.getTransactionUpdated();
 978  
 
 979  
                                 } else {
 980  0
                                         t = transactionEditor.getTransactionNew();
 981  0
                                         getDataModel().addTransaction(t);
 982  
                                 }
 983  
                         }
 984  0
                         catch (ModelException me){
 985  0
                                 Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error in record button in Transaction frame", me);
 986  0
                                 return;
 987  0
                         }
 988  
 
 989  0
                         getDataModel().updateAllBalances();
 990  
 
 991  0
                         getDataModel().finishBatchChange();
 992  
 
 993  0
                         transactionEditor.setTransaction(null, true, recordButton);
 994  0
                         list.clearSelection();
 995  0
                         updateButtons();
 996  
 
 997  
                         // Scroll the list view to make sure the newly-created transaction is visible.
 998  0
                         if (!isUpdate){
 999  0
                                 Date currentTransactionDate = t.getDate();
 1000  
 
 1001  
                                 // Iterate backwards through the list of transacations, looking for a transaction
 1002  
                                 // with the most recently inserted date, and scroll to that transaction's index.
 1003  
                                 // For the common case of inserted new transactions near the current day, this
 1004  
                                 // will be almost as fast as just scrolling to the end of the list, but always correct.
 1005  0
                                 for (int index = listModel.getSize() - 1; index >= 0; --index) {
 1006  0
                                         Transaction transactionToCheck = (Transaction) listModel.getElementAt(index);
 1007  0
                                         if (transactionToCheck.getDate().equals(currentTransactionDate)) {
 1008  0
                                                 list.ensureIndexIsVisible(index);
 1009  0
                                                 break;
 1010  
                                         }
 1011  
                                 }
 1012  
                         }
 1013  
 
 1014  0
                         disableListEvents = false;
 1015  
 
 1016  0
                         transactionEditor.resetSelection();
 1017  0
                         transactionEditor.setChanged(false);
 1018  
 
 1019  0
                         listModel.update();
 1020  0
                         this.updateContent();
 1021  0
                         parent.updateContent();
 1022  0
                 }
 1023  0
                 else if (e.getSource().equals(clearButton)){
 1024  0
                         String[] options = new String[2];
 1025  0
                         options[0] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_YES);
 1026  0
                         options[1] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_NO);
 1027  
 
 1028  0
                         if (!transactionEditor.isChanged()
 1029  
                                         || JOptionPane.showOptionDialog(
 1030  
                                                         TransactionFrame.this,
 1031  
                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.CLEAR_TRANSACTION_LOSE_CHANGES),
 1032  
                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.CLEAR_TRANSACTION),
 1033  
                                                         JOptionPane.YES_NO_OPTION,
 1034  
                                                         JOptionPane.QUESTION_MESSAGE,
 1035  
                                                         null,
 1036  
                                                         options,
 1037  
                                                         options[0]) == JOptionPane.YES_OPTION){
 1038  
 
 1039  0
                                 transactionEditor.setTransaction(null, true, recordButton);
 1040  0
                                 transactionEditor.updateContent();
 1041  0
                                 list.ensureIndexIsVisible(list.getModel().getSize() - 1);
 1042  0
                                 list.clearSelection();
 1043  
 
 1044  0
                                 updateButtons();
 1045  
                         }
 1046  0
                 }
 1047  0
                 else if (e.getSource().equals(deleteButton)){
 1048  0
                         if (deleteButton.getText().equals(TextFormatter.getTranslation(ButtonKeys.BUTTON_UNDELETE))){
 1049  0
                                 Transaction t = (Transaction) list.getSelectedValue();
 1050  
                                 try {
 1051  0
                                         t.setDeleted(false);
 1052  
                                 }
 1053  0
                                 catch (InvalidValueException ive){
 1054  0
                                         Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Invalid Value Exception", ive);
 1055  0
                                 }
 1056  
                                 
 1057  0
                                 ((Document) getDocument()).updateAllBalances();
 1058  0
                                 updateContent();
 1059  0
                                 this.repaint();
 1060  0
                         }
 1061  0
                         else if (deleteButton.getText().equals(TextFormatter.getTranslation(ButtonKeys.BUTTON_DELETE))){
 1062  0
                                 String[] options = new String[3];
 1063  0
                                 options[0] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_VOID);
 1064  0
                                 options[1] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_DELETE);
 1065  0
                                 options[2] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_CANCEL);
 1066  
 
 1067  0
                                 int deleteVoid = JOptionPane.showOptionDialog(
 1068  
                                                 TransactionFrame.this, 
 1069  
                                                 PrefsModel.getInstance().getTranslator().get(BuddiKeys.DELETE_TRANSACTION_OR_VOID_TRANSACTION),
 1070  
                                                 PrefsModel.getInstance().getTranslator().get(BuddiKeys.DELETE_TRANSACTION),
 1071  
                                                 JOptionPane.YES_NO_CANCEL_OPTION,
 1072  
                                                 JOptionPane.QUESTION_MESSAGE,
 1073  
                                                 null,
 1074  
                                                 options,
 1075  
                                                 options[PrefsModel.getInstance().getLastDeleteOption()]);
 1076  
 
 1077  
                                 //No means to Delete
 1078  0
                                 if (deleteVoid == JOptionPane.NO_OPTION){
 1079  0
                                         PrefsModel.getInstance().setLastDeleteOption(1);
 1080  0
                                         options = new String[2];
 1081  0
                                         options[0] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_YES);
 1082  0
                                         options[1] = PrefsModel.getInstance().getTranslator().get(ButtonKeys.BUTTON_NO);
 1083  
 
 1084  0
                                         if (JOptionPane.showOptionDialog(
 1085  
                                                         TransactionFrame.this, 
 1086  
                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.DELETE_TRANSACTION_LOSE_CHANGES),
 1087  
                                                         PrefsModel.getInstance().getTranslator().get(BuddiKeys.DELETE_TRANSACTION),
 1088  
                                                         JOptionPane.YES_NO_OPTION,
 1089  
                                                         JOptionPane.QUESTION_MESSAGE,
 1090  
                                                         null,
 1091  
                                                         options,
 1092  
                                                         options[0]) == JOptionPane.YES_OPTION){
 1093  
 
 1094  0
                                                 Transaction t = (Transaction) list.getSelectedValue();
 1095  0
                                                 int position = list.getSelectedIndex();
 1096  
                                                 try {
 1097  0
                                                         ((Document) getDocument()).removeTransaction(t);
 1098  0
                                                         ((Document) getDocument()).updateAllBalances();
 1099  
 //                                                        baseModel.remove(t, listModel);
 1100  
 
 1101  
 //                                                        updateAllTransactionWindows();
 1102  0
                                                         updateButtons();
 1103  
 //                                                        MainFrame.getInstance().getAccountListPanel().updateContent();
 1104  
 
 1105  0
                                                         list.setSelectedIndex(position);
 1106  0
                                                         if (list.getSelectedValue() instanceof Transaction){
 1107  0
                                                                 t = (Transaction) list.getSelectedValue();
 1108  0
                                                                 transactionEditor.setTransaction(t, true, recordButton);
 1109  0
                                                                 list.ensureIndexIsVisible(position);
 1110  
                                                         }
 1111  
                                                         else{
 1112  0
                                                                 transactionEditor.setTransaction(null, true, recordButton);
 1113  0
                                                                 list.clearSelection();
 1114  
                                                         }
 1115  
 
 1116  0
                                                         transactionEditor.setChanged(false);
 1117  
                                                 }
 1118  0
                                                 catch (ModelException me){
 1119  0
                                                         Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Model Exception", me);
 1120  0
                                                 }
 1121  0
                                         }
 1122  
                                 }
 1123  
                                 //Yes is to Void.
 1124  0
                                 else if (deleteVoid == JOptionPane.YES_OPTION){
 1125  0
                                         PrefsModel.getInstance().setLastDeleteOption(0);
 1126  0
                                         if (list.getSelectedValue() instanceof Transaction){
 1127  0
                                                 Transaction t = (Transaction) list.getSelectedValue();
 1128  
                                                 try {
 1129  0
                                                         t.setDeleted(true);
 1130  
                                                 }
 1131  0
                                                 catch (InvalidValueException ive){
 1132  0
                                                         Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Invalid Value Exception", ive);
 1133  0
                                                 }
 1134  
                                                 
 1135  0
                                                 ((Document) getDocument()).updateAllBalances();
 1136  0
                                                 updateContent();
 1137  0
                                                 this.repaint();
 1138  
                                         }
 1139  
                                 }
 1140  
                         }
 1141  
                 }
 1142  0
         }
 1143  
 
 1144  
         public void doClickRecord(){
 1145  0
                 recordButton.doClick();
 1146  0
         }
 1147  
 
 1148  
         public void doClickClearAndAdvance(){
 1149  0
                 transactionEditor.toggleCleared();
 1150  0
                 advanceList();
 1151  0
         }        
 1152  
         
 1153  
         public void doClickReconcileAndAdvance(){
 1154  0
                 transactionEditor.toggleReconciled();
 1155  0
                 advanceList();
 1156  0
         }
 1157  
         
 1158  
         private void advanceList(){
 1159  0
                 int newIndex = Math.min(list.getSelectedIndex() + 1, list.getModel().getSize() - 1);
 1160  0
                 list.setSelectedIndex(newIndex);
 1161  0
         }
 1162  
 
 1163  
         public void doClickClear(){
 1164  0
                 clearButton.doClick();
 1165  0
         }
 1166  
 
 1167  
         public void doClickDelete(){
 1168  0
                 deleteButton.doClick();
 1169  0
         }
 1170  
 
 1171  
         private Document getDataModel(){
 1172  0
                 return (Document) getDocument();
 1173  
         }
 1174  
 
 1175  
         public void fireStructureChanged(){
 1176  0
                 parent.fireStructureChanged();
 1177  0
         }
 1178  
 
 1179  
         /**
 1180  
          * Returns the associated account.  If this transaction frame was opened 
 1181  
          * by double clicking on an account, this will be the account which was
 1182  
          * clicked on.  If this transaction frame was opened by double clicking
 1183  
          * on a budget category, or by using the 'All Transactions' menu item,
 1184  
          * this will return null.
 1185  
          * @return
 1186  
          */
 1187  
         public Account getAssociatedAccount(){
 1188  0
                 return associatedAccount;
 1189  
         }
 1190  
 
 1191  
         /**
 1192  
          * Returns the associated source.  If this transaction frame was opened 
 1193  
          * by double clicking on an account, this will be the account which was
 1194  
          * clicked on.  If this transaction frame was opened by double clicking
 1195  
          * on a budget category, this will be the budget category which was clicked
 1196  
          * on.  If this was opened by using the 'All Transactions' menu item (and
 1197  
          * thus is not associated with any source), this will return null.
 1198  
          * @return
 1199  
          */
 1200  
         public Source getAssociatedSource(){
 1201  0
                 return associatedSource;
 1202  
         }
 1203  
 }