Skip to content

Commit

Permalink
[SVN] r1627 Inventory in /Projects/Inventory/
Browse files Browse the repository at this point in the history
[FIX] Generic handling of List Preferences
[ADD] Display keywords for a Category
[ADD] Better suggestions controls
[ADD] Mark current category as selected in suggestions
[FIX] Remove View detail page dependency on prefs
[FIX] Mark queries as non-translatable
[FIX] Introduce string constants for list pref values
  • Loading branch information
TWiStErRob committed May 31, 2015
1 parent ee288af commit 947d9b0
Show file tree
Hide file tree
Showing 11 changed files with 288 additions and 208 deletions.
2 changes: 2 additions & 0 deletions lint.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<issue id="ContentDescription" severity="ignore" />
<!-- TODO re-check when it's really translated -->
<issue id="MissingTranslation" severity="ignore" />
<!-- TODO re-check when it's really translated -->
<issue id="ExtraTranslation" severity="ignore" />
<!-- TODO review later -->
<issue id="Overdraw" severity="ignore" />
<issue id="UnusedResources">
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/net/twisterrob/inventory/android/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,18 @@ public static SharedPreferences getPrefs() {
return PreferenceManager.getDefaultSharedPreferences(getAppContext());
}

/** Get boolean Preference */
public static boolean getBPref(@StringRes int prefName, @BoolRes int defaultRes) {
String prefKey = App.getAppContext().getString(prefName);
boolean prefDefault = App.getAppContext().getResources().getBoolean(defaultRes);
return App.getPrefs().getBoolean(prefKey, prefDefault);
}
/** Get String Preference */
public static String getSPref(@StringRes int prefName, @StringRes int defaultRes) {
String prefKey = App.getAppContext().getString(prefName);
String prefDefault = App.getAppContext().getResources().getString(defaultRes);
return App.getPrefs().getString(prefKey, prefDefault);
}

/** @return You must call {@link SharedPreferences.Editor#commit} as per {@link SharedPreferences#edit} contract. */
@SuppressLint("CommitPrefEdits")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@ public class PreferencesActivity extends PreferenceActivity implements OnSharedP
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

addPreferencesFromResource(R.xml.preferences);
}

@Override
protected void onStart() {
super.onStart();
onSharedPreferenceChanged(getPrefs(), getString(R.string.pref_defaultEntityDetailsPage));
SharedPreferences prefs = getPrefs();
for (String prefKey : prefs.getAll().keySet()) {
Preference pref = findPreference(prefKey);
if (pref instanceof ListPreference) {
onSharedPreferenceChanged(getPrefs(), prefKey);
}
}
}

