Skip to content

Commit 9187e43

Browse files
committed
Settings: added Search feature
Filters the list of preferences based on specified keyword. Filtered list maintains preference tree structure for a user to better understand the context of filtered preferences Closes #1724
1 parent fef188c commit 9187e43

File tree

3 files changed

+202
-14
lines changed

3 files changed

+202
-14
lines changed

res/menu/settings_menu.xml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
* Copyright (C) 2018 Peter Gregus for GravityBox Project (C3C076@xda)
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
-->
16+
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
17+
<item android:id="@+id/search"
18+
android:title="@string/search"
19+
android:icon="@android:drawable/ic_menu_search"
20+
android:showAsAction="collapseActionView|ifRoom"
21+
android:actionViewClass="android.widget.SearchView"
22+
android:visible="false" />
23+
<item android:id="@+id/searchKeyword"
24+
android:title=""
25+
android:showAsAction="always"
26+
android:actionViewClass="android.widget.TextView"
27+
android:visible="false" />
28+
<item android:id="@+id/searchReset"
29+
android:title="@string/search_reset"
30+
android:icon="@android:drawable/ic_menu_close_clear_cancel"
31+
android:showAsAction="ifRoom"
32+
android:visible="false" />
33+
</menu>

res/values/strings.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,4 +2101,10 @@
21012101
<!-- BatteryBar: only while charging -->
21022102
<string name="pref_battery_bar_show_charging_title">Only when charging</string>
21032103

2104+
<!-- Search -->
2105+
<string name="search">Search</string>
2106+
<string name="search_reset">Reset search</string>
2107+
<string name="search_keyword_short">Keyword is too short</string>
2108+
<string name="search_no_match">No preferences found</string>
2109+
21042110
</resources>

src/com/ceco/oreo/gravitybox/GravityBoxSettings.java

