MoneyWiseMainTab.java
/*
* MoneyWise: Finance Application
* Copyright 2012-2026. Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package io.github.tonywasher.joceanus.moneywise.ui.panel;
import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
import io.github.tonywasher.joceanus.oceanus.event.OceanusEvent;
import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
import io.github.tonywasher.joceanus.oceanus.profile.OceanusProfile;
import io.github.tonywasher.joceanus.metis.help.MetisHelpModule;
import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseIOException;
import io.github.tonywasher.joceanus.moneywise.help.MoneyWiseHelp;
import io.github.tonywasher.joceanus.moneywise.lethe.ui.controls.MoneyWiseAnalysisSelect.MoneyWiseStatementSelect;
import io.github.tonywasher.joceanus.moneywise.lethe.ui.panel.MoneyWiseReportTab;
import io.github.tonywasher.joceanus.moneywise.lethe.ui.panel.MoneyWiseTransactionTable.MoneyWiseStatementPanel;
import io.github.tonywasher.joceanus.moneywise.tax.uk.MoneyWiseUKTaxYearCache;
import io.github.tonywasher.joceanus.moneywise.threads.MoneyWiseThreadId;
import io.github.tonywasher.joceanus.moneywise.threads.MoneyWiseThreadLoadArchive;
import io.github.tonywasher.joceanus.moneywise.threads.MoneyWiseThreadWriteQIF;
import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseGoToId;
import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseUIResource;
import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseView;
import io.github.tonywasher.joceanus.prometheus.toolkit.PrometheusToolkit;
import io.github.tonywasher.joceanus.prometheus.ui.PrometheusGoToEvent;
import io.github.tonywasher.joceanus.prometheus.ui.panel.PrometheusMainWindow;
import io.github.tonywasher.joceanus.prometheus.views.PrometheusDataEvent;
import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
import io.github.tonywasher.joceanus.tethys.api.dialog.TethysUIAboutBox;
import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
import io.github.tonywasher.joceanus.tethys.api.factory.TethysUILogTextArea;
import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIMainPanel;
import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIMenuBarManager;
import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIMenuBarManager.TethysUIMenuSubMenu;
import io.github.tonywasher.joceanus.tethys.api.pane.TethysUITabPaneManager;
import io.github.tonywasher.joceanus.tethys.api.pane.TethysUITabPaneManager.TethysUITabItem;
/**
* Main Window for MoneyWise.
*/
public class MoneyWiseMainTab
extends PrometheusMainWindow
implements TethysUIMainPanel {
/**
* Report tab title.
*/
private static final String TITLE_REPORT = MoneyWiseUIResource.MAIN_REPORT.getValue();
/**
* Register tab title.
*/
private static final String TITLE_REGISTER = MoneyWiseUIResource.MAIN_REGISTER.getValue();
/**
* Market tab title.
*/
private static final String TITLE_MARKET = MoneyWiseUIResource.MAIN_MARKET.getValue();
/**
* Maintenance tab title.
*/
private static final String TITLE_MAINT = MoneyWiseUIResource.MAIN_MAINTENANCE.getValue();
/**
* The data view.
*/
private final MoneyWiseView theView;
/**
* The tabs.
*/
private TethysUITabPaneManager theTabs;
/**
* The register panel.
*/
private MoneyWiseStatementPanel theRegister;
/**
* The MarketPanel.
*/
private MoneyWiseMarketTabs theMarket;
/**
* The maintenance panel.
*/
private MoneyWiseMaintenance theMaint;
/**
* The aboutBox.
*/
private TethysUIAboutBox theAboutBox;
/**
* Constructor.
*
* @param pFactory the factory
* @throws OceanusException on error
*/
public MoneyWiseMainTab(final TethysUIFactory<?> pFactory) throws OceanusException {
/* Create prometheus toolkit */
final PrometheusToolkit myToolkit = new PrometheusToolkit(pFactory);
/* create the view */
theView = new MoneyWiseView(myToolkit, new MoneyWiseUKTaxYearCache());
/* Build the main window */
buildMainWindow(theView, myToolkit);
/* Initialise visibility */
setVisibility();
}
@Override
public MoneyWiseView getView() {
return theView;
}
@Override
protected MetisHelpModule getHelpModule() throws OceanusException {
try {
return new MoneyWiseHelp();
} catch (OceanusException e) {
throw new MoneyWiseIOException("Unable to load help", e);
}
}
@Override
protected TethysUIComponent buildMainPanel() throws OceanusException {
/* Obtain the active profile */
OceanusProfile myTask = theView.getActiveTask();
myTask = myTask.startTask("buildMain");
/* Create the Tabbed Pane */
final TethysUIFactory<?> myFactory = theView.getGuiFactory();
theTabs = myFactory.paneFactory().newTabPane();
/* Create the Report Tab */
myTask.startTask(TITLE_REPORT);
final MoneyWiseReportTab myReports = new MoneyWiseReportTab(theView);
theTabs.addTabItem(TITLE_REPORT, myReports);
/* Create the Register Tab */
myTask.startTask(TITLE_REGISTER);
theRegister = new MoneyWiseStatementPanel(theView);
theTabs.addTabItem(TITLE_REGISTER, theRegister);
/* Create the Market Tab */
myTask.startTask(TITLE_MARKET);
theMarket = new MoneyWiseMarketTabs(theView);
theTabs.addTabItem(TITLE_MARKET, theMarket);
/* Create the Maintenance Tab */
myTask.startTask(TITLE_MAINT);
theMaint = new MoneyWiseMaintenance(theView);
theTabs.addTabItem(TITLE_MAINT, theMaint);
/* Create the log tab */
final TethysUILogTextArea myLog = myFactory.getLogSink();
final TethysUITabItem myLogTab = theTabs.addTabItem(MoneyWiseUIResource.MAIN_LOG.getValue(), myLog);
myLog.getEventRegistrar().addEventListener(TethysUIEvent.NEWVALUE, e -> myLogTab.setVisible(true));
myLog.getEventRegistrar().addEventListener(TethysUIEvent.WINDOWCLOSED, e -> myLogTab.setVisible(false));
myLogTab.setVisible(myLog.isActive());
/* Create listeners */
theTabs.getEventRegistrar().addEventListener(e -> determineFocus());
theView.getEventRegistrar().addEventListener(e -> setVisibility());
myReports.getEventRegistrar().addEventListener(this::handleGoToEvent);
theMarket.getEventRegistrar().addEventListener(e -> setVisibility());
setChildListeners(theRegister.getEventRegistrar());
setChildListeners(theMaint.getEventRegistrar());
/* Create listener and initialise focus */
determineFocus();
/* Complete task */
myTask.end();
/* Return the panel */
return theTabs;
}
/**
* setChildListeners.
*
* @param pRegistrar the registrar
*/
private void setChildListeners(final OceanusEventRegistrar<PrometheusDataEvent> pRegistrar) {
pRegistrar.addEventListener(PrometheusDataEvent.ADJUSTVISIBILITY, e -> setVisibility());
pRegistrar.addEventListener(PrometheusDataEvent.GOTOWINDOW, this::handleGoToEvent);
}
/**
* Add Data Menu items.
*
* @param pMenu the menu
*/
@Override
protected void addDataMenuItems(final TethysUIMenuSubMenu pMenu) {
/* Create the data menu items */
pMenu.newMenuItem(MoneyWiseThreadId.LOADARCHIVE, e -> loadSpreadsheet());
pMenu.newMenuItem(MoneyWiseThreadId.CREATEQIF, e -> createQIF());
/* Pass call on */
super.addDataMenuItems(pMenu);
}
@Override
public final boolean hasUpdates() {
/* Determine whether we have edit session updates */
boolean hasUpdates = theRegister.hasUpdates();
if (!hasUpdates) {
hasUpdates = theMarket.hasUpdates();
}
if (!hasUpdates) {
hasUpdates = theMaint.hasUpdates();
}
return hasUpdates;
}
/**
* Has this set of panels got the session focus?
*
* @return true/false
*/
public final boolean hasSession() {
/* Determine whether we have edit session updates */
boolean hasSession = theRegister.hasSession();
if (!hasSession) {
hasSession = theMarket.hasSession();
}
if (!hasSession) {
hasSession = theMaint.hasSession();
}
return hasSession;
}
/**
* Load Spreadsheet.
*/
public void loadSpreadsheet() {
/* Create the worker thread */
final MoneyWiseThreadLoadArchive myThread = new MoneyWiseThreadLoadArchive(theView);
startThread(myThread);
}
/**
* Create QIF file.
*/
public void createQIF() {
/* Create the worker thread */
final MoneyWiseThreadWriteQIF myThread = new MoneyWiseThreadWriteQIF(theView);
startThread(myThread);
}
/**
* Select a Statement.
*
* @param pSelect the statement request
*/
private void selectStatement(final MoneyWiseStatementSelect pSelect) {
/* Pass through to the Register view */
theRegister.selectStatement(pSelect);
/* Goto the Register tab */
gotoNamedTab(TITLE_REGISTER);
}
/**
* Select maintenance.
*
* @param pEvent the action request
*/
private void selectMaintenance(final PrometheusGoToEvent<MoneyWiseGoToId> pEvent) {
/* Pass through to the Maintenance view */
theMaint.selectMaintenance(pEvent);
/* Goto the Maintenance tab */
gotoNamedTab(TITLE_MAINT);
}
/**
* Goto the specific tab.
*
* @param pTabName the tab name
*/
private void gotoNamedTab(final String pTabName) {
/* Look up item and select it */
final TethysUITabItem myItem = theTabs.findItemByName(pTabName);
if (myItem != null) {
myItem.selectItem();
}
}
@Override
public final void setVisibility() {
/* Sort out underlying visibility */
super.setVisibility();
/* Determine whether we have any session focus */
final boolean hasSession = hasSession();
/* Note whether we have a worker thread */
final boolean hasWorker = hasWorker();
/* Note whether we have data */
final boolean hasControl = theView.getData().getControl() != null;
/* Obtain the menuBar */
final TethysUIMenuBarManager myMenuBar = getMenuBar();
/* Disable menus if we have no data */
myMenuBar.setEnabled(MoneyWiseThreadId.CREATEQIF, !hasWorker && hasControl);
/* Enable/Disable the reports tab */
boolean doEnabled = !hasWorker && !hasSession;
theTabs.enableItemByName(TITLE_REPORT, doEnabled);
/* Enable/Disable the register tab */
doEnabled = !hasWorker && (!hasSession || theRegister.hasSession());
theTabs.enableItemByName(TITLE_REGISTER, doEnabled);
/* Enable/Disable/Hide the spotPrices tab */
doEnabled = !hasWorker && (!hasSession || theMarket.hasSession());
final TethysUITabItem myItem = theTabs.findItemByName(TITLE_MARKET);
myItem.setEnabled(doEnabled);
myItem.setVisible(theView.hasActiveSecurities() || theView.hasMultipleCurrencies());
/* Enable/Disable the maintenance tab */
doEnabled = !hasWorker && (!hasSession || theMaint.hasSession());
theTabs.enableItemByName(TITLE_MAINT, doEnabled);
/* Enable/Disable the tabs */
theTabs.setEnabled(!hasWorker);
/* If we have updates disable the load backup/database option */
myMenuBar.setEnabled(MoneyWiseThreadId.LOADARCHIVE, !hasSession);
}
/**
* Determine focus.
*/
private void determineFocus() {
/* Access the selected component */
final TethysUITabItem myItem = theTabs.getSelectedTab();
final Integer myId = myItem.getId();
/* If the selected component is Register */
if (myId.equals(theRegister.getId())) {
/* Determine focus of Register */
theRegister.determineFocus();
/* If the selected component is Market */
} else if (myId.equals(theMarket.getId())) {
/* Determine focus of Market */
theMarket.determineFocus();
/* If the selected component is Maintenance */
} else if (myId.equals(theMaint.getId())) {
/* Determine focus of maintenance */
theMaint.determineFocus();
}
}
@Override
protected void displayAbout() {
/* Create about box if it does not exist */
if (theAboutBox == null) {
theAboutBox = theView.getGuiFactory().dialogFactory().newAboutBox();
}
theAboutBox.showDialog();
}
/**
* handle GoTo Event.
*
* @param pEvent the event
*/
private void handleGoToEvent(final OceanusEvent<PrometheusDataEvent> pEvent) {
/* Access details */
@SuppressWarnings("unchecked") final PrometheusGoToEvent<MoneyWiseGoToId> myEvent = pEvent.getDetails(PrometheusGoToEvent.class);
/* Access event and obtain details */
switch (myEvent.getId()) {
/* View the requested statement */
case STATEMENT:
final MoneyWiseStatementSelect mySelect = myEvent.getDetails(MoneyWiseStatementSelect.class);
selectStatement(mySelect);
break;
/* Access maintenance */
case ACCOUNT:
case CATEGORY:
case REGION:
case TAG:
case STATIC:
selectMaintenance(myEvent);
break;
default:
break;
}
}
}