Author: Bavencoff Date: 2013-06-06 16:53:06 +0200 (Thu, 06 Jun 2013) New Revision: 3678 Url: http://chorem.org/projects/lima/repository/revisions/3678 Log: user experience Modified: trunk/lima-swing/src/license/THIRD-PARTY.properties trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTable.java trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTableModel.java trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionView.jaxx trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionViewHandler.java trunk/lima-swing/src/main/resources/i18n/lima-swing_en_GB.properties trunk/lima-swing/src/main/resources/i18n/lima-swing_fr_FR.properties Modified: trunk/lima-swing/src/license/THIRD-PARTY.properties =================================================================== --- trunk/lima-swing/src/license/THIRD-PARTY.properties 2013-06-04 09:56:17 UTC (rev 3677) +++ trunk/lima-swing/src/license/THIRD-PARTY.properties 2013-06-06 14:53:06 UTC (rev 3678) @@ -1,31 +1,33 @@ # Generated by org.codehaus.mojo.license.AddThirdPartyMojo #------------------------------------------------------------------------------- # Already used licenses in project : -# - ANTLR 2 License # - Apache 2 # - Apache 2.0 # - Apache License 2.0 # - Apache Software License - Version 2.0 # - BSD +# - BSD License +# - CDDL # - CDDL 1.1 +# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 # - CPL -# - Common Development and Distribution License (CDDL) v1.0 # - Common Public License Version 1.0 # - Eclipse Public License - Version 1.0 +# - GNU General Lesser Public License (LGPL) version 3.0 # - GNU LESSER GENERAL PUBLIC LICENSE +# - GNU Lesser General Public Licence # - GNU Lesser General Public License # - GNU Library or Lesser General Public License # - GPL2 w/ CPE +# - GPLv2+CE # - General Public License (GPL) # - HSQLDB License, a BSD open source license # - LGPL 2.1 # - Lesser General Public License (LGPL) # - Lesser General Public License (LGPL) v 3.0 -# - License Agreement for Java Transaction API Classes -# - License Agreement for JavaMail(TM) API # - MIT License # - MPL 1.1 -# - Mozilla Public License +# - Mozilla Public License Version 2.0 # - New BSD License # - The Apache Software License, Version 2.0 # - The H2 License, Version 1.0 @@ -37,11 +39,9 @@ # Please fill the missing licenses for dependencies : # # -#Tue Dec 18 00:06:41 CET 2012 -antlr--antlr--2.7.6=ANTLR 2 License +#Tue Jun 04 10:01:31 CEST 2013 +antlr--antlr--2.7.6=BSD License commons-jxpath--commons-jxpath--1.3=The Apache Software License, Version 2.0 commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0 dom4j--dom4j--1.6.1=jdomlicence -javax.mail--mail--1.4.1=License Agreement for JavaMail(TM) API -javax.transaction--jta--1.1=License Agreement for Java Transaction API Classes -org.apache.commons--commons-email--1.2=The Apache Software License, Version 2.0 +javax.transaction--jta--1.1=COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 Modified: trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTable.java =================================================================== --- trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTable.java 2013-06-04 09:56:17 UTC (rev 3677) +++ trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTable.java 2013-06-06 14:53:06 UTC (rev 3678) @@ -25,11 +25,9 @@ package org.chorem.lima.ui.financialtransaction; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.lima.entity.Account; -import org.chorem.lima.entity.Entry; import org.chorem.lima.entity.FinancialTransaction; import org.chorem.lima.ui.celleditor.AccountTableCellEditor; import org.chorem.lima.ui.celleditor.BigDecimalTableCellEditor; @@ -42,17 +40,12 @@ import org.jdesktop.swingx.decorator.HighlightPredicate; import org.jdesktop.swingx.decorator.Highlighter; -import javax.swing.DefaultCellEditor; -import javax.swing.SwingWorker; -import java.awt.Color; -import java.awt.Component; +import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.math.BigDecimal; -import java.text.DecimalFormat; -import java.text.ParsePosition; import java.util.Date; /** @@ -73,13 +66,13 @@ private static final Log log = LogFactory.getLog(FinancialTransactionTable.class); - protected FinancialTransactionViewHandler handler; + protected final FinancialTransactionViewHandler handler; private int x_tab; private int y_tab; - public FinancialTransactionTable(FinancialTransactionViewHandler handler) { + public FinancialTransactionTable(final FinancialTransactionViewHandler handler) { this.handler = handler; addKeyListener(new MyKeyAdapter()); @@ -106,11 +99,54 @@ //get new Account renderer for empty cells setDefaultRenderer(Account.class, new EmptyCellRenderer()); - //highlight financial financial transactions + setShowHorizontalLines(true); + setShowVerticalLines(true); + setGridColor(new Color(210,210,210)); + + + // 1 transaction of 2 HighlightPredicate predicate = new HighlightPredicate() { @Override public boolean isHighlighted(Component renderer, ComponentAdapter adapter) { + int index = handler.view.getFinancialTransactionTableModel().getIndexTransaction(adapter.row); + return index % 2 == 1; + } + }; + Highlighter colorTransaction = + new ColorHighlighter(predicate, new Color(242, 242, 242), null); + addHighlighter(colorTransaction); + + predicate = new HighlightPredicate() { + @Override + public boolean isHighlighted(Component renderer, + ComponentAdapter adapter) { + int index = handler.view.getFinancialTransactionTableModel().getIndexTransaction(adapter.row); + return index % 2 == 0; + } + }; + colorTransaction = + new ColorHighlighter(predicate, getBackground(), null); + addHighlighter(colorTransaction); + + // highlight unbalanced financial transactions + predicate = new HighlightPredicate() { + @Override + public boolean isHighlighted(Component renderer, + ComponentAdapter adapter) { + + BigDecimal balance = handler.view.getFinancialTransactionTableModel().getBalanceTransactionInRow(adapter.row); + return balance.compareTo(BigDecimal.ZERO) != 0; + } + }; + colorTransaction = + new ColorHighlighter(predicate, null, new Color(240, 30, 30)); + addHighlighter(colorTransaction); + /*//highlight financial financial transactions + predicate = new HighlightPredicate() { + @Override + public boolean isHighlighted(Component renderer, + ComponentAdapter adapter) { return adapter.getValueAt(adapter.row, 0) instanceof Date; } }; @@ -145,7 +181,7 @@ //To color in red entry with debit and credit equals to zero colorTransaction = - new ColorHighlighter(predicate, new Color(255, 0, 0), null); + new ColorHighlighter(predicate, null , new Color(255, 0, 0)); addHighlighter(colorTransaction); HighlightPredicate debitCreditZero = new HighlightPredicate() { @@ -167,7 +203,7 @@ Highlighter entryDebitCreditZero = new ColorHighlighter(debitCreditZero, new Color(255, 198, 209), null); - addHighlighter(entryDebitCreditZero); + addHighlighter(entryDebitCreditZero);*/ } @@ -178,6 +214,7 @@ private class MyKeyAdapter extends KeyAdapter { FinancialTransactionTable table = FinancialTransactionTable.this; + FinancialTransactionTableModel tableModel = table.handler.view.getFinancialTransactionTableModel(); @Override public void keyPressed(KeyEvent e) { @@ -196,50 +233,6 @@ } } - // delete selected row with the key : delete or ctrl + clear - // ou de l'entree - if (e.getKeyCode() == KeyEvent.VK_DELETE - || e.getKeyCode() == KeyEvent.VK_CLEAR - && e.getModifiers() == KeyEvent.CTRL_MASK) { - handler.deleteSelectedRow(); - } - - // add entry with the key combination : insert or ctrl + enter - if (e.getKeyCode() == KeyEvent.VK_INSERT - || e.getKeyCode() == KeyEvent.VK_ENTER - && e.getModifiers() == KeyEvent.CTRL_MASK) { - handler.addEntry(); - } - - // copy : ctrl + c - - // add financial transaction with the key combination : ctrl + c - if (e.getKeyCode() == KeyEvent.VK_C - && e.getModifiers() == KeyEvent.CTRL_MASK) { - handler.copyRow(getSelectedRow()); - } - - // paste : ctrl + v - - // add financial transaction with the key combination : ctrl + v - if (e.getKeyCode() == KeyEvent.VK_V - && e.getModifiers() == KeyEvent.CTRL_MASK) { - handler.pasteRow(getSelectedRow()); - } - - // add financial transaction with the key combination : ctrl + tab - if (e.getKeyCode() == KeyEvent.VK_TAB - && e.getModifiers() == KeyEvent.CTRL_MASK) { - handler.addFinancialTransaction(); - } - - // clear row selection with the key: escape - if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - if (!isEditing()) { - clearSelection(); - } - } - /* * Touche tab * Incrémente le curseur de case tant que la case n'est pas editable @@ -255,82 +248,29 @@ int max_y = getRowCount(); x_tab = getSelectedColumn(); y_tab = getSelectedRow(); - Boolean end = true; - if (x_tab < max_x - 1) { - x_tab++; - } - //end of row - else { - x_tab = 0; - } + boolean end = false; - //skip all cell while not editable or if end of table add entry or transaction or end of table - while (!isCellEditable(y_tab, x_tab) && end) { - //if end of row - if (x_tab == max_x - 1) { - Object object = handler.view.getFinancialTransactionTableModel().getElementAt(y_tab); - - //if transaction, add entry - if (object instanceof FinancialTransaction) { - FinancialTransaction financialTransaction = (FinancialTransaction) object; - if (CollectionUtils.isEmpty(financialTransaction.getEntry())) { - handler.addEntry(); - setColumnSelectionInterval(0, 0); - } + FinancialTransaction transaction = tableModel.getTransactionAt(y_tab); + if (x_tab >= max_x - 1) { + if (y_tab + 1 > max_y || transaction != tableModel.getTransactionAt(y_tab + 1)) { + BigDecimal credit = transaction.getAmountCredit(); + BigDecimal debit = transaction.getAmountDebit(); + if (credit.compareTo(debit) != 0) { + table.handler.addEntry(); + x_tab = 1; + y_tab++; + end = true; + } else if (y_tab + 1 > max_y) { + table.handler.addFinancialTransaction(); + x_tab = 0; + y_tab++; + end = true; } - //if entry - else { - //FIXME set value is doing after key pressed - // so update not terminated before get balanced - //Swing Worker stop the UI 500ms - // found best solution ? - final int y_t = y_tab; - final int m_t = max_y; - new SwingWorker<Void, Void>() { - @Override - protected Void doInBackground() throws InterruptedException { - Thread.sleep(500); - return null; - } - - @Override - protected void done() { - Object object = handler.view.getFinancialTransactionTableModel().getElementAt(y_tab - 1); - FinancialTransaction financialTransaction = null; - if (object instanceof Entry) { - financialTransaction = ((Entry) object).getFinancialTransaction(); - } else if (object instanceof FinancialTransaction) { - financialTransaction = (FinancialTransaction) object; - } - BigDecimal amountC = financialTransaction.getAmountCredit(); - BigDecimal amountD = financialTransaction.getAmountDebit(); - if (amountC.equals(amountD)) { - if (y_t == m_t - 1) { - handler.addFinancialTransaction(); - setColumnSelectionInterval(0, 0); - } - } else { - handler.addEntry(); - setColumnSelectionInterval(0, 0); - y_tab++; - // positionne la sélection sur la nouvelle ligne créée - setRowSelectionInterval(y_tab, y_tab); - x_tab = 0; - } - } - }.execute(); - } - end = false; - } else { - if (x_tab < max_x) { - setRowSelectionInterval(y_tab, y_tab); - setColumnSelectionInterval(x_tab, x_tab); - x_tab++; - } } - } + setRowSelectionInterval(y_tab, y_tab); + setColumnSelectionInterval(x_tab, x_tab); } } Modified: trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTableModel.java =================================================================== --- trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTableModel.java 2013-06-04 09:56:17 UTC (rev 3677) +++ trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionTableModel.java 2013-06-06 14:53:06 UTC (rev 3678) @@ -38,6 +38,8 @@ import javax.swing.table.AbstractTableModel; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.List; @@ -60,8 +62,10 @@ /** Service (just to update setValueAt(). */ protected FinancialTransactionService financialTransactionService; - protected List<Object> transactionAndEntries; + protected List<Entry> entries; + protected List<FinancialTransaction> transactions; + /** * To decorate account objects. */ @@ -76,14 +80,21 @@ accountDecorator = decoratorProvider.getDecoratorByType(Account.class); } - public void setTransactionAndEntries(List<Object> transactionAndEntries) { - this.transactionAndEntries = transactionAndEntries; + public void setEntries(List<Entry> entries) { + this.entries = entries; + transactions = new ArrayList<FinancialTransaction>(); + for (Entry entry :entries) { + FinancialTransaction transaction = entry.getFinancialTransaction(); + if (!transactions.contains(transaction)) { + transactions.add(transaction); + } + } fireTableDataChanged(); } @Override public int getColumnCount() { - return 7; + return 6; } @Override @@ -110,9 +121,6 @@ case 5: result = BigDecimal.class; break; - case 6: - result = BigDecimal.class; - break; } return result; } @@ -140,9 +148,6 @@ case 5: result = _("lima.ui.financialtransaction.credit"); break; - case 6: - result = _("lima.ui.financialtransaction.balance"); - break; } return result; } @@ -151,8 +156,8 @@ public int getRowCount() { int result = 0; - if (transactionAndEntries != null) { - result = transactionAndEntries.size(); + if (entries != null) { + result = entries.size(); } return result; @@ -160,69 +165,35 @@ @Override public Object getValueAt(int row, int column) { - Object result = transactionAndEntries.get(row); - - if (result instanceof FinancialTransaction) { - // Transaction "header" line - FinancialTransaction currentRow = (FinancialTransaction) result; - BigDecimal amountDebit = currentRow.getAmountDebit(); - BigDecimal amountCredit = currentRow.getAmountCredit(); - - switch (column) { - case 0: - result = currentRow.getTransactionDate(); - break; - case 1: - result = null; //voucher - break; - case 2: - result = null; // account - break; - case 3: - result = null; // description - break; - case 4: - result = amountDebit; - break; - case 5: - result = amountCredit; - break; - case 6: - result = amountDebit.subtract(amountCredit); - break; - } - } else if (result instanceof Entry) { - // Transaction content line - Entry currentEntry = (Entry) result; - - switch (column) { - case 0: - result = null; // date - break; - case 1: - result = currentEntry.getVoucher(); - break; - case 2: // account - if (currentEntry.getAccount() == null) { - result = null; - } else { - Account acc = currentEntry.getAccount(); - result = accountDecorator.toString(acc); - } - break; - case 3: - result = currentEntry.getDescription(); - break; - case 4: - result = currentEntry.getDebit() ? currentEntry.getAmount() : BigDecimal.ZERO; - break; - case 5: - result = currentEntry.getDebit() ? BigDecimal.ZERO : currentEntry.getAmount(); - break; - case 6: + Entry entry = entries.get(row); + FinancialTransaction transaction = entry.getFinancialTransaction(); + Object result = null; + switch (column) { + case 0: + if (row == 0 || entries.get(row - 1).getFinancialTransaction() != transaction) { + result = transaction.getTransactionDate(); // date + } + break; + case 1: + result = entry.getVoucher(); + break; + case 2: // account + if (entry.getAccount() == null) { result = null; - break; - } + } else { + Account acc = entry.getAccount(); + result = accountDecorator.toString(acc); + } + break; + case 3: + result = entry.getDescription(); + break; + case 4: + result = entry.getDebit() ? entry.getAmount() : BigDecimal.ZERO; + break; + case 5: + result = entry.getDebit() ? BigDecimal.ZERO : entry.getAmount(); + break; } return result; } @@ -233,17 +204,9 @@ */ @Override public boolean isCellEditable(int rowIndex, int columnIndex) { - boolean editableCell = false; - Object currentRow = transactionAndEntries.get(rowIndex); - // cells editable for the financialtransaction row, no cells exclude the date - if (currentRow instanceof FinancialTransaction && (columnIndex == 0)) { - editableCell = true; - } - // cells editable for the entry row, all cells exclude the date - if (currentRow instanceof Entry && !(columnIndex == 0 || columnIndex == 6)) { - editableCell = true; - } - return editableCell; + return columnIndex > 0 + || rowIndex == 0 + || entries.get(rowIndex).getFinancialTransaction() != entries.get(rowIndex - 1).getFinancialTransaction(); } /** @@ -256,7 +219,7 @@ int result = -1; int currentRow = selectedRow; while (currentRow > -1) { - Object o = transactionAndEntries.get(currentRow); + Object o = entries.get(currentRow); if (o instanceof Entry) { // current row is still a entry book @@ -283,137 +246,146 @@ return result; } - public Object getObjectAt(int row) { + public Entry getEntryAt(int row) { if (row == -1) { return null; } - return transactionAndEntries.get(row); + return entries.get(row); } /** to modifiy financialtransaction or entry */ @Override public void setValueAt(Object value, int row, int column) { - Object currentRow = transactionAndEntries.get(row); + Entry entry = entries.get(row); + FinancialTransaction transaction = entry.getFinancialTransaction(); + String description; + boolean updateTransaction = false; + switch (column) { + case 0: + //update + transaction.setTransactionDate((Date) value); + break; + case 1: + String voucher = ((String) value).trim(); - FinancialTransaction currentFinancialTransaction; - if (currentRow instanceof FinancialTransaction) { - currentFinancialTransaction = (FinancialTransaction) currentRow; - switch (column) { - case 0: - //update - currentFinancialTransaction.setTransactionDate((Date) value); - break; - } - - // update transaction - financialTransactionService.updateFinancialTransaction(currentFinancialTransaction); + int firstEntryRow = getFirstEntry(row); + if (row == firstEntryRow) { - } else if (currentRow instanceof Entry) { + // let's update the voucher of all entries of + // the transaction + for (Entry entryNext : transaction.getEntry()) { + entryNext.setVoucher(voucher); + } - /*To stay with one value in debit or credit*/ - if ( !value.equals(BigDecimal.ZERO) && !value.equals(new BigDecimal("0.00"))) { + updateTransaction = true; + } else { - Entry currentEntry = (Entry) currentRow; - currentFinancialTransaction = currentEntry.getFinancialTransaction(); - boolean updateTransaction = false; - switch (column) { - case 1: - String voucher = ((String) value).trim(); + // not on first row, just update this entry voucher + entry.setVoucher(voucher); + } + break; + case 2: + Account account = (Account) value; + entry.setAccount(account); + // let's copy the account description + description = account.getLabel(); + firstEntryRow = getFirstEntry(row); + if (row == firstEntryRow) { + // let's update the description of all entries of + // the transaction - int firstEntryRow = getFirstEntry(row); - if (row == firstEntryRow) { + for (Entry entryNext : transaction.getEntry()) { + entryNext.setDescription(description); + } + updateTransaction = true; + } else { + // not on first row, just update this entry description + entry.setDescription(description); + } + break; + case 3: + description = ((String) value).trim(); + firstEntryRow = getFirstEntry(row); + if (row == firstEntryRow) { - // let's update the voucher of all entries of - // the transaction - for (Entry entry : currentFinancialTransaction.getEntry()) { - entry.setVoucher(voucher); - } + // let's update the description of all entries of + // the transaction - updateTransaction = true; - } else { + for (Entry entryNext : transaction.getEntry()) { + entryNext.setDescription(description); + } + updateTransaction = true; + } else { - // not on first row, just update this entry voucher - currentEntry.setVoucher(voucher); - } - break; - case 2: - Account account = (Account) value; - currentEntry.setAccount(account); - // let's copy the account description - String description1 = account.getLabel(); - firstEntryRow = getFirstEntry(row); - if (row == firstEntryRow) { - // let's update the description of all entries of - // the transaction + // not on first row, just update this entry description + entry.setDescription(description); + } + break; + case 4: - for (Entry entry : currentFinancialTransaction.getEntry()) { - entry.setDescription(description1); - } - updateTransaction = true; - } else { - // not on first row, just update this entry description - currentEntry.setDescription(description1); - } - break; - case 3: - String description = ((String) value).trim(); - firstEntryRow = getFirstEntry(row); - if (row == firstEntryRow) { + entry.setAmount((BigDecimal) value); + entry.setDebit(true); + break; + case 5: + entry.setAmount((BigDecimal) value); + entry.setDebit(false); + break; + } - // let's update the description of all entries of - // the transaction + // some modification must update all other + // first row modification update following rows + if (updateTransaction) { + // FIXME echatellier 20120413 make a single service call + for (Entry entryTmp : transaction.getEntry()) { + financialTransactionService.updateEntry(entryTmp); + } + } else { + financialTransactionService.updateEntry(entry); + } + /* + // FIXME echatellier 20120413 une modification des dates fait que l'ordre + // devient faux + int trIndex = indexOf(transaction); + int endIndex = trIndex; + if (transaction.getEntry() != null) { + endIndex += transaction.getEntry().size(); + } + fireTableRowsUpdated(trIndex, endIndex); */ + fireTableDataChanged(); - for (Entry entry : currentFinancialTransaction.getEntry()) { - entry.setDescription(description); - } - updateTransaction = true; - } else { + } - // not on first row, just update this entry description - currentEntry.setDescription(description); - } - break; - case 4: - currentEntry.setAmount((BigDecimal) value); - currentEntry.setDebit(true); - break; - case 5: - currentEntry.setAmount((BigDecimal) value); - currentEntry.setDebit(false); - break; - } + public int indexOf(Entry entry) { + return entries.indexOf(entry); + } - // some modification must update all other - // first row modification update following rows - if (updateTransaction) { - // FIXME echatellier 20120413 make a single service call - for (Entry entry : currentFinancialTransaction.getEntry()) { - financialTransactionService.updateEntry(entry); - } - } else { - financialTransactionService.updateEntry(currentEntry); - } - // FIXME echatellier 20120413 une modification des dates fait que l'ordre - // devient faux - int trIndex = indexOf(currentFinancialTransaction); - int endIndex = trIndex; - if (currentFinancialTransaction.getEntry() != null) { - endIndex += currentFinancialTransaction.getEntry().size(); - } - fireTableRowsUpdated(trIndex, endIndex); + public int indexOf(FinancialTransaction transaction) { + int index = 0; + Collection<Entry> entriesTransaction = transaction.getEntry(); + for (Entry entry : entries) { + if (!entriesTransaction.contains(entry)) { + index++; + } else { + break; } } + return index; } - public Object getElementAt(int row) { - Object result = transactionAndEntries.get(row); + public int indexOfEntryInTransaction(Entry entry) { + FinancialTransaction transaction = entry.getFinancialTransaction(); + int result = -1; + for (Entry entryTmp : entries) { + if (entryTmp.getFinancialTransaction() == transaction) { + result ++; + } + if (entry == entryTmp) { + break; + } + } return result; } - - public int indexOf(Object o) { - return transactionAndEntries.indexOf(o); - } /** * Delete row. @@ -421,29 +393,76 @@ * @param row row to delete */ public void deleteRow(int row) { - transactionAndEntries.remove(row); + Entry entry = entries.remove(row); + FinancialTransaction transaction = entry.getFinancialTransaction(); + if (transaction.sizeEntry() == 0) { + transactions.remove(transaction); + } fireTableRowsDeleted(row, row); } /** * Insert new row. * - * @param object object to insert + * @param entry entry to insert * @param newRow position */ - public void addRow(Object object, int newRow) { - transactionAndEntries.add(newRow, object); + public void addRow(Entry entry, int newRow) { + entries.add(newRow, entry); fireTableRowsInserted(newRow, newRow); } /** * Insert new row. * - * @param object object to insert + * @param entry entry to insert */ - public void addRow(Object object) { - transactionAndEntries.add(object); - fireTableRowsInserted(transactionAndEntries.size() - 1, transactionAndEntries.size() - 1); + public void addRow(Entry entry) { + entries.add(entry); + fireTableRowsInserted(entries.size() - 1, entries.size() - 1); } + + public FinancialTransaction getTransactionAt(int row) { + Entry entry = entries.get(row); + return entry.getFinancialTransaction(); + } + + public int getIndexTransaction(int row) { + FinancialTransaction transaction = getTransactionAt(row); + return transactions.indexOf(transaction); + } + + public BigDecimal getBalanceTransactionInRow(int row) { + FinancialTransaction transaction = getTransactionAt(row); + BigDecimal debit = transaction.getAmountDebit(); + BigDecimal credit = transaction.getAmountCredit(); + return debit.subtract(credit); + } + + public int size() { + int result = 0; + if (entries != null) { + result = entries.size(); + } + return result; + } + + public void addTransaction(FinancialTransaction transaction) { + int indexFirstEntry = entries.size(); + if (!transactions.contains(transaction)) { + transactions.add(transaction); + } + int indexLastEntry = entries.size(); + Collection<Entry> entriesTransaction = transaction.getEntry(); + for (Entry entry : entriesTransaction) { + if (!entries.contains(entry)) { + entries.add(entry); + indexLastEntry++; + } + } + fireTableRowsInserted(indexFirstEntry, indexLastEntry - 1); + } + + } Modified: trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionView.jaxx =================================================================== --- trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionView.jaxx 2013-06-04 09:56:17 UTC (rev 3677) +++ trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionView.jaxx 2013-06-06 14:53:06 UTC (rev 3678) @@ -31,6 +31,8 @@ org.chorem.lima.entity.FinancialPeriod org.chorem.lima.entity.EntryBook org.chorem.lima.ui.common.EntryBookListRenderer + java.awt.event.KeyEvent + javax.swing.KeyStroke </import> <FinancialTransactionViewHandler id="handler" constructorParams="this"/> @@ -43,6 +45,9 @@ <Boolean id="selectedRow" javaBean="false"/> + <Boolean id="transactionInClipBoard" javaBean="false"/> + <Boolean id="entryInClipBoard" javaBean="false"/> + <script> <![CDATA[ void $afterCompleteSetup() { @@ -51,7 +56,49 @@ ]]> </script> - <row weightx="1" weighty="0" anchor="center"> + <row > + <cell fill="horizontal" columns="8"> + <JMenuBar > + <JMenu text="lima.common.transaction" mnemonic="{'T'}"> + <JMenuItem text="lima.common.new" + onActionPerformed="handler.addFinancialTransaction()" + accelerator="{KeyStroke.getKeyStroke('N', KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK)}" /> + <JMenuItem text="lima.common.remove" + enabled="{isSelectedRow()}" + onActionPerformed="handler.deleteSelectedTransaction()" + accelerator="{KeyStroke.getKeyStroke(KeyEvent.VK_DELETE , KeyEvent.SHIFT_DOWN_MASK)}" /> + <JMenuItem text="lima.common.copy" + enabled="{isSelectedRow()}" + onActionPerformed="handler.copyTransaction(financialTransactionTable.getSelectedRow())" + accelerator="{KeyStroke.getKeyStroke('C', KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK)}" /> + <JMenuItem text="lima.common.paste" + enabled="{isTransactionInClipBoard()}" + onActionPerformed="handler.pasteTransaction(financialTransactionTable.getSelectedRow())" + accelerator="{KeyStroke.getKeyStroke('V', KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK)}" /> + </JMenu> + <JMenu text="lima.common.entry" mnemonic="{'E'}"> + <JMenuItem text="lima.common.new" + enabled="{isSelectedRow()}" + onActionPerformed="handler.addEntry()" + accelerator="{KeyStroke.getKeyStroke('N', KeyEvent.CTRL_DOWN_MASK)}" /> + <JMenuItem text="lima.common.remove" + enabled="{isSelectedRow()}" + onActionPerformed="handler.deleteSelectedEntry()" + accelerator="{KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)}" /> + <JMenuItem text="lima.common.copy" + enabled="{isSelectedRow()}" + onActionPerformed="handler.copyEntry(financialTransactionTable.getSelectedRow())" + accelerator="{KeyStroke.getKeyStroke('C', KeyEvent.CTRL_DOWN_MASK)}" /> + <JMenuItem text="lima.common.paste" + enabled="{isEntryInClipBoard()}" + onActionPerformed="handler.pasteEntry(financialTransactionTable.getSelectedRow())" + accelerator="{KeyStroke.getKeyStroke('V', KeyEvent.CTRL_DOWN_MASK)}" /> + </JMenu> + </JMenuBar> + </cell> + </row> + + <row > <cell anchor="east"> <JLabel text="lima.ui.financialtransaction.fiscalyear" labelFor='{fiscalPeriodComboBox}'/> </cell> @@ -88,26 +135,7 @@ </cell> </row> <row> - <cell weightx="1" columns="8"> - <JToolBar floatable="false"> - <JPanel layout='{new GridLayout(1,0)}'> - <JButton text="lima.common.copy" enabled="{isSelectedRow()}" - onActionPerformed="handler.copyRow(financialTransactionTable.getSelectedRow())"/> - <JButton text="lima.common.paste" enabled="{isSelectedRow()}" - onActionPerformed="handler.pasteRow(financialTransactionTable.getSelectedRow())"/> - <JButton text="lima.entries.addTransaction" - onActionPerformed="handler.addFinancialTransaction()"/> - <JButton text="lima.entries.addEntry" enabled="{isSelectedRow()}" - onActionPerformed="handler.addEntry()"/> - <JButton text="lima.common.remove" enabled="{isSelectedRow()}" - onActionPerformed="handler.deleteSelectedRow()"/> - - </JPanel> - </JToolBar> - </cell> - </row> - <row> - <cell fill="both" weightx="1" weighty="1" rows="3" columns="8"> + <cell fill="both" weightx="1" weighty="1" columns="8"> <JScrollPane> <FinancialTransactionTableModel id="financialTransactionTableModel"/> <FinancialTransactionTable Modified: trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionViewHandler.java =================================================================== --- trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionViewHandler.java 2013-06-04 09:56:17 UTC (rev 3677) +++ trunk/lima-swing/src/main/java/org/chorem/lima/ui/financialtransaction/FinancialTransactionViewHandler.java 2013-06-06 14:53:06 UTC (rev 3678) @@ -177,7 +177,7 @@ return; } - List<Object> transAndEntries = new ArrayList<Object>(); + List<Entry> transAndEntries = new ArrayList<Entry>(); List<FinancialTransaction> transactions; if (entryBook == null) { transactions = financialTransactionService.getAllFinancialTransactions(financialPeriod); @@ -187,61 +187,118 @@ // move it to unique collection for table rendering for (FinancialTransaction transaction : transactions) { - transAndEntries.add(transaction); + //transAndEntries.add(transaction); List<Entry> entries = (List<Entry>) transaction.getEntry(); Collections.sort(entries, new EntryComparator()); transAndEntries.addAll(entries); } - view.getFinancialTransactionTableModel().setTransactionAndEntries(transAndEntries); + view.getFinancialTransactionTableModel().setEntries(transAndEntries); } /** - * Copy selected row + * Copy selected Transaction * * @param indexSelectedRow */ - public void copyRow(int indexSelectedRow){ - clipBoard = view.getFinancialTransactionTableModel().getElementAt(indexSelectedRow); + public void copyTransaction(int indexSelectedRow){ + clipBoard = view.getFinancialTransactionTableModel().getTransactionAt(indexSelectedRow); + view.setTransactionInClipBoard(true); + view.setEntryInClipBoard(false); } - + /** - * Paste row. + * Copy selected Entry + * + * @param indexSelectedRow + */ + public void copyEntry(int indexSelectedRow){ + clipBoard = view.getFinancialTransactionTableModel().getEntryAt(indexSelectedRow); + view.setTransactionInClipBoard(false); + view.setEntryInClipBoard(true); + } + + /** + * Paste Transaction. * * @param indexSelectedRow selected row to paste */ - public void pasteRow(int indexSelectedRow){ + public void pasteTransaction(int indexSelectedRow){ FinancialTransactionTable table = view.getFinancialTransactionTable(); //select the new line ListSelectionModel selectionModel = table.getSelectionModel(); - if (clipBoard instanceof Entry) { - int index = addEntry((Entry) clipBoard, indexSelectedRow); - - selectionModel.setSelectionInterval(indexSelectedRow + 1, indexSelectedRow + 1); - //focus on second column - table.changeSelection(index, 1, false, false); - table.requestFocusInWindow(); - }else{ + if (clipBoard != null && clipBoard instanceof FinancialTransaction) { FinancialTransactionTableModel tableModel = view.getFinancialTransactionTableModel(); - FinancialTransaction financialTransactionTemp = (FinancialTransaction) clipBoard; - + FinancialTransaction transactionTemp = (FinancialTransaction) clipBoard; + //need to know number of entries of copied transaction //to select the new transaction - int nbentries = financialTransactionTemp.getEntry().size()+1; - + Collection<Entry> entriesTmp = transactionTemp.getEntry(); + int nbentries = entriesTmp.size()+1; + //new transaction with only entrybook and date - FinancialTransaction financialTransaction = new FinancialTransactionImpl(); - financialTransaction.setEntryBook(financialTransactionTemp.getEntryBook()); - financialTransaction.setTransactionDate(financialTransactionTemp.getTransactionDate()); - - financialTransactionService.createFinancialTransaction(financialTransaction); - tableModel.addRow(financialTransaction); - selectionModel.setSelectionInterval(indexSelectedRow + nbentries, indexSelectedRow + nbentries); + FinancialTransaction transaction = new FinancialTransactionImpl(); + transaction.setEntryBook(transactionTemp.getEntryBook()); + transaction.setTransactionDate(transactionTemp.getTransactionDate()); + transaction = financialTransactionService.createFinancialTransaction(transaction); + + for (Entry entryTmp : entriesTmp) { + Entry entry = new EntryImpl(); + entry.setFinancialTransaction(transaction); + entry.setVoucher(entryTmp.getVoucher()); + entry.setAccount(entryTmp.getAccount()); + entry.setDescription(entryTmp.getDescription()); + entry.setAmount(entryTmp.getAmount()); + entry.setDebit(entryTmp.getDebit()); + entry = financialTransactionService.createEntry(entry); + transaction.addEntry(entry); + } + + tableModel.addTransaction(transaction); + int index = tableModel.indexOf(transaction); + selectionModel.setSelectionInterval(index, index); } } - + /** + * Paste row. + * + * @param indexSelectedRow selected row to paste + */ + public void pasteEntry(int indexSelectedRow){ + FinancialTransactionTable table = view.getFinancialTransactionTable(); + FinancialTransactionTableModel tableModel = view.getFinancialTransactionTableModel(); + //select the new line + ListSelectionModel selectionModel = table.getSelectionModel(); + + if (clipBoard != null && clipBoard instanceof Entry) { + Entry entryTmp = (Entry) clipBoard; + FinancialTransaction transaction = tableModel.getTransactionAt(indexSelectedRow); + Entry entry = new EntryImpl(); + entry.setFinancialTransaction(transaction); + entry.setVoucher(entryTmp.getVoucher()); + entry.setAccount(entryTmp.getAccount()); + entry.setDescription(entryTmp.getDescription()); + entry.setAmount(entryTmp.getAmount()); + entry.setDebit(entryTmp.getDebit()); + + entry = financialTransactionService.createEntry(entry); + + transaction.addEntry(entry); + + + int index = tableModel.indexOf(transaction) + transaction.sizeEntry() - 1; + tableModel.addRow(entry, index); + + selectionModel.setSelectionInterval(index, index); + //focus on second column + table.changeSelection(index, 1, false, false); + table.requestFocusInWindow(); + } + } + + /** * @param entry * @param row * @return int: indexOf new Entry @@ -249,22 +306,8 @@ protected int addEntry(Entry entry, int row) { FinancialTransactionTableModel tableModel = view.getFinancialTransactionTableModel(); FinancialTransactionTable table = view.getFinancialTransactionTable(); - FinancialTransaction currentTransaction = null; + FinancialTransaction currentTransaction = tableModel.getTransactionAt(row); int financialTransactionRow = 0; - Object currentRow = tableModel.getElementAt(row); - //check if current row is a transaction or an entry - if (currentRow instanceof FinancialTransaction) { - currentTransaction = (FinancialTransaction) currentRow; - //update the financial transaction in entire - financialTransactionRow = tableModel.indexOf(currentRow); - } else if (currentRow instanceof Entry) { - Entry currentEntry = (Entry) currentRow; - //get back the parent transaction of the entry - currentTransaction = currentEntry.getFinancialTransaction(); - //update the financial transaction in entire - financialTransactionRow = tableModel.indexOf(((Entry) currentRow). - getFinancialTransaction()); - } //create it entry.setFinancialTransaction(currentTransaction); @@ -272,7 +315,7 @@ currentTransaction.addEntry(entry); // on met a jour l'ui - int newRow = financialTransactionRow + currentTransaction.getEntry().size() /*+ 1*/; + int newRow = row + 1; tableModel.addRow(newEntry, newRow); table.addRowSelectionInterval(newRow, newRow); return newRow; @@ -281,26 +324,11 @@ /** * Add new transaction. */ - public void addFinancialTransaction() { - FinancialTransactionTable table = view.getFinancialTransactionTable(); - ListSelectionModel selectionModel = table.getSelectionModel(); - addFinancialTransactionAfterService(); - //select the new line - int numberRow = table.getRowCount()-1; - selectionModel.setSelectionInterval(numberRow, numberRow); - //focus on first column - table.changeSelection(numberRow, 0, false, false); - table.scrollCellToVisible(numberRow, 0); - } - - /** - * Add new transaction after calling service. - */ - public void addFinancialTransactionAfterService() { - + public void addFinancialTransaction() { FinancialPeriod financialPeriod = (FinancialPeriod)view.getFinancialPeriodComboBox().getSelectedItem(); EntryBook entryBook = (EntryBook)view.getEntryBookComboBox().getSelectedItem(); - FinancialTransactionTableModel tableModel = view.getFinancialTransactionTableModel(); + FinancialTransactionTable table = view.getFinancialTransactionTable(); + FinancialTransactionTableModel tableModel = view.getFinancialTransactionTableModel(); FinancialTransaction financialTransaction = new FinancialTransactionImpl(); // can be defined later by user @@ -333,8 +361,25 @@ // create it FinancialTransaction fTransaction = financialTransactionService.createFinancialTransaction(financialTransaction); - //on recharge la liste - tableModel.addRow(fTransaction); + // create 2 first entry of this transaction + Entry entry = new EntryImpl(); + entry.setFinancialTransaction(fTransaction); + entry = financialTransactionService.createEntry(entry); + fTransaction.addEntry(entry); + // add it in ui + int addIndex = tableModel.size(); + tableModel.addRow(entry, addIndex); + + entry = new EntryImpl(); + entry.setFinancialTransaction(fTransaction); + entry = financialTransactionService.createEntry(entry); + fTransaction.addEntry(entry); + tableModel.addRow(entry, addIndex + 1); + + //select the new line + ListSelectionModel selectionModel = table.getSelectionModel(); + selectionModel.setSelectionInterval(addIndex, addIndex); + table.changeSelection(addIndex, 1, false, false); } /** @@ -353,12 +398,12 @@ //First case, where line selected is an entry : take its transaction //to select the last entry of the transaction - Object entryOrTransaction = tableModel.getObjectAt(indexSelectedRow); - if (entryOrTransaction instanceof Entry) { - lastEntryOfTransaction = financialTransactionService.getLastEntry(((Entry) entryOrTransaction).getFinancialTransaction()); - } else { //Second case, we have an instance of transaction, so select the last entry of it + Entry entryOrTransaction = tableModel.getEntryAt(indexSelectedRow); + //if (entryOrTransaction instanceof Entry) { + lastEntryOfTransaction = financialTransactionService.getLastEntry(entryOrTransaction.getFinancialTransaction()); + /*} else { //Second case, we have an instance of transaction, so select the last entry of it lastEntryOfTransaction = financialTransactionService.getLastEntry((FinancialTransaction)entryOrTransaction); - } + } */ if (log.isDebugEnabled()) { log.debug("Selected row : " + indexSelectedRow); @@ -405,7 +450,7 @@ // check if current row is a transaction or an entry FinancialTransaction currentTransaction = null; - Object currentRow = tableModel.getElementAt(indexSelectedRow); + Object currentRow = tableModel.getEntryAt(indexSelectedRow); if (currentRow instanceof FinancialTransaction) { currentTransaction = (FinancialTransaction) currentRow; } else if (currentRow instanceof Entry) { @@ -420,8 +465,7 @@ currentTransaction.addEntry(newEntry); // add it in ui - int addIndex = tableModel.indexOf(currentTransaction) + - currentTransaction.getEntry().size(); + int addIndex = tableModel.indexOf(lastEntryOfTransaction) + 1; tableModel.addRow(newEntry, addIndex); //select the new line @@ -437,64 +481,58 @@ } } - /** - * Delete selected row in table (could be transaction or entry). - * <p/> - * Called by table. - */ - public void deleteSelectedRow() { - + public void deleteSelectedTransaction() { FinancialTransactionTable table = view.getFinancialTransactionTable(); FinancialTransactionTableModel tableModel = view.getFinancialTransactionTableModel(); int indexSelectedRow = table.getSelectedRow(); - if (indexSelectedRow != -1) { + if (indexSelectedRow >= 0) { + FinancialTransaction transaction = tableModel.getTransactionAt(indexSelectedRow); + int response = JOptionPane.showConfirmDialog( + view, _("lima.ui.financialtransaction.messageremovetransaction"), + _("lima.ui.financialtransaction.titleremovetransaction"), JOptionPane.YES_NO_OPTION); - Object selectedValue = tableModel.getElementAt(indexSelectedRow); + if (response == JOptionPane.YES_OPTION) { + //must delete the entries of the deleted transaction + Collection<Entry> entries = transaction.getEntry(); + if (entries != null){ + for (Entry entry : entries){ + tableModel.deleteRow(tableModel.indexOf(entry)); + } + } - int response; - if (selectedValue instanceof FinancialTransaction) { - response = JOptionPane.showConfirmDialog( - view, _("lima.ui.financialtransaction.messageremovetransaction"), - _("lima.ui.financialtransaction.titleremovetransaction"), JOptionPane.YES_NO_OPTION); - } else { - response = JOptionPane.showConfirmDialog( - view, _("lima.ui.financialtransaction.messageremoveentry"), - _("lima.ui.financialtransaction.titleremoveentry"), JOptionPane.YES_NO_OPTION); + financialTransactionService.removeFinancialTransaction(transaction); + } + } + } + + public void deleteSelectedEntry() { + FinancialTransactionTable table = view.getFinancialTransactionTable(); + FinancialTransactionTableModel tableModel = view.getFinancialTransactionTableModel(); + + int indexSelectedRow = table.getSelectedRow(); + if (indexSelectedRow >= 0) { + Entry entry = tableModel.getEntryAt(indexSelectedRow); + int response = JOptionPane.showConfirmDialog( + view, _("lima.ui.financialtransaction.messageremoveentry"), + _("lima.ui.financialtransaction.titleremoveentry"), JOptionPane.YES_NO_OPTION); + if (response == JOptionPane.YES_OPTION) { - if (selectedValue instanceof FinancialTransaction) { - FinancialTransaction currentTransaction = (FinancialTransaction) selectedValue; - - //must delete the entries of the deleted transaction - Collection<Entry> entries = currentTransaction.getEntry(); - if (entries != null){ - for (Entry entry : entries){ - tableModel.deleteRow(tableModel.indexOf(entry)); - } - } - - financialTransactionService.removeFinancialTransaction(currentTransaction); - - } else if (selectedValue instanceof Entry) { - Entry currentEntry = (Entry) selectedValue; - financialTransactionService.removeEntry(currentEntry); - currentEntry.getFinancialTransaction().removeEntry(currentEntry); + tableModel.deleteRow(indexSelectedRow); + financialTransactionService.removeEntry(entry); + FinancialTransaction transaction = entry.getFinancialTransaction(); + transaction.removeEntry(entry); + if (transaction.sizeEntry() == 0) { + financialTransactionService.removeFinancialTransaction(transaction); } - tableModel.deleteRow(indexSelectedRow); - - //select the upper line - ListSelectionModel selectionModel = table.getSelectionModel(); - selectionModel.setSelectionInterval(indexSelectedRow - 1, indexSelectedRow - 1); } - } else { - if (log.isWarnEnabled()) { - log.warn("Call delete selected row without selection"); - } } } + + /** * Select previous value in combo box. * Modified: trunk/lima-swing/src/main/resources/i18n/lima-swing_en_GB.properties =================================================================== --- trunk/lima-swing/src/main/resources/i18n/lima-swing_en_GB.properties 2013-06-04 09:56:17 UTC (rev 3677) +++ trunk/lima-swing/src/main/resources/i18n/lima-swing_en_GB.properties 2013-06-06 14:53:06 UTC (rev 3678) @@ -53,6 +53,7 @@ lima.common.confirmation=Confirmation lima.common.copy=Copy lima.common.enddate=End +lima.common.entry=Entry lima.common.entrybook=EntryBook lima.common.entrybooks=EntryBooks lima.common.error=Error @@ -61,6 +62,7 @@ lima.common.info=Information lima.common.label=Label lima.common.movmentedfilter=Accounts filtered +lima.common.new=New lima.common.ok=OK lima.common.open=Open lima.common.paste=Paste @@ -70,6 +72,7 @@ lima.common.solde=Solde lima.common.soldecredit=Credit solde lima.common.soldedebit=Debit solde +lima.common.transaction=Transaction lima.common.update=Modify lima.config.category.directories=Directories lima.config.category.directories.description=Directories used by LIMA Modified: trunk/lima-swing/src/main/resources/i18n/lima-swing_fr_FR.properties =================================================================== --- trunk/lima-swing/src/main/resources/i18n/lima-swing_fr_FR.properties 2013-06-04 09:56:17 UTC (rev 3677) +++ trunk/lima-swing/src/main/resources/i18n/lima-swing_fr_FR.properties 2013-06-06 14:53:06 UTC (rev 3678) @@ -53,6 +53,7 @@ lima.common.confirmation=Confirmation lima.common.copy=Copier lima.common.enddate=Fin +lima.common.entry=Entrée lima.common.entrybook=Journal lima.common.entrybooks=Journaux lima.common.error=Erreur @@ -61,6 +62,7 @@ lima.common.info=Information lima.common.label=Libellé lima.common.movmentedfilter=Comptes mouvementés +lima.common.new=Nouveau lima.common.ok=OK lima.common.open=Ouvert lima.common.paste=Coller @@ -70,6 +72,7 @@ lima.common.solde=Solde lima.common.soldecredit=Solde Créditeur lima.common.soldedebit=Solde Débiteur +lima.common.transaction=Transaction lima.common.update=Modifier lima.config.category.directories=Répertoires lima.config.category.directories.description=Répertoires utilisés par Lima