use of io.jmix.core.common.datastruct.Node in project jmix by jmix-framework.
the class FilterEditor method init.
@Override
public void init(Map<String, Object> params) {
super.init(params);
if (Boolean.TRUE.equals(useShortConditionForm)) {
setCaption(messages.getMessage("filter.editor.captionShortForm"));
}
getDialogOptions().setWidth(theme.get("cuba.gui.filterEditor.dialog.width")).setHeight(theme.get("cuba.gui.filterEditor.dialog.height")).setResizable(true);
filterEntity = (FilterEntity) params.get("filterEntity");
if (filterEntity == null) {
throw new RuntimeException("Filter entity was not passed to filter editor");
}
filter = (Filter) params.get("filter");
ConditionsTree paramConditions = (ConditionsTree) params.get("conditionsTree");
conditions = paramConditions.createCopy();
refreshConditionsDs();
conditionsTree.expandTree();
MetaProperty property = metadata.getClassNN(FilterEntity.class).getProperty("name");
Map<String, Object> annotations = property.getAnnotations();
Integer maxLength = (Integer) annotations.get("length");
if (maxLength != null) {
filterName.setMaxLength(maxLength);
}
if (!messages.getMessage("filter.adHocFilter").equals(filterEntity.getName())) {
filterName.setValue(filterEntity.getName());
}
availableForAllCb.setValue(filterEntity.getUsername() == null);
defaultCb.setValue(filterEntity.getIsDefault());
applyDefaultCb.setValue(filterEntity.getApplyDefault());
globalDefaultCb.setValue(filterEntity.getGlobalDefault());
if (filterEntity.getUsername() != null) {
globalDefaultCb.setEnabled(false);
}
if (!security.isSpecificPermitted(GLOBAL_FILTER_PERMISSION)) {
availableForAllCb.setVisible(false);
availableForAllLabel.setVisible(false);
globalDefaultCb.setVisible(false);
globalDefaultLabel.setVisible(false);
}
availableForAllCb.addValueChangeListener(e -> {
Boolean isFilterAvailableForAll = e.getValue();
globalDefaultCb.setEnabled(isFilterAvailableForAll);
if (!isFilterAvailableForAll) {
globalDefaultCb.setValue(null);
}
});
boolean manualApplyRequired = filter.getManualApplyRequired() != null ? filter.getManualApplyRequired() : AppBeans.get(CubaProperties.class).isGenericFilterManualApplyRequired();
if (!manualApplyRequired) {
applyDefaultCb.setVisible(manualApplyRequired);
applyDefaultLabel.setVisible(manualApplyRequired);
}
if (!(filter.getFrame().getFrameOwner() instanceof LegacyFrame)) {
ScreenSettingsFacet settingsFacet = UiControllerUtils.getFacet(filter.getFrame(), ScreenSettingsFacet.class);
if (settingsFacet == null) {
defaultCb.setVisible(false);
defaultLabel.setVisible(false);
}
}
if (filterEntity.getFolder() != null) {
availableForAllCb.setVisible(false);
availableForAllLabel.setVisible(false);
globalDefaultCb.setVisible(false);
globalDefaultLabel.setVisible(false);
defaultCb.setVisible(false);
defaultLabel.setVisible(false);
}
conditionsDs.addItemChangeListener(e -> {
if (!treeItemChangeListenerEnabled) {
return;
}
// commit previously selected condition
if (activeConditionFrame != null) {
List<Validatable> validatables = new ArrayList<>();
Collection<Component> frameComponents = ComponentsHelper.getComponents(activeConditionFrame);
for (Component frameComponent : frameComponents) {
if (frameComponent instanceof Validatable) {
validatables.add((Validatable) frameComponent);
}
}
if (validate(validatables)) {
activeConditionFrame.commit();
} else {
treeItemChangeListenerEnabled = false;
conditionsTree.setSelected(e.getPrevItem());
treeItemChangeListenerEnabled = true;
return;
}
}
if (e.getItem() == null) {
activeConditionFrame = null;
} else {
if (e.getItem() instanceof PropertyCondition) {
activeConditionFrame = propertyConditionFrame;
} else if (e.getItem() instanceof DynamicAttributesCondition) {
activeConditionFrame = dynamicAttributesConditionFrame;
} else if (e.getItem() instanceof CustomCondition) {
activeConditionFrame = customConditionFrame;
} else if (e.getItem() instanceof GroupCondition) {
activeConditionFrame = groupConditionFrame;
} else if (e.getItem() instanceof FtsCondition) {
activeConditionFrame = ftsConditionFrame;
} else {
log.warn("Conditions frame for condition with type " + e.getItem().getClass().getSimpleName() + " not found");
}
}
propertyConditionFrame.setVisible(false);
customConditionFrame.setVisible(false);
dynamicAttributesConditionFrame.setVisible(false);
groupConditionFrame.setVisible(false);
ftsConditionFrame.setVisible(false);
if (activeConditionFrame != null) {
activeConditionFrame.setVisible(true);
activeConditionFrame.setCondition(e.getItem());
if (Boolean.TRUE.equals(useShortConditionForm)) {
for (String componentName : componentsToHideInShortForm) {
Component component = activeConditionFrame.getComponent(componentName);
if (component != null) {
if (BooleanUtils.isTrue(showConditionHiddenOption) && componentsForHiddenOption.contains(componentName)) {
continue;
}
component.setVisible(false);
}
}
}
}
});
addConditionHelper = new AddConditionHelper(filter, BooleanUtils.isTrue(hideDynamicAttributes), BooleanUtils.isTrue(hideCustomConditions), condition -> {
AbstractCondition item = conditionsDs.getItem();
if (item != null && item instanceof GroupCondition) {
Node<AbstractCondition> newNode = new Node<>(condition);
Node<AbstractCondition> selectedNode = conditions.getNode(item);
selectedNode.addChild(newNode);
refreshConditionsDs();
conditionsTree.expand(item);
} else {
conditions.getRootNodes().add(new Node<>(condition));
refreshConditionsDs();
}
conditionsTree.setSelected(condition);
});
FilterHelper filterHelper = AppBeans.get(FilterHelper.class);
filterHelper.initConditionsDragAndDrop(conditionsTree, conditions);
if (Boolean.TRUE.equals(useShortConditionForm)) {
filterPropertiesGrid.setVisible(false);
}
}
use of io.jmix.core.common.datastruct.Node in project jmix by jmix-framework.
the class FilterEditor method addGroup.
protected void addGroup(GroupType groupType) {
GroupConditionDescriptor conditionDescriptor = new GroupConditionDescriptor(groupType, filter.getId(), ((FilterImplementation) filter).getEntityMetaClass(), ((FilterImplementation) filter).getEntityAlias());
AbstractCondition condition = conditionDescriptor.createCondition();
AbstractCondition selectedCondition = conditionsDs.getItem();
Node<AbstractCondition> newNode = new Node<>(condition);
if (selectedCondition != null && selectedCondition instanceof GroupCondition) {
Node<AbstractCondition> node = conditions.getNode(selectedCondition);
if (node != null) {
node.addChild(newNode);
// refresh ds before expand, because it tries to get id from ds
refreshConditionsDs();
conditionsTree.expand(selectedCondition);
}
} else {
conditions.getRootNodes().add(newNode);
refreshConditionsDs();
}
conditionsTree.setSelected(condition);
}
use of io.jmix.core.common.datastruct.Node in project jmix by jmix-framework.
the class FilterDelegateImpl method recursivelyCreateConditionsLayout.
protected void recursivelyCreateConditionsLayout(ConditionsFocusType conditionsFocusType, boolean initialFocusSet, List<Node<AbstractCondition>> nodes, ComponentContainer parentContainer, int level) {
FilterDataContext filterDataContext = new FilterDataContext(filter.getFrame());
List<Node<AbstractCondition>> visibleConditionNodes = fetchVisibleNodes(nodes);
if (visibleConditionNodes.isEmpty()) {
if (level == 0)
controlsLayout.setStyleName("filter-control-no-border");
return;
}
// note that this is not grid columns count, but number of conditions (label cell + value cell) in one row
int conditionsCount = getColumnsCount();
int row = 0;
int nextColumnStart = 0;
GridLayout grid = uiComponents.create(GridLayout.class);
grid.setStyleName("conditions-grid");
grid.setColumns(conditionsCount * 2);
// set expand ratio only for cells with param edit components
for (int i = 0; i < conditionsCount; i++) {
grid.setColumnExpandRatio(i * 2 + 1, 1);
}
grid.setRows(1);
grid.setSpacing(true);
grid.setWidth("100%");
ParamEditor firstParamEditor = null;
ParamEditor lastParamEditor = null;
boolean currentFocusSet = initialFocusSet;
RuntimeException entityParamInformationException = null;
for (int i = 0; i < visibleConditionNodes.size(); i++) {
Node<AbstractCondition> node = visibleConditionNodes.get(i);
final AbstractCondition condition = node.getData();
BoxLayout labelAndOperationCellContent = null;
Component paramEditComponentCellContent = null;
Component groupCellContent = null;
if (condition.isGroup()) {
groupCellContent = createGroupConditionBox(condition, node, conditionsFocusType, currentFocusSet, level);
level++;
} else {
if (condition.getParam().getJavaClass() != null) {
Pair<ParamEditor, RuntimeException> pair = createParamEditorWithChecks(condition, filterDataContext);
ParamEditor paramEditor = pair.getFirst();
addParamEditor(condition, paramEditor);
if (pair.getSecond() != null) {
entityParamInformationException = pair.getSecond();
}
if (firstParamEditor == null)
firstParamEditor = paramEditor;
lastParamEditor = paramEditor;
currentFocusSet = true;
labelAndOperationCellContent = paramEditor.getLabelAndOperationLayout();
paramEditComponentCellContent = paramEditor.getParamEditComponentLayout();
} else {
BoxLayout paramLayout = uiComponents.create(HBoxLayout.class);
paramLayout.setSpacing(true);
paramLayout.setMargin(false);
labelAndOperationCellContent = paramLayout;
}
}
// groupBox for group conditions must occupy the whole line in conditions grid
Integer conditionWidth = condition.isGroup() ? (Integer) conditionsCount : condition.getWidth();
int nextColumnEnd = nextColumnStart + conditionWidth - 1;
if (nextColumnEnd >= conditionsCount) {
// complete current row in grid with gaps if next cell will be on next row
completeGridRowWithGaps(grid, row, nextColumnStart, false);
// place cell to next row in grid
nextColumnStart = 0;
nextColumnEnd = conditionWidth - 1;
row++;
grid.setRows(row + 1);
}
if (groupCellContent != null) {
grid.add(groupCellContent, nextColumnStart * 2, row, nextColumnEnd * 2 + 1, row);
}
if (labelAndOperationCellContent != null) {
labelAndOperationCellContent.addStyleName("param-label-layout");
grid.add(labelAndOperationCellContent, nextColumnStart * 2, row, nextColumnStart * 2, row);
if (nextColumnStart != 0)
labelAndOperationCellContent.setMargin(false, false, false, true);
}
if (paramEditComponentCellContent != null) {
paramEditComponentCellContent.addStyleName("param-field-layout");
if (condition.getParam().getType() == Param.Type.UNARY) {
paramEditComponentCellContent.addStyleName("unary-param-type");
}
grid.add(paramEditComponentCellContent, nextColumnStart * 2 + 1, row, nextColumnEnd * 2 + 1, row);
}
nextColumnStart = nextColumnEnd + 1;
// add next row if necessary
if (i < visibleConditionNodes.size() - 1) {
if (nextColumnStart >= conditionsCount) {
nextColumnStart = 0;
row++;
grid.setRows(row + 1);
}
}
}
filterDataContext.loadAll();
if (!initialFocusSet) {
switch(conditionsFocusType) {
case FIRST:
if (firstParamEditor != null) {
paramEditComponentToFocus = firstParamEditor;
}
break;
case LAST:
if (lastParamEditor != null) {
paramEditComponentToFocus = lastParamEditor;
}
break;
default:
// no action
break;
}
}
// complete last row in grid with gaps
completeGridRowWithGaps(grid, row, nextColumnStart, true);
if (parentContainer != null) {
parentContainer.add(grid);
}
if (level == 0)
controlsLayout.setStyleName(getControlsLayoutStyleName());
if (entityParamInformationException != null) {
getDialogs().createExceptionDialog().withThrowable(entityParamInformationException).show();
}
}
use of io.jmix.core.common.datastruct.Node in project jmix by jmix-framework.
the class FilterDelegateImpl method fillConditionsLayout.
/**
* Removes all components from conditionsLayout and fills it with components for editing filter conditions
*
* @param conditionsFocusType where to set focus (first condition, last condition, no focus)
*/
protected void fillConditionsLayout(ConditionsFocusType conditionsFocusType) {
for (Component component : conditionsLayout.getComponents()) {
conditionsLayout.remove(component);
}
paramEditComponentToFocus = null;
clearParamValueChangeSubscriptions();
clearParamEditors();
recursivelyCreateConditionsLayout(conditionsFocusType, false, conditions.getRootNodes(), conditionsLayout, 0);
if (isApplyImmediately()) {
List<Node<AbstractCondition>> nodes = conditions.getRootNodes();
subscribeToParamValueChangeEventRecursively(nodes);
}
conditionsLayout.setVisible(!conditionsLayout.getComponents().isEmpty());
}
use of io.jmix.core.common.datastruct.Node in project jmix by jmix-framework.
the class ConditionDescriptorsTreeBuilder method build.
@Override
public Tree<AbstractConditionDescriptor> build() {
Messages messages = AppBeans.get(Messages.class);
Class<? extends FrameOwner> controllerClass = filter.getFrame().getFrameOwner().getClass();
// todo rework
String messagesPack = UiControllerUtils.getPackage(controllerClass);
Tree<AbstractConditionDescriptor> tree = new Tree<>();
List<AbstractConditionDescriptor> propertyDescriptors = new ArrayList<>();
List<AbstractConditionDescriptor> customDescriptors = new ArrayList<>();
boolean propertiesExplicitlyDefined = false;
if (((HasXmlDescriptor) filter).getXmlDescriptor() != null) {
for (Element element : ((HasXmlDescriptor) filter).getXmlDescriptor().elements()) {
AbstractConditionDescriptor conditionDescriptor;
if ("properties".equals(element.getName())) {
addMultiplePropertyDescriptors(element, propertyDescriptors, filter);
propertiesExplicitlyDefined = true;
} else if ("property".equals(element.getName())) {
if (isKeyValueMetaClass) {
conditionDescriptor = createConditionDescriptorForKeyValueMetaProperty(messagesPack, element.attributeValue("name"), element.attributeValue("caption"));
if (conditionDescriptor != null) {
propertyDescriptors.add(conditionDescriptor);
}
} else {
conditionDescriptor = new PropertyConditionDescriptor(element, messagesPack, filterComponentName, entityMetaClass, entityAlias);
propertyDescriptors.add(conditionDescriptor);
}
propertiesExplicitlyDefined = true;
} else if ("custom".equals(element.getName())) {
conditionDescriptor = new CustomConditionDescriptor(element, messagesPack, filterComponentName, entityMetaClass, entityAlias);
customDescriptors.add(conditionDescriptor);
propertiesExplicitlyDefined = true;
} else {
throw new UnsupportedOperationException("Element not supported: " + element.getName());
}
}
}
if (!propertiesExplicitlyDefined) {
addMultiplePropertyDescriptors(".*", "", propertyDescriptors, filter);
}
propertyDescriptors.sort(new ConditionDescriptorComparator());
customDescriptors.sort(new ConditionDescriptorComparator());
HeaderConditionDescriptor propertyHeaderDescriptor = new HeaderConditionDescriptor("propertyConditions", messages.getMainMessage("filter.addCondition.propertyConditions"), filterComponentName, entityMetaClass, entityAlias);
HeaderConditionDescriptor customHeaderDescriptor = new HeaderConditionDescriptor("customConditions", messages.getMainMessage("filter.addCondition.customConditions"), filterComponentName, entityMetaClass, entityAlias);
Node<AbstractConditionDescriptor> propertyHeaderNode = new Node<>(propertyHeaderDescriptor);
Node<AbstractConditionDescriptor> customHeaderNode = new Node<>(customHeaderDescriptor);
int currentDepth = 0;
for (AbstractConditionDescriptor propertyDescriptor : propertyDescriptors) {
MetaClass propertyDsMetaClass = propertyDescriptor.getDatasourceMetaClass();
MetaPropertyPath propertyPath = propertyDsMetaClass.getPropertyPath(propertyDescriptor.getName());
if (propertyPath == null) {
log.error("Property path for {} of metaClass {} not found", propertyDescriptor.getName(), propertyDsMetaClass.getName());
continue;
}
MetaProperty metaProperty = propertyPath.getMetaProperty();
MetaClass propertyEnclosingMetaClass = metadataTools.getPropertyEnclosingMetaClass(propertyPath);
if (isPropertyAllowed(propertyEnclosingMetaClass, metaProperty) && !excludedProperties.contains(metaProperty.getName()) && (filter.getPropertiesFilterPredicate() == null || filter.getPropertiesFilterPredicate().test(propertyPath))) {
Node<AbstractConditionDescriptor> node = new Node<>(propertyDescriptor);
propertyHeaderNode.addChild(node);
if (currentDepth < hierarchyDepth) {
recursivelyFillPropertyDescriptors(node, currentDepth);
}
}
}
for (AbstractConditionDescriptor customDescriptor : customDescriptors) {
Node<AbstractConditionDescriptor> node = new Node<>(customDescriptor);
customHeaderNode.addChild(node);
}
List<Node<AbstractConditionDescriptor>> rootNodes = new ArrayList<>();
rootNodes.add(propertyHeaderNode);
if (!customDescriptors.isEmpty())
rootNodes.add(customHeaderNode);
if (!hideCustomConditions && security.isSpecificPermitted(CUSTOM_CONDITIONS_PERMISSION)) {
rootNodes.add(new Node<>(new CustomConditionCreator(filterComponentName, ((FilterImplementation) filter).getEntityMetaClass(), entityAlias)));
}
// todo dynamic attributes
/*if (!hideDynamicAttributes && !dynamicAttributes.getAttributesForMetaClass(entityMetaClass).isEmpty()) {
rootNodes.add(new Node<>(new DynamicAttributesConditionCreator(filterComponentName, entityMetaClass, "", entityAlias)));
}*/
/*if (FtsConfigHelper.getEnabled()) { todo fts
rootNodes.add(new Node<>(new FtsConditionDescriptor(filterComponentName, entityMetaClass, entityAlias)));
}*/
tree.setRootNodes(rootNodes);
return tree;
}
Aggregations