OSDN Git Service

am 28539897: am 8815f032: Merge "Always set right auth_type value in apn."
[android-x86/packages-apps-Settings.git] / src / com / android / settings / SettingsPreferenceFragment.java
1 /*
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
17 package com.android.settings;
18
19 import android.app.Activity;
20 import android.app.Dialog;
21 import android.app.DialogFragment;
22 import android.app.Fragment;
23 import android.content.ContentResolver;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.content.res.Resources;
27 import android.os.Bundle;
28 import android.preference.PreferenceActivity;
29 import android.preference.PreferenceFragment;
30 import android.text.TextUtils;
31 import android.util.Log;
32 import android.view.View;
33 import android.view.View.OnClickListener;
34 import android.widget.Button;
35
36 /**
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  */
41 interface DialogCreatable {
42     public Dialog onCreateDialog(int dialogId);
43 }
44
45 /**
46  * Base class for Settings fragments, with some helper functions and dialog management.
47  */
48 public class SettingsPreferenceFragment extends PreferenceFragment
49         implements DialogCreatable {
50
51     private static final String TAG = "SettingsPreferenceFragment";
52
53     // 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
59     private SettingsDialogFragment mDialogFragment;
60
61     private int mResultCode = Activity.RESULT_CANCELED;
62     private Intent mResultData;
63
64     private Button mNextButton;
65
66     @Override
67     public void onResume() {
68         super.onResume();
69
70         final Fragment f = getTargetFragment();
71         final int requestCode = getTargetRequestCode();
72
73         // TargetFragment becomes invalid when this object is resumed. Notify it to
74         // FragmentManager. Without this code, FragmentManager wrongly take the TargetFragment
75         // as live, and throws IllegalStateException.
76         setTargetFragment(null, -1);
77
78         if (f != null && (f instanceof SettingsPreferenceFragment)) {
79             final SettingsPreferenceFragment spf = (SettingsPreferenceFragment)f;
80             final int resultCode = spf.getResultCode();
81             final Intent resultData = spf.getResultData();
82             onActivityResult(requestCode, resultCode, resultData);
83         }
84     }
85
86     @Override
87     public void onActivityCreated(Bundle savedInstanceState) {
88         super.onActivityCreated(savedInstanceState);
89         setupButtonBar();
90     }
91
92     public final void setResult(int resultCode) {
93         mResultCode = resultCode;
94         mResultData = null;
95     }
96
97     public final void setResult(int resultCode, Intent data) {
98         mResultCode = resultCode;
99         mResultData = data;
100     }
101
102     public final int getResultCode() {
103         return mResultCode;
104     }
105
106     public final Intent getResultData() {
107         return mResultData;
108     }
109
110     /*
111      * The name is intentionally made different from Activity#finish(), so that
112      * users won't misunderstand its meaning.
113      */
114     public final void finishFragment() {
115         getActivity().onBackPressed();
116     }
117
118     // Some helpers for functions used by the settings fragments when they were activities
119
120     /**
121      * Returns the ContentResolver from the owning Activity.
122      */
123     protected ContentResolver getContentResolver() {
124         return getActivity().getContentResolver();
125     }
126
127     /**
128      * Returns the specified system service from the owning Activity.
129      */
130     protected Object getSystemService(final String name) {
131         return getActivity().getSystemService(name);
132     }
133
134     /**
135      * Returns the Resources from the owning Activity.
136      */
137     protected Resources getResources() {
138         return getActivity().getResources();
139     }
140
141     /**
142      * Returns the PackageManager from the owning Activity.
143      */
144     protected PackageManager getPackageManager() {
145         return getActivity().getPackageManager();
146     }
147
148     // Dialog management
149
150     protected void showDialog(int dialogId) {
151         if (mDialogFragment != null) {
152             Log.e(TAG, "Old dialog fragment not null!");
153         }
154         mDialogFragment = new SettingsDialogFragment(this, dialogId);
155         mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
156     }
157
158     @Override
159     public Dialog onCreateDialog(int dialogId) {
160         return null;
161     }
162
163     protected void removeDialog(int dialogId) {
164         if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId
165                 && mDialogFragment.isVisible()) {
166             mDialogFragment.dismiss();
167         }
168         mDialogFragment = null;
169     }
170
171     static class SettingsDialogFragment extends DialogFragment {
172         private int mDialogId;
173
174         private DialogCreatable mFragment;
175
176         SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
177             mDialogId = dialogId;
178             mFragment = fragment;
179         }
180
181         @Override
182         public Dialog onCreateDialog(Bundle savedInstanceState) {
183             return mFragment.onCreateDialog(mDialogId);
184         }
185
186         public int getDialogId() {
187             return mDialogId;
188         }
189     }
190
191     protected boolean hasNextButton() {
192         return mNextButton != null;
193     }
194
195     protected Button getNextButton() {
196         return mNextButton;
197     }
198
199     public void finish() {
200         getActivity().onBackPressed();
201     }
202
203     public boolean startFragment(
204             Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
205         if (getActivity() instanceof PreferenceActivity) {
206             PreferenceActivity preferenceActivity = (PreferenceActivity)getActivity();
207             Fragment f = Fragment.instantiate(getActivity(), fragmentClass, extras);
208             caller.setTargetFragment(f, requestCode);
209             preferenceActivity.switchToHeader(fragmentClass, extras);
210             return true;
211         } else {
212             Log.w(TAG, "Parent isn't PreferenceActivity, thus there's no way to launch the "
213                     + "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode
214                     + ")");
215             return false;
216         }
217     }
218
219     /**
220      * Sets up Button Bar possibly required in the Fragment. Probably available only in
221      * phones.
222      *
223      * Previously {@link PreferenceActivity} had the capability as hidden functionality.
224      */
225     private void setupButtonBar() {
226         // Originally from PreferenceActivity, which has had button bar inside its layout.
227         final Activity activity = getActivity();
228         final Intent intent = activity.getIntent();
229         final View buttonBar = activity.findViewById(com.android.internal.R.id.button_bar);
230         if (!intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false) || buttonBar == null) {
231             return;
232         }
233
234         buttonBar.setVisibility(View.VISIBLE);
235         View tmpView = activity.findViewById(com.android.internal.R.id.back_button);
236         if (tmpView != null) {
237             // TODO: Assume this is pressed only in single pane, finishing current Activity.
238             try {
239                 final Button backButton = (Button)tmpView;
240                 backButton.setOnClickListener(new OnClickListener() {
241                     public void onClick(View v) {
242                         activity.setResult(Activity.RESULT_CANCELED);
243                         activity.finish();
244                     }
245                 });
246                 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
247                     String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
248                     if (TextUtils.isEmpty(buttonText)) {
249                         backButton.setVisibility(View.GONE);
250                     }
251                     else {
252                         backButton.setText(buttonText);
253                     }
254                 }
255             } catch (ClassCastException e) {
256                 Log.w(TAG, "The view originally for back_button is used not as Button. " +
257                         "Ignored.");
258             }
259         }
260
261         tmpView = activity.findViewById(com.android.internal.R.id.skip_button);
262         if (tmpView != null) {
263             try {
264                 final Button skipButton = (Button)tmpView;
265                 skipButton.setOnClickListener(new OnClickListener() {
266                     public void onClick(View v) {
267                         activity.setResult(Activity.RESULT_OK);
268                         activity.finish();
269                     }
270                 });
271                 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
272                     skipButton.setVisibility(View.VISIBLE);
273                 }
274             } catch (ClassCastException e) {
275                 Log.w(TAG, "The view originally for skip_button is used not as Button. " +
276                         "Ignored.");
277             }
278         }
279
280         tmpView = activity.findViewById(com.android.internal.R.id.next_button);
281         if (tmpView != null) {
282             try {
283                 mNextButton = (Button)tmpView;
284                 mNextButton.setOnClickListener(new OnClickListener() {
285                     public void onClick(View v) {
286                         activity.setResult(Activity.RESULT_OK);
287                         activity.finish();
288                     }
289                 });
290                 // set our various button parameters
291                 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
292                     String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
293                     if (TextUtils.isEmpty(buttonText)) {
294                         mNextButton.setVisibility(View.GONE);
295                     }
296                     else {
297                         mNextButton.setText(buttonText);
298                     }
299                 }
300             } catch (ClassCastException e) {
301                 Log.w(TAG, "The view originally for next_button is used not as Button. " +
302                         "Ignored.");
303                 mNextButton = null;
304             }
305         }
306     }
307 }