Lines changed: 163 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,21 @@
5656
import android.preference.Preference.OnPreferenceChangeListener;
5757
import android.preference.PreferenceCategory;
5858
import android.preference.PreferenceFragment;
59+
import android.preference.PreferenceGroup;
5960
import android.preference.PreferenceScreen;
6061
import android.preference.RingtonePreference;
6162
import android.preference.SwitchPreference;
63+
import android.text.TextUtils.TruncateAt;
6264
import android.text.method.LinkMovementMethod;
6365
import android.util.Log;
6466
import android.util.TypedValue;
6567
import android.view.Display;
68+
import android.view.Menu;
69+
import android.view.MenuInflater;
70+
import android.view.MenuItem;
71+
import android.view.MenuItem.OnMenuItemClickListener;
72+
import android.widget.SearchView;
73+
import android.widget.SearchView.OnQueryTextListener;
6674
import android.widget.TextView;
6775
import android.widget.Toast;
6876
import android.Manifest.permission;
@@ -1072,6 +1080,9 @@ public SystemProperties(Bundle data) {
10721080
public static SystemProperties sSystemProperties;
10731081
private Dialog mAlertDialog;
10741082
private ProgressDialog mProgressDialog;
1083+
private String mSearchQuery;
1084+
private PrefsFragment mPrefsFragment;
1085+
10751086
private Runnable mGetSystemPropertiesTimeout = new Runnable() {
10761087
@Override
10771088
public void run() {
@@ -1095,6 +1106,14 @@ public void onClick(DialogInterface dialog, int which) {
10951106
protected void onCreate(Bundle savedInstanceState) {
10961107
super.onCreate(savedInstanceState);
10971108

1109+
if (savedInstanceState != null) {
1110+
mSearchQuery = savedInstanceState.getString("mSearchQuery", null);
1111+
mPrefsFragment = (PrefsFragment) getFragmentManager().getFragment(savedInstanceState, "mPrefsFragment");
1112+
if (mPrefsFragment != null) {
1113+
mPrefsFragment.setSearchQuery(mSearchQuery);
1114+
}
1115+
}
1116+
10981117
// fix folder permissions
10991118
SettingsManager.getInstance(this).fixFolderPermissionsAsync();
11001119

@@ -1127,7 +1146,7 @@ public void onClick(DialogInterface dialog, int which) {
11271146
return;
11281147
}
11291148

1130-
if (savedInstanceState == null || sSystemProperties == null) {
1149+
if (savedInstanceState == null || sSystemProperties == null || mPrefsFragment == null) {
11311150
mReceiver = new GravityBoxResultReceiver(new Handler());
11321151
mReceiver.setReceiver(this);
11331152
Intent intent = new Intent();
@@ -1158,6 +1177,79 @@ protected void onDestroy() {
11581177
super.onDestroy();
11591178
}
11601179

1180+
@Override
1181+
public void onSaveInstanceState(Bundle bundle) {
1182+
bundle.putString("mSearchQuery", mSearchQuery);
1183+
getFragmentManager().putFragment(bundle, "mPrefsFragment", mPrefsFragment);
1184+
super.onSaveInstanceState(bundle);
1185+
}
1186+
1187+
@Override
1188+
public boolean onCreateOptionsMenu(Menu menu) {
1189+
MenuInflater inflater = getMenuInflater();
1190+
inflater.inflate(R.menu.settings_menu, menu);
1191+
1192+
final MenuItem search = menu.findItem(R.id.search);
1193+
final SearchView searchView = (SearchView) search.getActionView();
1194+
final MenuItem searchKeyword = menu.findItem(R.id.searchKeyword);
1195+
final TextView searchKeywordView = (TextView) searchKeyword.getActionView();
1196+
final MenuItem searchReset = menu.findItem(R.id.searchReset);
1197+
1198+
searchView.setOnQueryTextListener(new OnQueryTextListener() {
1199+
@Override
1200+
public boolean onQueryTextChange(String text) {
1201+
return false;
1202+
}
1203+
@Override
1204+
public boolean onQueryTextSubmit(String text) {
1205+
if (text.trim().length() < 3) {
1206+
Toast.makeText(GravityBoxSettings.this,
1207+
R.string.search_keyword_short, Toast.LENGTH_SHORT).show();
1208+
} else {
1209+
mSearchQuery = text.trim();
1210+
searchView.clearFocus();
1211+
search.collapseActionView();
1212+
search.setVisible(false);
1213+
searchReset.setVisible(true);
1214+
searchKeyword.setVisible(true);
1215+
searchKeywordView.setText(mSearchQuery);
1216+
mPrefsFragment.filterPreferences(mSearchQuery);
1217+
}
1218+
return true;
1219+
}
1220+
});
1221+
1222+
searchReset.setOnMenuItemClickListener(new OnMenuItemClickListener() {
1223+
@Override
1224+
public boolean onMenuItemClick(MenuItem item) {
1225+
mSearchQuery = null;
1226+
search.setVisible(true);
1227+
searchReset.setVisible(false);
1228+
searchKeyword.setVisible(false);
1229+
searchKeywordView.setText(null);
1230+
mPrefsFragment = new PrefsFragment();
1231+
getFragmentManager().beginTransaction().replace(android.R.id.content, mPrefsFragment).commit();
1232+
return true;
1233+
}
1234+
});
1235+
1236+
searchKeywordView.setSingleLine(true);
1237+
searchKeywordView.setEllipsize(TruncateAt.END);
1238+
Point size = new Point();
1239+
getWindowManager().getDefaultDisplay().getSize(size);
1240+
searchKeywordView.setMaxWidth(size.x / 3);
1241+
1242+
if (mSearchQuery != null) {
1243+
searchReset.setVisible(true);
1244+
searchKeyword.setVisible(true);
1245+
searchKeywordView.setText(mSearchQuery);
1246+
} else {
1247+
search.setVisible(true);
1248+
}
1249+
1250+
return true;
1251+
}
1252+
11611253
@Override
11621254
public void onReceiveResult(int resultCode, Bundle resultData) {
11631255
if (mHandler != null) {
@@ -1168,7 +1260,9 @@ public void onReceiveResult(int resultCode, Bundle resultData) {
11681260
Log.d("GravityBox", "result received: resultCode=" + resultCode);
11691261
if (resultCode == SystemPropertyProvider.RESULT_SYSTEM_PROPERTIES) {
11701262
sSystemProperties = new SystemProperties(resultData);
1171-
getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment()).commit();
1263+
mPrefsFragment = new PrefsFragment();
1264+
mPrefsFragment.setSearchQuery(mSearchQuery);
1265+
getFragmentManager().beginTransaction().replace(android.R.id.content, mPrefsFragment).commit();
11721266
} else {
11731267
finish();
11741268
}
@@ -1350,6 +1444,7 @@ public static class PrefsFragment extends PreferenceFragment
13501444
//private PreferenceScreen mPrefCatCellTile;
13511445
private ListPreference mPrefBatteryTileTempUnit;
13521446
private EditTextPreference mPrefPowerCameraVp;
1447+
private String mSearchQuery;
13531448

13541449
@Override
13551450
public void onCreate(Bundle savedInstanceState) {
@@ -1877,6 +1972,52 @@ public void onCreate(Bundle savedInstanceState) {
18771972
checkPermissions();
18781973
}
18791974

1975+
protected void setSearchQuery(String query) {
1976+
mSearchQuery = query;
1977+
}
1978+
1979+
protected void filterPreferences() {
1980+
filterPreferences(mSearchQuery);
1981+
}
1982+
1983+
protected void filterPreferences(String query) {
1984+
setSearchQuery(query);
1985+
if (filterPreferencesInternal(getPreferenceScreen(), null) == 0) {
1986+
Toast.makeText(getActivity(), R.string.search_no_match,
1987+
Toast.LENGTH_SHORT).show();
1988+
}
1989+
}
1990+
1991+
private int filterPreferencesInternal(PreferenceGroup prefGroup, PreferenceGroup parentGroup) {
1992+
if (mSearchQuery == null) return -1;
1993+
1994+
final int count = prefGroup.getPreferenceCount();
1995+
1996+
int matchCount = 0;
1997+
for (int i = count-1; i >= 0; i--) {
1998+
Preference p = prefGroup.getPreference(i);
1999+
p.setDependency(null);
2000+
if (p instanceof PreferenceGroup && p.getIntent() == null) {
2001+
matchCount += filterPreferencesInternal((PreferenceGroup)p, prefGroup);
2002+
} else {
2003+
String title = (p.getTitle() == null ? "null" :
2004+
p.getTitle().toString()).toLowerCase(Locale.getDefault());
2005+
String summary = (p.getSummary() == null ? "null" :
2006+
p.getSummary().toString()).toLowerCase(Locale.getDefault());
2007+
if (p.isEnabled() && (title.contains(mSearchQuery) || summary.contains(mSearchQuery))) {
2008+
matchCount++;
2009+
} else {
2010+
prefGroup.removePreference(p);
2011+
}
2012+
}
2013+
}
2014+
if (parentGroup != null && matchCount == 0 && prefGroup.getIntent() == null) {
2015+
parentGroup.removePreference(prefGroup);
2016+
}
2017+
2018+
return matchCount;
2019+
}
2020+
18802021
private void initFingerprintLauncher() {
18812022
PreferenceCategory catFingers = (PreferenceCategory) findPreference(
18822023
PREF_CAT_KEY_FINGERPRINT_LAUNCHER_FINGERS);
@@ -2003,6 +2144,7 @@ public void onStart() {
20032144
super.onStart();
20042145
mPrefs.registerOnSharedPreferenceChangeListener(this);
20052146
updatePreferences(null);
2147+
filterPreferences();
20062148
}
20072149

20082150
@Override
@@ -2264,7 +2406,7 @@ private void updatePreferences(String key) {
22642406
if (key == null || key.equals(PREF_KEY_VOLUME_ROCKER_WAKE)) {
22652407
mPrefVolumeRockerWake.setSummary(mPrefVolumeRockerWake.getEntry());
22662408
Preference p = findPreference(PREF_KEY_VOLUME_ROCKER_WAKE_ALLOW_MUSIC);
2267-
p.setEnabled("enabled".equals(mPrefVolumeRockerWake.getValue()));
2409+
if (p != null) p.setEnabled("enabled".equals(mPrefVolumeRockerWake.getValue()));
22682410
}
22692411

22702412
if (key == null || key.equals(PREF_KEY_DATA_TRAFFIC_OMNI_MODE)) {
@@ -2407,15 +2549,17 @@ private void updatePreferences(String key) {
24072549
key.equals(PREF_KEY_LOCKSCREEN_DIRECT_UNLOCK_POLICY)) {
24082550
ListPreference du = (ListPreference) findPreference(PREF_KEY_LOCKSCREEN_DIRECT_UNLOCK);
24092551
ListPreference dup = (ListPreference) findPreference(PREF_KEY_LOCKSCREEN_DIRECT_UNLOCK_POLICY);
2410-
dup.setEnabled(!"OFF".equals(du.getValue()));
2411-
dup.setSummary(dup.getEntry());
2412-
Preference p = findPreference(PREF_KEY_LOCKSCREEN_DIRECT_UNLOCK_TRANS_LEVEL);
2413-
if (p != null) p.setEnabled("SEE_THROUGH".equals(du.getValue()));
2552+
if (du != null && dup != null) {
2553+
dup.setEnabled(!"OFF".equals(du.getValue()));
2554+
dup.setSummary(dup.getEntry());
2555+
Preference p = findPreference(PREF_KEY_LOCKSCREEN_DIRECT_UNLOCK_TRANS_LEVEL);
2556+
if (p != null) p.setEnabled("SEE_THROUGH".equals(du.getValue()));
2557+
}
24142558
}
24152559

24162560
if (key == null || key.equals(PREF_KEY_LOCKSCREEN_SMART_UNLOCK_POLICY)) {
24172561
ListPreference sup = (ListPreference) findPreference(PREF_KEY_LOCKSCREEN_SMART_UNLOCK_POLICY);
2418-
sup.setSummary(sup.getEntry());
2562+
if (sup != null) sup.setSummary(sup.getEntry());
24192563
}
24202564

24212565
if (key == null || key.equals(PREF_KEY_LOCKSCREEN_IMPRINT_MODE)) {
@@ -2428,7 +2572,7 @@ private void updatePreferences(String key) {
24282572
if (p != null) {
24292573
p.setSummary(p.getEntry());
24302574
Preference dp = findPreference(PREF_KEY_DND_TILE_DURATION);
2431-
dp.setEnabled(p.isEnabled() && "CUSTOM".equals(p.getValue()));
2575+
if (dp != null) dp.setEnabled(p.isEnabled() && "CUSTOM".equals(p.getValue()));
24322576
}
24332577
}
24342578

@@ -2459,15 +2603,16 @@ private void updatePreferences(String key) {
24592603
if (key == null || key.equals(PREF_KEY_NAVBAR_CUSTOM_KEY_ICON_STYLE) ||
24602604
key.equals(PREF_KEY_NAVBAR_CUSTOM_KEY_ENABLE)) {
24612605
ListPreference p = (ListPreference) findPreference(PREF_KEY_NAVBAR_CUSTOM_KEY_ICON_STYLE);
2462-
p.setSummary(p.getEntry());
2606+
if (p != null) p.setSummary(p.getEntry());
24632607
Preference p2 = findPreference(PREF_KEY_NAVBAR_CUSTOM_KEY_IMAGE);
2464-
p2.setEnabled(mPrefs.getBoolean(PREF_KEY_NAVBAR_CUSTOM_KEY_ENABLE, false) &&
2608+
if (p != null && p2 != null)
2609+
p2.setEnabled(mPrefs.getBoolean(PREF_KEY_NAVBAR_CUSTOM_KEY_ENABLE, false) &&
24652610
"CUSTOM".equals(p.getValue()));
24662611
}
24672612

24682613
if (key == null || key.equals(PREF_KEY_FORCE_AOSP)) {
24692614
CheckBoxPreference p = (CheckBoxPreference) findPreference(PREF_KEY_FORCE_AOSP);
2470-
p.setChecked(Utils.isAospForced());
2615+
if (p != null) p.setChecked(Utils.isAospForced());
24712616
}
24722617

24732618
if (key == null || key.equals(PREF_KEY_LOCKSCREEN_BOTTOM_ACTIONS_HIDE)) {
@@ -2490,16 +2635,18 @@ private void updatePreferences(String key) {
24902635

24912636
if (key == null || key.equals(PREF_KEY_QS_LOCKED_TILE_INDICATOR)) {
24922637
ListPreference p = (ListPreference) findPreference(PREF_KEY_QS_LOCKED_TILE_INDICATOR);
2493-
p.setSummary(p.getEntry());
2638+
if (p != null) p.setSummary(p.getEntry());
24942639
}
24952640

24962641
if (key == null || key.equals(PREF_KEY_APP_LAUNCHER_THEME)) {
24972642
ListPreference p = (ListPreference) findPreference(PREF_KEY_APP_LAUNCHER_THEME);
2498-
p.setSummary(p.getEntry());
2643+
if (p != null) p.setSummary(p.getEntry());
24992644
}
25002645

25012646
for (String caKey : customAppKeys) {
25022647
ListPreference caPref = (ListPreference) findPreference(caKey);
2648+
if (caPref == null)
2649+
continue;
25032650
if ((caKey + "_custom").equals(key) && mPrefCustomApp.getValue() != null) {
25042651
caPref.setSummary(mPrefCustomApp.getSummary());
25052652
Intent intent = new Intent(ACTION_PREF_HWKEY_CHANGED);
@@ -2523,6 +2670,8 @@ private void updatePreferences(String key) {
25232670

25242671
for (String rtKey : ringToneKeys) {
25252672
RingtonePreference rtPref = (RingtonePreference) findPreference(rtKey);
2673+
if (rtPref == null)
2674+
continue;
25262675
String val = mPrefs.getString(rtKey, null);
25272676
if (val != null && !val.isEmpty()) {
25282677
if (rtKey.equals(PREF_KEY_CHARGER_PLUGGED_SOUND_WIRELESS) &&

0 commit comments

Comments
 (0)