/* * Artcodes recognises a different marker scheme that allows the * creation of aesthetically pleasing, even beautiful, codes. * Copyright (C) 2013-2016 The University of Nottingham * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package uk.ac.horizon.artcodes.fragment; import android.app.Activity; import android.app.Dialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentManager; import android.support.v7.app.AlertDialog; import android.text.InputFilter; import android.text.InputType; import android.text.method.DigitsKeyListener; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import java.util.Collections; import java.util.UUID; import uk.ac.horizon.artcodes.Feature; import uk.ac.horizon.artcodes.R; import uk.ac.horizon.artcodes.activity.ExperienceActivityBase; import uk.ac.horizon.artcodes.databinding.ActionCodeBinding; import uk.ac.horizon.artcodes.databinding.ActionEditBinding; import uk.ac.horizon.artcodes.model.Action; import uk.ac.horizon.artcodes.model.Experience; import uk.ac.horizon.artcodes.scanner.ScannerActivity; import uk.ac.horizon.artcodes.ui.ActionEditor; import uk.ac.horizon.artcodes.ui.MarkerFormat; import uk.ac.horizon.artcodes.ui.SimpleTextWatcher; public class ActionEditDialogFragment extends DialogFragment { private static final int ACTION_EDIT_DIALOG = 193; private static final int SCAN_CODE_REQUEST = 931; private ActionEditBinding binding; static void show(FragmentManager fragmentManager, ActionEditListFragment fragment, int num) { final ActionEditDialogFragment dialog = new ActionEditDialogFragment(); if (fragment != null) { dialog.setTargetFragment(fragment, ACTION_EDIT_DIALOG); } final Bundle args = new Bundle(); args.putInt("action", num); dialog.setArguments(args); dialog.show(fragmentManager, "Edit Action Dialog"); } @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) throws NullPointerException { binding = ActionEditBinding.inflate(getActivity().getLayoutInflater()); binding.newMarkerCode.setFilters(new InputFilter[]{new MarkerFormat()}); String currentKeyboard = Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); Log.i("Keyboard", currentKeyboard); if (currentKeyboard.contains("com.lge.ime")) { binding.newMarkerCode.setKeyListener(DigitsKeyListener.getInstance("0123456789:")); binding.newMarkerCode.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); } binding.newMarkerCode.addTextChangedListener(new SimpleTextWatcher() { @Override public String getText() { return null; } @Override public void onTextChanged(String value) { if (!value.isEmpty()) { binding.newMarkerCode.setText(""); Action action = getAction(); action.getCodes().add(value); ActionCodeBinding codeBinding = createCodeBinding(binding, action, action.getCodes().size() - 1); codeBinding.editMarkerCode.requestFocus(); } } }); binding.scanButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getActivity(), ScannerActivity.class); intent.putExtra("experience", "{\"name\":\"Scan Code\"}"); startActivityForResult(intent, SCAN_CODE_REQUEST); } }); final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setView(binding.getRoot()); final Dialog dialog = builder.create(); binding.deleteButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (getArguments().containsKey("action")) { dialog.dismiss(); final int index = getArguments().getInt("action"); if (getTargetFragment() instanceof ActionEditListFragment) { ((ActionEditListFragment) getTargetFragment()).getAdapter().deleteAction(index); } else { getExperience().getActions().remove(index); } } } }); binding.doneButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (getArguments().containsKey("action")) { updateAction(); // make sure code is sorted if (getAction().getCodes().size() == 1) { // Actions with only 1 code can not be a group or sequence! getAction().setMatch(Action.Match.any); } final int index = getArguments().getInt("action"); if (getTargetFragment() instanceof ActionEditListFragment) { ((ActionEditListFragment) getTargetFragment()).getAdapter().actionUpdated(index); } } dialog.dismiss(); } }); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this.getContext(), R.array.match_type_descriptions, R.layout.match_type_spinner_item); binding.matchSpinner.setAdapter(adapter); binding.matchSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) { if (getAction() != null) { switch (i) { case 0: getAction().setMatch(Action.Match.any); break; case 1: getAction().setMatch(Action.Match.all); break; case 2: getAction().setMatch(Action.Match.sequence); break; } } } @Override public void onNothingSelected(AdapterView<?> adapterView) { } }); if (Feature.get(getContext(), R.bool.feature_combined_markers).isEnabled()) { binding.selectLayout.setVisibility(View.GONE); binding.matchSpinner.setVisibility(View.VISIBLE); } // Upload to artcodes.co.uk feature button: if (Feature.get(getContext(), R.bool.feature_upload_to_artcodes_co_uk).isEnabled()) { binding.uploadToArtcodesCoUkButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { UUID uuid = UUID.randomUUID(); String url = "http://www.artcodes.co.uk/test1234/?file=A" + uuid.toString() + "&source=artcodes-android-app"; getAction().setUrl(url); updateAction(); Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url + "&dontCheckForFiles")); startActivity(intent); } }); binding.uploadToArtcodesCoUkButton.setVisibility(View.VISIBLE); } return dialog; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == SCAN_CODE_REQUEST && resultCode == Activity.RESULT_OK) { String code = data.getStringExtra("marker"); Action action = getAction(); if (code != null && (action.getMatch() == Action.Match.sequence || !action.getCodes().contains(code))) { action.getCodes().add(code); ActionCodeBinding codeBinding = createCodeBinding(binding, action, action.getCodes().size() - 1); codeBinding.editMarkerCode.requestFocus(); } } } @Override public void onResume() { super.onResume(); updateAction(); } private Experience getExperience() { if (getActivity() instanceof ExperienceActivityBase) { return ((ExperienceActivityBase) getActivity()).getExperience(); } return null; } @NonNull private Action getAction() throws NullPointerException { Experience experience = getExperience(); if (experience != null) { if (getArguments().containsKey("action")) { int index = getArguments().getInt("action"); return experience.getActions().get(index); } } throw new NullPointerException("Couldn't get action"); } private void updateAction() { final Action action = getAction(); binding.setAction(action); binding.setActionEditor(new ActionEditor(action)); updateCodes(binding, action); updateMatchType(binding, action); } private void updateCodes(final ActionEditBinding binding, final Action action) { binding.markerCodeList.removeAllViews(); if (action != null && action.getMatch() != Action.Match.sequence) { // only sort codes if not a sequence! Collections.sort(action.getCodes()); } for (int index = 0; index < action.getCodes().size(); index++) { createCodeBinding(binding, action, index); } } private void updateMatchType(final ActionEditBinding binding, final Action action) { if (action != null) { binding.matchSpinner.setSelection(action.getMatch() == Action.Match.any ? 0 : (action.getMatch() == Action.Match.all ? 1 : 2)); } } private ActionCodeBinding createCodeBinding(final ActionEditBinding binding, final Action action, final int codeIndex) { final String code = action.getCodes().get(codeIndex); final ActionCodeBinding codeBinding = ActionCodeBinding.inflate(getActivity().getLayoutInflater(), binding.markerCodeList, false); codeBinding.editMarkerCode.setText(code); String currentKeyboard = Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); if (currentKeyboard.contains("com.lge.ime")) { codeBinding.editMarkerCode.setKeyListener(DigitsKeyListener.getInstance("0123456789:")); codeBinding.editMarkerCode.setRawInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); } codeBinding.editMarkerCode.setFilters(new InputFilter[]{new MarkerFormat()}); codeBinding.editMarkerCode.addTextChangedListener(new SimpleTextWatcher() { @Override public String getText() { return null; } @Override public void onTextChanged(String value) { if (value.isEmpty()) { action.getCodes().remove(codeIndex); updateCodes(binding, action); binding.newMarkerCode.requestFocus(); } else { action.getCodes().set(codeIndex, value); } } }); binding.markerCodeList.addView(codeBinding.getRoot()); return codeBinding; } }