14cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann/*
2ef3f8f045ed4150caa64749742227acd0e6b85d8Daniel Lehmann * Copyright (C) 2010 The Android Open Source Project
34cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *
44cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License");
54cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * you may not use this file except in compliance with the License.
64cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * You may obtain a copy of the License at
74cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *
84cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *      http://www.apache.org/licenses/LICENSE-2.0
94cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann *
104cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Unless required by applicable law or agreed to in writing, software
114cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS,
124cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * See the License for the specific language governing permissions and
144cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * limitations under the License
154cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann */
164cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann
17c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmannpackage com.android.contacts.util;
187e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
197e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.app.Activity;
207e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.app.Dialog;
217e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.content.DialogInterface;
227e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.content.DialogInterface.OnDismissListener;
237e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.os.Bundle;
247e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannimport android.view.View;
257e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
26e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
27e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
287e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann/**
297e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * Manages creation and destruction of Dialogs that are to be shown by Views. Unlike how Dialogs
307e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * are regularly used, the Dialogs are not recycled but immediately destroyed after dismissal.
317e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * To be able to do that, two IDs are required which are used consecutively.
327e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * How to use:<ul>
337e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>The owning Activity creates on instance of this class, passing itself and two Ids that are
347e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann *    not used by other Dialogs of the Activity.</li>
357e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>Views owning Dialogs must implement {@link DialogManager.DialogShowingView}</li>
367e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>After creating the Views, configureManagingViews must be called to configure all views
377e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann *    that implement {@link DialogManager.DialogShowingView}</li>
387e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * <li>In the implementation of {@link Activity#onCreateDialog}, calls for the
397e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann *    ViewId are forwarded to {@link DialogManager#onCreateDialog(int, Bundle)}</li>
407e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * </ul>
417e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * To actually show a Dialog, the View uses {@link DialogManager#showDialogInView(View, Bundle)},
427e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann * passing itself as a first parameter
437e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann */
447e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmannpublic class DialogManager {
457e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    private final Activity mActivity;
467e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    private boolean mUseDialogId2 = false;
477e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    public final static String VIEW_ID_KEY = "view_id";
487e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
493b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann    public static final boolean isManagedId(int id) {
503b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann        return (id == R.id.dialog_manager_id_1) || (id == R.id.dialog_manager_id_2);
513b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann    }
523b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann
537e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    /**
547e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * Creates a new instance of this class for the given Activity.
557e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * @param activity The activity this object is used for
567e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     */
573b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann    public DialogManager(final Activity activity) {
587e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        if (activity == null) throw new IllegalArgumentException("activity must not be null");
597e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        mActivity = activity;
607e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    }
617e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
627e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    /**
637e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * Called by a View to show a dialog. It has to pass itself and a Bundle with extra information.
647e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * If the view can show several dialogs, it should distinguish them using an item in the Bundle.
657e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * The View needs to have a valid and unique Id. This function modifies the bundle by adding a
667e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * new item named {@link DialogManager#VIEW_ID_KEY}
677e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     */
687e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    public void showDialogInView(final View view, final Bundle bundle) {
697e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        final int viewId = view.getId();
707e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        if (bundle.containsKey(VIEW_ID_KEY)) {
717e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            throw new IllegalArgumentException("Bundle already contains a " + VIEW_ID_KEY);
727e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        }
737e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        if (viewId == View.NO_ID) {
747e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            throw new IllegalArgumentException("View does not have a proper ViewId");
757e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        }
767e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        bundle.putInt(VIEW_ID_KEY, viewId);
773b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann        int dialogId = mUseDialogId2 ? R.id.dialog_manager_id_2 : R.id.dialog_manager_id_1;
787e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        mActivity.showDialog(dialogId, bundle);
797e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    }
807e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
817e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    /**
827e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * Callback function called by the Activity to handle View-managed Dialogs.
837e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * This function returns null if the id is not one of the two reserved Ids.
847e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     */
857e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    public Dialog onCreateDialog(final int id, final Bundle bundle) {
863b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann        if (id == R.id.dialog_manager_id_1) {
877e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            mUseDialogId2 = true;
883b7d5949bfa524534e5d1aa29b8eaff8733ae00cDaniel Lehmann        } else if (id == R.id.dialog_manager_id_2) {
897e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            mUseDialogId2 = false;
907e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        } else {
917e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            return null;
927e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        }
937e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        if (!bundle.containsKey(VIEW_ID_KEY)) {
947e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            throw new IllegalArgumentException("Bundle does not contain a ViewId");
957e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        }
967e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        final int viewId = bundle.getInt(VIEW_ID_KEY);
977e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        final View view = mActivity.findViewById(viewId);
987e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        if (view == null || !(view instanceof DialogShowingView)) {
997e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            return null;
1007e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        }
1017e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        final Dialog dialog = ((DialogShowingView)view).createDialog(bundle);
1020a6fa1de53d1c95c75b5841d4dc25e2a3367bdc1Dmitri Plotnikov        if (dialog == null) {
1030a6fa1de53d1c95c75b5841d4dc25e2a3367bdc1Dmitri Plotnikov            return dialog;
1040a6fa1de53d1c95c75b5841d4dc25e2a3367bdc1Dmitri Plotnikov        }
1057e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
1067e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        // As we will never re-use this dialog, we can completely kill it here
1077e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        dialog.setOnDismissListener(new OnDismissListener() {
1087e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            public void onDismiss(DialogInterface dialogInterface) {
1097e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann                mActivity.removeDialog(id);
1107e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann            }
1117e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        });
1127e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        return dialog;
1137e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    }
1147e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
1157e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    /**
1167e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * Interface to implemented by Views that show Dialogs
1177e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     */
1187e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    public interface DialogShowingView {
11994c70ac5e5c8c261e962ef96b4b7974e25927fd9Daniel Lehmann        /**
12094c70ac5e5c8c261e962ef96b4b7974e25927fd9Daniel Lehmann         * Callback function to create a Dialog. Notice that the DialogManager overwrites the
1217e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann         * OnDismissListener on the returned Dialog, so the View should not use this Listener itself
1227e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann         */
1237e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        Dialog createDialog(Bundle bundle);
1247e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    }
1257e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann
1267e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    /**
1277e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     * Interface to implemented by Activities that host View-showing dialogs
1287e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann     */
1297e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    public interface DialogShowingViewActivity {
1307e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann        DialogManager getDialogManager();
1317e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann    }
1327e91428b4c39aa40ace1a627bf236634f5e2391fDaniel Lehmann}
133