From http://www.jwz.org/xscreensaver/xscreensaver-5.35.tar.gz
[xscreensaver] / android / project / xscreensaver / src / org / jwz / xscreensaver / XScreenSaverSettings.java
1 /* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
3  * and Dennis Sheil <dennis@panaceasupplies.com>
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation.  No representations are made about the suitability of this
10  * software for any purpose.  It is provided "as is" without express or 
11  * implied warranty.
12  *
13  * The superclass of every saver's preferences panel.
14  *
15  * The only reason the subclasses of this class exist is so that we know
16  * which "_settings.xml" to read -- we extract the base name from self's
17  * class.
18  *
19  * project/xscreensaver/res/xml/SAVER_dream.xml refers to it as
20  * android:settingsActivity="SAVER_Settings".  If there was some way
21  * to pass an argument from the XML into here, or to otherwise detect
22  * which Dream was instantiating this Settings, we wouldn't need those
23  * hundreds of Settings subclasses.
24  */
25
26 package org.jwz.xscreensaver;
27
28 import android.content.SharedPreferences;
29 import android.os.Bundle;
30
31 import android.content.SharedPreferences;
32 import android.preference.PreferenceActivity;
33 import android.preference.Preference;
34 import android.preference.ListPreference;
35 import android.preference.EditTextPreference;
36 import android.preference.CheckBoxPreference;
37 import org.jwz.xscreensaver.SliderPreference;
38
39 import org.jwz.xscreensaver.R;
40 import java.util.Map;
41 import java.lang.reflect.Field;
42
43 public abstract class XScreenSaverSettings extends PreferenceActivity
44   implements SharedPreferences.OnSharedPreferenceChangeListener {
45
46   @Override
47   protected void onCreate (Bundle icicle) {
48     super.onCreate (icicle);
49
50     // Extract the saver name from e.g. "BouncingCowSettings"
51     String name = this.getClass().getSimpleName();
52     String tail = "Settings";
53     if (name.endsWith(tail))
54       name = name.substring (0, name.length() - tail.length());
55     name = name.toLowerCase();
56
57     // #### All of these have been deprecated:
58     //   getPreferenceManager()
59     //   addPreferencesFromResource(int)
60     //   findPreference(CharSequence)
61
62     getPreferenceManager().setSharedPreferencesName (name);
63
64     // read R.xml.SAVER_settings dynamically
65     int res = -1;
66     String pref_class = name + "_settings";
67     try { res = R.xml.class.getDeclaredField(pref_class).getInt (null); }
68     catch (Exception e) { }
69     if (res != -1)
70       addPreferencesFromResource (res);
71
72     final int res_final = res;
73
74     SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
75     prefs.registerOnSharedPreferenceChangeListener (this);
76     updateAllPrefsSummaries (prefs);
77
78     // Find the "Reset to defaults" button and install a click handler on it.
79     //
80     Preference reset = findPreference (name + "_reset");
81     reset.setOnPreferenceClickListener(
82       new Preference.OnPreferenceClickListener() {
83         @Override
84         public boolean onPreferenceClick(Preference preference) {
85
86           SharedPreferences prefs =
87             getPreferenceManager().getSharedPreferences();
88
89           // Wipe everything from the preferences hash, then reload defaults.
90           prefs.edit().clear().commit();
91           getPreferenceScreen().removeAll();
92           addPreferencesFromResource (res_final);
93
94           // I guess we need to re-get this after the removeAll?
95           prefs = getPreferenceManager().getSharedPreferences();
96
97           // But now we need to iterate over every Preference widget and
98           // push the new value down into it.  If you think this all looks
99           // ridiculously non-object-oriented and completely insane, that's
100           // because it is.
101
102           Map <String, ?> keys = prefs.getAll();
103           for (Map.Entry <String, ?> entry : keys.entrySet()) {
104             String key = entry.getKey();
105             String val = String.valueOf (entry.getValue());
106
107             Preference pref = findPreference (key);
108             if (pref instanceof ListPreference) {
109               ((ListPreference) pref).setValue (prefs.getString (key, ""));
110             } else if (pref instanceof SliderPreference) {
111               ((SliderPreference) pref).setValue (prefs.getFloat (key, 0));
112             } else if (pref instanceof EditTextPreference) {
113               ((EditTextPreference) pref).setText (prefs.getString (key, ""));
114             } else if (pref instanceof CheckBoxPreference) {
115               ((CheckBoxPreference) pref).setChecked (
116                 prefs.getBoolean (key,false));
117             }
118
119             updatePrefsSummary (prefs, pref);
120           }
121           return true;
122         }
123       });
124   }
125
126   @Override
127   protected void onResume() {
128     super.onResume();
129     SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
130     prefs.registerOnSharedPreferenceChangeListener (this);
131     updateAllPrefsSummaries(prefs);
132   }
133
134   @Override
135   protected void onPause() {
136     getPreferenceManager().getSharedPreferences().
137       unregisterOnSharedPreferenceChangeListener(this);
138     super.onPause();
139   }
140
141   @Override
142   protected void onDestroy() {
143     getPreferenceManager().getSharedPreferences().
144       unregisterOnSharedPreferenceChangeListener(this);
145     super.onDestroy();
146   }
147
148   public void onSharedPreferenceChanged (SharedPreferences sharedPreferences,
149                                          String key) {
150     updatePrefsSummary(sharedPreferences, findPreference(key));
151   }
152
153   protected void updatePrefsSummary(SharedPreferences sharedPreferences,
154                                     Preference pref) {
155     if (pref == null)
156       return;
157
158     if (pref instanceof ListPreference) {
159       pref.setTitle (((ListPreference) pref).getEntry());
160     } else if (pref instanceof SliderPreference) {
161       float v = ((SliderPreference) pref).getValue();
162       int i = (int) Math.floor (v);
163       if (v == i)
164         pref.setSummary (String.valueOf (i));
165       else
166         pref.setSummary (String.valueOf (v));
167     } else if (pref instanceof EditTextPreference) {
168       pref.setSummary (((EditTextPreference) pref).getText());
169     }
170   }
171
172   protected void updateAllPrefsSummaries(SharedPreferences prefs) {
173
174     Map <String, ?> keys = prefs.getAll();
175     for (Map.Entry <String, ?> entry : keys.entrySet()) {
176       updatePrefsSummary (prefs, findPreference (entry.getKey()));
177     }
178   }
179 }