1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.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.event.OceanusEvent;
22 import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
23 import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
24 import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
25 import io.github.tonywasher.joceanus.oceanus.profile.OceanusProfile;
26 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
27 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
28 import io.github.tonywasher.joceanus.metis.ui.MetisAction;
29 import io.github.tonywasher.joceanus.metis.ui.MetisErrorPanel;
30 import io.github.tonywasher.joceanus.metis.ui.MetisIcon;
31 import io.github.tonywasher.joceanus.metis.viewer.MetisViewerEntry;
32 import io.github.tonywasher.joceanus.metis.viewer.MetisViewerManager;
33 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
34 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicResource;
35 import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseUIResource;
36 import io.github.tonywasher.joceanus.moneywise.ui.base.MoneyWiseBaseTable;
37 import io.github.tonywasher.joceanus.moneywise.ui.controls.MoneyWiseSpotRatesSelect;
38 import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseSpotExchangeRate;
39 import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseSpotExchangeRate.MoneyWiseSpotExchangeList;
40 import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseView;
41 import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseViewResource;
42 import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseYQLDownloader;
43 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
44 import io.github.tonywasher.joceanus.prometheus.ui.PrometheusActionButtons;
45 import io.github.tonywasher.joceanus.prometheus.views.PrometheusDataEvent;
46 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
47 import io.github.tonywasher.joceanus.prometheus.views.PrometheusUIEvent;
48 import io.github.tonywasher.joceanus.prometheus.views.PrometheusViewerEntryId;
49 import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
50 import io.github.tonywasher.joceanus.tethys.api.button.TethysUIButton;
51 import io.github.tonywasher.joceanus.tethys.api.control.TethysUIControl.TethysUIIconMapSet;
52 import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
53 import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBorderPaneManager;
54 import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIPaneFactory;
55 import io.github.tonywasher.joceanus.tethys.api.table.TethysUITableManager;
56
57
58
59
60 public class MoneyWiseMarketRatesTable
61 extends MoneyWiseBaseTable<MoneyWiseSpotExchangeRate> {
62
63
64
65 private final MoneyWiseSpotRatesSelect theSelect;
66
67
68
69
70 private MoneyWiseSpotExchangeList theRates;
71
72
73
74
75 private OceanusDate theDate;
76
77
78
79
80
81
82
83
84 MoneyWiseMarketRatesTable(final MoneyWiseView pView,
85 final PrometheusEditSet pEditSet,
86 final MetisErrorPanel pError) {
87
88 super(pView, pEditSet, pError, MoneyWiseBasicDataType.EXCHANGERATE);
89
90
91 final TethysUIFactory<?> myGuiFactory = pView.getGuiFactory();
92 final TethysUITableManager<MetisDataFieldId, MoneyWiseSpotExchangeRate> myTable = getTable();
93
94
95 final TethysUIButton myNewButton = myGuiFactory.buttonFactory().newButton();
96 MetisIcon.configureNewIconButton(myNewButton);
97
98
99 theSelect = new MoneyWiseSpotRatesSelect(myGuiFactory, pView);
100
101
102 myTable.setDisabled(MoneyWiseSpotExchangeRate::isDisabled)
103 .setComparator(MoneyWiseSpotExchangeRate::compareTo);
104
105
106 myTable.declareStringColumn(MoneyWiseBasicResource.XCHGRATE_FROM)
107 .setCellValueFactory(r -> r.getToCurrency().getDesc())
108 .setEditable(false)
109 .setColumnWidth(WIDTH_NAME);
110
111
112 myTable.declareStringColumn(MoneyWiseBasicResource.XCHGRATE_TO)
113 .setCellValueFactory(r -> r.getToCurrency().getName())
114 .setName(MoneyWiseUIResource.SPOTRATE_COLUMN_SYMBOL.getValue())
115 .setEditable(false)
116 .setColumnWidth(WIDTH_NAME);
117
118
119 myTable.declareRatioColumn(MoneyWiseBasicResource.XCHGRATE_RATE)
120 .setCellValueFactory(MoneyWiseSpotExchangeRate::getExchangeRate)
121 .setEditable(true)
122 .setCellEditable(r -> !r.isDisabled())
123 .setColumnWidth(WIDTH_PRICE)
124 .setOnCommit((r, v) -> updateField(MoneyWiseSpotExchangeRate::setExchangeRate, r, v));
125
126
127 myTable.declareRatioColumn(MoneyWiseViewResource.SPOTRATE_PREVRATE)
128 .setCellValueFactory(MoneyWiseSpotExchangeRate::getPrevRate)
129 .setName(MoneyWiseViewResource.SPOTRATE_PREVRATE.getValue())
130 .setEditable(false)
131 .setColumnWidth(WIDTH_PRICE);
132
133
134 myTable.declareDateColumn(MoneyWiseViewResource.SPOTEVENT_PREVDATE)
135 .setCellValueFactory(MoneyWiseSpotExchangeRate::getPrevDate)
136 .setName(MoneyWiseViewResource.SPOTEVENT_PREVDATE.getValue())
137 .setEditable(false)
138 .setColumnWidth(WIDTH_DATE);
139
140
141 final TethysUIIconMapSet<MetisAction> myActionMapSet = MetisIcon.configureStatusIconButton(myGuiFactory);
142 myTable.declareIconColumn(PrometheusDataResource.DATAITEM_TOUCH, MetisAction.class)
143 .setIconMapSet(r -> myActionMapSet)
144 .setCellValueFactory(r -> r.getExchangeRate() != null && !r.isDisabled() ? MetisAction.DELETE : MetisAction.DO)
145 .setName(MoneyWiseUIResource.STATICDATA_ACTIVE.getValue())
146 .setEditable(true)
147 .setCellEditable(r -> r.getExchangeRate() != null && !r.isDisabled())
148 .setColumnWidth(WIDTH_ICON)
149 .setOnCommit((r, v) -> updateField(this::deleteRow, r, v));
150
151
152 theSelect.getEventRegistrar().addEventListener(PrometheusDataEvent.SELECTIONCHANGED, e -> handleNewSelection());
153 theSelect.getEventRegistrar().addEventListener(PrometheusDataEvent.DOWNLOAD, e -> downloadPrices());
154 pView.getEventRegistrar().addEventListener(e -> refreshData());
155 pEditSet.getEventRegistrar().addEventListener(e -> updateTableData());
156 }
157
158
159
160
161
162
163 MoneyWiseSpotRatesSelect getSelect() {
164 return theSelect;
165 }
166
167 @Override
168 protected void refreshData() {
169
170 OceanusProfile myTask = getView().getActiveTask();
171 myTask = myTask.startTask("SpotRates1");
172
173
174 theSelect.refreshData();
175
176
177 setSelection(theSelect.getDate());
178
179
180 theSelect.createSavePoint();
181
182
183 myTask.end();
184 }
185
186
187
188
189
190
191 public void setSelection(final OceanusDate pDate) {
192
193 theDate = pDate;
194
195
196 if (theDate != null) {
197
198 theRates = new MoneyWiseSpotExchangeList(getView(), pDate);
199
200
201 theSelect.setAdjacent(theRates.getPrev(), theRates.getNext());
202
203
204 } else {
205
206 theRates = null;
207 theSelect.setAdjacent(null, null);
208 }
209
210
211 getTable().setItems(theRates.getUnderlyingList());
212 getEditEntry().setDataList(theRates);
213 theSelect.setEnabled(true);
214 }
215
216
217
218
219 private void handleNewSelection() {
220
221 final OceanusDate myDate = theSelect.getDate();
222
223
224 if (!MetisDataDifference.isEqual(theDate, myDate)) {
225
226 setSelection(myDate);
227
228
229 theSelect.createSavePoint();
230 }
231 }
232
233 @Override
234 protected boolean isFiltered(final MoneyWiseSpotExchangeRate pRow) {
235
236 return !pRow.isDisabled();
237 }
238
239 @Override
240 protected void deleteRow(final MoneyWiseSpotExchangeRate pRow,
241 final Object pValue) throws OceanusException {
242 pRow.setExchangeRate(null);
243 }
244
245
246
247
248 public void determineFocus() {
249
250 getTable().requestFocus();
251 }
252
253 @Override
254 protected void notifyChanges() {
255 theSelect.setEnabled(!hasUpdates());
256 super.notifyChanges();
257 }
258
259
260
261
262 private void downloadPrices() {
263
264 cancelEditing();
265
266
267 try {
268
269 if (MoneyWiseYQLDownloader.downloadRates(theRates)) {
270
271 getEditSet().incrementVersion();
272
273
274 updateTableData();
275 notifyChanges();
276 }
277 } catch (OceanusException e) {
278
279 setError(e);
280 }
281 }
282
283
284
285
286 public static class MoneyWiseSpotRatesPanel
287 implements TethysUIComponent, OceanusEventProvider<PrometheusDataEvent> {
288
289
290
291 private static final String NLS_DATAENTRY = MoneyWiseUIResource.RATES_DATAENTRY.getValue();
292
293
294
295
296 private final OceanusEventManager<PrometheusDataEvent> theEventManager;
297
298
299
300
301 private final PrometheusEditSet theEditSet;
302
303
304
305
306 private final MetisErrorPanel theError;
307
308
309
310
311 private final PrometheusActionButtons theActionButtons;
312
313
314
315
316 private final MoneyWiseMarketRatesTable theTable;
317
318
319
320
321 private final TethysUIBorderPaneManager thePanel;
322
323
324
325
326 private final MetisViewerEntry theViewerRate;
327
328
329
330
331
332
333 public MoneyWiseSpotRatesPanel(final MoneyWiseView pView) {
334
335 theEditSet = new PrometheusEditSet(pView);
336
337
338 theEventManager = new OceanusEventManager<>();
339
340
341 final MetisViewerEntry mySection = pView.getViewerEntry(PrometheusViewerEntryId.VIEW);
342 final MetisViewerManager myViewer = pView.getViewerManager();
343 theViewerRate = myViewer.newEntry(mySection, NLS_DATAENTRY);
344 theViewerRate.setTreeObject(theEditSet);
345
346
347 theError = pView.getToolkit().getToolkit().newErrorPanel(theViewerRate);
348
349
350 theTable = new MoneyWiseMarketRatesTable(pView, theEditSet, theError);
351
352
353 final TethysUIFactory<?> myGuiFactory = pView.getGuiFactory();
354 theActionButtons = new PrometheusActionButtons(myGuiFactory, theEditSet);
355 theActionButtons.setVisible(false);
356
357
358 final TethysUIPaneFactory myPanes = myGuiFactory.paneFactory();
359 final TethysUIBorderPaneManager myHeader = myPanes.newBorderPane();
360 myHeader.setCentre(theTable.getSelect());
361 myHeader.setNorth(theError);
362 myHeader.setEast(theActionButtons);
363
364
365 thePanel = myPanes.newBorderPane();
366 thePanel.setNorth(myHeader);
367 thePanel.setCentre(theTable);
368
369
370 theError.getEventRegistrar().addEventListener(e -> handleErrorPane());
371 theActionButtons.getEventRegistrar().addEventListener(this::handleActionButtons);
372 theTable.getEventRegistrar().addEventListener(e -> notifyChanges());
373 }
374
375 @Override
376 public TethysUIComponent getUnderlying() {
377 return thePanel;
378 }
379
380 @Override
381 public void setEnabled(final boolean pEnabled) {
382 thePanel.setEnabled(pEnabled);
383 }
384
385 @Override
386 public void setVisible(final boolean pVisible) {
387 thePanel.setVisible(pVisible);
388 }
389
390 @Override
391 public OceanusEventRegistrar<PrometheusDataEvent> getEventRegistrar() {
392 return theEventManager.getEventRegistrar();
393 }
394
395
396
397
398 private void handleErrorPane() {
399
400 final boolean isError = theError.hasError();
401
402
403 theTable.getSelect().setVisible(!isError);
404
405
406 theTable.setEnabled(!isError);
407
408
409 theActionButtons.setEnabled(!isError);
410 }
411
412
413
414
415
416
417 private void handleActionButtons(final OceanusEvent<PrometheusUIEvent> pEvent) {
418
419 theTable.cancelEditing();
420
421
422 theEditSet.processCommand(pEvent.getEventId(), theError);
423
424
425 theTable.notifyChanges();
426 }
427
428
429
430
431 public void determineFocus() {
432
433 theTable.determineFocus();
434
435
436 theViewerRate.setFocus();
437 }
438
439
440
441
442 private void notifyChanges() {
443
444 final boolean hasUpdates = hasUpdates();
445
446
447 theActionButtons.setEnabled(true);
448 theActionButtons.setVisible(hasUpdates);
449
450
451 theEventManager.fireEvent(PrometheusDataEvent.ADJUSTVISIBILITY);
452 }
453
454
455
456
457
458
459 public boolean hasUpdates() {
460 return theTable.hasUpdates();
461 }
462
463
464
465
466
467
468 public boolean hasSession() {
469 return theTable.hasUpdates();
470 }
471
472
473
474
475
476
477 public boolean hasErrors() {
478 return theTable.hasErrors();
479 }
480 }
481 }
482