1d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani/*
2d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * Copyright (C) 2010 The Android Open Source Project
3d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani *
4d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
5d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * you may not use this file except in compliance with the License.
6d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * You may obtain a copy of the License at
7d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani *
8d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
9d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani *
10d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * Unless required by applicable law or agreed to in writing, software
11d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
12d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * See the License for the specific language governing permissions and
14d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * limitations under the License.
15d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani */
16d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
17d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasanipackage com.android.settings;
18d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
195bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglioimport android.app.Activity;
20d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.app.Dialog;
21d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.app.DialogFragment;
22b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawaimport android.app.Fragment;
23d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.content.ContentResolver;
24350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasaniimport android.content.Context;
250ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyanimport android.content.DialogInterface;
26d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.content.pm.PackageManager;
27c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglioimport android.database.DataSetObserver;
286602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglioimport android.graphics.drawable.Drawable;
29d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.os.Bundle;
309627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasaniimport android.preference.Preference;
315bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglioimport android.preference.PreferenceActivity;
32d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.preference.PreferenceFragment;
33c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglioimport android.preference.PreferenceGroupAdapter;
34b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasaniimport android.text.TextUtils;
35d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasaniimport android.util.Log;
3686159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglioimport android.view.LayoutInflater;
37b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasaniimport android.view.Menu;
38b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasaniimport android.view.MenuInflater;
39b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasaniimport android.view.MenuItem;
40f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglioimport android.view.View;
4186159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglioimport android.view.ViewGroup;
429c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawaimport android.widget.Button;
43c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglioimport android.widget.ListAdapter;
446602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglioimport android.widget.ListView;
45d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
46f58090d5224fa03e8f4d8a980306952686a152f0Daisuke Miyakawa/**
47d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani * Base class for Settings fragments, with some helper functions and dialog management.
48d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani */
496465054995f8470e52ecaf68ea9508a28f8a5363Gilles Debunnepublic class SettingsPreferenceFragment extends PreferenceFragment implements DialogCreatable {
50d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
51d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    private static final String TAG = "SettingsPreferenceFragment";
52d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
53b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    private static final int MENU_HELP = Menu.FIRST + 100;
54eced780ff55e16079b0e96c0eaf57d8648f972dfFabrice Di Meglio    private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
556602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
566602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
57b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani
58d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    private SettingsDialogFragment mDialogFragment;
59d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
60b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    private String mHelpUrl;
61b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani
62350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani    // Cache the content resolver for async callbacks
63350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani    private ContentResolver mContentResolver;
64350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani
65f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    private String mPreferenceKey;
666602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    private boolean mPreferenceHighlighted = false;
674a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio    private Drawable mHighlightDrawable;
686602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
69d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio    private ListAdapter mCurrentRootAdapter;
70829c8fb2bc728cb871bc398c66ff71b56aa7ebb9Fabrice Di Meglio    private boolean mIsDataSetObserverRegistered = false;
71c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio    private DataSetObserver mDataSetObserver = new DataSetObserver() {
72c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio        @Override
73c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio        public void onChanged() {
74c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio            highlightPreferenceIfNeeded();
75c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio        }
76c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio
77c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio        @Override
78c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio        public void onInvalidated() {
79c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio            highlightPreferenceIfNeeded();
80c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio        }
81c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio    };
82c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio
8386159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    private ViewGroup mPinnedHeaderFrameLayout;
8486159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio
85b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    @Override
86b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    public void onCreate(Bundle icicle) {
87b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani        super.onCreate(icicle);
88b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani
896602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio        if (icicle != null) {
906602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio            mPreferenceHighlighted = icicle.getBoolean(SAVE_HIGHLIGHTED_KEY);
916602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio        }
926602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
93b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani        // Prepare help url and enable menu if necessary
94b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani        int helpResource = getHelpResource();
95b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani        if (helpResource != 0) {
96b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani            mHelpUrl = getResources().getString(helpResource);
97b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani        }
98b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    }
99b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani
100b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa    @Override
10186159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    public View onCreateView(LayoutInflater inflater, ViewGroup container,
10286159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio            Bundle savedInstanceState) {
10386159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio        final View root = super.onCreateView(inflater, container, savedInstanceState);
10486159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio        mPinnedHeaderFrameLayout = (ViewGroup) root.findViewById(R.id.pinned_header);
10586159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio        return root;
10686159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    }
10786159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio
10886159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    public void setPinnedHeaderView(View pinnedHeader) {
10986159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio        mPinnedHeaderFrameLayout.addView(pinnedHeader);
11086159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio        mPinnedHeaderFrameLayout.setVisibility(View.VISIBLE);
11186159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    }
11286159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio
11386159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    public void clearPinnedHeaderView() {
11486159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio        mPinnedHeaderFrameLayout.removeAllViews();
11586159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio        mPinnedHeaderFrameLayout.setVisibility(View.GONE);
11686159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    }
11786159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio
11886159283c98fd862723ce317f1621bcb16d451ceFabrice Di Meglio    @Override
1196602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    public void onSaveInstanceState(Bundle outState) {
1206602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio        super.onSaveInstanceState(outState);
1216602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
1226602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio        outState.putBoolean(SAVE_HIGHLIGHTED_KEY, mPreferenceHighlighted);
1236602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    }
1246602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
1256602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    @Override
126d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public void onActivityCreated(Bundle savedInstanceState) {
127d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        super.onActivityCreated(savedInstanceState);
128b3a593eb766ed499274202db0b817f710c09b8b0Amith Yamasani        if (!TextUtils.isEmpty(mHelpUrl)) {
129b3a593eb766ed499274202db0b817f710c09b8b0Amith Yamasani            setHasOptionsMenu(true);
130b3a593eb766ed499274202db0b817f710c09b8b0Amith Yamasani        }
1314a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio    }
1324a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio
1334a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio    @Override
1344a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio    public void onResume() {
1354a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio        super.onResume();
136c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio
137c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio        final Bundle args = getArguments();
138c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio        if (args != null) {
139f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            mPreferenceKey = args.getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
140f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            highlightPreferenceIfNeeded();
141f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        }
142f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    }
143f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
144f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    @Override
145f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    protected void onBindPreferences() {
146405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio        registerObserverIfNeeded();
147405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio    }
148405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio
149405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio    @Override
150d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio    protected void onUnbindPreferences() {
151d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio        unregisterObserverIfNeeded();
152d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio    }
153d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio
154d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio    @Override
155405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio    public void onStop() {
156405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio        super.onStop();
157405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio
158405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio        unregisterObserverIfNeeded();
159405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio    }
160405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio
161405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio    public void registerObserverIfNeeded() {
162d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio        if (!mIsDataSetObserverRegistered) {
163d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio            if (mCurrentRootAdapter != null) {
164d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio                mCurrentRootAdapter.unregisterDataSetObserver(mDataSetObserver);
1657c435f6b441cfc281f77d2467a58a85a4167ffcdFabrice Di Meglio            }
166d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio            mCurrentRootAdapter = getPreferenceScreen().getRootAdapter();
167d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio            mCurrentRootAdapter.registerDataSetObserver(mDataSetObserver);
168d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio            mIsDataSetObserverRegistered = true;
169829c8fb2bc728cb871bc398c66ff71b56aa7ebb9Fabrice Di Meglio        }
170c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio    }
171c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio
172405febf56adbb2dfb3b2c68d8e76cc5212b9d683Fabrice Di Meglio    public void unregisterObserverIfNeeded() {
173d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio        if (mIsDataSetObserverRegistered) {
174d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio            if (mCurrentRootAdapter != null) {
175d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio                mCurrentRootAdapter.unregisterDataSetObserver(mDataSetObserver);
176d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio                mCurrentRootAdapter = null;
1777c435f6b441cfc281f77d2467a58a85a4167ffcdFabrice Di Meglio            }
178d83b3c2a39e4716b4a4276b8b8ce0db2b9a62b9eFabrice Di Meglio            mIsDataSetObserverRegistered = false;
179829c8fb2bc728cb871bc398c66ff71b56aa7ebb9Fabrice Di Meglio        }
180f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    }
181f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
182f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    public void highlightPreferenceIfNeeded() {
183c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio        if (isAdded() && !mPreferenceHighlighted &&!TextUtils.isEmpty(mPreferenceKey)) {
184f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            highlightPreference(mPreferenceKey);
185f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        }
186f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    }
187f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
188f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    private Drawable getHighlightDrawable() {
1894a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio        if (mHighlightDrawable == null) {
1904a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio            mHighlightDrawable = getActivity().getDrawable(R.drawable.preference_highlight);
1914a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio        }
1924a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio        return mHighlightDrawable;
193f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    }
194f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
195f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    /**
196f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio     * Return a valid ListView position or -1 if none is found
197f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio     */
198f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    private int canUseListViewForHighLighting(String key) {
199f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        if (!hasListView()) {
200f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            return -1;
201f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        }
202f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
203f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        ListView listView = getListView();
204f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        ListAdapter adapter = listView.getAdapter();
205f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
206f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        if (adapter != null && adapter instanceof PreferenceGroupAdapter) {
207f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            return findListPositionFromKey(adapter, key);
2086602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio        }
209f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
210f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        return -1;
2116602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    }
2126602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
2136602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    private void highlightPreference(String key) {
214f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        final Drawable highlight = getHighlightDrawable();
215f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
216f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        final int position = canUseListViewForHighLighting(key);
2176602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio        if (position >= 0) {
2184a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio            mPreferenceHighlighted = true;
2194a2ee7e2b610131452dd26e9b4e17f1bcc865bb9Fabrice Di Meglio
2206602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio            final ListView listView = getListView();
2216602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio            final ListAdapter adapter = listView.getAdapter();
2226602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
223f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            ((PreferenceGroupAdapter) adapter).setHighlightedDrawable(highlight);
224f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            ((PreferenceGroupAdapter) adapter).setHighlighted(position);
225f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio
226f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            listView.post(new Runnable() {
227f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                @Override
228f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                public void run() {
229f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                    listView.setSelection(position);
230f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                    listView.postDelayed(new Runnable() {
231f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                        @Override
232f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                        public void run() {
2332fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                            final int index = position - listView.getFirstVisiblePosition();
2342fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                            if (index >= 0 && index < listView.getChildCount()) {
2352fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                                final View v = listView.getChildAt(index);
2362fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                                final int centerX = v.getWidth() / 2;
2372fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                                final int centerY = v.getHeight() / 2;
2382fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                                highlight.setHotspot(centerX, centerY);
2392fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                                v.setPressed(true);
2402fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                                v.setPressed(false);
2412fed4d4256bd2c77b8b6de50579ec2916649f019Alan Viverette                            }
242c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio                        }
243f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                    }, DELAY_HIGHLIGHT_DURATION_MILLIS);
244f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                }
245f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            });
246c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio        }
247c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio    }
248c1457323d271309d5d1955743cd806417c84b9d6Fabrice Di Meglio
249f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio    private int findListPositionFromKey(ListAdapter adapter, String key) {
250f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        final int count = adapter.getCount();
251f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        for (int n = 0; n < count; n++) {
252f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            final Object item = adapter.getItem(n);
253f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            if (item instanceof Preference) {
254f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                Preference preference = (Preference) item;
255f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                final String preferenceKey = preference.getKey();
256f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                if (preferenceKey != null && preferenceKey.equals(key)) {
257f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                    return n;
258f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio                }
259f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio            }
260f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        }
261f2a5226c1e981ebb0c34aaf39524c382f996196aFabrice Di Meglio        return -1;
2626602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio    }
2636602d02f57ec7375115da26a42357485ff1a778fFabrice Di Meglio
2649627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani    protected void removePreference(String key) {
2659627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani        Preference pref = findPreference(key);
2669627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani        if (pref != null) {
2679627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani            getPreferenceScreen().removePreference(pref);
2689627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani        }
2699627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani    }
2709627a8ea151c1f27e5e9f34592c7b34fea3101c3Amith Yamasani
271b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    /**
272b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani     * Override this if you want to show a help item in the menu, by returning the resource id.
273b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani     * @return the resource id for the help url
274b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani     */
275b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    protected int getHelpResource() {
276b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani        return 0;
277b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    }
278b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani
279b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    @Override
280b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
281aeb57edaef1abdcdcd21eb443047386940ffb755Amith Yamasani        if (mHelpUrl != null && getActivity() != null) {
282b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani            MenuItem helpItem = menu.add(0, MENU_HELP, 0, R.string.help_label);
283aeb57edaef1abdcdcd21eb443047386940ffb755Amith Yamasani            HelpUtils.prepareHelpMenuItem(getActivity(), helpItem, mHelpUrl);
284b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani        }
285b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani    }
286b0b37ae21c172491bc170659b5f429601858ddc1Amith Yamasani
287b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa    /*
288b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa     * The name is intentionally made different from Activity#finish(), so that
289b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa     * users won't misunderstand its meaning.
290b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa     */
291b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa    public final void finishFragment() {
292b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa        getActivity().onBackPressed();
293b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa    }
294b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa
295d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    // Some helpers for functions used by the settings fragments when they were activities
296d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
297d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    /**
298d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani     * Returns the ContentResolver from the owning Activity.
299d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani     */
300d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    protected ContentResolver getContentResolver() {
301350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani        Context context = getActivity();
302350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani        if (context != null) {
303350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani            mContentResolver = context.getContentResolver();
304350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani        }
305350938ecc69085badef2edc16491ff7a461dfb08Amith Yamasani        return mContentResolver;
306d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    }
307d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
308d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    /**
309d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani     * Returns the specified system service from the owning Activity.
310d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani     */
311d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    protected Object getSystemService(final String name) {
312d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        return getActivity().getSystemService(name);
313d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    }
314d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
315d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    /**
316d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani     * Returns the PackageManager from the owning Activity.
317d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani     */
318d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    protected PackageManager getPackageManager() {
319d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        return getActivity().getPackageManager();
320d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    }
321d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
3220385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn    @Override
3230385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn    public void onDetach() {
3240385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn        if (isRemoving()) {
3250385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn            if (mDialogFragment != null) {
3260385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn                mDialogFragment.dismiss();
3270385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn                mDialogFragment = null;
3280385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn            }
3290385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn        }
3300385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn        super.onDetach();
3310385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn    }
3320385cf14a1b02fafc3d1a094ccfee45de4e9b03aDianne Hackborn
333d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    // Dialog management
334d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
335d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    protected void showDialog(int dialogId) {
336d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        if (mDialogFragment != null) {
337d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani            Log.e(TAG, "Old dialog fragment not null!");
338d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        }
339d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        mDialogFragment = new SettingsDialogFragment(this, dialogId);
340377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio        mDialogFragment.show(getChildFragmentManager(), Integer.toString(dialogId));
341d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    }
342d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
343d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    public Dialog onCreateDialog(int dialogId) {
344d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        return null;
345d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    }
346d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
347d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    protected void removeDialog(int dialogId) {
348adc83d83127edd58ff1f823b429cb99871e4488dHung-ying Tyan        // mDialogFragment may not be visible yet in parent fragment's onResume().
349adc83d83127edd58ff1f823b429cb99871e4488dHung-ying Tyan        // To be able to dismiss dialog at that time, don't check
350adc83d83127edd58ff1f823b429cb99871e4488dHung-ying Tyan        // mDialogFragment.isVisible().
351adc83d83127edd58ff1f823b429cb99871e4488dHung-ying Tyan        if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId) {
352d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani            mDialogFragment.dismiss();
353d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        }
354d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        mDialogFragment = null;
355d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    }
356d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
3570ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan    /**
3580ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     * Sets the OnCancelListener of the dialog shown. This method can only be
3590ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     * called after showDialog(int) and before removeDialog(int). The method
3600ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     * does nothing otherwise.
3610ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     */
3620ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan    protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
3630ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        if (mDialogFragment != null) {
3640ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            mDialogFragment.mOnCancelListener = listener;
3650ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        }
3660ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan    }
3670ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan
3680ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan    /**
3690ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     * Sets the OnDismissListener of the dialog shown. This method can only be
3700ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     * called after showDialog(int) and before removeDialog(int). The method
3710ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     * does nothing otherwise.
3720ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan     */
3730ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan    protected void setOnDismissListener(DialogInterface.OnDismissListener listener) {
3740ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        if (mDialogFragment != null) {
3750ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            mDialogFragment.mOnDismissListener = listener;
3760ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        }
3770ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan    }
3780ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan
379c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani    public void onDialogShowing() {
380c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani        // override in subclass to attach a dismiss listener, for instance
381c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani    }
382c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani
38343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public static class SettingsDialogFragment extends DialogFragment {
384749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov        private static final String KEY_DIALOG_ID = "key_dialog_id";
385749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov        private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
386749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov
387d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        private int mDialogId;
388d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
389749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov        private Fragment mParentFragment;
390749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov
3910ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        private DialogInterface.OnCancelListener mOnCancelListener;
3920ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        private DialogInterface.OnDismissListener mOnDismissListener;
3930ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan
394749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov        public SettingsDialogFragment() {
395749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov            /* do nothing */
396749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov        }
397d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
39843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
399d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani            mDialogId = dialogId;
400749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov            if (!(fragment instanceof Fragment)) {
401749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov                throw new IllegalArgumentException("fragment argument must be an instance of "
402749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov                        + Fragment.class.getName());
403749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov            }
404749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov            mParentFragment = (Fragment) fragment;
405749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov        }
406749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov
407749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov        @Override
408300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn        public void onSaveInstanceState(Bundle outState) {
409300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn            super.onSaveInstanceState(outState);
410300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn            if (mParentFragment != null) {
411300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn                outState.putInt(KEY_DIALOG_ID, mDialogId);
412300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn                outState.putInt(KEY_PARENT_FRAGMENT_ID, mParentFragment.getId());
413300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn            }
414300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn        }
415300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn
416300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn        @Override
417c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani        public void onStart() {
418c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani            super.onStart();
419c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani
420c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani            if (mParentFragment != null && mParentFragment instanceof SettingsPreferenceFragment) {
421c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani                ((SettingsPreferenceFragment) mParentFragment).onDialogShowing();
422c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani            }
423c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani        }
424c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani
425c861cf84479d2bb289546e8c4f116beb794842c0Amith Yamasani        @Override
426300768fea5e1bedbf667c8c8a83d5aa3981312d3Dianne Hackborn        public Dialog onCreateDialog(Bundle savedInstanceState) {
427749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov            if (savedInstanceState != null) {
428749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov                mDialogId = savedInstanceState.getInt(KEY_DIALOG_ID, 0);
429377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                mParentFragment = getParentFragment();
430749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov                int mParentFragmentId = savedInstanceState.getInt(KEY_PARENT_FRAGMENT_ID, -1);
431b7bd72f297c9a33e7d819e3a309d304eac165919Fabrice Di Meglio                if (mParentFragment == null) {
432b7bd72f297c9a33e7d819e3a309d304eac165919Fabrice Di Meglio                    mParentFragment = getFragmentManager().findFragmentById(mParentFragmentId);
433b7bd72f297c9a33e7d819e3a309d304eac165919Fabrice Di Meglio                }
434377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                if (!(mParentFragment instanceof DialogCreatable)) {
435377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                    throw new IllegalArgumentException(
436377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                            (mParentFragment != null
437377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                                    ? mParentFragment.getClass().getName()
438377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                                    : mParentFragmentId)
439377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                                    + " must implement "
440377dd62bd7d767b9b944351f4b37b911d0d71b58Fabrice Di Meglio                                    + DialogCreatable.class.getName());
441749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov                }
4428875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                // This dialog fragment could be created from non-SettingsPreferenceFragment
4438875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                if (mParentFragment instanceof SettingsPreferenceFragment) {
4448875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                    // restore mDialogFragment in mParentFragment
4458875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                    ((SettingsPreferenceFragment) mParentFragment).mDialogFragment = this;
4468875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                }
447749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov            }
448749ba652279bb4131a1a9dbe3f5d2cc4302c596dSvetoslav Ganov            return ((DialogCreatable) mParentFragment).onCreateDialog(mDialogId);
449d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        }
450d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani
4510ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        @Override
4520ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        public void onCancel(DialogInterface dialog) {
4530ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            super.onCancel(dialog);
4540ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            if (mOnCancelListener != null) {
4550ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan                mOnCancelListener.onCancel(dialog);
4560ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            }
4570ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        }
4580ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan
4590ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        @Override
4600ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        public void onDismiss(DialogInterface dialog) {
4610ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            super.onDismiss(dialog);
4620ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            if (mOnDismissListener != null) {
4630ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan                mOnDismissListener.onDismiss(dialog);
4640ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan            }
4650ee51e04fb5c39a6272d142efc09d36aa3fbd0ecHung-ying Tyan        }
4668875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani
467d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        public int getDialogId() {
468d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani            return mDialogId;
469d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani        }
47018eb39d085c69d99188e59b01678a092ff36b557Hung-ying Tyan
47118eb39d085c69d99188e59b01678a092ff36b557Hung-ying Tyan        @Override
47218eb39d085c69d99188e59b01678a092ff36b557Hung-ying Tyan        public void onDetach() {
47318eb39d085c69d99188e59b01678a092ff36b557Hung-ying Tyan            super.onDetach();
47418eb39d085c69d99188e59b01678a092ff36b557Hung-ying Tyan
4758875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani            // This dialog fragment could be created from non-SettingsPreferenceFragment
4768875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani            if (mParentFragment instanceof SettingsPreferenceFragment) {
4778875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                // in case the dialog is not explicitly removed by removeDialog()
4788875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                if (((SettingsPreferenceFragment) mParentFragment).mDialogFragment == this) {
4798875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                    ((SettingsPreferenceFragment) mParentFragment).mDialogFragment = null;
4808875edede1f441f66578feb4d09eb314ac40c25eAmith Yamasani                }
48118eb39d085c69d99188e59b01678a092ff36b557Hung-ying Tyan            }
48218eb39d085c69d99188e59b01678a092ff36b557Hung-ying Tyan        }
483d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani    }
4849c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawa
4859c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawa    protected boolean hasNextButton() {
48679c5fd971e71fe7a7f3037474285c1812e3c2c5bDaisuke Miyakawa        return ((ButtonBarHandler)getActivity()).hasNextButton();
4879c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawa    }
4889c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawa
4899c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawa    protected Button getNextButton() {
49079c5fd971e71fe7a7f3037474285c1812e3c2c5bDaisuke Miyakawa        return ((ButtonBarHandler)getActivity()).getNextButton();
4919c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawa    }
4929c8bde576ab18fcfe653587f3e63604430c8791cDaisuke Miyakawa
4936ebf8619d7f09e9642aed84310b56d9847eead94Daisuke Miyakawa    public void finish() {
4946ebf8619d7f09e9642aed84310b56d9847eead94Daisuke Miyakawa        getActivity().onBackPressed();
4956ebf8619d7f09e9642aed84310b56d9847eead94Daisuke Miyakawa    }
4966ebf8619d7f09e9642aed84310b56d9847eead94Daisuke Miyakawa
4975bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio    public boolean startFragment(Fragment caller, String fragmentClass, int titleRes,
4985bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio            int requestCode, Bundle extras) {
4995bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio        final Activity activity = getActivity();
5005bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio        if (activity instanceof SettingsActivity) {
5015bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio            SettingsActivity sa = (SettingsActivity) activity;
5025bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio            sa.startPreferencePanel(fragmentClass, extras, titleRes, null, caller, requestCode);
5035bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio            return true;
5045bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio        } else if (activity instanceof PreferenceActivity) {
5055bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio            PreferenceActivity sa = (PreferenceActivity) activity;
5065bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio            sa.startPreferencePanel(fragmentClass, extras, titleRes, null, caller, requestCode);
50725af150c9804cbca83461588fa5277908baa943dDaisuke Miyakawa            return true;
508b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa        } else {
5095bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio            Log.w(TAG,
5105bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio                    "Parent isn't SettingsActivity nor PreferenceActivity, thus there's no way to "
5115bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio                    + "launch the given Fragment (name: " + fragmentClass
5125bdf0423f9dbc3cf5970045aacdfef79daacc430Fabrice Di Meglio                    + ", requestCode: " + requestCode + ")");
513b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa            return false;
514b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa        }
515b5647c5720ab65a72de7744fb1e7ec7e6dec0b12Daisuke Miyakawa    }
516d79934731c8d33f6fc63b21c120b9ffba5d06f54Amith Yamasani}
517