blob: ac2c513200966d72bc4acd44d0698f768a9f7d56 [file] [log] [blame]
Steve McKayd0a2a2c2015-03-25 14:35:33 -07001/*
2 * Copyright (C) 2015 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
Steve McKayb6006b22016-09-29 09:23:45 -070017package com.android.documentsui.files;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070018
Steve McKaydf5add42016-01-28 12:02:57 -080019import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN;
Steve McKay7ef09a22015-05-06 12:16:40 -070020
Steve McKay7295c482017-03-15 17:51:32 -070021import android.app.ActivityManager.TaskDescription;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070022import android.content.Intent;
Tony Huangf7b05c42019-05-02 16:51:01 +080023import android.graphics.Color;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070024import android.net.Uri;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070025import android.os.Bundle;
Steve McKay0599a442015-05-05 14:50:00 -070026import android.view.KeyEvent;
Ben Lina8673232016-09-28 15:40:04 -070027import android.view.KeyboardShortcutGroup;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070028import android.view.Menu;
29import android.view.MenuItem;
Tony Huangf7b05c42019-05-02 16:51:01 +080030import android.view.View;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070031
Sunny Goyal5b225532018-07-03 12:44:03 -070032import androidx.annotation.CallSuper;
Tony Huang8d8d92f2018-09-13 14:41:16 +080033import androidx.fragment.app.FragmentManager;
Sunny Goyal5b225532018-07-03 12:44:03 -070034
Tony Huangcf747152019-11-18 13:43:41 +080035import com.android.documentsui.AbstractActionHandler;
Steve McKaybd9f05a2016-10-10 10:18:36 -070036import com.android.documentsui.ActionModeController;
Steve McKay16e0c1f2016-09-15 12:41:13 -070037import com.android.documentsui.BaseActivity;
Steve McKay365e3cb2017-08-31 10:27:08 -070038import com.android.documentsui.DocsSelectionHelper;
Steve McKay16e0c1f2016-09-15 12:41:13 -070039import com.android.documentsui.DocumentsApplication;
Ben Lin75b7b902016-11-02 15:59:29 -070040import com.android.documentsui.FocusManager;
Steve McKay92ae43d2016-11-08 12:06:58 -080041import com.android.documentsui.Injector;
Ben Lin7c35b032016-05-31 13:24:01 -070042import com.android.documentsui.MenuManager.DirectoryDetails;
Steve McKay16e0c1f2016-09-15 12:41:13 -070043import com.android.documentsui.OperationDialogFragment;
Steve McKaydf5add42016-01-28 12:02:57 -080044import com.android.documentsui.OperationDialogFragment.DialogType;
Garfield Tan239ab972016-09-16 13:33:48 -070045import com.android.documentsui.ProviderExecutor;
46import com.android.documentsui.R;
Steve McKay04718262016-11-08 11:01:35 -080047import com.android.documentsui.SharedInputHandler;
Steve McKay052985f2017-06-07 11:30:46 -070048import com.android.documentsui.ShortcutsUpdater;
Steve McKayd0805062016-09-15 14:30:38 -070049import com.android.documentsui.base.DocumentInfo;
Steve McKay98f8c5f2017-03-03 13:52:14 -080050import com.android.documentsui.base.Features;
Steve McKayd0805062016-09-15 14:30:38 -070051import com.android.documentsui.base.RootInfo;
Steve McKayd9caa6a2016-09-15 16:36:45 -070052import com.android.documentsui.base.State;
Garfield, Tan9666ce62016-07-12 11:02:09 -070053import com.android.documentsui.clipping.DocumentClipper;
Steve McKay988d8a32016-09-27 09:41:17 -070054import com.android.documentsui.dirlist.AnimationView.AnimationType;
Tony Huange092d2d2018-12-26 19:02:51 +080055import com.android.documentsui.dirlist.AppsRowManager;
Steve McKayf68210e2015-11-03 15:23:16 -080056import com.android.documentsui.dirlist.DirectoryFragment;
Ben Lin30b0dc12017-03-07 15:37:16 -080057import com.android.documentsui.prefs.ScopedPreferences;
Steve McKayc83baa02016-01-06 18:32:13 -080058import com.android.documentsui.services.FileOperationService;
Steve McKayd0805062016-09-15 14:30:38 -070059import com.android.documentsui.sidebar.RootsFragment;
Steve McKayc8889af2016-09-23 11:22:41 -070060import com.android.documentsui.ui.DialogController;
Steve McKay92ae43d2016-11-08 12:06:58 -080061import com.android.documentsui.ui.MessageBuilder;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070062
Tomasz Mikolajewski332d8192015-04-13 19:38:43 +090063import java.util.ArrayList;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070064import java.util.List;
Steve McKayd0a2a2c2015-03-25 14:35:33 -070065
Steve McKayb68dd222015-04-20 17:18:15 -070066/**
Steve McKay64ac2512015-05-12 12:49:58 -070067 * Standalone file management activity.
Steve McKayb68dd222015-04-20 17:18:15 -070068 */
Tony Huangcf747152019-11-18 13:43:41 +080069public class FilesActivity extends BaseActivity implements AbstractActionHandler.CommonAddons {
Steve McKayedc65bb2015-07-31 14:35:22 -070070
Steve McKay6525a192016-10-18 14:28:00 -070071 private static final String TAG = "FilesActivity";
Steve McKay92ae43d2016-11-08 12:06:58 -080072 static final String PREFERENCES_SCOPE = "files";
Steve McKayd0a2a2c2015-03-25 14:35:33 -070073
Steve McKay92ae43d2016-11-08 12:06:58 -080074 private Injector<ActionHandler<FilesActivity>> mInjector;
Ben Lin79ae3a72016-10-13 10:57:45 -070075 private ActivityInputHandler mActivityInputHandler;
Steve McKay04718262016-11-08 11:01:35 -080076 private SharedInputHandler mSharedInputHandler;
Steve McKayb68dd222015-04-20 17:18:15 -070077
Steve McKayb6006b22016-09-29 09:23:45 -070078 public FilesActivity() {
Steve McKay0fbfc652015-08-20 16:48:49 -070079 super(R.layout.files_activity, TAG);
Steve McKayb68dd222015-04-20 17:18:15 -070080 }
Steve McKayd0a2a2c2015-03-25 14:35:33 -070081
Tobias Thierere3830da2017-07-14 12:51:34 +010082 // make these methods visible in this package to work around compiler bug http://b/62218600
83 @Override protected boolean focusSidebar() { return super.focusSidebar(); }
84 @Override protected boolean popDir() { return super.popDir(); }
85
Steve McKayd0a2a2c2015-03-25 14:35:33 -070086 @Override
87 public void onCreate(Bundle icicle) {
Steve McKay6525a192016-10-18 14:28:00 -070088
Steve McKay92ae43d2016-11-08 12:06:58 -080089 MessageBuilder messages = new MessageBuilder(this);
Steve McKay5bd5cb42017-04-02 08:36:50 -070090 Features features = Features.create(this);
Steve McKay0ce04b72017-06-05 13:23:54 -070091 ScopedPreferences prefs = ScopedPreferences.create(this, PREFERENCES_SCOPE);
92
Steve McKay92ae43d2016-11-08 12:06:58 -080093 mInjector = new Injector<>(
Tomasz Mikolajewski0d83d322017-02-07 12:29:39 +090094 features,
Steve McKay92ae43d2016-11-08 12:06:58 -080095 new Config(),
96 ScopedPreferences.create(this, PREFERENCES_SCOPE),
97 messages,
shawnlin8dafe612019-08-14 20:10:18 +080098 DialogController.create(features, this),
Steve McKay0ce04b72017-06-05 13:23:54 -070099 DocumentsApplication.getFileTypeLookup(this),
100 new ShortcutsUpdater(this, prefs)::update);
Steve McKay6525a192016-10-18 14:28:00 -0700101
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700102 super.onCreate(icicle);
103
Steve McKay92ae43d2016-11-08 12:06:58 -0800104 DocumentClipper clipper = DocumentsApplication.getDocumentClipper(this);
Riddle Hsu0c375982018-06-21 22:06:43 +0800105 mInjector.selectionMgr = DocsSelectionHelper.create();
Steve McKay04718262016-11-08 11:01:35 -0800106
Steve McKay92ae43d2016-11-08 12:06:58 -0800107 mInjector.focusManager = new FocusManager(
Steve McKay98f8c5f2017-03-03 13:52:14 -0800108 mInjector.features,
Ben Lin340ab172017-01-27 11:41:26 -0800109 mInjector.selectionMgr,
110 mDrawer,
111 this::focusSidebar,
Tony Huang09571b22019-03-14 14:47:53 +0800112 getColor(R.color.primary));
Steve McKay04718262016-11-08 11:01:35 -0800113
Steve McKay92ae43d2016-11-08 12:06:58 -0800114 mInjector.menuManager = new MenuManager(
Steve McKay710248d2017-03-14 10:09:30 -0700115 mInjector.features,
Steve McKaye5d6ca22016-09-19 20:27:24 -0700116 mSearchManager,
117 mState,
118 new DirectoryDetails(this) {
119 @Override
120 public boolean hasItemsToPaste() {
Steve McKay92ae43d2016-11-08 12:06:58 -0800121 return clipper.hasItemsToPaste();
Steve McKaye5d6ca22016-09-19 20:27:24 -0700122 }
Jon Mann253a9922017-03-21 18:53:27 -0700123 },
124 getApplicationContext(),
125 mInjector.selectionMgr,
Jon Mann9bd40992017-03-24 12:34:34 -0700126 mProviders::getApplicationName,
Tony Huang76c6c9d2019-08-12 18:04:06 +0800127 mInjector.getModel()::getItemUri,
128 mInjector.getModel()::getItemCount);
Steve McKaybd9f05a2016-10-10 10:18:36 -0700129
Steve McKay92ae43d2016-11-08 12:06:58 -0800130 mInjector.actionModeController = new ActionModeController(
Steve McKaybd9f05a2016-10-10 10:18:36 -0700131 this,
Steve McKay92ae43d2016-11-08 12:06:58 -0800132 mInjector.selectionMgr,
133 mInjector.menuManager,
134 mInjector.messages);
Steve McKaybd9f05a2016-10-10 10:18:36 -0700135
Steve McKay92ae43d2016-11-08 12:06:58 -0800136 mInjector.actions = new ActionHandler<>(
Steve McKayc8889af2016-09-23 11:22:41 -0700137 this,
Steve McKayc8889af2016-09-23 11:22:41 -0700138 mState,
Jon Mann9bd40992017-03-24 12:34:34 -0700139 mProviders,
Garfield Tan63bf8132016-10-11 11:00:49 -0700140 mDocs,
Garfield Tan63bf8132016-10-11 11:00:49 -0700141 mSearchManager,
Steve McKay988d8a32016-09-27 09:41:17 -0700142 ProviderExecutor::forAuthority,
Steve McKay92ae43d2016-11-08 12:06:58 -0800143 mInjector.actionModeController,
Steve McKay92ae43d2016-11-08 12:06:58 -0800144 clipper,
Jon Mann30d8c792017-02-21 17:44:49 -0800145 DocumentsApplication.getClipStore(this),
Garfield Tanda2c0f02017-04-11 13:47:58 -0700146 DocumentsApplication.getDragAndDropManager(this),
Jon Mann30d8c792017-02-21 17:44:49 -0800147 mInjector);
Steve McKay1f199482015-05-20 15:58:42 -0700148
Garfield Tane9670332017-03-06 18:33:23 -0800149 mInjector.searchManager = mSearchManager;
150
Tony Huange092d2d2018-12-26 19:02:51 +0800151 mAppsRowManager = new AppsRowManager(mInjector.actions);
152 mInjector.appsRowManager = mAppsRowManager;
153
Steve McKay92ae43d2016-11-08 12:06:58 -0800154 mActivityInputHandler =
shawnlin8dafe612019-08-14 20:10:18 +0800155 new ActivityInputHandler(mInjector.actions::showDeleteDialog);
Steve McKay98f8c5f2017-03-03 13:52:14 -0800156 mSharedInputHandler =
Ben Lin0902f072017-03-13 18:25:29 -0700157 new SharedInputHandler(
158 mInjector.focusManager,
159 mInjector.selectionMgr,
160 mInjector.searchManager::cancelSearch,
161 this::popDir,
Rhed Jao23c4bc02018-05-18 16:24:04 +0800162 mInjector.features,
Bill Lin35bfbef2019-08-05 16:09:53 +0800163 mDrawer,
164 mInjector.searchManager::onSearchBarClicked);
Ben Lin79ae3a72016-10-13 10:57:45 -0700165
Tony Huang8d8d92f2018-09-13 14:41:16 +0800166 RootsFragment.show(getSupportFragmentManager(), null);
Steve McKay459bc2b2015-09-16 15:07:31 -0700167
Tomasz Mikolajewskicdbbbe02015-12-25 17:06:52 +0900168 final Intent intent = getIntent();
Steve McKay4d0255f2015-09-25 16:02:56 -0700169
Steve McKay92ae43d2016-11-08 12:06:58 -0800170 mInjector.actions.initLocation(intent);
Steve McKay7295c482017-03-15 17:51:32 -0700171
172 // Allow the activity to masquerade as another, so we can look both like
173 // Downloads and Files, but with only a single underlying activity.
174 if (intent.hasExtra(LauncherActivity.TASK_LABEL_RES)
175 && intent.hasExtra(LauncherActivity.TASK_ICON_RES)) {
176 updateTaskDescription(intent);
177 }
178
Tony Huangf7b05c42019-05-02 16:51:01 +0800179 // Set save container background to transparent for edge to edge nav bar.
180 View saveContainer = findViewById(R.id.container_save);
181 saveContainer.setBackgroundColor(Color.TRANSPARENT);
182
Steve McKay988d8a32016-09-27 09:41:17 -0700183 presentFileErrors(icicle, intent);
184 }
Steve McKay739f94b2016-09-22 14:54:23 -0700185
Steve McKay7295c482017-03-15 17:51:32 -0700186 // This is called in the intent contains label and icon resources.
187 // When that is true, the launcher activity has supplied them so we
188 // can adapt our presentation to how we were launched.
189 // Without this code, overlaying launcher_icon and launcher_label
190 // resources won't create a complete illusion of the activity being renamed.
191 // E.g. if we re-brand Files to Downloads by overlaying label and icon
192 // when the user tapped recents they'd see not "Downloads", but the
193 // underlying Activity description...Files.
194 // Alternate if we rename this activity, when launching other ways
195 // like when browsing files on a removable disk, the app would be
196 // called Downloads, which is also not the desired behavior.
197 private void updateTaskDescription(final Intent intent) {
198 int labelRes = intent.getIntExtra(LauncherActivity.TASK_LABEL_RES, -1);
199 assert(labelRes > -1);
200 String label = getResources().getString(labelRes);
201
202 int iconRes = intent.getIntExtra(LauncherActivity.TASK_ICON_RES, -1);
203 assert(iconRes > -1);
204
Sunny Goyal5b225532018-07-03 12:44:03 -0700205 setTaskDescription(new TaskDescription(label, iconRes));
Steve McKay7295c482017-03-15 17:51:32 -0700206 }
207
Steve McKay988d8a32016-09-27 09:41:17 -0700208 private void presentFileErrors(Bundle icicle, final Intent intent) {
Tomasz Mikolajewskidd2b31c2016-01-22 16:22:51 +0900209 final @DialogType int dialogType = intent.getIntExtra(
210 FileOperationService.EXTRA_DIALOG_TYPE, DIALOG_TYPE_UNKNOWN);
Tomasz Mikolajewskicdbbbe02015-12-25 17:06:52 +0900211 // DialogFragment takes care of restoring the dialog on configuration change.
212 // Only show it manually for the first time (icicle is null).
Tomasz Mikolajewskidd2b31c2016-01-22 16:22:51 +0900213 if (icicle == null && dialogType != DIALOG_TYPE_UNKNOWN) {
214 final int opType = intent.getIntExtra(
Garfield, Tan48334772016-06-28 17:17:38 -0700215 FileOperationService.EXTRA_OPERATION_TYPE,
Tomasz Mikolajewskidd2b31c2016-01-22 16:22:51 +0900216 FileOperationService.OPERATION_COPY);
Steve McKay99f1dc32016-12-29 16:02:01 -0800217 final ArrayList<DocumentInfo> docList =
218 intent.getParcelableArrayListExtra(FileOperationService.EXTRA_FAILED_DOCS);
Tomasz Mikolajewski664025e2017-02-01 11:54:48 +0900219 final ArrayList<Uri> uriList =
Steve McKay99f1dc32016-12-29 16:02:01 -0800220 intent.getParcelableArrayListExtra(FileOperationService.EXTRA_FAILED_URIS);
Tomasz Mikolajewskidd2b31c2016-01-22 16:22:51 +0900221 OperationDialogFragment.show(
Tony Huang8d8d92f2018-09-13 14:41:16 +0800222 getSupportFragmentManager(),
Tomasz Mikolajewskidd2b31c2016-01-22 16:22:51 +0900223 dialogType,
Steve McKay99f1dc32016-12-29 16:02:01 -0800224 docList,
225 uriList,
Tomasz Mikolajewskicdbbbe02015-12-25 17:06:52 +0900226 mState.stack,
Steve McKayc83baa02016-01-06 18:32:13 -0800227 opType);
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700228 }
229 }
230
Steve McKay0fbfc652015-08-20 16:48:49 -0700231 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700232 public void includeState(State state) {
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700233 final Intent intent = getIntent();
Ben Kwa0574b182015-09-08 07:31:19 -0700234
Garfield Tan78ade2b2017-02-28 13:19:53 -0800235 // This is a remnant of old logic where we used to initialize accept MIME types in
Jon Mann9bd40992017-03-24 12:34:34 -0700236 // BaseActivity. ProvidersAccess still rely on this being correctly initialized so we still have
Garfield Tan78ade2b2017-02-28 13:19:53 -0800237 // to initialize it in FilesActivity.
238 state.initAcceptMimes(intent, "*/*");
Steve McKay459bc2b2015-09-16 15:07:31 -0700239 state.action = State.ACTION_BROWSE;
Ben Kwa0574b182015-09-08 07:31:19 -0700240 state.allowMultiple = true;
Steve McKay64ac2512015-05-12 12:49:58 -0700241
Steve McKay459bc2b2015-09-16 15:07:31 -0700242 // Options specific to the DocumentsActivity.
Steve McKay0af8afd2016-02-25 13:34:03 -0800243 assert(!intent.hasExtra(Intent.EXTRA_LOCAL_ONLY));
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700244 }
245
246 @Override
247 protected void onPostCreate(Bundle savedInstanceState) {
248 super.onPostCreate(savedInstanceState);
Steve McKaya8fa58d2015-12-08 17:02:03 -0800249 // This check avoids a flicker from "Recents" to "Home".
250 // Only update action bar at this point if there is an active
Dooper0930d4c2017-06-02 10:32:00 -0700251 // search. Why? Because this avoid an early (undesired) load of
Steve McKaya8fa58d2015-12-08 17:02:03 -0800252 // the recents root...which is the default root in other activities.
253 // In Files app "Home" is the default, but it is loaded async.
Steve McKay18d01e82016-02-03 11:15:57 -0800254 // update will be called once Home root is loaded.
Steve McKaya8fa58d2015-12-08 17:02:03 -0800255 // Except while searching we need this call to ensure the
Dooper0930d4c2017-06-02 10:32:00 -0700256 // search bits get laid out correctly.
Steve McKaya8fa58d2015-12-08 17:02:03 -0800257 if (mSearchManager.isSearching()) {
Steve McKay18d01e82016-02-03 11:15:57 -0800258 mNavigator.update();
Steve McKaya8fa58d2015-12-08 17:02:03 -0800259 }
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700260 }
261
262 @Override
Steve McKay459bc2b2015-09-16 15:07:31 -0700263 public void onResume() {
264 super.onResume();
265
266 final RootInfo root = getCurrentRoot();
267
268 // If we're browsing a specific root, and that root went away, then we
269 // have no reason to hang around.
270 // TODO: Rather than just disappearing, maybe we should inform
271 // the user what has happened, let them close us. Less surprising.
Jon Mann9bd40992017-03-24 12:34:34 -0700272 if (mProviders.getRootBlocking(root.authority, root.rootId) == null) {
Steve McKay459bc2b2015-09-16 15:07:31 -0700273 finish();
274 }
275 }
276
277 @Override
Steve McKay18d01e82016-02-03 11:15:57 -0800278 public String getDrawerTitle() {
Steve McKay17f7e582016-04-04 15:26:48 -0700279 Intent intent = getIntent();
280 return (intent != null && intent.hasExtra(Intent.EXTRA_TITLE))
281 ? intent.getStringExtra(Intent.EXTRA_TITLE)
Steve McKaya0b52652016-10-27 12:56:55 -0700282 : getString(R.string.app_label);
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700283 }
284
285 @Override
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700286 public boolean onPrepareOptionsMenu(Menu menu) {
Steve McKaye9809272015-10-01 11:39:24 -0700287 super.onPrepareOptionsMenu(menu);
Steve McKay92ae43d2016-11-08 12:06:58 -0800288 mInjector.menuManager.updateOptionMenu(menu);
Steve McKaye9809272015-10-01 11:39:24 -0700289 return true;
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700290 }
291
292 @Override
Steve McKay1f199482015-05-20 15:58:42 -0700293 public boolean onOptionsItemSelected(MenuItem item) {
Jon Mann49be24c2017-02-13 17:29:20 -0800294 DirectoryFragment dir;
Steve McKayf2c8b0d2015-09-23 15:44:24 -0700295 switch (item.getItemId()) {
Ben Linff7f3ae2017-04-25 16:08:52 -0700296 case R.id.option_menu_create_dir:
Steve McKay0af8afd2016-02-25 13:34:03 -0800297 assert(canCreateDirectory());
Ben Linff7f3ae2017-04-25 16:08:52 -0700298 mInjector.actions.showCreateDirectoryDialog();
Aga Wronska4972d712016-03-30 13:55:19 -0700299 break;
Ben Linff7f3ae2017-04-25 16:08:52 -0700300 case R.id.option_menu_new_window:
Steve McKay92ae43d2016-11-08 12:06:58 -0800301 mInjector.actions.openInNewWindow(mState.stack);
Aga Wronska4972d712016-03-30 13:55:19 -0700302 break;
Ben Linff7f3ae2017-04-25 16:08:52 -0700303 case R.id.option_menu_settings:
Steve McKay92ae43d2016-11-08 12:06:58 -0800304 mInjector.actions.openSettings(getCurrentRoot());
Ben Lin5668b862016-06-28 17:12:52 -0700305 break;
Ben Linff7f3ae2017-04-25 16:08:52 -0700306 case R.id.option_menu_select_all:
Jon Mann30d8c792017-02-21 17:44:49 -0800307 mInjector.actions.selectAllFiles();
Jon Mann49be24c2017-02-13 17:29:20 -0800308 break;
Steve McKay0c7ad032017-08-09 11:50:10 -0700309 case R.id.option_menu_inspect:
Steve McKayefd10ac2017-07-25 13:33:57 -0700310 mInjector.actions.showInspector(getCurrentDirectory());
311 break;
Aga Wronska4972d712016-03-30 13:55:19 -0700312 default:
313 return super.onOptionsItemSelected(item);
Steve McKay1f199482015-05-20 15:58:42 -0700314 }
Aga Wronska4972d712016-03-30 13:55:19 -0700315 return true;
Steve McKay1f199482015-05-20 15:58:42 -0700316 }
317
318 @Override
Ben Lina8673232016-09-28 15:40:04 -0700319 public void onProvideKeyboardShortcuts(
320 List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
Steve McKay92ae43d2016-11-08 12:06:58 -0800321 mInjector.menuManager.updateKeyboardShortcutsMenu(data, this::getString);
Ben Lina8673232016-09-28 15:40:04 -0700322 }
323
324 @Override
Steve McKay988d8a32016-09-27 09:41:17 -0700325 public void refreshDirectory(@AnimationType int anim) {
Tony Huang8d8d92f2018-09-13 14:41:16 +0800326 final FragmentManager fm = getSupportFragmentManager();
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700327 final RootInfo root = getCurrentRoot();
328 final DocumentInfo cwd = getCurrentDirectory();
329
Steve McKay0af8afd2016-02-25 13:34:03 -0800330 assert(!mSearchManager.isSearching());
Aga Wronskaaf5ace52016-02-17 13:50:42 -0800331
Garfield Tane9670332017-03-06 18:33:23 -0800332 if (mState.stack.isRecents()) {
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700333 DirectoryFragment.showRecentsOpen(fm, anim);
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700334 } else {
Aga Wronskaaf5ace52016-02-17 13:50:42 -0800335 // Normal boring directory
336 DirectoryFragment.showDirectory(fm, root, cwd, anim);
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700337 }
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700338 }
339
340 @Override
Steve McKay351a7492015-08-04 10:11:01 -0700341 public void onDocumentsPicked(List<DocumentInfo> docs) {
342 throw new UnsupportedOperationException();
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700343 }
344
Steve McKay351a7492015-08-04 10:11:01 -0700345 @Override
Steve McKayeed2f4e2016-10-03 20:30:52 -0700346 public void onDocumentPicked(DocumentInfo doc) {
Tomasz Mikolajewskid22cc182017-03-15 16:13:46 +0900347 throw new UnsupportedOperationException();
Tomasz Mikolajewskibe4e38b2016-04-07 18:00:08 +0900348 }
349
Garfield, Tan804133e2016-04-20 15:13:56 -0700350 @Override
Steve McKay16e0c1f2016-09-15 12:41:13 -0700351 public void onDirectoryCreated(DocumentInfo doc) {
Ben Lin81afd7f2016-08-22 18:24:03 -0700352 assert(doc.isDirectory());
Steve McKay92ae43d2016-11-08 12:06:58 -0800353 mInjector.focusManager.focusDocument(doc.documentId);
Ben Lin81afd7f2016-08-22 18:24:03 -0700354 }
355
Takamasa Kuramitsu59710522018-06-29 18:42:21 +0900356 @Override
357 protected boolean canInspectDirectory() {
358 return getCurrentDirectory() != null && mInjector.getModel().doc != null;
359 }
360
Ben Linaa66c432016-10-12 12:11:24 -0700361 @CallSuper
362 @Override
363 public boolean onKeyDown(int keyCode, KeyEvent event) {
Steve McKay04718262016-11-08 11:01:35 -0800364 return mActivityInputHandler.onKeyDown(keyCode, event)
Bill Lin35bfbef2019-08-05 16:09:53 +0800365 || mSharedInputHandler.onKeyDown(keyCode, event)
Steve McKay04718262016-11-08 11:01:35 -0800366 || super.onKeyDown(keyCode, event);
Ben Linaa66c432016-10-12 12:11:24 -0700367 }
368
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700369 @Override
Steve McKay0599a442015-05-05 14:50:00 -0700370 public boolean onKeyShortcut(int keyCode, KeyEvent event) {
371 DirectoryFragment dir;
Steve McKayd4800812016-02-02 11:41:03 -0800372 // TODO: All key events should be statically bound using alphabeticShortcut.
373 // But not working.
Steve McKay0599a442015-05-05 14:50:00 -0700374 switch (keyCode) {
375 case KeyEvent.KEYCODE_A:
Jon Mann30d8c792017-02-21 17:44:49 -0800376 mInjector.actions.selectAllFiles();
Steve McKay0599a442015-05-05 14:50:00 -0700377 return true;
Ben Linff4d5842016-04-18 14:35:28 -0700378 case KeyEvent.KEYCODE_X:
Steve McKay92ae43d2016-11-08 12:06:58 -0800379 mInjector.actions.cutToClipboard();
Ben Linff4d5842016-04-18 14:35:28 -0700380 return true;
Steve McKay1f199482015-05-20 15:58:42 -0700381 case KeyEvent.KEYCODE_C:
Steve McKay92ae43d2016-11-08 12:06:58 -0800382 mInjector.actions.copyToClipboard();
Steve McKay6035b3c2015-12-04 11:19:09 -0800383 return true;
384 case KeyEvent.KEYCODE_V:
Steve McKayd4800812016-02-02 11:41:03 -0800385 dir = getDirectoryFragment();
386 if (dir != null) {
387 dir.pasteFromClipboard();
388 }
Steve McKay6035b3c2015-12-04 11:19:09 -0800389 return true;
390 default:
391 return super.onKeyShortcut(keyCode, event);
Steve McKay0599a442015-05-05 14:50:00 -0700392 }
393 }
394
Steve McKayb68dd222015-04-20 17:18:15 -0700395 @Override
Steve McKay92ae43d2016-11-08 12:06:58 -0800396 public Injector<ActionHandler<FilesActivity>> getInjector() {
397 return mInjector;
Steve McKayc8889af2016-09-23 11:22:41 -0700398 }
Steve McKayd0a2a2c2015-03-25 14:35:33 -0700399}