• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.files;
18 
19 import android.app.Fragment;
20 import android.content.Context;
21 import android.content.res.Resources;
22 import android.net.Uri;
23 import android.view.KeyEvent;
24 import android.view.KeyboardShortcutGroup;
25 import android.view.KeyboardShortcutInfo;
26 import android.view.Menu;
27 import android.view.MenuInflater;
28 import android.view.MenuItem;
29 import android.view.View;
30 
31 import com.android.documentsui.R;
32 import com.android.documentsui.base.DocumentInfo;
33 import com.android.documentsui.base.Features;
34 import com.android.documentsui.base.Lookup;
35 import com.android.documentsui.base.RootInfo;
36 import com.android.documentsui.base.State;
37 import com.android.documentsui.queries.SearchViewManager;
38 import com.android.documentsui.selection.SelectionManager;
39 
40 import java.util.List;
41 import java.util.function.Function;
42 import java.util.function.IntFunction;
43 
44 public final class MenuManager extends com.android.documentsui.MenuManager {
45 
46     private final Features mFeatures;
47     private final Context mContext;
48     private final SelectionManager mSelectionManager;
49     private final Lookup<String, Uri> mUriLookup;
50     private final Lookup<String, String> mAppNameLookup;
51 
MenuManager( Features features, SearchViewManager searchManager, State displayState, DirectoryDetails dirDetails, Context context, SelectionManager selectionManager, Lookup<String, String> appNameLookup, Lookup<String, Uri> uriLookup)52     public MenuManager(
53             Features features,
54             SearchViewManager searchManager,
55             State displayState,
56             DirectoryDetails dirDetails,
57             Context context,
58             SelectionManager selectionManager,
59             Lookup<String, String> appNameLookup,
60             Lookup<String, Uri> uriLookup) {
61         super(searchManager, displayState, dirDetails);
62         mFeatures = features;
63         mContext = context;
64         mSelectionManager = selectionManager;
65         mAppNameLookup = appNameLookup;
66         mUriLookup = uriLookup;
67     }
68 
69     @Override
updateOptionMenu(Menu menu)70     public void updateOptionMenu(Menu menu) {
71         super.updateOptionMenu(menu);
72 
73         // It hides icon if searching in progress
74         mSearchManager.updateMenu();
75     }
76 
77     @Override
updateKeyboardShortcutsMenu( List<KeyboardShortcutGroup> data, IntFunction<String> stringSupplier)78     public void updateKeyboardShortcutsMenu(
79             List<KeyboardShortcutGroup> data, IntFunction<String> stringSupplier) {
80         KeyboardShortcutGroup group = new KeyboardShortcutGroup(
81                 stringSupplier.apply(R.string.app_label));
82         group.addItem(new KeyboardShortcutInfo(
83                 stringSupplier.apply(R.string.menu_cut_to_clipboard), KeyEvent.KEYCODE_X,
84                 KeyEvent.META_CTRL_ON));
85         group.addItem(new KeyboardShortcutInfo(
86                 stringSupplier.apply(R.string.menu_copy_to_clipboard), KeyEvent.KEYCODE_C,
87                 KeyEvent.META_CTRL_ON));
88         group.addItem(new KeyboardShortcutInfo(
89                 stringSupplier.apply(R.string.menu_paste_from_clipboard), KeyEvent.KEYCODE_V,
90                 KeyEvent.META_CTRL_ON));
91         group.addItem(new KeyboardShortcutInfo(
92                 stringSupplier.apply(R.string.menu_create_dir), KeyEvent.KEYCODE_E,
93                 KeyEvent.META_CTRL_ON));
94         group.addItem(new KeyboardShortcutInfo(
95                 stringSupplier.apply(R.string.menu_select_all), KeyEvent.KEYCODE_A,
96                 KeyEvent.META_CTRL_ON));
97         group.addItem(new KeyboardShortcutInfo(
98                 stringSupplier.apply(R.string.menu_new_window), KeyEvent.KEYCODE_N,
99                 KeyEvent.META_CTRL_ON));
100         data.add(group);
101     }
102 
103     @Override
showContextMenu(Fragment f, View v, float x, float y)104     public void showContextMenu(Fragment f, View v, float x, float y) {
105         // Register context menu here so long-press doesn't trigger this context floating menu.
106         f.registerForContextMenu(v);
107         v.showContextMenu(x, y);
108         f.unregisterForContextMenu(v);
109     }
110 
111     @Override
inflateContextMenuForContainer(Menu menu, MenuInflater inflater)112     public void inflateContextMenuForContainer(Menu menu, MenuInflater inflater) {
113         inflater.inflate(R.menu.container_context_menu, menu);
114         updateContextMenuForContainer(menu);
115     }
116 
117     @Override
inflateContextMenuForDocs( Menu menu, MenuInflater inflater, SelectionDetails selectionDetails)118     public void inflateContextMenuForDocs(
119             Menu menu, MenuInflater inflater, SelectionDetails selectionDetails) {
120         final boolean hasDir = selectionDetails.containsDirectories();
121         final boolean hasFile = selectionDetails.containsFiles();
122 
123         assert(hasDir || hasFile);
124         if (!hasDir) {
125             inflater.inflate(R.menu.file_context_menu, menu);
126             updateContextMenuForFiles(menu, selectionDetails);
127             return;
128         }
129 
130         if (!hasFile) {
131             inflater.inflate(R.menu.dir_context_menu, menu);
132             updateContextMenuForDirs(menu, selectionDetails);
133             return;
134         }
135 
136         inflater.inflate(R.menu.mixed_context_menu, menu);
137         updateContextMenu(menu, selectionDetails);
138     }
139 
140     @Override
updateSettings(MenuItem settings, RootInfo root)141     protected void updateSettings(MenuItem settings, RootInfo root) {
142         settings.setVisible(true);
143         settings.setEnabled(root.hasSettings());
144     }
145 
146     @Override
updateEject(MenuItem eject, RootInfo root)147     protected void updateEject(MenuItem eject, RootInfo root) {
148         eject.setVisible(root.supportsEject());
149         eject.setEnabled(!root.ejecting);
150     }
151 
152     @Override
updateSettings(MenuItem settings)153     protected void updateSettings(MenuItem settings) {
154         boolean enabled = mDirDetails.hasRootSettings();
155         settings.setVisible(enabled);
156         settings.setEnabled(enabled);
157     }
158 
159     @Override
updateNewWindow(MenuItem newWindow)160     protected void updateNewWindow(MenuItem newWindow) {
161         newWindow.setVisible(true);
162     }
163 
164     @Override
updateOpenInContextMenu(MenuItem open, SelectionDetails selectionDetails)165     protected void updateOpenInContextMenu(MenuItem open, SelectionDetails selectionDetails) {
166         open.setVisible(true);
167         open.setEnabled(selectionDetails.size() == 1
168                 && !selectionDetails.containsPartialFiles());
169     }
170 
171     @Override
updateOpenWith(MenuItem openWith, SelectionDetails selectionDetails)172     protected void updateOpenWith(MenuItem openWith, SelectionDetails selectionDetails) {
173         openWith.setVisible(true);
174         openWith.setEnabled(selectionDetails.canOpenWith());
175     }
176 
177     @Override
updateOpenInNewWindow( MenuItem openInNewWindow, SelectionDetails selectionDetails)178     protected void updateOpenInNewWindow(
179             MenuItem openInNewWindow, SelectionDetails selectionDetails) {
180         openInNewWindow.setVisible(true);
181         openInNewWindow.setEnabled(selectionDetails.size() == 1
182             && !selectionDetails.containsPartialFiles());
183     }
184 
185     @Override
updateOpenInNewWindow(MenuItem openInNewWindow, RootInfo root)186     protected void updateOpenInNewWindow(MenuItem openInNewWindow, RootInfo root) {
187         assert(openInNewWindow.isVisible() && openInNewWindow.isEnabled());
188     }
189 
190     @Override
updateMoveTo(MenuItem moveTo, SelectionDetails selectionDetails)191     protected void updateMoveTo(MenuItem moveTo, SelectionDetails selectionDetails) {
192         moveTo.setVisible(true);
193         moveTo.setEnabled(!selectionDetails.containsPartialFiles() && selectionDetails.canDelete());
194     }
195 
196     @Override
updateCopyTo(MenuItem copyTo, SelectionDetails selectionDetails)197     protected void updateCopyTo(MenuItem copyTo, SelectionDetails selectionDetails) {
198         copyTo.setVisible(true);
199         copyTo.setEnabled(!selectionDetails.containsPartialFiles() &&
200                 !selectionDetails.canExtract());
201     }
202 
203     @Override
updateCompress(MenuItem compress, SelectionDetails selectionDetails)204     protected void updateCompress(MenuItem compress, SelectionDetails selectionDetails) {
205         final boolean readOnly = !mDirDetails.canCreateDoc();
206         compress.setVisible(mFeatures.isArchiveCreationEnabled());
207         compress.setEnabled(!readOnly && !selectionDetails.containsPartialFiles() &&
208                 !selectionDetails.canExtract());
209     }
210 
211     @Override
updateExtractTo(MenuItem extractTo, SelectionDetails selectionDetails)212     protected void updateExtractTo(MenuItem extractTo, SelectionDetails selectionDetails) {
213         boolean enabled = selectionDetails.canExtract();
214         extractTo.setVisible(enabled);
215         extractTo.setEnabled(enabled);
216     }
217 
218     @Override
updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails)219     protected void updatePasteInto(MenuItem pasteInto, SelectionDetails selectionDetails) {
220         pasteInto.setVisible(true);
221         pasteInto.setEnabled(selectionDetails.canPasteInto() && mDirDetails.hasItemsToPaste());
222     }
223 
224     @Override
updatePasteInto(MenuItem pasteInto, RootInfo root, DocumentInfo docInfo)225     protected void updatePasteInto(MenuItem pasteInto, RootInfo root, DocumentInfo docInfo) {
226         pasteInto.setVisible(true);
227         pasteInto.setEnabled(root.supportsCreate()
228                 && docInfo != null
229                 && docInfo.isCreateSupported()
230                 && mDirDetails.hasItemsToPaste());
231     }
232 
233     @Override
updateSelectAll(MenuItem selectAll)234     protected void updateSelectAll(MenuItem selectAll) {
235         selectAll.setVisible(true);
236         selectAll.setEnabled(true);
237     }
238 
239     @Override
updateCreateDir(MenuItem createDir)240     protected void updateCreateDir(MenuItem createDir) {
241         createDir.setVisible(true);
242         createDir.setEnabled(mDirDetails.canCreateDirectory());
243     }
244 
245     @Override
updateShare(MenuItem share, SelectionDetails selectionDetails)246     protected void updateShare(MenuItem share, SelectionDetails selectionDetails) {
247         boolean enabled = !selectionDetails.containsDirectories()
248                 && !selectionDetails.containsPartialFiles()
249                 && !selectionDetails.canExtract();
250         share.setVisible(enabled);
251         share.setEnabled(enabled);
252     }
253 
254     @Override
updateDelete(MenuItem delete, SelectionDetails selectionDetails)255     protected void updateDelete(MenuItem delete, SelectionDetails selectionDetails) {
256         boolean enabled = selectionDetails.canDelete();
257         delete.setVisible(enabled);
258         delete.setEnabled(enabled);
259     }
260 
261     @Override
updateRename(MenuItem rename, SelectionDetails selectionDetails)262     protected void updateRename(MenuItem rename, SelectionDetails selectionDetails) {
263         rename.setVisible(true);
264         rename.setEnabled(!selectionDetails.containsPartialFiles() && selectionDetails.canRename());
265     }
266 
267     @Override
updateViewInOwner(MenuItem view, SelectionDetails selectionDetails)268     protected void updateViewInOwner(MenuItem view, SelectionDetails selectionDetails) {
269         if (selectionDetails.canViewInOwner()) {
270             view.setVisible(true);
271             view.setEnabled(true);
272             Resources res = mContext.getResources();
273             String selectedModelId = mSelectionManager.getSelection().iterator().next();
274             Uri selectedUri = mUriLookup.lookup(selectedModelId);
275             String appName = mAppNameLookup.lookup(selectedUri.getAuthority());
276             String title = res.getString(R.string.menu_view_in_owner, appName);
277             view.setTitle(title);
278         }
279         else {
280             view.setVisible(false);
281         }
282     }
283 }
284