/*
* Copyright 2014 Red Hat, Inc. and/or its affiliates.
*
* 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 org.drools.workbench.screens.guided.dtree.client.widget.popups;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.Widget;
import org.drools.workbench.models.guided.dtree.shared.model.nodes.ActionRetractNode;
import org.drools.workbench.models.guided.dtree.shared.model.nodes.ActionUpdateNode;
import org.drools.workbench.models.guided.dtree.shared.model.nodes.Node;
import org.drools.workbench.models.guided.dtree.shared.model.nodes.TypeNode;
import org.drools.workbench.models.guided.dtree.shared.model.nodes.impl.TypeNodeImpl;
import org.drools.workbench.screens.guided.dtree.client.resources.i18n.GuidedDecisionTreeConstants;
import org.drools.workbench.screens.guided.dtree.client.widget.utils.BindingUtilities;
import org.gwtbootstrap3.client.ui.FormGroup;
import org.gwtbootstrap3.client.ui.HelpBlock;
import org.gwtbootstrap3.client.ui.Label;
import org.gwtbootstrap3.client.ui.constants.ValidationState;
import org.uberfire.ext.widgets.common.client.common.popups.BaseModal;
import org.uberfire.ext.widgets.common.client.common.popups.footers.ModalFooterOKCancelButtons;
public class EditTypePopup extends BaseModal {
interface EditTypeBinder
extends
UiBinder<Widget, EditTypePopup> {
}
private static EditTypeBinder uiBinder = GWT.create( EditTypeBinder.class );
private final TypeNode node;
private final TypeNode clone;
private final Command callback;
private final Command okCommand = new Command() {
@Override
public void execute() {
onOKButtonClick();
}
};
private final Command cancelCommand = new Command() {
@Override
public void execute() {
hide();
}
};
private final ModalFooterOKCancelButtons footer = new ModalFooterOKCancelButtons( okCommand,
cancelCommand );
@UiField
Label classNameLabel;
@UiField
FormGroup bindingGroup;
@UiField
HelpBlock bindingHelpInline;
@UiField
BindingTextBox bindingTextBox;
/**
* Edit the given TypeNode. A clone is taken whilst editing is in progress to preserve the state
* of the original node should editing be cancelled by the User. Bindings are checked to be unique
* in the path from this node being edited to the tree's root. When the User commits the changes
* the provided callback is executed and this popup closed.
* @param node The node to edit
* @param callback Callback to execute when the User commits changes
*/
public EditTypePopup( final TypeNode node,
final Command callback ) {
setTitle( GuidedDecisionTreeConstants.INSTANCE.popupTitleEditType() );
setBody( uiBinder.createAndBindUi( this ) );
add( footer );
bindingTextBox.addKeyPressHandler( new KeyPressHandler() {
@Override
public void onKeyPress( final KeyPressEvent event ) {
bindingGroup.setValidationState( ValidationState.NONE );
bindingHelpInline.setText( "" );
}
} );
bindingTextBox.addBlurHandler( new BlurHandler() {
@Override
public void onBlur( final BlurEvent event ) {
clone.setBinding( bindingTextBox.getText() );
}
} );
this.node = node;
this.clone = cloneNode( node );
this.callback = callback;
this.classNameLabel.setText( clone.getClassName() );
this.bindingTextBox.setText( clone.getBinding() );
}
//Clone node whilst editing to preserve original node should User cancel the edit
private TypeNode cloneNode( final TypeNode node ) {
final TypeNode clone = new TypeNodeImpl( node.getClassName() );
clone.setParent( node.getParent() );
clone.setBinding( node.getBinding() );
return clone;
}
private void onOKButtonClick() {
boolean hasError = false;
final String binding = clone.getBinding();
if ( !( binding == null || binding.isEmpty() ) ) {
if ( !BindingUtilities.isUniqueInPath( binding,
clone ) ) {
bindingGroup.setValidationState( ValidationState.ERROR );
bindingHelpInline.setText( GuidedDecisionTreeConstants.INSTANCE.bindingIsNotUnique() );
hasError = true;
}
} else if ( hasBoundChildren( node ) ) {
bindingGroup.setValidationState( ValidationState.ERROR );
bindingHelpInline.setText( GuidedDecisionTreeConstants.INSTANCE.bindingIsUsed() );
hasError = true;
} else {
bindingGroup.setValidationState( ValidationState.NONE );
}
if ( hasError ) {
return;
}
//Copy changes into the original node
node.setBinding( clone.getBinding() );
if ( callback != null ) {
callback.execute();
}
hide();
}
private boolean hasBoundChildren( final Node node ) {
for ( Node n : node.getChildren() ) {
if ( n instanceof ActionRetractNode ) {
final ActionRetractNode arn = (ActionRetractNode) n;
if ( arn.getBoundNode().equals( node ) ) {
return true;
}
} else if ( n instanceof ActionUpdateNode ) {
final ActionUpdateNode aun = (ActionUpdateNode) n;
if ( aun.getBoundNode().equals( node ) ) {
return true;
}
}
if ( hasBoundChildren( n ) ) {
return true;
}
}
return false;
}
}