View Javadoc
1   /*
2    * MoneyWise: Finance Application
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.moneywise.lethe.ui.panel;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
21  import io.github.tonywasher.joceanus.oceanus.date.OceanusDateConfig;
22  import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
23  import io.github.tonywasher.joceanus.oceanus.decimal.OceanusDecimal;
24  import io.github.tonywasher.joceanus.oceanus.event.OceanusEvent;
25  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
26  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
27  import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
28  import io.github.tonywasher.joceanus.oceanus.profile.OceanusProfile;
29  import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
30  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
31  import io.github.tonywasher.joceanus.metis.ui.MetisAction;
32  import io.github.tonywasher.joceanus.metis.ui.MetisErrorPanel;
33  import io.github.tonywasher.joceanus.metis.ui.MetisIcon;
34  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerEntry;
35  import io.github.tonywasher.joceanus.metis.viewer.MetisViewerManager;
36  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetDirection;
37  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
38  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicResource;
39  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransAsset;
40  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransCategory;
41  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransTag;
42  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction;
43  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction.MoneyWiseTransactionList;
44  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransInfoClass;
45  import io.github.tonywasher.joceanus.moneywise.data.validate.MoneyWiseValidateTransaction;
46  import io.github.tonywasher.joceanus.moneywise.lethe.ui.controls.MoneyWiseAnalysisSelect;
47  import io.github.tonywasher.joceanus.moneywise.lethe.ui.controls.MoneyWiseAnalysisSelect.MoneyWiseStatementSelect;
48  import io.github.tonywasher.joceanus.moneywise.lethe.ui.dialog.MoneyWiseTransactionDialog;
49  import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter;
50  import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisView;
51  import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseAnalysisColumnSet;
52  import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseIcon;
53  import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseUIResource;
54  import io.github.tonywasher.joceanus.moneywise.ui.base.MoneyWiseBaseTable;
55  import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseView;
56  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
57  import io.github.tonywasher.joceanus.prometheus.ui.PrometheusActionButtons;
58  import io.github.tonywasher.joceanus.prometheus.views.PrometheusDataEvent;
59  import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
60  import io.github.tonywasher.joceanus.prometheus.views.PrometheusUIEvent;
61  import io.github.tonywasher.joceanus.prometheus.views.PrometheusViewerEntryId;
62  import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
63  import io.github.tonywasher.joceanus.tethys.api.button.TethysUIButton;
64  import io.github.tonywasher.joceanus.tethys.api.control.TethysUIControl.TethysUIIconMapSet;
65  import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
66  import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
67  import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBorderPaneManager;
68  import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIPaneFactory;
69  import io.github.tonywasher.joceanus.tethys.api.table.TethysUITableManager;
70  
71  import java.util.Map;
72  
73  /**
74   * MoneyWise Transaction Table.
75   */
76  public class MoneyWiseTransactionTable
77          extends MoneyWiseBaseTable<MoneyWiseTransaction> {
78      /**
79       * The analysis data entry.
80       */
81      private final MetisViewerEntry theViewerAnalysis;
82  
83      /**
84       * The filter data entry.
85       */
86      private final MetisViewerEntry theViewerFilter;
87  
88      /**
89       * The transaction dialog.
90       */
91      private final MoneyWiseTransactionDialog theActiveTran;
92  
93      /**
94       * The new button.
95       */
96      private final TethysUIButton theNewButton;
97  
98      /**
99       * Analysis View.
100      */
101     private final MoneyWiseAnalysisView theAnalysisView;
102 
103     /**
104      * Analysis Selection panel.
105      */
106     private final MoneyWiseAnalysisSelect theSelect;
107 
108     /**
109      * The action buttons.
110      */
111     private final PrometheusActionButtons theActionButtons;
112 
113     /**
114      * The UpdateSet.
115      */
116     private final PrometheusEditSet theEditSet;
117 
118     /**
119      * The error panel.
120      */
121     private final MetisErrorPanel theError;
122 
123     /**
124      * The date range.
125      */
126     private OceanusDateRange theRange;
127 
128     /**
129      * The analysis filter.
130      */
131     private MoneyWiseAnalysisFilter<?, ?> theFilter;
132 
133     /**
134      * The edit list.
135      */
136     private MoneyWiseTransactionList theTransactions;
137 
138     /**
139      * ColumnSet.
140      */
141     private MoneyWiseAnalysisColumnSet theColumnSet;
142 
143     /**
144      * Constructor.
145      *
146      * @param pView     the view
147      * @param pEditSet  the editSet
148      * @param pError    the error panel
149      * @param pFilter   the filter viewer entry
150      * @param pAnalysis the analysis viewer entry
151      */
152     MoneyWiseTransactionTable(final MoneyWiseView pView,
153                               final PrometheusEditSet pEditSet,
154                               final MetisErrorPanel pError,
155                               final MetisViewerEntry pFilter,
156                               final MetisViewerEntry pAnalysis) {
157         /* Store parameters */
158         super(pView, pEditSet, pError, MoneyWiseBasicDataType.TRANSACTION);
159 
160         /* store parameters */
161         theEditSet = pEditSet;
162         theError = pError;
163 
164         /* Store viewer entries */
165         theViewerAnalysis = pAnalysis;
166         theViewerFilter = pFilter;
167 
168         /* Access gui factory */
169         final TethysUIFactory<?> myGuiFactory = pView.getGuiFactory();
170         final TethysUITableManager<MetisDataFieldId, MoneyWiseTransaction> myTable = getTable();
171 
172         /* Create new button */
173         theNewButton = myGuiFactory.buttonFactory().newButton();
174         MetisIcon.configureNewIconButton(theNewButton);
175 
176         /* Create the Analysis View */
177         theAnalysisView = new MoneyWiseAnalysisView(pView, getEditSet());
178 
179         /* Create the Analysis Selection */
180         theSelect = new MoneyWiseAnalysisSelect(myGuiFactory, pView, theAnalysisView, theNewButton);
181 
182         /* Create the action buttons */
183         theActionButtons = new PrometheusActionButtons(myGuiFactory, getEditSet());
184 
185         /* Create a transaction panel */
186         theActiveTran = new MoneyWiseTransactionDialog(myGuiFactory, pEditSet, theSelect, this);
187         declareItemPanel(theActiveTran);
188 
189         /* Set table configuration */
190         myTable.setDisabled(MoneyWiseTransaction::isDisabled)
191                 .setComparator(MoneyWiseTransaction::compareTo);
192 
193         /* Create the date column */
194         myTable.declareDateColumn(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE)
195                 .setDateConfigurator((r, c) -> handleDateEvent(c))
196                 .setCellValueFactory(this::getFilteredDate)
197                 .setEditable(true)
198                 .setCellEditable(r -> !r.isHeader() && !r.isReconciled())
199                 .setColumnWidth(WIDTH_DATE)
200                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setDate, r, v));
201 
202         /* Create the account column */
203         myTable.declareScrollColumn(MoneyWiseBasicResource.TRANSACTION_ACCOUNT, MoneyWiseTransAsset.class)
204                 .setMenuConfigurator(this::buildAccountMenu)
205                 .setCellValueFactory(MoneyWiseTransaction::getAccount)
206                 .setEditable(true)
207                 .setCellEditable(r -> !r.isHeader() && !r.isReconciled())
208                 .setColumnWidth(WIDTH_NAME)
209                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setAccount, r, v));
210 
211         /* Create the category column */
212         myTable.declareScrollColumn(MoneyWiseBasicDataType.TRANSCATEGORY, MoneyWiseTransCategory.class)
213                 .setMenuConfigurator(this::buildCategoryMenu)
214                 .setCellValueFactory(MoneyWiseTransaction::getCategory)
215                 .setEditable(true)
216                 .setCellEditable(r -> !r.isHeader() && !r.isReconciled())
217                 .setColumnWidth(WIDTH_NAME)
218                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setCategory, r, v));
219 
220         /* Create the direction column */
221         final Map<Boolean, TethysUIIconMapSet<MoneyWiseAssetDirection>> myDirMapSets = MoneyWiseIcon.configureDirectionIconButton(myGuiFactory);
222         myTable.declareIconColumn(MoneyWiseBasicResource.TRANSACTION_DIRECTION, MoneyWiseAssetDirection.class)
223                 .setIconMapSet(r -> myDirMapSets.get(determineDirectionState(r)))
224                 .setCellValueFactory(MoneyWiseTransactionTable::getFilteredDirection)
225                 .setEditable(true)
226                 .setCellEditable(r -> !r.isHeader() && !r.isReconciled() && r.canSwitchDirection())
227                 .setColumnWidth(WIDTH_ICON)
228                 .setOnCommit((r, v) -> updateField(this::setDirection, r, v));
229 
230         /* Create the partner column */
231         myTable.declareScrollColumn(MoneyWiseBasicResource.TRANSACTION_PARTNER, MoneyWiseTransAsset.class)
232                 .setMenuConfigurator(this::buildPartnerMenu)
233                 .setCellValueFactory(MoneyWiseTransaction::getPartner)
234                 .setEditable(true)
235                 .setCellEditable(r -> !r.isHeader() && !r.isReconciled())
236                 .setColumnWidth(WIDTH_NAME)
237                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setPartner, r, v));
238 
239         /* Create the reconciled column */
240         final Map<Boolean, TethysUIIconMapSet<Boolean>> myRecMapSets = MoneyWiseIcon.configureReconciledIconButton(myGuiFactory);
241         myTable.declareIconColumn(MoneyWiseBasicResource.TRANSACTION_RECONCILED, Boolean.class)
242                 .setIconMapSet(r -> myRecMapSets.get(determineReconciledState(r)))
243                 .setCellValueFactory(MoneyWiseTransaction::isReconciled)
244                 .setEditable(true)
245                 .setCellEditable(r -> !r.isHeader() && !r.isLocked())
246                 .setColumnWidth(WIDTH_ICON)
247                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setReconciled, r, v));
248 
249         /* Create the comments column */
250         myTable.declareStringColumn(MoneyWiseTransInfoClass.COMMENTS)
251                 .setCellValueFactory(MoneyWiseTransactionTable::getFilteredComments)
252                 .setEditable(true)
253                 .setCellEditable(r -> !r.isHeader())
254                 .setColumnWidth(WIDTH_DESC)
255                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setComments, r, v));
256 
257         /* Create the amount column */
258         myTable.declareMoneyColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT)
259                 .setCellValueFactory(MoneyWiseTransaction::getAmount)
260                 .setEditable(true)
261                 .setColumnWidth(WIDTH_MONEY)
262                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setAmount, r, v));
263 
264         /* Create the tag column */
265         myTable.declareListColumn(MoneyWiseTransInfoClass.TRANSTAG, MoneyWiseTransTag.class)
266                 .setSelectables(c -> theActiveTran.buildTransactionTags())
267                 .setCellValueFactory(MoneyWiseTransaction::getTransactionTags)
268                 .setEditable(true)
269                 .setColumnWidth(WIDTH_NAME)
270                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setTransactionTags, r, v));
271 
272         /* Create the reference column */
273         myTable.declareStringColumn(MoneyWiseTransInfoClass.REFERENCE)
274                 .setCellValueFactory(MoneyWiseTransaction::getReference)
275                 .setEditable(true)
276                 .setColumnWidth(WIDTH_DESC)
277                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setReference, r, v));
278 
279         /* Create the taxCredit column */
280         myTable.declareMoneyColumn(MoneyWiseTransInfoClass.TAXCREDIT)
281                 .setCellValueFactory(MoneyWiseTransaction::getTaxCredit)
282                 .setEditable(true)
283                 .setColumnWidth(WIDTH_MONEY)
284                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setTaxCredit, r, v));
285 
286         /* Create the EeNatIns column */
287         myTable.declareMoneyColumn(MoneyWiseTransInfoClass.EMPLOYEENATINS)
288                 .setCellValueFactory(MoneyWiseTransaction::getEmployeeNatIns)
289                 .setEditable(true)
290                 .setColumnWidth(WIDTH_MONEY)
291                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setEmployeeNatIns, r, v));
292 
293         /* Create the ErNatIns column */
294         myTable.declareMoneyColumn(MoneyWiseTransInfoClass.EMPLOYERNATINS)
295                 .setCellValueFactory(MoneyWiseTransaction::getEmployerNatIns)
296                 .setEditable(true)
297                 .setColumnWidth(WIDTH_MONEY)
298                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setEmployerNatIns, r, v));
299 
300         /* Create the Benefit column */
301         myTable.declareMoneyColumn(MoneyWiseTransInfoClass.DEEMEDBENEFIT)
302                 .setCellValueFactory(MoneyWiseTransaction::getDeemedBenefit)
303                 .setEditable(true)
304                 .setColumnWidth(WIDTH_MONEY)
305                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setDeemedBenefit, r, v));
306 
307         /* Create the Withheld column */
308         myTable.declareMoneyColumn(MoneyWiseTransInfoClass.WITHHELD)
309                 .setCellValueFactory(MoneyWiseTransaction::getWithheld)
310                 .setEditable(true)
311                 .setColumnWidth(WIDTH_MONEY)
312                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setWithheld, r, v));
313 
314         /* Create the AccountUnits column */
315         myTable.declareUnitsColumn(MoneyWiseTransInfoClass.ACCOUNTDELTAUNITS)
316                 .setCellValueFactory(MoneyWiseTransaction::getAccountDeltaUnits)
317                 .setEditable(true)
318                 .setColumnWidth(WIDTH_UNITS)
319                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setAccountDeltaUnits, r, v));
320 
321         /* Create the PartnerUnits column */
322         myTable.declareUnitsColumn(MoneyWiseTransInfoClass.PARTNERDELTAUNITS)
323                 .setCellValueFactory(MoneyWiseTransaction::getPartnerDeltaUnits)
324                 .setEditable(true)
325                 .setColumnWidth(WIDTH_UNITS)
326                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setPartnerDeltaUnits, r, v));
327 
328         /* Create the Dilution column */
329         myTable.declareRatioColumn(MoneyWiseTransInfoClass.DILUTION)
330                 .setCellValueFactory(MoneyWiseTransaction::getDilution)
331                 .setEditable(true)
332                 .setColumnWidth(WIDTH_UNITS)
333                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setDilution, r, v));
334 
335         /* Create the QualifyYears column */
336         myTable.declareIntegerColumn(MoneyWiseTransInfoClass.QUALIFYYEARS)
337                 .setCellValueFactory(MoneyWiseTransaction::getYears)
338                 .setEditable(true)
339                 .setColumnWidth(WIDTH_UNITS)
340                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setYears, r, v));
341 
342         /* Create the returned cash account column */
343         myTable.declareScrollColumn(MoneyWiseTransInfoClass.RETURNEDCASHACCOUNT, MoneyWiseTransAsset.class)
344                 .setMenuConfigurator(this::buildReturnedMenu)
345                 .setCellValueFactory(MoneyWiseTransaction::getReturnedCashAccount)
346                 .setEditable(true)
347                 .setCellEditable(r -> !r.isReconciled())
348                 .setColumnWidth(WIDTH_NAME)
349                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setReturnedCashAccount, r, v));
350 
351         /* Create the returned cash column */
352         myTable.declareMoneyColumn(MoneyWiseTransInfoClass.RETURNEDCASH)
353                 .setCellValueFactory(MoneyWiseTransaction::getReturnedCash)
354                 .setEditable(true)
355                 .setColumnWidth(WIDTH_MONEY)
356                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setReturnedCash, r, v));
357 
358         /* Create the partner amount column */
359         myTable.declareMoneyColumn(MoneyWiseTransInfoClass.PARTNERAMOUNT)
360                 .setCellValueFactory(MoneyWiseTransaction::getPartnerAmount)
361                 .setEditable(true)
362                 .setColumnWidth(WIDTH_MONEY)
363                 .setOnCommit((r, v) -> updateField(MoneyWiseTransaction::setPartnerAmount, r, v));
364 
365         /* Create the debit column */
366         myTable.declareRawDecimalColumn(MoneyWiseTransDataId.DEBIT)
367                 .setCellValueFactory(this::getFilteredDebit)
368                 .setEditable(false)
369                 .setColumnWidth(WIDTH_MONEY);
370 
371         /* Create the credit column */
372         myTable.declareRawDecimalColumn(MoneyWiseTransDataId.CREDIT)
373                 .setCellValueFactory(this::getFilteredCredit)
374                 .setEditable(false)
375                 .setColumnWidth(WIDTH_MONEY);
376 
377         /* Create the balance column */
378         myTable.declareRawDecimalColumn(MoneyWiseTransDataId.BALANCE)
379                 .setCellValueFactory(this::getFilteredBalance)
380                 .setEditable(false)
381                 .setColumnWidth(WIDTH_MONEY);
382 
383         /* Create the Active column */
384         final TethysUIIconMapSet<MetisAction> myActionMapSet = MetisIcon.configureStatusIconButton(myGuiFactory);
385         myTable.declareIconColumn(PrometheusDataResource.DATAITEM_TOUCH, MetisAction.class)
386                 .setIconMapSet(r -> myActionMapSet)
387                 .setCellValueFactory(MoneyWiseTransactionTable::getFilteredAction)
388                 .setName(MoneyWiseUIResource.STATICDATA_ACTIVE.getValue())
389                 .setEditable(true)
390                 .setCellEditable(r -> !r.isHeader() && !r.isReconciled())
391                 .setColumnWidth(WIDTH_ICON)
392                 .setOnCommit((r, v) -> updateField(this::deleteRow, r, v));
393 
394         /* Add listeners */
395         pView.getEventRegistrar().addEventListener(e -> refreshData());
396         theActionButtons.getEventRegistrar().addEventListener(this::handleActionButtons);
397         theNewButton.getEventRegistrar().addEventListener(e -> addNewItem());
398         theError.getEventRegistrar().addEventListener(e -> handleErrorPane());
399         theSelect.getEventRegistrar().addEventListener(PrometheusDataEvent.SELECTIONCHANGED, e -> handleFilterSelection());
400         theSelect.getEventRegistrar().addEventListener(PrometheusDataEvent.SAVETOFILE, e -> writeCSVToFile(pView.getGuiFactory()));
401         theActiveTran.getEventRegistrar().addEventListener(PrometheusDataEvent.ADJUSTVISIBILITY, e -> handlePanelState());
402 
403         /* Hide the action buttons initially */
404         theActionButtons.setVisible(false);
405         theFilter = theSelect.getFilter();
406 
407         /* Initialise the columns */
408         adjustColumns(theSelect.showColumns()
409                 ? theSelect.getColumns()
410                 : MoneyWiseAnalysisColumnSet.BALANCE);
411     }
412 
413     /**
414      * Obtain the selection panel.
415      *
416      * @return the select panel
417      */
418     MoneyWiseAnalysisSelect getSelect() {
419         return theSelect;
420     }
421 
422     /**
423      * Obtain the action buttons.
424      *
425      * @return the action buttons
426      */
427     PrometheusActionButtons getActionButtons() {
428         return theActionButtons;
429     }
430 
431     /**
432      * Delete row.
433      *
434      * @param pRow   the row
435      * @param pValue the value (ignored)
436      * @throws OceanusException on error
437      */
438     protected void setDirection(final MoneyWiseTransaction pRow,
439                                 final Object pValue) throws OceanusException {
440         pRow.switchDirection();
441     }
442 
443     @Override
444     protected boolean isItemEditing() {
445         return theActiveTran.isEditing();
446     }
447 
448     /**
449      * handle Date event.
450      *
451      * @param pConfig the dateConfig
452      */
453     private void handleDateEvent(final OceanusDateConfig pConfig) {
454         pConfig.setEarliestDate(theRange == null
455                 ? null
456                 : theRange.getStart());
457         pConfig.setLatestDate(theRange == null
458                 ? null
459                 : theRange.getEnd());
460     }
461 
462     @Override
463     public boolean isFieldChanged(final MetisDataFieldId pField,
464                                   final MoneyWiseTransaction pItem) {
465         if (pField.equals(MoneyWiseTransDataId.DEBIT)
466                 || pField.equals(MoneyWiseTransDataId.CREDIT)
467                 || pField.equals(MoneyWiseTransDataId.BALANCE)) {
468             return false;
469         }
470         return super.isFieldChanged(pField, pItem);
471     }
472 
473     /**
474      * Determine reconciled state.
475      *
476      * @param pTrans the transaction
477      * @return the state
478      */
479     private static boolean determineReconciledState(final MoneyWiseTransaction pTrans) {
480         return pTrans.isLocked();
481     }
482 
483     /**
484      * Determine direction state.
485      *
486      * @param pTrans the transaction
487      * @return the state
488      */
489     private static boolean determineDirectionState(final MoneyWiseTransaction pTrans) {
490         return pTrans.isReconciled();
491     }
492 
493     /**
494      * Determine Focus.
495      */
496     protected void determineFocus() {
497         /* Request the focus */
498         getTable().requestFocus();
499     }
500 
501     /**
502      * Obtain filtered debit for transaction.
503      *
504      * @param pTrans the transaction
505      * @return the debit
506      */
507     private OceanusDecimal getFilteredDebit(final MoneyWiseTransaction pTrans) {
508         return theFilter.getDebitForTransaction(pTrans);
509     }
510 
511     /**
512      * Obtain filtered debit for transaction.
513      *
514      * @param pTrans the transaction
515      * @return the debit
516      */
517     private OceanusDecimal getFilteredCredit(final MoneyWiseTransaction pTrans) {
518         return theFilter.getCreditForTransaction(pTrans);
519     }
520 
521     /**
522      * Obtain filtered debit for transaction.
523      *
524      * @param pTrans the transaction
525      * @return the debit
526      */
527     private OceanusDecimal getFilteredBalance(final MoneyWiseTransaction pTrans) {
528         return pTrans.isHeader() ? theFilter.getStartingBalance() : theFilter.getBalanceForTransaction(pTrans);
529     }
530 
531     /**
532      * Obtain date value.
533      *
534      * @param pTrans the transaction
535      * @return the date value
536      */
537     private OceanusDate getFilteredDate(final MoneyWiseTransaction pTrans) {
538         return pTrans.isHeader() ? theRange.getStart() : pTrans.getDate();
539     }
540 
541     /**
542      * Obtain date value.
543      *
544      * @param pTrans the transaction
545      * @return the date value
546      */
547     private static String getFilteredComments(final MoneyWiseTransaction pTrans) {
548         return pTrans.isHeader() ? MoneyWiseUIResource.STATEMENT_OPENINGBALANCE.getValue() : pTrans.getComments();
549     }
550 
551     /**
552      * Obtain direction value.
553      *
554      * @param pTrans the transaction
555      * @return the direction value
556      */
557     private static MoneyWiseAssetDirection getFilteredDirection(final MoneyWiseTransaction pTrans) {
558         return pTrans.isHeader() ? null : pTrans.getDirection();
559     }
560 
561     /**
562      * Obtain date value.
563      *
564      * @param pTrans the transaction
565      * @return the date value
566      */
567     private static MetisAction getFilteredAction(final MoneyWiseTransaction pTrans) {
568         return (pTrans.isHeader() || pTrans.isReconciled()) ? MetisAction.DO : MetisAction.DELETE;
569     }
570 
571     @Override
572     protected void selectItem(final MoneyWiseTransaction pTrans) {
573         final MoneyWiseTransaction myTrans = pTrans != null && !pTrans.isHeader() ? pTrans : null;
574         theActiveTran.setItem(myTrans);
575     }
576 
577     /**
578      * Select Statement.
579      *
580      * @param pSelect the selection
581      */
582     void selectStatement(final MoneyWiseStatementSelect pSelect) {
583         /* Update selection */
584         theSelect.selectStatement(pSelect);
585 
586         /* Set the filter */
587         theFilter = theSelect.getFilter();
588 
589         /* Ensure that columns are correct */
590         adjustColumns(theSelect.showColumns()
591                 ? theSelect.getColumns()
592                 : MoneyWiseAnalysisColumnSet.BALANCE);
593 
594         /* Update the lists */
595         updateList();
596     }
597 
598     /**
599      * handleErrorPane.
600      */
601     private void handleErrorPane() {
602         /* Determine whether we have an error */
603         final boolean isError = theError.hasError();
604 
605         /* Hide selection panel on error */
606         theSelect.setVisible(!isError);
607 
608         /* Lock scroll area */
609         getTable().setEnabled(!isError);
610 
611         /* Lock Action Buttons */
612         theActionButtons.setEnabled(!isError);
613     }
614 
615     @Override
616     protected void refreshData() {
617         /* Obtain the active profile */
618         OceanusProfile myTask = getView().getActiveTask();
619         myTask = myTask.startTask("refreshData");
620 
621         /* Update the selection */
622         theSelect.refreshData();
623 
624         /* Set the filter */
625         theFilter = theSelect.getFilter();
626 
627         /* Update the list */
628         updateList();
629 
630         /* Complete the task */
631         myTask.end();
632     }
633 
634     /**
635      * Handle filter selection.
636      */
637     private void handleFilterSelection() {
638         /* Set the filter */
639         theFilter = theSelect.getFilter();
640 
641         /* Ensure that columns are correct */
642         adjustColumns(theSelect.showColumns()
643                 ? theSelect.getColumns()
644                 : MoneyWiseAnalysisColumnSet.BALANCE);
645 
646         /* Set the selection */
647         final OceanusDateRange myRange = theSelect.getRange();
648         if (MetisDataDifference.isEqual(myRange, theRange)) {
649             /* Handle a simple filter change */
650             theViewerFilter.setObject(theFilter);
651             updateTableData();
652         } else {
653             /* Update new lists */
654             updateList();
655         }
656     }
657 
658 
659     @Override
660     protected boolean isFiltered(final MoneyWiseTransaction pRow) {
661         /* Handle no filter */
662         if (theFilter == null) {
663             return false;
664         }
665 
666         /* Handle header visibility */
667         if (pRow.isHeader()) {
668             return MoneyWiseAnalysisColumnSet.BALANCE.equals(theColumnSet);
669         }
670 
671         /* Return visibility of row */
672         return super.isFiltered(pRow) && !theFilter.filterTransaction(pRow);
673     }
674 
675     @Override
676     public void notifyChanges() {
677         /* Determine whether we have updates */
678         final boolean hasUpdates = hasUpdates();
679         final boolean isItemEditing = theActiveTran.isEditing();
680 
681         /* Update the table buttons */
682         theActionButtons.setEnabled(true);
683         theActionButtons.setVisible(hasUpdates && !isItemEditing);
684         theSelect.setEnabled(!isItemEditing);
685         theNewButton.setEnabled(!isItemEditing);
686 
687         /* Adjust enable of the table */
688         if (!isItemEditing) {
689             setEnabled(true);
690         } else {
691             setTableEnabled(false);
692         }
693 
694         /* Pass call on */
695         super.notifyChanges();
696     }
697 
698     /**
699      * Update lists.
700      */
701     private void updateList() {
702         /* Access the transactions */
703         theTransactions = theAnalysisView.getTransactions();
704         theRange = theAnalysisView.getRange();
705 
706         /* If we have data */
707         if (theTransactions != null) {
708             MoneyWiseTransaction myHeader = theTransactions.findItemById(AnalysisHeader.ID_VALUE);
709             if (myHeader == null) {
710                 /* Create the header */
711                 myHeader = new AnalysisHeader(theTransactions);
712                 theTransactions.add(myHeader);
713             }
714 
715             /* Notify panel of refresh */
716             theActiveTran.refreshData();
717             theActiveTran.updateEditors(theRange);
718 
719             /* Notify the builder */
720             theTransactions.getValidator().setRange(theRange);
721             theTransactions.getValidator().setEditSet(theEditSet);
722         }
723 
724         /* Update lists */
725         getTable().setItems(theTransactions == null ? null : theTransactions.getUnderlyingList());
726         theActionButtons.setEnabled(true);
727         theSelect.setEnabled(!hasUpdates());
728 
729         /* Touch the filter and updateSet */
730         theViewerFilter.setObject(theFilter);
731         theViewerAnalysis.setTreeObject(getEditSet());
732         restoreSelected();
733     }
734 
735     @Override
736     public void cancelEditing() {
737         super.cancelEditing();
738         theActiveTran.setEditable(false);
739     }
740 
741     /**
742      * Select transaction.
743      *
744      * @param pTran the transaction to select
745      */
746     void selectTran(final MoneyWiseTransaction pTran) {
747         /* Select the row */
748         getTable().selectRow(pTran);
749     }
750 
751     @Override
752     protected void handleRewind() {
753         /* Only action if we are not editing */
754         if (!theActiveTran.isEditing()) {
755             /* Handle the reWind */
756             setEnabled(true);
757             super.handleRewind();
758         }
759 
760         /* Adjust for changes */
761         notifyChanges();
762     }
763 
764     /**
765      * handle Action Buttons.
766      *
767      * @param pEvent the event
768      */
769     private void handleActionButtons(final OceanusEvent<PrometheusUIEvent> pEvent) {
770         /* Cancel editing */
771         cancelEditing();
772 
773         /* Perform the command */
774         theEditSet.processCommand(pEvent.getEventId(), theError);
775 
776         /* Adjust for changes */
777         notifyChanges();
778     }
779 
780     /**
781      * Handle panel state.
782      */
783     private void handlePanelState() {
784         /* Only action if we are not editing */
785         if (!theActiveTran.isEditing()) {
786             /* handle the edit transition */
787             setEnabled(true);
788             final MoneyWiseTransaction myTrans = theActiveTran.getSelectedItem();
789             updateTableData();
790             if (myTrans != null) {
791                 getTable().selectRow(myTrans);
792             } else {
793                 restoreSelected();
794             }
795         } else {
796             getTable().cancelEditing();
797         }
798 
799         /* Note changes */
800         notifyChanges();
801     }
802 
803     /**
804      * Obtain the popUpMenu for Accounts.
805      *
806      * @param pTrans the transaction
807      * @param pMenu  the menu to build
808      */
809     private void buildAccountMenu(final MoneyWiseTransaction pTrans,
810                                   final TethysUIScrollMenu<MoneyWiseTransAsset> pMenu) {
811         /* Build the menu */
812         theActiveTran.buildAccountMenu(pMenu, pTrans);
813     }
814 
815     /**
816      * Obtain the popUpMenu for Partner Accounts.
817      *
818      * @param pTrans the transaction
819      * @param pMenu  the menu to build
820      */
821     private void buildPartnerMenu(final MoneyWiseTransaction pTrans,
822                                   final TethysUIScrollMenu<MoneyWiseTransAsset> pMenu) {
823         /* Build the menu */
824         theActiveTran.buildPartnerMenu(pMenu, pTrans);
825     }
826 
827     /**
828      * Build the popUpMenu for categories.
829      *
830      * @param pTrans the transaction
831      * @param pMenu  the menu to build
832      */
833     private void buildCategoryMenu(final MoneyWiseTransaction pTrans,
834                                    final TethysUIScrollMenu<MoneyWiseTransCategory> pMenu) {
835         /* Build the menu */
836         theActiveTran.buildCategoryMenu(pMenu, pTrans);
837     }
838 
839     /**
840      * Build the popUpMenu for categories.
841      *
842      * @param pTrans the transaction
843      * @param pMenu  the menu to build
844      */
845     private void buildReturnedMenu(final MoneyWiseTransaction pTrans,
846                                    final TethysUIScrollMenu<MoneyWiseTransAsset> pMenu) {
847         /* Build the menu */
848         theActiveTran.buildReturnedAccountMenu(pMenu, pTrans);
849     }
850 
851     /**
852      * New item.
853      */
854     private void addNewItem() {
855         /* Make sure that we have finished editing */
856         cancelEditing();
857 
858         /* Create a new profile */
859         final OceanusProfile myTask = getView().getNewProfile("addNewItem");
860 
861         /* Create the new transaction */
862         myTask.startTask("buildItem");
863         final MoneyWiseValidateTransaction myBuilder = (MoneyWiseValidateTransaction) theTransactions.getValidator();
864         final MoneyWiseTransaction myTrans = theFilter.buildNewTransaction(myBuilder);
865 
866         /* If we have one available */
867         if (myTrans != null) {
868             /* Add the new item */
869             myTask.startTask("addToList");
870             theTransactions.add(myTrans);
871             myTrans.setNewVersion();
872 
873             /* Validate the new item and notify of the changes */
874             myTask.startTask("incrementVersion");
875             getEditSet().incrementVersion();
876 
877             /* validate the item */
878             myTask.startTask("validate");
879             myTrans.validate();
880 
881             /* Lock the table */
882             myTask.startTask("setItem");
883             theActiveTran.setNewItem(myTrans);
884             setTableEnabled(false);
885         }
886 
887         /* End the task */
888         myTask.end();
889     }
890 
891     /**
892      * Adjust columns.
893      *
894      * @param pSet the set to display.
895      */
896     private void adjustColumns(final MoneyWiseAnalysisColumnSet pSet) {
897         /* Ignore if we are already the right set */
898         if (pSet.equals(theColumnSet)) {
899             return;
900         }
901 
902         /* Hide all columns */
903         final TethysUITableManager<MetisDataFieldId, MoneyWiseTransaction> myTable = getTable();
904         hideAllColumns();
905 
906         /* Switch on column set */
907         switch (pSet) {
908             case BALANCE:
909                 myTable.getColumn(MoneyWiseTransInfoClass.COMMENTS).setVisible(true);
910                 myTable.getColumn(MoneyWiseTransDataId.DEBIT).setVisible(true);
911                 myTable.getColumn(MoneyWiseTransDataId.CREDIT).setVisible(true);
912                 myTable.getColumn(MoneyWiseTransDataId.BALANCE).setVisible(true);
913                 break;
914             case STANDARD:
915                 myTable.getColumn(MoneyWiseTransInfoClass.COMMENTS).setVisible(true);
916                 myTable.getColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT).setVisible(true);
917                 myTable.getColumn(MoneyWiseTransInfoClass.TRANSTAG).setVisible(true);
918                 myTable.getColumn(MoneyWiseTransInfoClass.REFERENCE).setVisible(true);
919                 myTable.getColumn(MoneyWiseTransInfoClass.PARTNERAMOUNT).setVisible(true);
920                 break;
921             case SALARY:
922                 myTable.getColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT).setVisible(true);
923                 myTable.getColumn(MoneyWiseTransInfoClass.TAXCREDIT).setVisible(true);
924                 myTable.getColumn(MoneyWiseTransInfoClass.EMPLOYEENATINS).setVisible(true);
925                 myTable.getColumn(MoneyWiseTransInfoClass.EMPLOYERNATINS).setVisible(true);
926                 myTable.getColumn(MoneyWiseTransInfoClass.DEEMEDBENEFIT).setVisible(true);
927                 myTable.getColumn(MoneyWiseTransInfoClass.WITHHELD).setVisible(true);
928                 break;
929             case INTEREST:
930                 myTable.getColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT).setVisible(true);
931                 myTable.getColumn(MoneyWiseTransInfoClass.TAXCREDIT).setVisible(true);
932                 myTable.getColumn(MoneyWiseTransInfoClass.WITHHELD).setVisible(true);
933                 break;
934             case DIVIDEND:
935                 myTable.getColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT).setVisible(true);
936                 myTable.getColumn(MoneyWiseTransInfoClass.TAXCREDIT).setVisible(true);
937                 myTable.getColumn(MoneyWiseTransInfoClass.ACCOUNTDELTAUNITS).setVisible(true);
938                 break;
939             case SECURITY:
940                 myTable.getColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT).setVisible(true);
941                 myTable.getColumn(MoneyWiseTransInfoClass.ACCOUNTDELTAUNITS).setVisible(true);
942                 myTable.getColumn(MoneyWiseTransInfoClass.PARTNERDELTAUNITS).setVisible(true);
943                 myTable.getColumn(MoneyWiseTransInfoClass.DILUTION).setVisible(true);
944                 myTable.getColumn(MoneyWiseTransInfoClass.RETURNEDCASHACCOUNT).setVisible(true);
945                 myTable.getColumn(MoneyWiseTransInfoClass.RETURNEDCASH).setVisible(true);
946                 myTable.getColumn(MoneyWiseTransInfoClass.QUALIFYYEARS).setVisible(true);
947                 break;
948             case ALL:
949             default:
950                 myTable.getColumn(MoneyWiseTransInfoClass.COMMENTS).setVisible(true);
951                 myTable.getColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT).setVisible(true);
952                 myTable.getColumn(MoneyWiseTransInfoClass.TRANSTAG).setVisible(true);
953                 myTable.getColumn(MoneyWiseTransInfoClass.REFERENCE).setVisible(true);
954                 myTable.getColumn(MoneyWiseTransInfoClass.TAXCREDIT).setVisible(true);
955                 myTable.getColumn(MoneyWiseTransInfoClass.EMPLOYERNATINS).setVisible(true);
956                 myTable.getColumn(MoneyWiseTransInfoClass.EMPLOYEENATINS).setVisible(true);
957                 myTable.getColumn(MoneyWiseTransInfoClass.DEEMEDBENEFIT).setVisible(true);
958                 myTable.getColumn(MoneyWiseTransInfoClass.WITHHELD).setVisible(true);
959                 myTable.getColumn(MoneyWiseTransInfoClass.ACCOUNTDELTAUNITS).setVisible(true);
960                 myTable.getColumn(MoneyWiseTransInfoClass.PARTNERDELTAUNITS).setVisible(true);
961                 myTable.getColumn(MoneyWiseTransInfoClass.PARTNERAMOUNT).setVisible(true);
962                 myTable.getColumn(MoneyWiseTransInfoClass.DILUTION).setVisible(true);
963                 myTable.getColumn(MoneyWiseTransInfoClass.RETURNEDCASHACCOUNT).setVisible(true);
964                 myTable.getColumn(MoneyWiseTransInfoClass.RETURNEDCASH).setVisible(true);
965                 myTable.getColumn(MoneyWiseTransInfoClass.QUALIFYYEARS).setVisible(true);
966                 break;
967         }
968 
969         /* Store the column set */
970         theColumnSet = pSet;
971     }
972 
973     /**
974      * Hide all columns.
975      */
976     private void hideAllColumns() {
977         final TethysUITableManager<MetisDataFieldId, MoneyWiseTransaction> myTable = getTable();
978         myTable.getColumn(MoneyWiseTransDataId.DEBIT).setVisible(false);
979         myTable.getColumn(MoneyWiseTransDataId.CREDIT).setVisible(false);
980         myTable.getColumn(MoneyWiseTransDataId.BALANCE).setVisible(false);
981         myTable.getColumn(MoneyWiseTransInfoClass.COMMENTS).setVisible(false);
982         myTable.getColumn(MoneyWiseBasicResource.TRANSACTION_AMOUNT).setVisible(false);
983         myTable.getColumn(MoneyWiseTransInfoClass.TRANSTAG).setVisible(false);
984         myTable.getColumn(MoneyWiseTransInfoClass.REFERENCE).setVisible(false);
985         myTable.getColumn(MoneyWiseTransInfoClass.TAXCREDIT).setVisible(false);
986         myTable.getColumn(MoneyWiseTransInfoClass.EMPLOYERNATINS).setVisible(false);
987         myTable.getColumn(MoneyWiseTransInfoClass.EMPLOYEENATINS).setVisible(false);
988         myTable.getColumn(MoneyWiseTransInfoClass.DEEMEDBENEFIT).setVisible(false);
989         myTable.getColumn(MoneyWiseTransInfoClass.WITHHELD).setVisible(false);
990         myTable.getColumn(MoneyWiseTransInfoClass.ACCOUNTDELTAUNITS).setVisible(false);
991         myTable.getColumn(MoneyWiseTransInfoClass.PARTNERDELTAUNITS).setVisible(false);
992         myTable.getColumn(MoneyWiseTransInfoClass.PARTNERAMOUNT).setVisible(false);
993         myTable.getColumn(MoneyWiseTransInfoClass.DILUTION).setVisible(false);
994         myTable.getColumn(MoneyWiseTransInfoClass.RETURNEDCASHACCOUNT).setVisible(false);
995         myTable.getColumn(MoneyWiseTransInfoClass.RETURNEDCASH).setVisible(false);
996         myTable.getColumn(MoneyWiseTransInfoClass.QUALIFYYEARS).setVisible(false);
997     }
998 
999 
1000     /**
1001      * Analysis Header class.
1002      */
1003     private static class AnalysisHeader
1004             extends MoneyWiseTransaction {
1005         /**
1006          * Analysis Header Id.
1007          */
1008         static final int ID_VALUE = 1;
1009 
1010         /**
1011          * Constructor.
1012          *
1013          * @param pList the Transaction list
1014          */
1015         protected AnalysisHeader(final MoneyWiseTransactionList pList) {
1016             super(pList);
1017             setHeader(true);
1018             setIndexedId(ID_VALUE);
1019         }
1020     }
1021 
1022     /**
1023      * Transaction DataIds.
1024      */
1025     private enum MoneyWiseTransDataId
1026             implements MetisDataFieldId {
1027         /**
1028          * Debit.
1029          */
1030         DEBIT(MoneyWiseUIResource.STATEMENT_COLUMN_DEBIT),
1031 
1032         /**
1033          * Credit.
1034          */
1035         CREDIT(MoneyWiseUIResource.STATEMENT_COLUMN_CREDIT),
1036 
1037         /**
1038          * Balance.
1039          */
1040         BALANCE(MoneyWiseUIResource.STATEMENT_COLUMN_BALANCE);
1041 
1042         /**
1043          * The Value.
1044          */
1045         private final String theValue;
1046 
1047         /**
1048          * Constructor.
1049          *
1050          * @param pKeyName the key name
1051          */
1052         MoneyWiseTransDataId(final MetisDataFieldId pKeyName) {
1053             theValue = pKeyName.getId();
1054         }
1055 
1056         @Override
1057         public String getId() {
1058             return theValue;
1059         }
1060 
1061         @Override
1062         public String toString() {
1063             return getId();
1064         }
1065     }
1066 
1067     /**
1068      * Transaction Panel.
1069      */
1070     public static class MoneyWiseStatementPanel
1071             implements TethysUIComponent, OceanusEventProvider<PrometheusDataEvent> {
1072         /**
1073          * Text for DataEntry Title.
1074          */
1075         private static final String NLS_DATAENTRY = MoneyWiseUIResource.REGISTER_DATAENTRY.getValue();
1076 
1077         /**
1078          * Text for Filter DataEntry Title.
1079          */
1080         private static final String NLS_FILTERDATAENTRY = MoneyWiseUIResource.FILTER_DATAENTRY.getValue();
1081 
1082         /**
1083          * Text for Transactions DataEntry Title.
1084          */
1085         private static final String NLS_TRANSDATAENTRY = MoneyWiseUIResource.TRANSACTION_DATAENTRY.getValue();
1086 
1087         /**
1088          * The Event Manager.
1089          */
1090         private final OceanusEventManager<PrometheusDataEvent> theEventManager;
1091 
1092         /**
1093          * The updateSet.
1094          */
1095         private final PrometheusEditSet theEditSet;
1096 
1097         /**
1098          * The analysis data entry.
1099          */
1100         private final MetisViewerEntry theViewerAnalysis;
1101 
1102         /**
1103          * The error panel.
1104          */
1105         private final MetisErrorPanel theError;
1106 
1107         /**
1108          * The table.
1109          */
1110         private final MoneyWiseTransactionTable theTable;
1111 
1112         /**
1113          * The panel.
1114          */
1115         private final TethysUIBorderPaneManager thePanel;
1116 
1117         /**
1118          * Constructor.
1119          *
1120          * @param pView the data view
1121          */
1122         public MoneyWiseStatementPanel(final MoneyWiseView pView) {
1123             /* Build the Update set and entry */
1124             theEditSet = new PrometheusEditSet(pView);
1125 
1126             /* Create the event manager */
1127             theEventManager = new OceanusEventManager<>();
1128 
1129             /* Create the top level viewer entry for this view */
1130             final MetisViewerManager myViewer = pView.getViewerManager();
1131             final MetisViewerEntry mySection = pView.getViewerEntry(PrometheusViewerEntryId.VIEW);
1132             final MetisViewerEntry myRegister = myViewer.newEntry(mySection, NLS_DATAENTRY);
1133             final MetisViewerEntry myViewerFilter = myViewer.newEntry(myRegister, NLS_FILTERDATAENTRY);
1134             theViewerAnalysis = myViewer.newEntry(myRegister, NLS_TRANSDATAENTRY);
1135             theViewerAnalysis.setTreeObject(theEditSet);
1136 
1137             /* Create the error panel for this view */
1138             theError = pView.getToolkit().getToolkit().newErrorPanel(theViewerAnalysis);
1139 
1140             /* Create the table */
1141             theTable = new MoneyWiseTransactionTable(pView, theEditSet, theError, myViewerFilter, theViewerAnalysis);
1142 
1143             /* Create the action buttons */
1144             final TethysUIFactory<?> myGuiFactory = pView.getGuiFactory();
1145 
1146             /* Create the header panel */
1147             final TethysUIPaneFactory myPanes = myGuiFactory.paneFactory();
1148             final TethysUIBorderPaneManager myHeader = myPanes.newBorderPane();
1149             myHeader.setCentre(theTable.getSelect());
1150             myHeader.setNorth(theError);
1151             myHeader.setEast(theTable.getActionButtons());
1152 
1153             /* Create the panel */
1154             thePanel = myPanes.newBorderPane();
1155             thePanel.setNorth(myHeader);
1156             thePanel.setCentre(theTable);
1157 
1158             /* Add listeners */
1159             theError.getEventRegistrar().addEventListener(e -> handleErrorPane());
1160             theTable.getActionButtons().getEventRegistrar().addEventListener(this::handleActionButtons);
1161             theTable.getEventRegistrar().addEventListener(PrometheusDataEvent.ADJUSTVISIBILITY, e -> notifyChanges());
1162             theTable.getEventRegistrar().addEventListener(PrometheusDataEvent.GOTOWINDOW, theEventManager::cascadeEvent);
1163         }
1164 
1165         @Override
1166         public TethysUIComponent getUnderlying() {
1167             return thePanel;
1168         }
1169 
1170         @Override
1171         public void setEnabled(final boolean pEnabled) {
1172             thePanel.setEnabled(pEnabled);
1173         }
1174 
1175         @Override
1176         public void setVisible(final boolean pVisible) {
1177             thePanel.setVisible(pVisible);
1178         }
1179 
1180         @Override
1181         public OceanusEventRegistrar<PrometheusDataEvent> getEventRegistrar() {
1182             return theEventManager.getEventRegistrar();
1183         }
1184 
1185         /**
1186          * Select Statement.
1187          *
1188          * @param pSelect the selection
1189          */
1190         public void selectStatement(final MoneyWiseStatementSelect pSelect) {
1191             theTable.selectStatement(pSelect);
1192         }
1193 
1194         /**
1195          * handleErrorPane.
1196          */
1197         private void handleErrorPane() {
1198             /* Determine whether we have an error */
1199             final boolean isError = theError.hasError();
1200 
1201             /* Hide selection panel on error */
1202             theTable.getSelect().setVisible(!isError);
1203 
1204             /* Lock scroll area */
1205             theTable.setEnabled(!isError);
1206 
1207             /* Lock Action Buttons */
1208             theTable.getActionButtons().setEnabled(!isError);
1209         }
1210 
1211         /**
1212          * handle Action Buttons.
1213          *
1214          * @param pEvent the event
1215          */
1216         private void handleActionButtons(final OceanusEvent<PrometheusUIEvent> pEvent) {
1217             /* Cancel editing */
1218             theTable.cancelEditing();
1219 
1220             /* Perform the command */
1221             theEditSet.processCommand(pEvent.getEventId(), theError);
1222 
1223             /* Adjust for changes */
1224             theTable.notifyChanges();
1225         }
1226 
1227         /**
1228          * Determine Focus.
1229          */
1230         public void determineFocus() {
1231             /* Request the focus */
1232             theTable.determineFocus();
1233 
1234             /* Focus on the Data entry */
1235             theViewerAnalysis.setFocus();
1236         }
1237 
1238         /**
1239          * Call underlying controls to take notice of changes in view/selection.
1240          */
1241         private void notifyChanges() {
1242             /* Notify listeners */
1243             theEventManager.fireEvent(PrometheusDataEvent.ADJUSTVISIBILITY);
1244         }
1245 
1246         /**
1247          * Does the panel have updates?
1248          *
1249          * @return true/false
1250          */
1251         public boolean hasUpdates() {
1252             return theTable.hasUpdates();
1253         }
1254 
1255         /**
1256          * Does the panel have a session?
1257          *
1258          * @return true/false
1259          */
1260         public boolean hasSession() {
1261             return theTable.hasUpdates();
1262         }
1263 
1264         /**
1265          * Does the panel have errors?
1266          *
1267          * @return true/false
1268          */
1269         public boolean hasErrors() {
1270             return theTable.hasErrors();
1271         }
1272     }
1273 }