1 /*
2  * Copyright (C) 2014 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.documentsui.picker;
18 
19 import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
20 import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
21 import static com.android.documentsui.services.FileOperationService.OPERATION_COMPRESS;
22 import static com.android.documentsui.services.FileOperationService.OPERATION_EXTRACT;
23 import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
24 import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
25 
26 import android.os.Bundle;
27 import android.text.TextUtils;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.Button;
32 import android.widget.TextView;
33 
34 import androidx.fragment.app.Fragment;
35 import androidx.fragment.app.FragmentActivity;
36 import androidx.fragment.app.FragmentManager;
37 import androidx.fragment.app.FragmentTransaction;
38 
39 import com.android.documentsui.BaseActivity;
40 import com.android.documentsui.Injector;
41 import com.android.documentsui.R;
42 import com.android.documentsui.base.DocumentInfo;
43 import com.android.documentsui.base.State;
44 import com.android.documentsui.services.FileOperationService.OpType;
45 
46 /**
47  * Display pick confirmation bar, usually for selecting a directory.
48  */
49 public class PickFragment extends Fragment {
50     public static final String TAG = "PickFragment";
51 
52     private static final String ACTION_KEY = "action";
53     private static final String COPY_OPERATION_SUBTYPE_KEY = "copyOperationSubType";
54     private static final String PICK_TARGET_KEY = "pickTarget";
55 
56     private final View.OnClickListener mPickListener = new View.OnClickListener() {
57         @Override
58         public void onClick(View v) {
59             mInjector.actions.pickDocument(getChildFragmentManager(), mPickTarget);
60         }
61     };
62 
63     private final View.OnClickListener mCancelListener = new View.OnClickListener() {
64         @Override
65         public void onClick(View v) {
66             mInjector.pickResult.increaseActionCount();
67             final BaseActivity activity = BaseActivity.get(PickFragment.this);
68             activity.setResult(FragmentActivity.RESULT_CANCELED);
69             activity.finish();
70         }
71     };
72 
73     private Injector<ActionHandler<PickActivity>> mInjector;
74     private int mAction;
75     // Only legal values are OPERATION_COPY, OPERATION_COMPRESS, OPERATION_EXTRACT,
76     // OPERATION_MOVE, and unset (OPERATION_UNKNOWN).
77     private @OpType int mCopyOperationSubType = OPERATION_UNKNOWN;
78     private DocumentInfo mPickTarget;
79     private View mContainer;
80     private TextView mPick;
81     private TextView mCancel;
82 
show(FragmentManager fm)83     public static void show(FragmentManager fm) {
84         // Fragment can be restored by FragmentManager automatically.
85         if (get(fm) != null) {
86             return;
87         }
88 
89         final PickFragment fragment = new PickFragment();
90         final FragmentTransaction ft = fm.beginTransaction();
91         ft.replace(R.id.container_save, fragment, TAG);
92         ft.commitAllowingStateLoss();
93     }
94 
get(FragmentManager fm)95     public static PickFragment get(FragmentManager fm) {
96         return (PickFragment) fm.findFragmentByTag(TAG);
97     }
98 
99     @Override
onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)100     public View onCreateView(
101             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
102         mContainer = inflater.inflate(R.layout.fragment_pick, container, false);
103 
104         mPick = (Button) mContainer.findViewById(android.R.id.button1);
105         mPick.setOnClickListener(mPickListener);
106 
107         mCancel = (Button) mContainer.findViewById(android.R.id.button2);
108         mCancel.setOnClickListener(mCancelListener);
109 
110         updateView();
111         return mContainer;
112     }
113 
114     @Override
onActivityCreated(Bundle savedInstanceState)115     public void onActivityCreated(Bundle savedInstanceState) {
116         super.onActivityCreated(savedInstanceState);
117         if (savedInstanceState != null) {
118             // Restore status
119             mAction = savedInstanceState.getInt(ACTION_KEY);
120             mCopyOperationSubType =
121                     savedInstanceState.getInt(COPY_OPERATION_SUBTYPE_KEY);
122             mPickTarget = savedInstanceState.getParcelable(PICK_TARGET_KEY);
123             updateView();
124         }
125 
126         mInjector = ((PickActivity) getActivity()).getInjector();
127     }
128 
129     @Override
onSaveInstanceState(final Bundle outState)130     public void onSaveInstanceState(final Bundle outState) {
131         super.onSaveInstanceState(outState);
132         outState.putInt(ACTION_KEY, mAction);
133         outState.putInt(COPY_OPERATION_SUBTYPE_KEY, mCopyOperationSubType);
134         outState.putParcelable(PICK_TARGET_KEY, mPickTarget);
135     }
136 
137     /**
138      * @param action Which action defined in State is the picker shown for.
139      */
setPickTarget( int action, @OpType int copyOperationSubType, DocumentInfo pickTarget)140     public void setPickTarget(
141             int action, @OpType int copyOperationSubType, DocumentInfo pickTarget) {
142         assert(copyOperationSubType != OPERATION_DELETE);
143 
144         mAction = action;
145         mCopyOperationSubType = copyOperationSubType;
146         mPickTarget = pickTarget;
147         if (mContainer != null) {
148             updateView();
149         }
150     }
151 
152     /**
153      * Applies the state of fragment to the view components.
154      */
updateView()155     private void updateView() {
156         if (mPickTarget != null && (
157                 mAction == State.ACTION_OPEN_TREE ||
158                         mPickTarget.isCreateSupported())) {
159             mContainer.setVisibility(View.VISIBLE);
160         } else {
161             mContainer.setVisibility(View.GONE);
162             return;
163         }
164 
165         switch (mAction) {
166             case State.ACTION_OPEN_TREE:
167                 final BaseActivity activity = (BaseActivity) getActivity();
168                 final String target = activity.getCurrentTitle();
169                 final String text = TextUtils.isEmpty(target)
170                         ? getString(R.string.button_select)
171                         : getString(R.string.open_tree_button, target);
172                 mPick.setText(text);
173                 mPick.setWidth(Integer.MAX_VALUE);
174                 mCancel.setVisibility(View.GONE);
175                 break;
176             case State.ACTION_PICK_COPY_DESTINATION:
177                 int titleId;
178                 switch (mCopyOperationSubType) {
179                     case OPERATION_COPY:
180                         titleId = R.string.button_copy;
181                         break;
182                     case OPERATION_COMPRESS:
183                         titleId = R.string.button_compress;
184                         break;
185                     case OPERATION_EXTRACT:
186                         titleId = R.string.button_extract;
187                         break;
188                     case OPERATION_MOVE:
189                         titleId = R.string.button_move;
190                         break;
191                     default:
192                         throw new UnsupportedOperationException();
193                 }
194                 mPick.setText(titleId);
195                 mCancel.setVisibility(View.VISIBLE);
196                 break;
197             default:
198                 mContainer.setVisibility(View.GONE);
199                 return;
200         }
201     }
202 }
203