blob: 6f0c91f00c9476fe731c29cc5cb3de1ffecf59a0 [file] [log] [blame]
Amith Yamasanid7993472010-08-18 13:59:28 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
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
17package com.android.settings;
18
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070019import android.app.Activity;
Amith Yamasanid7993472010-08-18 13:59:28 -070020import android.app.Dialog;
21import android.app.DialogFragment;
Daisuke Miyakawab5647c52010-09-10 18:04:02 -070022import android.app.Fragment;
Amith Yamasanid7993472010-08-18 13:59:28 -070023import android.content.ContentResolver;
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070024import android.content.Intent;
Amith Yamasanid7993472010-08-18 13:59:28 -070025import android.content.pm.PackageManager;
Amith Yamasanid7993472010-08-18 13:59:28 -070026import android.os.Bundle;
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070027import android.preference.PreferenceActivity;
Amith Yamasanid7993472010-08-18 13:59:28 -070028import android.preference.PreferenceFragment;
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070029import android.text.TextUtils;
Amith Yamasanid7993472010-08-18 13:59:28 -070030import android.util.Log;
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070031import android.view.View;
32import android.view.View.OnClickListener;
33import android.widget.Button;
Amith Yamasanid7993472010-08-18 13:59:28 -070034
Daisuke Miyakawaf58090d2010-09-12 17:27:33 -070035/**
Amith Yamasanid7993472010-08-18 13:59:28 -070036 * Base class for Settings fragments, with some helper functions and dialog management.
37 */
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070038public class SettingsPreferenceFragment extends PreferenceFragment
39 implements DialogCreatable {
Amith Yamasanid7993472010-08-18 13:59:28 -070040
41 private static final String TAG = "SettingsPreferenceFragment";
42
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070043 // Originally from PreferenceActivity.
44 private static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
45 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
46 private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
47 private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
48
Amith Yamasanid7993472010-08-18 13:59:28 -070049 private SettingsDialogFragment mDialogFragment;
50
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070051 private Button mNextButton;
52
Daisuke Miyakawab5647c52010-09-10 18:04:02 -070053 @Override
Amith Yamasanid7993472010-08-18 13:59:28 -070054 public void onActivityCreated(Bundle savedInstanceState) {
55 super.onActivityCreated(savedInstanceState);
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070056 setupButtonBar();
Amith Yamasanid7993472010-08-18 13:59:28 -070057 }
58
Daisuke Miyakawab5647c52010-09-10 18:04:02 -070059 /*
60 * The name is intentionally made different from Activity#finish(), so that
61 * users won't misunderstand its meaning.
62 */
63 public final void finishFragment() {
64 getActivity().onBackPressed();
65 }
66
Amith Yamasanid7993472010-08-18 13:59:28 -070067 // Some helpers for functions used by the settings fragments when they were activities
68
69 /**
70 * Returns the ContentResolver from the owning Activity.
71 */
72 protected ContentResolver getContentResolver() {
73 return getActivity().getContentResolver();
74 }
75
76 /**
77 * Returns the specified system service from the owning Activity.
78 */
79 protected Object getSystemService(final String name) {
80 return getActivity().getSystemService(name);
81 }
82
83 /**
Amith Yamasanid7993472010-08-18 13:59:28 -070084 * Returns the PackageManager from the owning Activity.
85 */
86 protected PackageManager getPackageManager() {
87 return getActivity().getPackageManager();
88 }
89
90 // Dialog management
91
92 protected void showDialog(int dialogId) {
93 if (mDialogFragment != null) {
94 Log.e(TAG, "Old dialog fragment not null!");
95 }
96 mDialogFragment = new SettingsDialogFragment(this, dialogId);
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070097 mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
Amith Yamasanid7993472010-08-18 13:59:28 -070098 }
99
100 public Dialog onCreateDialog(int dialogId) {
101 return null;
102 }
103
104 protected void removeDialog(int dialogId) {
105 if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId
106 && mDialogFragment.isVisible()) {
107 mDialogFragment.dismiss();
108 }
109 mDialogFragment = null;
110 }
111
Amith Yamasani43c69782010-12-01 09:04:36 -0800112 public static class SettingsDialogFragment extends DialogFragment {
Svetoslav Ganov749ba652010-12-09 14:53:02 -0800113 private static final String KEY_DIALOG_ID = "key_dialog_id";
114 private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
115
Amith Yamasanid7993472010-08-18 13:59:28 -0700116 private int mDialogId;
117
Svetoslav Ganov749ba652010-12-09 14:53:02 -0800118 private Fragment mParentFragment;
119
120 public SettingsDialogFragment() {
121 /* do nothing */
122 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700123
Amith Yamasani43c69782010-12-01 09:04:36 -0800124 public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
Amith Yamasanid7993472010-08-18 13:59:28 -0700125 mDialogId = dialogId;
Svetoslav Ganov749ba652010-12-09 14:53:02 -0800126 if (!(fragment instanceof Fragment)) {
127 throw new IllegalArgumentException("fragment argument must be an instance of "
128 + Fragment.class.getName());
129 }
130 mParentFragment = (Fragment) fragment;
131 }
132
133 @Override
134 public void onActivityCreated(Bundle savedInstanceState) {
135 if (savedInstanceState != null) {
136 mDialogId = savedInstanceState.getInt(KEY_DIALOG_ID, 0);
137 int mParentFragmentId = savedInstanceState.getInt(KEY_PARENT_FRAGMENT_ID, -1);
138 if (mParentFragmentId > -1) {
139 mParentFragment = getFragmentManager().findFragmentById(mParentFragmentId);
140 if (!(mParentFragment instanceof DialogCreatable)) {
141 throw new IllegalArgumentException(
142 KEY_PARENT_FRAGMENT_ID + " must implement "
143 + DialogCreatable.class.getName());
144 }
145 }
146 }
147 super.onActivityCreated(savedInstanceState);
148 }
149
150 @Override
151 public void onSaveInstanceState(Bundle outState) {
152 super.onSaveInstanceState(outState);
153 if (mParentFragment != null) {
154 outState.putInt(KEY_DIALOG_ID, mDialogId);
155 outState.putInt(KEY_PARENT_FRAGMENT_ID, mParentFragment.getId());
156 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700157 }
158
159 @Override
160 public Dialog onCreateDialog(Bundle savedInstanceState) {
Svetoslav Ganov749ba652010-12-09 14:53:02 -0800161 return ((DialogCreatable) mParentFragment).onCreateDialog(mDialogId);
Amith Yamasanid7993472010-08-18 13:59:28 -0700162 }
163
164 public int getDialogId() {
165 return mDialogId;
166 }
167 }
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -0700168
169 protected boolean hasNextButton() {
170 return mNextButton != null;
171 }
172
173 protected Button getNextButton() {
174 return mNextButton;
175 }
176
Daisuke Miyakawa6ebf8612010-09-10 09:48:51 -0700177 public void finish() {
178 getActivity().onBackPressed();
179 }
180
Daisuke Miyakawab5647c52010-09-10 18:04:02 -0700181 public boolean startFragment(
182 Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
Daisuke Miyakawa25af1502010-09-24 11:29:31 -0700183 if (getActivity() instanceof PreferenceActivity) {
184 PreferenceActivity preferenceActivity = (PreferenceActivity)getActivity();
Amith Yamasani928e78a2010-11-12 08:51:01 -0800185 preferenceActivity.startPreferencePanel(fragmentClass, extras, 0, null, caller,
186 requestCode);
Daisuke Miyakawa25af1502010-09-24 11:29:31 -0700187 return true;
Daisuke Miyakawab5647c52010-09-10 18:04:02 -0700188 } else {
Daisuke Miyakawa25af1502010-09-24 11:29:31 -0700189 Log.w(TAG, "Parent isn't PreferenceActivity, thus there's no way to launch the "
190 + "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode
191 + ")");
Daisuke Miyakawab5647c52010-09-10 18:04:02 -0700192 return false;
193 }
194 }
195
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -0700196 /**
197 * Sets up Button Bar possibly required in the Fragment. Probably available only in
198 * phones.
199 *
200 * Previously {@link PreferenceActivity} had the capability as hidden functionality.
201 */
202 private void setupButtonBar() {
203 // Originally from PreferenceActivity, which has had button bar inside its layout.
204 final Activity activity = getActivity();
205 final Intent intent = activity.getIntent();
206 final View buttonBar = activity.findViewById(com.android.internal.R.id.button_bar);
207 if (!intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false) || buttonBar == null) {
208 return;
209 }
210
211 buttonBar.setVisibility(View.VISIBLE);
212 View tmpView = activity.findViewById(com.android.internal.R.id.back_button);
213 if (tmpView != null) {
214 // TODO: Assume this is pressed only in single pane, finishing current Activity.
215 try {
216 final Button backButton = (Button)tmpView;
217 backButton.setOnClickListener(new OnClickListener() {
218 public void onClick(View v) {
219 activity.setResult(Activity.RESULT_CANCELED);
220 activity.finish();
221 }
222 });
223 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
224 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
225 if (TextUtils.isEmpty(buttonText)) {
226 backButton.setVisibility(View.GONE);
227 }
228 else {
229 backButton.setText(buttonText);
230 }
231 }
232 } catch (ClassCastException e) {
233 Log.w(TAG, "The view originally for back_button is used not as Button. " +
234 "Ignored.");
235 }
236 }
237
238 tmpView = activity.findViewById(com.android.internal.R.id.skip_button);
239 if (tmpView != null) {
240 try {
241 final Button skipButton = (Button)tmpView;
242 skipButton.setOnClickListener(new OnClickListener() {
243 public void onClick(View v) {
244 activity.setResult(Activity.RESULT_OK);
245 activity.finish();
246 }
247 });
248 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
249 skipButton.setVisibility(View.VISIBLE);
250 }
251 } catch (ClassCastException e) {
252 Log.w(TAG, "The view originally for skip_button is used not as Button. " +
253 "Ignored.");
254 }
255 }
256
257 tmpView = activity.findViewById(com.android.internal.R.id.next_button);
258 if (tmpView != null) {
259 try {
260 mNextButton = (Button)tmpView;
261 mNextButton.setOnClickListener(new OnClickListener() {
262 public void onClick(View v) {
263 activity.setResult(Activity.RESULT_OK);
264 activity.finish();
265 }
266 });
267 // set our various button parameters
268 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
269 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
270 if (TextUtils.isEmpty(buttonText)) {
271 mNextButton.setVisibility(View.GONE);
272 }
273 else {
274 mNextButton.setText(buttonText);
275 }
276 }
277 } catch (ClassCastException e) {
278 Log.w(TAG, "The view originally for next_button is used not as Button. " +
279 "Ignored.");
280 mNextButton = null;
281 }
282 }
283 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700284}