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