16e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey/*
26e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * Copyright (C) 2014 The Android Open Source Project
36e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey *
46e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
56e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * you may not use this file except in compliance with the License.
66e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * You may obtain a copy of the License at
76e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey *
86e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
96e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey *
106e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
116e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
126e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * See the License for the specific language governing permissions and
146e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * limitations under the License.
156e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey */
166e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
17d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKaypackage com.android.documentsui.picker;
186e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
19c8bdc7f8c692c22afa3312bc5ff672449b0a58a5Steve McKayimport static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
20bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewskiimport static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
21bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewskiimport static com.android.documentsui.services.FileOperationService.OPERATION_COMPRESS;
22bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewskiimport static com.android.documentsui.services.FileOperationService.OPERATION_EXTRACT;
23f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKayimport static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
24c8bdc7f8c692c22afa3312bc5ff672449b0a58a5Steve McKayimport static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
25f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKay
26676453ce79abc53cd2ec4d41cce3829e21697f49Daichi Hironoimport android.app.Activity;
276e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.app.Fragment;
286e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.app.FragmentManager;
296e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.app.FragmentTransaction;
306e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.os.Bundle;
316e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.view.LayoutInflater;
326e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.view.View;
336e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.view.ViewGroup;
346e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeyimport android.widget.Button;
3510e77bf308e4a4e6c5ad28bcf25714d7ae33e35fGarfield Tanimport android.widget.TextView;
366e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
37d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.BaseActivity;
3823ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tanimport com.android.documentsui.Injector;
39d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.R;
40d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport com.android.documentsui.base.DocumentInfo;
41d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport com.android.documentsui.base.State;
42f171934ad7a9d901e81a33bbd0ec74aa34a48787Steve McKayimport com.android.documentsui.services.FileOperationService.OpType;
436e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
446e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey/**
456e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey * Display pick confirmation bar, usually for selecting a directory.
466e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey */
476e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkeypublic class PickFragment extends Fragment {
486e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    public static final String TAG = "PickFragment";
496e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
50242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    private static final String ACTION_KEY = "action";
51242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    private static final String COPY_OPERATION_SUBTYPE_KEY = "copyOperationSubType";
52242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    private static final String PICK_TARGET_KEY = "pickTarget";
53242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan
54242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    private final View.OnClickListener mPickListener = new View.OnClickListener() {
55242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        @Override
56242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        public void onClick(View v) {
5723ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan            mInjector.actions.pickDocument(mPickTarget);
58242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        }
59242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    };
60242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan
61242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    private final View.OnClickListener mCancelListener = new View.OnClickListener() {
62242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        @Override
63242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        public void onClick(View v) {
64242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            final BaseActivity activity = BaseActivity.get(PickFragment.this);
65242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            activity.setResult(Activity.RESULT_CANCELED);
66242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            activity.finish();
67242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        }
68242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    };
69242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan
7023ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan    private Injector<ActionHandler<PickActivity>> mInjector;
714e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono    private int mAction;
72bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski    // Only legal values are OPERATION_COPY, OPERATION_COMPRESS, OPERATION_EXTRACT,
73bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski    // OPERATION_MOVE, and unset (OPERATION_UNKNOWN).
74c8bdc7f8c692c22afa3312bc5ff672449b0a58a5Steve McKay    private @OpType int mCopyOperationSubType = OPERATION_UNKNOWN;
756e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    private DocumentInfo mPickTarget;
766e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    private View mContainer;
7710e77bf308e4a4e6c5ad28bcf25714d7ae33e35fGarfield Tan    private TextView mPick;
7810e77bf308e4a4e6c5ad28bcf25714d7ae33e35fGarfield Tan    private TextView mCancel;
796e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
806e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    public static void show(FragmentManager fm) {
814e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        // Fragment can be restored by FragmentManager automatically.
824e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        if (get(fm) != null) {
834e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono            return;
844e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        }
856e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
864e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        final PickFragment fragment = new PickFragment();
876e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        final FragmentTransaction ft = fm.beginTransaction();
886e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        ft.replace(R.id.container_save, fragment, TAG);
896e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        ft.commitAllowingStateLoss();
906e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    }
916e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
926e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    public static PickFragment get(FragmentManager fm) {
936e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        return (PickFragment) fm.findFragmentByTag(TAG);
946e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    }
956e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
966e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    @Override
976e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    public View onCreateView(
986e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
996e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        mContainer = inflater.inflate(R.layout.fragment_pick, container, false);
1006e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
10110e77bf308e4a4e6c5ad28bcf25714d7ae33e35fGarfield Tan        mPick = (TextView) mContainer.findViewById(android.R.id.button1);
1026e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        mPick.setOnClickListener(mPickListener);
1036e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
10410e77bf308e4a4e6c5ad28bcf25714d7ae33e35fGarfield Tan        mCancel = (TextView) mContainer.findViewById(android.R.id.button2);
105676453ce79abc53cd2ec4d41cce3829e21697f49Daichi Hirono        mCancel.setOnClickListener(mCancelListener);
106676453ce79abc53cd2ec4d41cce3829e21697f49Daichi Hirono
1074e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        updateView();
1086e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        return mContainer;
1096e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    }
1106e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
111242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    @Override
112242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    public void onActivityCreated(Bundle savedInstanceState) {
113242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        super.onActivityCreated(savedInstanceState);
114242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        if (savedInstanceState != null) {
115242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            // Restore status
116242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            mAction = savedInstanceState.getInt(ACTION_KEY);
117242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            mCopyOperationSubType =
118242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan                    savedInstanceState.getInt(COPY_OPERATION_SUBTYPE_KEY);
119242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            mPickTarget = savedInstanceState.getParcelable(PICK_TARGET_KEY);
120242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan            updateView();
1216e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        }
12223ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan
12323ac60cd2b1beb59b6cd760b91c7e1b1f7e8fe49Garfield Tan        mInjector = ((PickActivity) getActivity()).getInjector();
124242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    }
1256e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
126242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    @Override
127242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    public void onSaveInstanceState(final Bundle outState) {
128242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        super.onSaveInstanceState(outState);
129242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        outState.putInt(ACTION_KEY, mAction);
130242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        outState.putInt(COPY_OPERATION_SUBTYPE_KEY, mCopyOperationSubType);
131242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan        outState.putParcelable(PICK_TARGET_KEY, mPickTarget);
132242cb88857ccc197286181ce85cbf0859ae7d71dGarfield Tan    }
1336e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey
134676453ce79abc53cd2ec4d41cce3829e21697f49Daichi Hirono    /**
135f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKay     * @param action Which action defined in State is the picker shown for.
136676453ce79abc53cd2ec4d41cce3829e21697f49Daichi Hirono     */
137c8bdc7f8c692c22afa3312bc5ff672449b0a58a5Steve McKay    public void setPickTarget(
138c8bdc7f8c692c22afa3312bc5ff672449b0a58a5Steve McKay            int action, @OpType int copyOperationSubType, DocumentInfo pickTarget) {
1390af8afd3309538dec784ed0c9c35b252a8213123Steve McKay        assert(copyOperationSubType != OPERATION_DELETE);
1400af8afd3309538dec784ed0c9c35b252a8213123Steve McKay
1414e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        mAction = action;
142c8bdc7f8c692c22afa3312bc5ff672449b0a58a5Steve McKay        mCopyOperationSubType = copyOperationSubType;
1434e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        mPickTarget = pickTarget;
144f4943e16a80a7ae37ee19e9301017c15061df378Jeff Sharkey        if (mContainer != null) {
1454e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono            updateView();
1464e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        }
1474e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono    }
1484e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono
1494e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono    /**
1504e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono     * Applies the state of fragment to the view components.
1514e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono     */
1524e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono    private void updateView() {
1534e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        switch (mAction) {
154f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKay            case State.ACTION_OPEN_TREE:
1554e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                mPick.setText(R.string.button_select);
1564e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                mCancel.setVisibility(View.GONE);
1574e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                break;
158ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa            case State.ACTION_PICK_COPY_DESTINATION:
159bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                int titleId;
160bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                switch (mCopyOperationSubType) {
161bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                    case OPERATION_COPY:
162bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        titleId = R.string.button_copy;
163bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        break;
164bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                    case OPERATION_COMPRESS:
165bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        titleId = R.string.button_compress;
166bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        break;
167bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                    case OPERATION_EXTRACT:
168bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        titleId = R.string.button_extract;
169bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        break;
170bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                    case OPERATION_MOVE:
171bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        titleId = R.string.button_move;
172bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        break;
173bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                    default:
174bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                        throw new UnsupportedOperationException();
175bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                }
176bc7eb5fc39b5555eedc7d7b3591687343ecda18dTomasz Mikolajewski                mPick.setText(titleId);
1774e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                mCancel.setVisibility(View.VISIBLE);
1784e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                break;
1794e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono            default:
180f4943e16a80a7ae37ee19e9301017c15061df378Jeff Sharkey                mContainer.setVisibility(View.GONE);
1814e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                return;
1824e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        }
1834e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono
1844e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        if (mPickTarget != null && (
185f8a5e08bfb793e0b1ec7e3ac455a6158ff968afcSteve McKay                mAction == State.ACTION_OPEN_TREE ||
1864e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono                mPickTarget.isCreateSupported())) {
1874e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono            mContainer.setVisibility(View.VISIBLE);
1884e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono        } else {
1894e2bb18dbb0ee7c24888e99e1cba386edbad1dc3Daichi Hirono            mContainer.setVisibility(View.GONE);
1906e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey        }
1916e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey    }
1926e565ffab8916af6c991c4f189a7ec438bce6978Jeff Sharkey}
193