@Override
Expand All @@ -35,7 +42,7 @@ protected void onPause() {

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
if (key.equals(getString(R.string.pref_defaultEntityDetailsPage))) {
if (pref instanceof ListPreference) {
pref.setSummary(((ListPreference)pref).getEntry());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import org.slf4j.*;

import android.app.Activity;
import android.app.*;
import android.content.*;
import android.database.Cursor;
import android.graphics.Bitmap.CompressFormat;
Expand Down Expand Up @@ -159,76 +159,8 @@ public void onClick(View v) {
@Override public void onTextChanged(CharSequence s, int start, int before, int count) {
isClean = false;
if (doValidateTitle()) {
Collection<Suggestion> suggestions = CategoryDTO.getSuggester(getContext()).suggest(s);

if (!suggestions.isEmpty()) {
hint.setText(buildHint(suggestions));
hint.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
public @NonNull CharSequence buildHint(@NonNull Collection<Suggestion> suggestions) {
LongSparseArray<Map<CharSequence, Collection<Suggestion>>> grouped = group(suggestions);

SpannableStringBuilder builder = new SpannableStringBuilder("Suggested categories:\n");
for (int i = 0; i < grouped.size(); ++i) {
Map<CharSequence, Collection<Suggestion>> matchGroup = grouped.valueAt(i);

final Suggestion first = matchGroup.entrySet().iterator().next().getValue().iterator().next();
int start = builder.length();
builder.append(first.getCategoryPath());
int end = builder.length();

builder.setSpan(new ClickableSpan() {
@Override public void onClick(View widget) {
AndroidTools.selectByID(type, first.category);
}
}, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

builder.append(" (");
for (Iterator<Entry<CharSequence, Collection<Suggestion>>> sugIt =
matchGroup.entrySet().iterator(); sugIt.hasNext(); ) {
Entry<CharSequence, Collection<Suggestion>> group = sugIt.next();
int matchStart = builder.length();
builder.append(group.getKey());
for (Suggestion suggestion : group.getValue()) {
builder.setSpan(new ForegroundColorSpan(Color.RED),
matchStart + suggestion.matchStart,
matchStart + suggestion.matchEnd,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
if (sugIt.hasNext()) {
builder.append(", ");
}
}
builder.append(")");
if (i < grouped.size() - 1) {
builder.append("\n");
}
updateHint(s, false);
}
return builder;
}
private LongSparseArray<Map<CharSequence, Collection<Suggestion>>> group(
@NonNull Collection<Suggestion> suggestions) {
LongSparseArray<Map<CharSequence, Collection<Suggestion>>> grouped = new LongSparseArray<>();
for (Suggestion suggestion : suggestions) {
Map<CharSequence, Collection<Suggestion>> matchGroup = grouped.get(suggestion.category);
if (matchGroup == null) {
matchGroup = new TreeMap<>();
grouped.put(suggestion.category, matchGroup);
}
Collection<Suggestion> group = matchGroup.get(suggestion.match);
if (group == null) {
group = new TreeSet<>(new Comparator<Suggestion>() {
@Override public int compare(Suggestion lhs, Suggestion rhs) {
return lhs.search.toString().compareToIgnoreCase(rhs.search.toString());
}
});
matchGroup.put(suggestion.match, group);
}
group.add(suggestion);
}
return grouped;
}
});

Expand Down Expand Up @@ -284,7 +216,7 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long
isClean = cleanBefore;
}
reloadImage();
updateHint(true);
updateHint(name.getText(), false);
}
});

Expand All @@ -293,14 +225,115 @@ public void onItemSelected(AdapterView<?> parent, View view, int position, long
}
}

private void updateHint(CharSequence s, boolean forceSuggest) {
String suggest = App.getSPref(R.string.pref_suggestCategory, R.string.pref_suggestCategory_default);
String always = getString(R.string.pref_suggestCategory_always);
String unmatched = getString(R.string.pref_suggestCategory_unmatched);
CharSequence hintText = null;
if (always.equals(suggest) || unmatched.equals(suggest) || forceSuggest) {
Collection<Suggestion> suggestions = CategoryDTO.getSuggester(name.getContext()).suggest(s);

if (!suggestions.isEmpty()) {
hintText = buildHint(suggestions, getTypeName());
if (unmatched.equals(suggest) && !forceSuggest) {
for (Suggestion suggestion : suggestions) {
String currentCategoryKey = getTypeName();
if (suggestion.getCategoryKey().equals(currentCategoryKey)) {
hintText = null;
}
}
}
} else {
if (forceSuggest) {
hintText = "Can't find any matching categories, sorry.";
}
}
}
hint.setText(hintText);
hint.setMovementMethod(LinkMovementMethod.getInstance());
AndroidTools.displayedIfHasText(hint);
}
public CharSequence buildHint(@NonNull Collection<Suggestion> suggestions, String current) {
LongSparseArray<Map<CharSequence, Collection<Suggestion>>> grouped = group(suggestions);

SpannableStringBuilder builder = new SpannableStringBuilder();
for (int i = 0; i < grouped.size(); ++i) {
Map<CharSequence, Collection<Suggestion>> matchGroup = grouped.valueAt(i);

final Suggestion categorySuggestion = matchGroup.entrySet().iterator().next().getValue().iterator().next();
boolean isCurrent = categorySuggestion.getCategoryKey().equals(current);

if (isCurrent) {
builder.append("\u2714");
}
int start = builder.length();
builder.append(categorySuggestion.getCategoryPath());
int end = builder.length();

if (!isCurrent) {
builder.setSpan(new ClickableSpan() {
@Override public void onClick(View widget) {
AndroidTools.selectByID(type, categorySuggestion.category);
}
}, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}

builder.append(" (");
for (Iterator<Entry<CharSequence, Collection<Suggestion>>> sugIt =
matchGroup.entrySet().iterator(); sugIt.hasNext(); ) {
Entry<CharSequence, Collection<Suggestion>> group = sugIt.next();
int matchStart = builder.length();
builder.append(group.getKey());
for (Suggestion suggestion : group.getValue()) {
builder.setSpan(new ForegroundColorSpan(Color.RED),
matchStart + suggestion.matchStart,
matchStart + suggestion.matchEnd,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
if (sugIt.hasNext()) {
builder.append(", ");
}
}
builder.append(")");
if (i < grouped.size() - 1) {
builder.append("\n");
}
}
return builder;
}
private LongSparseArray<Map<CharSequence, Collection<Suggestion>>> group(
@NonNull Collection<Suggestion> suggestions) {
LongSparseArray<Map<CharSequence, Collection<Suggestion>>> grouped = new LongSparseArray<>();
for (Suggestion suggestion : suggestions) {
Map<CharSequence, Collection<Suggestion>> matchGroup = grouped.get(suggestion.category);
if (matchGroup == null) {
matchGroup = new TreeMap<>();
grouped.put(suggestion.category, matchGroup);
}
Collection<Suggestion> group = matchGroup.get(suggestion.match);
if (group == null) {
group = new TreeSet<>(new Comparator<Suggestion>() {
@Override public int compare(Suggestion lhs, Suggestion rhs) {
return lhs.search.toString().compareToIgnoreCase(rhs.search.toString());
}
});
matchGroup.put(suggestion.match, group);
}
group.add(suggestion);
}
return grouped;
}

@Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
onPrepareContextMenu(menu, getActivity().getMenuInflater());
}

private void onPrepareContextMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.edit_context, menu);
menu.findItem(R.id.action_hint_expand).setChecked(isHintExpanded());
String suggest = App.getSPref(R.string.pref_suggestCategory, R.string.pref_suggestCategory_default);
String always = getString(R.string.pref_suggestCategory_always);
menu.findItem(R.id.action_category_suggest).setVisible(!always.equals(suggest));
}

@Override public boolean onContextItemSelected(MenuItem item) {
Expand All @@ -311,34 +344,22 @@ private void onPrepareContextMenu(Menu menu, MenuInflater inflater) {
case R.id.action_category_help:
startActivity(MainActivity.list(MainActivity.PAGE_CATEGORY_HELP));
return true;
case R.id.action_hint_expand:
updateHint(false);
case R.id.action_category_suggest:
updateHint(name.getText(), true);
return true;
case R.id.action_category_keywords:
CharSequence categoryTitle = AndroidTools.getText(getContext(), getTypeName());
CharSequence categoryKeywords = CategoryDTO.getKeywords(getContext(), getTypeName());
new AlertDialog.Builder(getContext())
.setTitle(getString(R.string.category_keywords, categoryTitle))
.setMessage(categoryKeywords)
.show()
;
return true;
}
return super.onContextItemSelected(item);
}

private void updateHint(boolean keepExpanded) {
String categoryName = getTypeName();
boolean isExpanded = isHintExpanded();
isExpanded = keepExpanded? isExpanded : !isExpanded;
CharSequence hint;
if (isExpanded) {
hint = CategoryDTO.getKeywords(getContext(), categoryName);
} else {
hint = CategoryDTO.getShortKeywords(getContext(), categoryName);
}
this.hint.setText(hint);
this.hint.setTag(isExpanded);
AndroidTools.displayedIf(this.hint, this.hint.getText().length() != 0);
}

private boolean isHintExpanded() {
Boolean isExpandedTag = (Boolean)this.hint.getTag();
return isExpandedTag != null? isExpandedTag
: App.getBPref(R.string.pref_preferExpandedKeywords, R.bool.pref_preferExpandedKeywords_default);
}

protected abstract boolean isNew();

public void save() {
Expand Down
Loading

0 comments on commit 947d9b0

Please sign in to comment.