blob: 3c771f592eef8310626289a0364c7912335a8e8d [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;
26import android.content.res.Resources;
27import android.os.Bundle;
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070028import android.preference.PreferenceActivity;
Amith Yamasanid7993472010-08-18 13:59:28 -070029import android.preference.PreferenceFragment;
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070030import android.text.TextUtils;
Amith Yamasanid7993472010-08-18 13:59:28 -070031import android.util.Log;
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070032import android.view.View;
33import android.view.View.OnClickListener;
34import android.widget.Button;
Amith Yamasanid7993472010-08-18 13:59:28 -070035
Daisuke Miyakawaf58090d2010-09-12 17:27:33 -070036/**
37 * Letting the class, assumed to be Fragment, create a Dialog on it. Should be useful
38 * you want to utilize some capability in {@link SettingsPreferenceFragment} but don't want
39 * the class inherit the class itself (See {@link ProxySelector} for example).
40 */
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070041interface DialogCreatable {
42 public Dialog onCreateDialog(int dialogId);
43}
44
Amith Yamasanid7993472010-08-18 13:59:28 -070045/**
46 * Base class for Settings fragments, with some helper functions and dialog management.
47 */
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070048public class SettingsPreferenceFragment extends PreferenceFragment
49 implements DialogCreatable {
Amith Yamasanid7993472010-08-18 13:59:28 -070050
51 private static final String TAG = "SettingsPreferenceFragment";
52
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070053 // Originally from PreferenceActivity.
54 private static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
55 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
56 private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
57 private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
58
Amith Yamasanid7993472010-08-18 13:59:28 -070059 private SettingsDialogFragment mDialogFragment;
60
Daisuke Miyakawab5647c52010-09-10 18:04:02 -070061 private int mResultCode = Activity.RESULT_CANCELED;
62 private Intent mResultData;
Amith Yamasanid7993472010-08-18 13:59:28 -070063
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070064 private Button mNextButton;
65
Daisuke Miyakawab5647c52010-09-10 18:04:02 -070066 @Override
Amith Yamasanid7993472010-08-18 13:59:28 -070067 public void onActivityCreated(Bundle savedInstanceState) {
68 super.onActivityCreated(savedInstanceState);
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -070069 setupButtonBar();
Amith Yamasanid7993472010-08-18 13:59:28 -070070 }
71
Daisuke Miyakawab5647c52010-09-10 18:04:02 -070072 /*
73 * The name is intentionally made different from Activity#finish(), so that
74 * users won't misunderstand its meaning.
75 */
76 public final void finishFragment() {
77 getActivity().onBackPressed();
78 }
79
Amith Yamasanid7993472010-08-18 13:59:28 -070080 // Some helpers for functions used by the settings fragments when they were activities
81
82 /**
83 * Returns the ContentResolver from the owning Activity.
84 */
85 protected ContentResolver getContentResolver() {
86 return getActivity().getContentResolver();
87 }
88
89 /**
90 * Returns the specified system service from the owning Activity.
91 */
92 protected Object getSystemService(final String name) {
93 return getActivity().getSystemService(name);
94 }
95
96 /**
Amith Yamasanid7993472010-08-18 13:59:28 -070097 * Returns the PackageManager from the owning Activity.
98 */
99 protected PackageManager getPackageManager() {
100 return getActivity().getPackageManager();
101 }
102
103 // Dialog management
104
105 protected void showDialog(int dialogId) {
106 if (mDialogFragment != null) {
107 Log.e(TAG, "Old dialog fragment not null!");
108 }
109 mDialogFragment = new SettingsDialogFragment(this, dialogId);
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700110 mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
Amith Yamasanid7993472010-08-18 13:59:28 -0700111 }
112
113 public Dialog onCreateDialog(int dialogId) {
114 return null;
115 }
116
117 protected void removeDialog(int dialogId) {
118 if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId
119 && mDialogFragment.isVisible()) {
120 mDialogFragment.dismiss();
121 }
122 mDialogFragment = null;
123 }
124
125 static class SettingsDialogFragment extends DialogFragment {
126 private int mDialogId;
127
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700128 private DialogCreatable mFragment;
Amith Yamasanid7993472010-08-18 13:59:28 -0700129
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700130 SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
Amith Yamasanid7993472010-08-18 13:59:28 -0700131 mDialogId = dialogId;
132 mFragment = fragment;
133 }
134
135 @Override
136 public Dialog onCreateDialog(Bundle savedInstanceState) {
137 return mFragment.onCreateDialog(mDialogId);
138 }
139
140 public int getDialogId() {
141 return mDialogId;
142 }
143 }
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -0700144
145 protected boolean hasNextButton() {
146 return mNextButton != null;
147 }
148
149 protected Button getNextButton() {
150 return mNextButton;
151 }
152
Daisuke Miyakawa6ebf8612010-09-10 09:48:51 -0700153 public void finish() {
154 getActivity().onBackPressed();
155 }
156
Daisuke Miyakawab5647c52010-09-10 18:04:02 -0700157 public boolean startFragment(
158 Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
Daisuke Miyakawa25af1502010-09-24 11:29:31 -0700159 if (getActivity() instanceof PreferenceActivity) {
160 PreferenceActivity preferenceActivity = (PreferenceActivity)getActivity();
Amith Yamasani928e78a2010-11-12 08:51:01 -0800161 preferenceActivity.startPreferencePanel(fragmentClass, extras, 0, null, caller,
162 requestCode);
Daisuke Miyakawa25af1502010-09-24 11:29:31 -0700163 return true;
Daisuke Miyakawab5647c52010-09-10 18:04:02 -0700164 } else {
Daisuke Miyakawa25af1502010-09-24 11:29:31 -0700165 Log.w(TAG, "Parent isn't PreferenceActivity, thus there's no way to launch the "
166 + "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode
167 + ")");
Daisuke Miyakawab5647c52010-09-10 18:04:02 -0700168 return false;
169 }
170 }
171
Daisuke Miyakawa9c8bde52010-08-25 11:58:37 -0700172 /**
173 * Sets up Button Bar possibly required in the Fragment. Probably available only in
174 * phones.
175 *
176 * Previously {@link PreferenceActivity} had the capability as hidden functionality.
177 */
178 private void setupButtonBar() {
179 // Originally from PreferenceActivity, which has had button bar inside its layout.
180 final Activity activity = getActivity();
181 final Intent intent = activity.getIntent();
182 final View buttonBar = activity.findViewById(com.android.internal.R.id.button_bar);
183 if (!intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false) || buttonBar == null) {
184 return;
185 }
186
187 buttonBar.setVisibility(View.VISIBLE);
188 View tmpView = activity.findViewById(com.android.internal.R.id.back_button);
189 if (tmpView != null) {
190 // TODO: Assume this is pressed only in single pane, finishing current Activity.
191 try {
192 final Button backButton = (Button)tmpView;
193 backButton.setOnClickListener(new OnClickListener() {
194 public void onClick(View v) {
195 activity.setResult(Activity.RESULT_CANCELED);
196 activity.finish();
197 }
198 });
199 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
200 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
201 if (TextUtils.isEmpty(buttonText)) {
202 backButton.setVisibility(View.GONE);
203 }
204 else {
205 backButton.setText(buttonText);
206 }
207 }
208 } catch (ClassCastException e) {
209 Log.w(TAG, "The view originally for back_button is used not as Button. " +
210 "Ignored.");
211 }
212 }
213
214 tmpView = activity.findViewById(com.android.internal.R.id.skip_button);
215 if (tmpView != null) {
216 try {
217 final Button skipButton = (Button)tmpView;
218 skipButton.setOnClickListener(new OnClickListener() {
219 public void onClick(View v) {
220 activity.setResult(Activity.RESULT_OK);
221 activity.finish();
222 }
223 });
224 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
225 skipButton.setVisibility(View.VISIBLE);
226 }
227 } catch (ClassCastException e) {
228 Log.w(TAG, "The view originally for skip_button is used not as Button. " +
229 "Ignored.");
230 }
231 }
232
233 tmpView = activity.findViewById(com.android.internal.R.id.next_button);
234 if (tmpView != null) {
235 try {
236 mNextButton = (Button)tmpView;
237 mNextButton.setOnClickListener(new OnClickListener() {
238 public void onClick(View v) {
239 activity.setResult(Activity.RESULT_OK);
240 activity.finish();
241 }
242 });
243 // set our various button parameters
244 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
245 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
246 if (TextUtils.isEmpty(buttonText)) {
247 mNextButton.setVisibility(View.GONE);
248 }
249 else {
250 mNextButton.setText(buttonText);
251 }
252 }
253 } catch (ClassCastException e) {
254 Log.w(TAG, "The view originally for next_button is used not as Button. " +
255 "Ignored.");
256 mNextButton = null;
257 }
258 }
259 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700260}