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