package dev.ukanth.ufirewall.log; import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnMultiChoiceClickListener; import android.content.res.TypedArray; import android.preference.ListPreference; import android.util.AttributeSet; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import dev.ukanth.ufirewall.Api; import dev.ukanth.ufirewall.Api.PackageInfoData; import dev.ukanth.ufirewall.util.PackageComparator; public class MultiSelectListPreference extends ListPreference { private String separator; private static final String DEFAULT_SEPARATOR = ","; private boolean[] entryChecked; private Context ctx; public MultiSelectListPreference(Context context, AttributeSet attributeSet) { super(context, attributeSet); this.ctx = context; if(getEntries() == null){ setData(); } entryChecked = new boolean[getEntries().length]; separator = DEFAULT_SEPARATOR; } public MultiSelectListPreference(Context context) { this(context, null); } private void setData() { try { List<PackageInfoData> apps; if (Api.applications == null) { apps = Api.getApps(ctx, null); } else { apps = Api.applications; } try { Collections.sort(apps, new PackageComparator()); }catch(Exception e) { Log.e(Api.TAG, "Exception on Sort " + e.getMessage()); } CharSequence[] entries = new CharSequence[apps.size()]; CharSequence[] entryValues = new CharSequence[apps.size()]; //int i = 0; for(int i=0; i < apps.size(); i++) { entries[i] = apps.get(i).toStringWithUID(); entryValues[i] = apps.get(i).uid + ""; } setEntries(entries); setEntryValues(entryValues); } catch(Exception e) { } } @Override protected void onPrepareDialogBuilder(Builder builder) { try { List<PackageInfoData> apps; if (Api.applications == null) { apps = Api.getApps(ctx, null); } else { apps = Api.applications; } try { Collections.sort(apps, new PackageComparator()); }catch(Exception e) { Log.e(Api.TAG, "Exception on Sort " + e.getMessage()); } CharSequence[] entries = new CharSequence[apps.size()]; CharSequence[] entryValues = new CharSequence[apps.size()]; for(int i=0; i < apps.size(); i++) { entries[i] = apps.get(i).toStringWithUID(); entryValues[i] = apps.get(i).uid + ""; } setEntries(entries); setEntryValues(entryValues); if (entries == null || entryValues == null || entries.length != entryValues.length) { throw new IllegalStateException( "MultiSelectListPreference requires an entries array and an entryValues " + "array which are both the same length"); } restoreCheckedEntries(); OnMultiChoiceClickListener listener = new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int which, boolean val) { entryChecked[which] = val; } }; builder.setMultiChoiceItems(entries, entryChecked, listener); } catch (Exception e) { } } private CharSequence[] unpack(CharSequence val) { if (val == null || "".equals(val)) { return new CharSequence[0]; } else { return ((String) val).split(separator); } } /** * Gets the entries values that are selected * * @return the selected entries values */ public CharSequence[] getCheckedValues() { return unpack(getValue()); } private void restoreCheckedEntries() { CharSequence[] entryValues = getEntryValues(); // Explode the string read in sharedpreferences CharSequence[] vals = unpack(getValue()); if (vals != null) { List<CharSequence> valuesList = Arrays.asList(vals); for (int i = 0; i < entryValues.length; i++) { CharSequence entry = entryValues[i]; entryChecked[i] = valuesList.contains(entry); } } } @Override protected void onDialogClosed(boolean positiveResult) { List<CharSequence> values = new ArrayList<CharSequence>(); CharSequence[] entryValues = getEntryValues(); if (positiveResult && entryValues != null) { for (int i = 0; i < entryValues.length; i++) { if (entryChecked[i] == true) { String val = (String) entryValues[i]; values.add(val); } } String value = join(values, separator); setSummary(prepareSummary(values)); setValueAndEvent(value); } } private void setValueAndEvent(String value) { if (callChangeListener(unpack(value))) { setValue(value); } } private CharSequence prepareSummary(List<CharSequence> joined) { List<String> titles = new ArrayList<String>(); CharSequence[] entryTitle = getEntries(); CharSequence[] entryValues = getEntryValues(); int ix = 0; for (CharSequence value : entryValues) { if (joined.contains(value)) { titles.add((String) entryTitle[ix]); } ix += 1; } return join(titles, ", "); } @Override protected Object onGetDefaultValue(TypedArray typedArray, int index) { return typedArray.getTextArray(index); } @Override protected void onSetInitialValue(boolean restoreValue, Object rawDefaultValue) { String value = null; CharSequence[] defaultValue; if (rawDefaultValue == null) { defaultValue = new CharSequence[0]; } else { defaultValue = (CharSequence[]) rawDefaultValue; } List<CharSequence> joined = Arrays.asList(defaultValue); String joinedDefaultValue = join(joined, separator); if (restoreValue) { if(joinedDefaultValue instanceof java.lang.String) { value = getPersistedString(joinedDefaultValue); } } else { value = joinedDefaultValue; } setSummary(prepareSummary(Arrays.asList(unpack(value)))); setValueAndEvent(value); } protected static String join(Iterable<?> iterable, String separator) { Iterator<?> oIter; if (iterable == null || (!(oIter = iterable.iterator()).hasNext())) return ""; StringBuilder oBuilder = new StringBuilder(String.valueOf(oIter.next())); while (oIter.hasNext()) oBuilder.append(separator).append(oIter.next()); return oBuilder.toString(); } }