MoneyWiseItemPanel.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.base;
import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionValues;
import io.github.tonywasher.joceanus.metis.list.MetisListKey;
import io.github.tonywasher.joceanus.moneywise.atlas.views.MoneyWiseXAnalysisFilter;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetBase;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCategoryBase;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseRegion;
import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransTag;
import io.github.tonywasher.joceanus.moneywise.lethe.ui.controls.MoneyWiseAnalysisSelect.MoneyWiseStatementSelect;
import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter;
import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseGoToId;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInfoClass;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues.PrometheusInfoSetItem;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem;
import io.github.tonywasher.joceanus.prometheus.ui.PrometheusGoToEvent;
import io.github.tonywasher.joceanus.prometheus.ui.panel.PrometheusDataItemPanel;
import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
import io.github.tonywasher.joceanus.tethys.api.base.TethysUIGenericWrapper;
import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollSubMenu;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* MoneyWise Data Item Panel.
*
* @param <T> the item type
*/
public abstract class MoneyWiseItemPanel<T extends PrometheusDataItem>
extends PrometheusDataItemPanel<T, MoneyWiseGoToId> {
/**
* Filter text.
*/
private static final String FILTER_MENU = "Filter";
/**
* The Owning table.
*/
private final MoneyWiseBaseTable<T> theOwner;
/**
* The DataItem GoToMenuMap.
*/
private final List<PrometheusDataItem> theGoToItemList;
/**
* The Filter GoToMenuMap.
*/
private final List<MoneyWiseAnalysisFilter<?, ?>> theGoToFilterList;
/**
* Constructor.
*
* @param pFactory the GUI factory
* @param pEditSet the edit set
* @param pOwner the owning table
*/
protected MoneyWiseItemPanel(final TethysUIFactory<?> pFactory,
final PrometheusEditSet pEditSet,
final MoneyWiseBaseTable<T> pOwner) {
super(pFactory, pEditSet, pOwner.getErrorPanel());
theOwner = pOwner;
theGoToFilterList = new ArrayList<>();
theGoToItemList = new ArrayList<>();
getFieldSet().setChanged(this::isFieldChanged);
}
/**
* Obtain the owner.
*
* @return the owner
*/
protected MoneyWiseBaseTable<T> getOwner() {
return theOwner;
}
/**
* Set preferred Size.
*/
void setPreferredSize() {
/* we should take up a quarter if the standard panel dimensions */
final int[] mySize = getFactory().getProgramDefinitions().getPanelDimensions();
getFieldSet().setPreferredWidthAndHeight(mySize[0], mySize[1] >> 2);
}
/**
* is field changed?
*
* @param pField the field
* @param pItem the item
* @return true/false
*/
private boolean isFieldChanged(final T pItem,
final MetisDataFieldId pField) {
/* If the field is a dataInfoClass as part of an infoSetItem */
if (pField instanceof PrometheusDataInfoClass myClass
&& pItem instanceof PrometheusInfoSetItem myItem) {
/* Check with the infoSet whether the field has changed */
return myItem.getInfoSet().fieldChanged(myClass).isDifferent();
}
/* Look at the base values as a standard item */
final MetisFieldVersionValues myBaseValues = getBaseValues();
return pField != null
&& myBaseValues != null;
}
/**
* is Valid name?
*
* @param pNewName the new name
* @return error message or null
*/
public String isValidName(final String pNewName) {
return theOwner.isValidName(pNewName, getItem());
}
/**
* is Valid description?
*
* @param pNewDesc the new description
* @return error message or null
*/
public String isValidDesc(final String pNewDesc) {
return theOwner.isValidDesc(pNewDesc, getItem());
}
@Override
protected void buildGoToMenu(final TethysUIScrollMenu<TethysUIGenericWrapper> pMenu) {
/* Clear the goTo lists */
theGoToFilterList.clear();
theGoToItemList.clear();
/* Clear the menu */
pMenu.removeAllItems();
/* Declare the goTo items */
declareGoToItems(getEditSet().hasUpdates());
/* Process the goTo items */
processGoToItems(pMenu);
}
/**
* Declare GoTo Items.
*
* @param pUpdates are there active updates?
*/
protected abstract void declareGoToItems(boolean pUpdates);
/**
* Declare GoTo Item.
*
* @param pItem the item to declare
*/
protected void declareGoToItem(final PrometheusDataItem pItem) {
/* Ignore null items */
if (pItem == null) {
return;
}
/* Ignore if the item is already listed */
if (theGoToItemList.contains(pItem)) {
return;
}
/* remember the item */
theGoToItemList.add(pItem);
}
/**
* Declare GoTo Filter.
*
* @param pFilter the filter to declare
*/
protected void declareGoToFilter(final MoneyWiseAnalysisFilter<?, ?> pFilter) {
/* Ignore null filters */
if (pFilter == null) {
return;
}
/* Ignore if the item is already listed */
if (theGoToFilterList.contains(pFilter)) {
return;
}
/* remember the item */
theGoToFilterList.add(pFilter);
}
/**
* Declare GoTo Filter.
*
* @param pFilter the filter to declare
*/
protected void declareGoToFilter(final MoneyWiseXAnalysisFilter<?, ?> pFilter) {
/* TODO */
}
/**
* Process goTo items.
*
* @param pMenu the menu
*/
private void processGoToItems(final TethysUIScrollMenu<TethysUIGenericWrapper> pMenu) {
/* Process goTo filters */
processGoToFilters(pMenu);
/* Create a simple map for top-level categories */
final Map<MetisListKey, TethysUIScrollSubMenu<TethysUIGenericWrapper>> myMap = new HashMap<>();
/* Loop through the items */
for (PrometheusDataItem myItem : theGoToItemList) {
/* Determine DataType and obtain parent menu */
final MetisListKey myType = myItem.getItemType();
final TethysUIScrollSubMenu<TethysUIGenericWrapper> myMenu = myMap.computeIfAbsent(myType, t -> pMenu.addSubMenu(myType.getItemName()));
/* set default values */
MoneyWiseGoToId myId = null;
String myName = null;
/* Handle differing items */
if (myItem instanceof PrometheusStaticDataItem myStatic) {
myId = MoneyWiseGoToId.STATIC;
myName = myStatic.getName();
} else if (myItem instanceof MoneyWiseAssetBase myAccount) {
myId = MoneyWiseGoToId.ACCOUNT;
myName = myAccount.getName();
} else if (myItem instanceof MoneyWiseCategoryBase myCategory) {
myId = MoneyWiseGoToId.CATEGORY;
myName = myCategory.getName();
} else if (myItem instanceof MoneyWiseRegion myRegion) {
myId = MoneyWiseGoToId.REGION;
myName = myRegion.getName();
} else if (myItem instanceof MoneyWiseTransTag myTag) {
myId = MoneyWiseGoToId.TAG;
myName = myTag.getName();
}
/* Build the item */
final PrometheusGoToEvent<MoneyWiseGoToId> myEvent = createGoToEvent(myId, myItem);
myMenu.getSubMenu().addItem(new TethysUIGenericWrapper(myEvent), myName);
}
}
/**
* Process goTo filters.
*
* @param pMenu the menu
*/
private void processGoToFilters(final TethysUIScrollMenu<TethysUIGenericWrapper> pMenu) {
/* Create a simple map for top-level categories */
TethysUIScrollSubMenu<TethysUIGenericWrapper> myMenu = null;
/* Loop through the items */
for (MoneyWiseAnalysisFilter<?, ?> myFilter : theGoToFilterList) {
/* If this is a new menu */
if (myMenu == null) {
/* Create a new JMenu and add it to the popUp */
myMenu = pMenu.addSubMenu(FILTER_MENU);
}
/* Determine action */
final MoneyWiseStatementSelect myStatement = new MoneyWiseStatementSelect(null, myFilter);
final MoneyWiseGoToId myId = MoneyWiseGoToId.STATEMENT;
/* Build the item */
final PrometheusGoToEvent<MoneyWiseGoToId> myEvent = createGoToEvent(myId, myStatement);
myMenu.getSubMenu().addItem(new TethysUIGenericWrapper(myEvent), myFilter.getName());
}
}
}