package org.openhab.habclient.rule; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; import android.widget.SpinnerAdapter; import android.widget.TextView; import org.openhab.domain.IOpenHABWidgetProvider; import org.openhab.domain.IUnitEntityDataTypeProvider; import org.openhab.domain.model.OpenHABWidget; import org.openhab.domain.model.OpenHABWidgetTypeSet; import org.openhab.domain.rule.EntityDataTypeSource; import org.openhab.domain.rule.IEntityDataType; import org.openhab.domain.rule.IRuleOperationBuildListener; import org.openhab.domain.rule.IRuleProvider; import org.openhab.domain.rule.RuleOperation; import org.openhab.domain.rule.UnitEntityDataType; import org.openhab.domain.rule.operators.RuleOperator; import org.openhab.habclient.HABApplication; import org.openhab.habclient.dagger.DaggerRuleOperandComponent; import org.openhab.habdroid.R; import java.util.Map; import javax.inject.Inject; /** * Created by Tony Alpskog in 2014. */ public class RuleOperandDialogFragment extends DialogFragment implements DialogInterface.OnClickListener, IRuleOperationBuildListener { private static final String ARG_ID = "operand"; // protected static final String ARG_DIALOG_TITLE = "dialogTitle"; protected static final String ARG_POSITION = "mPosition"; protected static final String ARG_SHOW_NEXT_BUTTON = "showNextButton"; private Button mButtonUnit; private TextView mTextUnit; private Button mButtonOperation; private TextView mTextOperation; private TextView mTextLabelStaticValue; private TextView mTextLabelOperation; private EditText mEditNewOperation; private Spinner mSpinnerValue; private SpinnerAdapter mSpinnerAdapter; private EditText mEditStaticValue; private boolean mShowNextButton; private OpenHABWidget mFirstOperandWidgetIfAny; private IEntityDataType mLeftSideOperand; private IRuleOperationBuildListener mListener; private IEntityDataType mOldOperand; private int mPosition;//The operand order number. The leftmost = first = 0 @Inject IOpenHABWidgetProvider mWidgetProvider; @Inject IUnitEntityDataTypeProvider mUnitEntityDataTypeProvider; @Inject IAdapterProvider mAdapterProvider; @Inject IRuleProvider mRuleProvider; public static RuleOperandDialogFragment newInstance(int position, boolean showNextButton) { final RuleOperandDialogFragment fragment = new RuleOperandDialogFragment(); final Bundle args = new Bundle(); // args.putString(ARG_DIALOG_TITLE, dialogTitle); args.putInt(ARG_POSITION, position); args.putBoolean(ARG_SHOW_NEXT_BUTTON, showNextButton); fragment.setArguments(args); return fragment; } @Override public void onAttach(Activity activity) { super.onAttach(activity); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DaggerRuleOperandComponent.builder() .appComponent(((HABApplication)getActivity().getApplication()).appComponent()) .build() .inject(this); final Bundle args = getArguments(); if(args == null) return; mPosition = args.getInt(ARG_POSITION); mShowNextButton = args.getBoolean(ARG_SHOW_NEXT_BUTTON); Activity activity = getActivity(); if(activity == null) throw new IllegalArgumentException("activity is null"); mListener = ((RuleEditActivity)activity).getRuleOperationBuildListener(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); return super.onCreateView(inflater, container, savedInstanceState); } private View createCustomView(Context context) { LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.fragment_rule_select_operand, null); if(view != null) { mButtonUnit = (Button) view.findViewById(R.id.button_rule_operation_builder_unit); mTextUnit = (TextView) view.findViewById(R.id.text_rule_operation_builder_unit); mButtonOperation = (Button) view.findViewById(R.id.button_rule_operation_builder_operation); mTextLabelOperation = (TextView) view.findViewById(R.id.text_rule_operation_builder_operation_label); mTextOperation = (TextView) view.findViewById(R.id.text_rule_operation_builder_operation); mEditNewOperation = (EditText) view.findViewById(R.id.edit_rule_operation_builder_new_operation); mTextLabelStaticValue = (TextView) view.findViewById(R.id.text_rule_operation_builder_static_value_label); mSpinnerValue = (Spinner) view.findViewById(R.id.spinner_rule_operation_builder_static_value); mEditStaticValue = (EditText) view.findViewById(R.id.edit_rule_operation_builder_static_value); final IRuleOperationBuildListener localListener = this; mButtonUnit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((RuleEditActivity)getActivity()).setRuleOperationBuildListener(localListener); final UnitOperandSelectionDialogFragment dialogFragment = UnitOperandSelectionDialogFragment.newInstance(mWidgetProvider.getItemNameListByWidgetType(OpenHABWidgetTypeSet.UnitItem) , mButtonUnit.getText().toString(), mPosition, mShowNextButton); dialogFragment.show(getFragmentManager(), "String_Selection_Dialog_Tag"); } }); mButtonOperation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((RuleEditActivity)getActivity()).setRuleOperationBuildListener(localListener); final OperationOperandSelectionDialogFragment dialogFragment = OperationOperandSelectionDialogFragment.newInstance(mRuleProvider.getUserRules(RuleListActivity.TemporaryHardCodedUserId) , mButtonUnit.getText().toString(), mPosition, mShowNextButton); dialogFragment.show(getFragmentManager(), "String_Selection_Dialog_Tag"); } }); } Map<String, ?> staticValuesCompatibleWithFirstOperand = null; boolean enableStaticValueSpinner = false; if(mPosition > 0) {//Try to enable views for static value input if this isn“t the first operand. try { mLeftSideOperand = ((RuleEditActivity) getActivity()).getOperationToEdit().getOperand(0); if(mLeftSideOperand.getSourceType() == EntityDataTypeSource.OPERATION) { staticValuesCompatibleWithFirstOperand = RuleOperation.getStaticEntityDataType(null).getStaticValues(); mSpinnerAdapter = mAdapterProvider.getStaticOperationValueAdapter(getActivity(), true); } else { mFirstOperandWidgetIfAny = mWidgetProvider.getWidgetByItemName(mLeftSideOperand.getDataSourceId()); staticValuesCompatibleWithFirstOperand = mUnitEntityDataTypeProvider.getUnitEntityDataType(mFirstOperandWidgetIfAny).getStaticValues(); mSpinnerAdapter = mAdapterProvider.getStaticUnitValueAdapter(getActivity(), mFirstOperandWidgetIfAny); } } catch (Exception e) {}; enableStaticValueSpinner = staticValuesCompatibleWithFirstOperand != null && staticValuesCompatibleWithFirstOperand.size() > 0; mSpinnerValue.setAdapter(mSpinnerAdapter); mEditStaticValue.setVisibility(enableStaticValueSpinner ? View.GONE : View.VISIBLE); mSpinnerValue.setVisibility(enableStaticValueSpinner ? View.VISIBLE : View.GONE); mTextLabelStaticValue.setVisibility(View.VISIBLE); //Set operation selection visibility int operationVisibility = mLeftSideOperand == null || mLeftSideOperand.getSourceType() == EntityDataTypeSource.OPERATION? View.VISIBLE : View.GONE; mTextLabelOperation.setVisibility(operationVisibility); mButtonOperation.setVisibility(operationVisibility); mTextOperation.setVisibility(operationVisibility); mEditNewOperation.setVisibility(operationVisibility); int unitVisibility = mLeftSideOperand == null || mLeftSideOperand.getSourceType() != EntityDataTypeSource.OPERATION? View.VISIBLE : View.GONE; mButtonUnit.setVisibility(unitVisibility); mTextUnit.setVisibility(unitVisibility); } else { mButtonUnit.setVisibility(View.VISIBLE); mTextUnit.setVisibility(View.VISIBLE); mTextLabelStaticValue.setVisibility(View.GONE); mEditStaticValue.setVisibility(View.GONE); mSpinnerValue.setVisibility(View.GONE); //Set operation selection visibility mTextLabelOperation.setVisibility(View.VISIBLE); mButtonOperation.setVisibility(View.VISIBLE); mTextOperation.setVisibility(View.VISIBLE); mEditNewOperation.setVisibility(View.VISIBLE); } mOldOperand = ((RuleEditActivity)getActivity()).getOperandToEdit(); if(mOldOperand != null) { switch (mOldOperand.getSourceType()) { case UNIT: mTextUnit.setText(mOldOperand.toString()); break; case OPERATION: mTextOperation.setText(mOldOperand.toString()); break; case STATIC: if(mSpinnerValue.getVisibility() == View.VISIBLE) { //Set current value (if any) in spinner if(mOldOperand.getValue() != null) for(int i = 1 ; i < mSpinnerAdapter.getCount(); i++) if(mSpinnerAdapter.getItem(i).equals(mOldOperand.getValue())){ mSpinnerValue.setSelection(i); continue; } } else mEditStaticValue.setText(mOldOperand.toString()); break; } } mSpinnerValue.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { } @Override public void onNothingSelected(AdapterView<?> parent) { } }); return view; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Activity activity = getActivity(); if(activity == null) throw new IllegalStateException("activity is null"); if(mShowNextButton) return new AlertDialog.Builder(activity).setTitle("Select " + (mPosition == 0 ? "left" : "right") + " side operand") .setView(createCustomView(activity)) .setPositiveButton(activity.getString(R.string.choice_next), this) .setNegativeButton(activity.getString(R.string.choice_cancel), this) .setNeutralButton(activity.getString(R.string.choice_done), this) .create(); return new AlertDialog.Builder(activity).setTitle("Select " + (mPosition == 0 ? "left" : "right") + " side operand") .setView(createCustomView(activity)) .setNegativeButton(activity.getString(R.string.choice_cancel), this) .setNeutralButton(activity.getString(R.string.choice_done), this) .create(); } @Override public void onClick(DialogInterface dialog, int which) { if(mListener != null) { switch (which) { case DialogInterface.BUTTON_NEUTRAL: //Done case DialogInterface.BUTTON_POSITIVE://Next //This code shall handle new/edited/unchanged values for EntityDataTypeSource.STATIC and EntityDataTypeSource.OPERATION selection //AND unchanged EntityDataTypeSource.UNIT values. IRuleOperationBuildListener.RuleOperationSelectionInterface resultingSelectionType; IEntityDataType operand = mFirstOperandWidgetIfAny != null ? mUnitEntityDataTypeProvider.getStaticEntityDataType(mFirstOperandWidgetIfAny, null) : null; if (mEditNewOperation.getText().length() > 0) { //User selected a new RuleOperation as an operand. operand = new RuleOperation(mEditNewOperation.getText().toString()); resultingSelectionType = IRuleOperationBuildListener.RuleOperationSelectionInterface.NEW_OPERATION; } else if (mEditStaticValue.getVisibility() == View.VISIBLE && mEditStaticValue.getText().length() > 0) { //The operand is a static text vale entered by the user. ((UnitEntityDataType) operand).setValue(operand.valueOf(mEditStaticValue.getText().toString()), false); resultingSelectionType = IRuleOperationBuildListener.RuleOperationSelectionInterface.STATIC; } else if (mSpinnerValue.getSelectedItemPosition() > 0) { //Spinner selection if (mLeftSideOperand != null && mLeftSideOperand.getSourceType() == EntityDataTypeSource.OPERATION) {//TODO - TA: Fix this shit. //The user has selected a static operation result (true or false). Map<String, ?> staticValuesCompatibleWithFirstOperand = RuleOperation.getStaticEntityDataType(null).getStaticValues(); operand = RuleOperation.getStaticEntityDataType(mSpinnerValue.getSelectedItemPosition() > 0 ? mSpinnerValue.getSelectedItem().toString() : null); resultingSelectionType = IRuleOperationBuildListener.RuleOperationSelectionInterface.STATIC; } else { //The user has selected a static operand value. Map<String, ?> staticValuesCompatibleWithFirstOperand = mUnitEntityDataTypeProvider.getUnitEntityDataType(mFirstOperandWidgetIfAny).getStaticValues(); ((UnitEntityDataType) operand).setValue(mSpinnerValue.getSelectedItemPosition() > 0 ? staticValuesCompatibleWithFirstOperand.get(mSpinnerValue.getSelectedItem()) : null, false); resultingSelectionType = IRuleOperationBuildListener.RuleOperationSelectionInterface.STATIC; } } else { //Unchanged value of any type operand = mOldOperand; resultingSelectionType = which == DialogInterface.BUTTON_POSITIVE? RuleOperationSelectionInterface.UNIT : RuleOperationSelectionInterface.NA; } mListener.onOperationBuildResult(resultingSelectionType , which == DialogInterface.BUTTON_POSITIVE? IRuleOperationBuildListener.RuleOperationDialogButtonInterface.NEXT : IRuleOperationBuildListener.RuleOperationDialogButtonInterface.DONE , operand, mPosition, null); break; default: mListener.onOperationBuildResult(IRuleOperationBuildListener.RuleOperationSelectionInterface.NEW_OPERATION//Just a default non-used value since we are aborting. , IRuleOperationBuildListener.RuleOperationDialogButtonInterface.CANCEL , null, mPosition, null); } } else throw new IllegalArgumentException("listener is null"); } @Override public <T> void onOperationBuildResult(IRuleOperationBuildListener.RuleOperationSelectionInterface ruleOperationSelectionInterface, IRuleOperationBuildListener.RuleOperationDialogButtonInterface ruleOperationDialogButtonInterface, IEntityDataType<T> operand, int operandPosition, RuleOperator<T> ruleOperator) { if(ruleOperationDialogButtonInterface != IRuleOperationBuildListener.RuleOperationDialogButtonInterface.CANCEL) { mListener.onOperationBuildResult(ruleOperationSelectionInterface, ruleOperationDialogButtonInterface, operand, operandPosition, ruleOperator); dismiss(); } } }