blob: 914c7c56c463a83e1ecb5344d3868d32fa41ffb4 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005'use strict';
6
Torne (Richard Coles)58218062012-11-14 11:43:16 +00007var CommandUtil = {};
8
9/**
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010010 * Extracts path on which command event was dispatched.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011 *
Ben Murdoch32409262013-08-07 11:04:47 +010012 * @param {DirectoryTree|DirectoryItem|NavigationList|HTMLLIElement|cr.ui.List}
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010013 * element Directory to extract a path from.
14 * @return {?string} Path of the found node.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000015 */
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010016CommandUtil.getCommandPath = function(element) {
Ben Murdoch32409262013-08-07 11:04:47 +010017 if (element instanceof NavigationList) {
18 // element is a NavigationList.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010019 return element.selectedItem;
Ben Murdoch32409262013-08-07 11:04:47 +010020 } else if (element instanceof NavigationListItem) {
21 // element is a subitem of NavigationList.
22 var navigationList = element.parentElement;
23 var index = navigationList.getIndexOfListItem(element);
24 return (index != -1) ? navigationList.dataModel.item(index) : null;
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010025 } else if (element instanceof DirectoryTree) {
26 // element is a DirectoryTree.
27 var item = element.selectedItem;
28 return item && item.fullPath;
29 } else if (element instanceof DirectoryItem) {
30 // element is a sub item in DirectoryTree.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000031
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010032 // DirectoryItem.fullPath is set on initialization, but entry is lazily.
33 // We may use fullPath just in case that the entry has not been set yet.
34 return element.entry && element.entry.fullPath ||
35 element.fullPath;
36 } else if (cr.ui.List) {
37 // element is a normal List (eg. the file list on the right panel).
38 var entry = element.selectedItem;
39 return entry && entry.fullPath;
40 } else {
41 console.warn('Unsupported element');
42 return null;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010043 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +000044};
45
46/**
Ben Murdoch32409262013-08-07 11:04:47 +010047 * @param {NavigationList} navigationList navigation list to extract root node.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010048 * @return {?RootType} Type of the found root.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000049 */
Ben Murdoch32409262013-08-07 11:04:47 +010050CommandUtil.getCommandRootType = function(navigationList) {
51 var root = CommandUtil.getCommandPath(navigationList);
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010052 return root && PathUtil.isRootPath(root) && PathUtil.getRootType(root);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000053};
54
55/**
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000056 * Checks if command can be executed on drive.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000057 * @param {Event} event Command event to mark.
58 * @param {FileManager} fileManager FileManager to use.
59 */
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000060CommandUtil.canExecuteEnabledOnDriveOnly = function(event, fileManager) {
61 event.canExecute = fileManager.isOnDrive();
62};
63
64/**
65 * Checks if command should be visible on drive.
66 * @param {Event} event Command event to mark.
67 * @param {FileManager} fileManager FileManager to use.
68 */
69CommandUtil.canExecuteVisibleOnDriveOnly = function(event, fileManager) {
70 event.canExecute = fileManager.isOnDrive();
71 event.command.setHidden(!fileManager.isOnDrive());
72};
73
74/**
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010075 * Checks if command should be visible on drive with pressing ctrl key.
76 * @param {Event} event Command event to mark.
77 * @param {FileManager} fileManager FileManager to use.
78 */
79CommandUtil.canExecuteVisibleOnDriveWithCtrlKeyOnly =
80 function(event, fileManager) {
81 event.canExecute = fileManager.isOnDrive() && fileManager.isCtrlKeyPressed();
82 event.command.setHidden(!event.canExecute);
83};
84
85/**
Ben Murdocheb525c52013-07-10 11:40:50 +010086 * Sets as the command as always enabled.
87 * @param {Event} event Command event to mark.
88 */
89CommandUtil.canExecuteAlways = function(event) {
90 event.canExecute = true;
91};
92
93/**
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000094 * Returns a single selected/passed entry or null.
95 * @param {Event} event Command event.
96 * @param {FileManager} fileManager FileManager to use.
97 * @return {FileEntry} The entry or null.
98 */
99CommandUtil.getSingleEntry = function(event, fileManager) {
100 if (event.target.entry) {
101 return event.target.entry;
102 }
103 var selection = fileManager.getSelection();
104 if (selection.totalCount == 1) {
105 return selection.entries[0];
106 }
107 return null;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000108};
109
110/**
111 * Registers handler on specific command on specific node.
112 * @param {Node} node Node to register command handler on.
113 * @param {string} commandId Command id to respond to.
114 * @param {{execute:function, canExecute:function}} handler Handler to use.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000115 * @param {...Object} var_args Additional arguments to pass to handler.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000116 */
117CommandUtil.registerCommand = function(node, commandId, handler, var_args) {
118 var args = Array.prototype.slice.call(arguments, 3);
119
120 node.addEventListener('command', function(event) {
121 if (event.command.id == commandId) {
122 handler.execute.apply(handler, [event].concat(args));
123 event.cancelBubble = true;
124 }
125 });
126
127 node.addEventListener('canExecute', function(event) {
128 if (event.command.id == commandId)
129 handler.canExecute.apply(handler, [event].concat(args));
130 });
131};
132
133/**
134 * Sets Commands.defaultCommand for the commandId and prevents handling
135 * the keydown events for this command. Not doing that breaks relationship
136 * of original keyboard event and the command. WebKit would handle it
137 * differently in some cases.
138 * @param {Node} node to register command handler on.
139 * @param {string} commandId Command id to respond to.
140 */
141CommandUtil.forceDefaultHandler = function(node, commandId) {
142 var doc = node.ownerDocument;
143 var command = doc.querySelector('command[id="' + commandId + '"]');
144 node.addEventListener('keydown', function(e) {
145 if (command.matchesEvent(e)) {
146 // Prevent cr.ui.CommandManager of handling it and leave it
147 // for the default handler.
148 e.stopPropagation();
149 }
150 });
151 CommandUtil.registerCommand(node, commandId, Commands.defaultCommand, doc);
152};
153
154var Commands = {};
155
156/**
157 * Forwards all command events to standard document handlers.
158 */
159Commands.defaultCommand = {
160 execute: function(event, document) {
161 document.execCommand(event.command.id);
162 },
163 canExecute: function(event, document) {
164 event.canExecute = document.queryCommandEnabled(event.command.id);
165 }
166};
167
168/**
169 * Unmounts external drive.
170 */
171Commands.unmountCommand = {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000172 /**
173 * @param {Event} event Command event.
Ben Murdochbb1529c2013-08-08 10:24:53 +0100174 * @param {FileManager} fileManager The file manager instance.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000175 */
Ben Murdochbb1529c2013-08-08 10:24:53 +0100176 execute: function(event, fileManager) {
177 var root = CommandUtil.getCommandPath(event.target);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000178 if (root)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100179 fileManager.unmountVolume(PathUtil.getRootPath(root));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000180 },
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000181 /**
182 * @param {Event} event Command event.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000183 */
Ben Murdochbb1529c2013-08-08 10:24:53 +0100184 canExecute: function(event) {
185 var rootType = CommandUtil.getCommandRootType(event.target);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000186
187 event.canExecute = (rootType == RootType.ARCHIVE ||
188 rootType == RootType.REMOVABLE);
Ben Murdochbbcdd452013-07-25 10:06:34 +0100189 event.command.setHidden(!event.canExecute);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000190 event.command.label = rootType == RootType.ARCHIVE ?
191 str('CLOSE_ARCHIVE_BUTTON_LABEL') :
192 str('UNMOUNT_DEVICE_BUTTON_LABEL');
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000193 }
194};
195
196/**
197 * Formats external drive.
198 */
199Commands.formatCommand = {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000200 /**
201 * @param {Event} event Command event.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100202 * @param {FileManager} fileManager The file manager instance.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000203 */
Ben Murdochbb1529c2013-08-08 10:24:53 +0100204 execute: function(event, fileManager) {
205 var root = CommandUtil.getCommandPath(event.target);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000206
207 if (root) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100208 var url = util.makeFilesystemUrl(PathUtil.getRootPath(root));
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000209 fileManager.confirm.show(
210 loadTimeData.getString('FORMATTING_WARNING'),
211 chrome.fileBrowserPrivate.formatDevice.bind(null, url));
212 }
213 },
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000214 /**
215 * @param {Event} event Command event.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100216 * @param {FileManager} fileManager The file manager instance.
217 * @param {DirectoryModel} directoryModel The directory model instance.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000218 */
Ben Murdochbb1529c2013-08-08 10:24:53 +0100219 canExecute: function(event, fileManager, directoryModel) {
220 var root = CommandUtil.getCommandPath(event.target);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000221 var removable = root &&
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100222 PathUtil.getRootType(root) == RootType.REMOVABLE;
223 var isReadOnly = root && directoryModel.isPathReadOnly(root);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000224 event.canExecute = removable && !isReadOnly;
225 event.command.setHidden(!removable);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000226 }
227};
228
229/**
230 * Imports photos from external drive
231 */
232Commands.importCommand = {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000233 /**
234 * @param {Event} event Command event.
Ben Murdoch32409262013-08-07 11:04:47 +0100235 * @param {NavigationList} navigationList Target navigation list.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000236 */
Ben Murdoch32409262013-08-07 11:04:47 +0100237 execute: function(event, navigationList) {
238 var root = CommandUtil.getCommandPath(navigationList);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000239 if (!root)
240 return;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000241
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100242 // TODO(mtomasz): Implement launching Photo Importer.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000243 },
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000244 /**
245 * @param {Event} event Command event.
Ben Murdoch32409262013-08-07 11:04:47 +0100246 * @param {NavigationList} navigationList Target navigation list.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000247 */
Ben Murdoch32409262013-08-07 11:04:47 +0100248 canExecute: function(event, navigationList) {
249 var rootType = CommandUtil.getCommandRootType(navigationList);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000250 event.canExecute = (rootType != RootType.DRIVE);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000251 }
252};
253
254/**
255 * Initiates new folder creation.
256 */
257Commands.newFolderCommand = {
258 execute: function(event, fileManager) {
259 fileManager.createNewFolder();
260 },
261 canExecute: function(event, fileManager, directoryModel) {
262 event.canExecute = !fileManager.isOnReadonlyDirectory() &&
Ben Murdocheb525c52013-07-10 11:40:50 +0100263 !fileManager.isRenamingInProgress() &&
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000264 !directoryModel.isSearching() &&
Ben Murdocheb525c52013-07-10 11:40:50 +0100265 !directoryModel.isScanning();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000266 }
267};
268
269/**
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000270 * Initiates new window creation.
271 */
272Commands.newWindowCommand = {
Ben Murdocheb525c52013-07-10 11:40:50 +0100273 execute: function(event, fileManager, directoryModel) {
274 chrome.runtime.getBackgroundPage(function(background) {
275 var appState = {
276 defaultPath: directoryModel.getCurrentDirPath()
277 };
278 background.launchFileManager(appState);
279 });
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000280 },
281 canExecute: function(event, fileManager) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100282 event.canExecute = (fileManager.dialogType == DialogType.FULL_PAGE);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000283 }
284};
285
286/**
287 * Changed the default app handling inserted media.
288 */
289Commands.changeDefaultAppCommand = {
290 execute: function(event, fileManager) {
291 fileManager.showChangeDefaultAppPicker();
292 },
Ben Murdocheb525c52013-07-10 11:40:50 +0100293 canExecute: CommandUtil.canExecuteAlways
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000294};
295
296/**
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000297 * Deletes selected files.
298 */
299Commands.deleteFileCommand = {
300 execute: function(event, fileManager) {
301 fileManager.deleteSelection();
302 },
303 canExecute: function(event, fileManager) {
304 var selection = fileManager.getSelection();
305 event.canExecute = !fileManager.isOnReadonlyDirectory() &&
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000306 selection &&
307 selection.totalCount > 0;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000308 }
309};
310
311/**
312 * Pastes files from clipboard.
313 */
314Commands.pasteFileCommand = {
315 execute: Commands.defaultCommand.execute,
316 canExecute: function(event, document, fileTransferController) {
317 event.canExecute = (fileTransferController &&
318 fileTransferController.queryPasteCommandEnabled());
319 }
320};
321
322/**
323 * Initiates file renaming.
324 */
325Commands.renameFileCommand = {
326 execute: function(event, fileManager) {
327 fileManager.initiateRename();
328 },
329 canExecute: function(event, fileManager) {
330 var selection = fileManager.getSelection();
331 event.canExecute =
332 !fileManager.isRenamingInProgress() &&
333 !fileManager.isOnReadonlyDirectory() &&
334 selection &&
335 selection.totalCount == 1;
336 }
337};
338
339/**
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000340 * Opens drive help.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000341 */
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000342Commands.volumeHelpCommand = {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000343 execute: function() {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000344 if (fileManager.isOnDrive())
Ben Murdocheb525c52013-07-10 11:40:50 +0100345 chrome.windows.create({url: FileManager.GOOGLE_DRIVE_HELP});
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000346 else
Ben Murdocheb525c52013-07-10 11:40:50 +0100347 chrome.windows.create({url: FileManager.FILES_APP_HELP});
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000348 },
Ben Murdocheb525c52013-07-10 11:40:50 +0100349 canExecute: CommandUtil.canExecuteAlways
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000350};
351
352/**
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000353 * Opens drive buy-more-space url.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000354 */
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000355Commands.driveBuySpaceCommand = {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000356 execute: function() {
Ben Murdocheb525c52013-07-10 11:40:50 +0100357 chrome.windows.create({url: FileManager.GOOGLE_DRIVE_BUY_STORAGE});
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000358 },
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000359 canExecute: CommandUtil.canExecuteVisibleOnDriveOnly
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000360};
361
362/**
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000363 * Clears drive cache.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000364 */
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000365Commands.driveClearCacheCommand = {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000366 execute: function() {
367 chrome.fileBrowserPrivate.clearDriveCache();
368 },
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100369 canExecute: CommandUtil.canExecuteVisibleOnDriveWithCtrlKeyOnly
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000370};
371
372/**
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000373 * Opens drive.google.com.
374 */
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000375Commands.driveGoToDriveCommand = {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000376 execute: function() {
Ben Murdocheb525c52013-07-10 11:40:50 +0100377 chrome.windows.create({url: FileManager.GOOGLE_DRIVE_ROOT});
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000378 },
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000379 canExecute: CommandUtil.canExecuteVisibleOnDriveOnly
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000380};
381
382/**
383 * Displays open with dialog for current selection.
384 */
385Commands.openWithCommand = {
386 execute: function(event, fileManager) {
387 var tasks = fileManager.getSelection().tasks;
388 if (tasks) {
389 tasks.showTaskPicker(fileManager.defaultTaskPicker,
390 str('OPEN_WITH_BUTTON_LABEL'),
391 null,
392 function(task) {
393 tasks.execute(task.taskId);
394 });
395 }
396 },
397 canExecute: function(event, fileManager) {
398 var tasks = fileManager.getSelection().tasks;
399 event.canExecute = tasks && tasks.size() > 1;
400 }
401};
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000402
403/**
404 * Focuses search input box.
405 */
406Commands.searchCommand = {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100407 execute: function(event, fileManager, element) {
408 element.focus();
Torne (Richard Coles)5e3f23d2013-06-11 16:24:11 +0100409 element.select();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000410 },
411 canExecute: function(event, fileManager) {
412 event.canExecute = !fileManager.isRenamingInProgress();
413 }
414};
415
416/**
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100417 * Activates the n-th volume.
418 */
419Commands.volumeSwitchCommand = {
Ben Murdoch32409262013-08-07 11:04:47 +0100420 execute: function(event, navigationList, index) {
421 navigationList.selectByIndex(index - 1);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100422 },
Ben Murdoch32409262013-08-07 11:04:47 +0100423 canExecute: function(event, navigationList, index) {
424 event.canExecute = index > 0 && index <= navigationList.dataModel.length;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100425 }
426};
427
428/**
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000429 * Flips 'available offline' flag on the file.
430 */
431Commands.togglePinnedCommand = {
432 execute: function(event, fileManager) {
433 var pin = !event.command.checked;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000434 event.command.checked = pin;
Ben Murdochca12bfa2013-07-23 11:17:05 +0100435 var entries = Commands.togglePinnedCommand.getTargetEntries_();
Ben Murdocheb525c52013-07-10 11:40:50 +0100436 var currentEntry;
437 var error = false;
438 var steps = {
439 // Pick an entry and pin it.
440 start: function() {
441 // Check if all the entries are pinned or not.
442 if (entries.length == 0)
443 return;
444 currentEntry = entries.shift();
445 chrome.fileBrowserPrivate.pinDriveFile(
446 currentEntry.toURL(),
447 pin,
448 steps.entryPinned);
449 },
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000450
Ben Murdocheb525c52013-07-10 11:40:50 +0100451 // Check the result of pinning
452 entryPinned: function() {
453 // Convert to boolean.
454 error = !!chrome.runtime.lastError;
455 if (error && pin) {
456 fileManager.metadataCache_.get(
457 currentEntry, 'filesystem', steps.showError);
458 }
459 fileManager.metadataCache_.clear(currentEntry, 'drive');
460 fileManager.metadataCache_.get(
461 currentEntry, 'drive', steps.updateUI.bind(this));
462 },
463
464 // Update the user interface accoding to the cache state.
465 updateUI: function(drive) {
466 fileManager.updateMetadataInUI_(
467 'drive', [currentEntry.toURL()], [drive]);
468 if (!error)
469 steps.start();
470 },
471
472 // Show the error
473 showError: function(filesystem) {
474 fileManager.alert.showHtml(str('DRIVE_OUT_OF_SPACE_HEADER'),
475 strf('DRIVE_OUT_OF_SPACE_MESSAGE',
476 unescape(currentEntry.name),
477 util.bytesToString(filesystem.size)));
478 }
479 };
480 steps.start();
481 },
482
483 canExecute: function(event, fileManager) {
Ben Murdochca12bfa2013-07-23 11:17:05 +0100484 var entries = Commands.togglePinnedCommand.getTargetEntries_();
Ben Murdocheb525c52013-07-10 11:40:50 +0100485 var checked = true;
486 for (var i = 0; i < entries.length; i++) {
487 checked = checked && entries[i].pinned;
488 }
489 if (entries.length > 0) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000490 event.canExecute = true;
491 event.command.setHidden(false);
Ben Murdocheb525c52013-07-10 11:40:50 +0100492 event.command.checked = checked;
493 } else {
494 event.canExecute = false;
495 event.command.setHidden(true);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000496 }
Ben Murdocheb525c52013-07-10 11:40:50 +0100497 },
498
499 /**
500 * Obtains target entries from the selection.
501 * If directories are included in the selection, it just returns an empty
502 * array to avoid confusing because pinning directory is not supported
503 * currently.
504 *
505 * @return {Array.<Entry>} Target entries.
506 * @private
507 */
508 getTargetEntries_: function() {
509 var hasDirectory = false;
510 var results = fileManager.getSelection().entries.filter(function(entry) {
511 hasDirectory = hasDirectory || entry.isDirectory;
512 if (!entry || hasDirectory)
513 return false;
514 var metadata = fileManager.metadataCache_.getCached(entry, 'drive');
515 if (!metadata || metadata.hosted)
516 return false;
517 entry.pinned = metadata.pinned;
518 return true;
519 });
520 return hasDirectory ? [] : results;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000521 }
522};
523
524/**
525 * Creates zip file for current selection.
526 */
527Commands.zipSelectionCommand = {
528 execute: function(event, fileManager, directoryModel) {
529 var dirEntry = directoryModel.getCurrentDirEntry();
530 var selectionEntries = fileManager.getSelection().entries;
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100531 fileManager.copyManager_.zipSelection(dirEntry, selectionEntries);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000532 },
533 canExecute: function(event, fileManager) {
534 var selection = fileManager.getSelection();
535 event.canExecute = !fileManager.isOnReadonlyDirectory() &&
536 !fileManager.isOnDrive() &&
537 selection && selection.totalCount > 0;
538 }
539};
Ben Murdocheb525c52013-07-10 11:40:50 +0100540
541/**
542 * Shows the share dialog for the current selection (single only).
543 */
544Commands.shareCommand = {
545 execute: function(event, fileManager) {
546 fileManager.shareSelection();
547 },
548 canExecute: function(event, fileManager) {
549 var selection = fileManager.getSelection();
550 event.canExecute = fileManager.isOnDrive() &&
551 !fileManager.isDriveOffline() &&
Ben Murdochbbcdd452013-07-25 10:06:34 +0100552 selection && selection.totalCount == 1;
Ben Murdocheb525c52013-07-10 11:40:50 +0100553 event.command.setHidden(!fileManager.isOnDrive());
554 }
555};
556
557/**
Ben Murdochbbcdd452013-07-25 10:06:34 +0100558 * Creates a shortcut of the selected folder (single only).
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100559 */
Ben Murdochbbcdd452013-07-25 10:06:34 +0100560Commands.createFolderShortcutCommand = {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100561 /**
562 * @param {Event} event Command event.
563 * @param {FileManager} fileManager The file manager instance.
564 */
565 execute: function(event, fileManager) {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100566 var path = CommandUtil.getCommandPath(event.target);
567 if (path)
568 fileManager.createFolderShortcut(path);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100569 },
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100570
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100571 /**
572 * @param {Event} event Command event.
573 * @param {FileManager} fileManager The file manager instance.
574 */
575 canExecute: function(event, fileManager) {
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100576 var target = event.target;
Ben Murdochca12bfa2013-07-23 11:17:05 +0100577 // TODO(yoshiki): remove this after launching folder shortcuts feature.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100578 if (!fileManager.isFolderShortcutsEnabled() ||
Ben Murdoch32409262013-08-07 11:04:47 +0100579 (!target instanceof NavigationListItem &&
580 !target instanceof DirectoryItem)) {
Ben Murdochca12bfa2013-07-23 11:17:05 +0100581 event.command.setHidden(true);
582 return;
583 }
584
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100585 var path = CommandUtil.getCommandPath(event.target);
586 var folderShortcutExists = path && fileManager.folderShortcutExists(path);
587
588 var onlyOneFolderSelected = true;
589 // Only on list, user can select multiple files. The command is enabled only
590 // when a single file is selected.
591 if (event.target instanceof cr.ui.List) {
592 var items = event.target.selectedItems;
593 onlyOneFolderSelected = (items.length == 1 && items[0].isDirectory);
594 }
595
596 var eligible = path && PathUtil.isEligibleForFolderShortcut(path);
597 event.canExecute =
598 eligible && onlyOneFolderSelected && !folderShortcutExists;
Ben Murdochbb1529c2013-08-08 10:24:53 +0100599 event.command.setHidden(!eligible || !onlyOneFolderSelected);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100600 }
601};
602
603/**
Ben Murdochbbcdd452013-07-25 10:06:34 +0100604 * Removes the folder shortcut.
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100605 */
Ben Murdochbbcdd452013-07-25 10:06:34 +0100606Commands.removeFolderShortcutCommand = {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100607 /**
608 * @param {Event} event Command event.
609 * @param {FileManager} fileManager The file manager instance.
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100610 */
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100611 execute: function(event, fileManager) {
612 var path = CommandUtil.getCommandPath(event.target);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100613 if (path)
Ben Murdochbbcdd452013-07-25 10:06:34 +0100614 fileManager.removeFolderShortcut(path);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100615 },
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100616
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100617 /**
618 * @param {Event} event Command event.
619 * @param {FileManager} fileManager The file manager instance.
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100620 */
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100621 canExecute: function(event, fileManager) {
622 var target = event.target;
Ben Murdochca12bfa2013-07-23 11:17:05 +0100623 // TODO(yoshiki): remove this after launching folder shortcut feature.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100624 if (!fileManager.isFolderShortcutsEnabled() ||
Ben Murdoch32409262013-08-07 11:04:47 +0100625 (!target instanceof NavigationListItem &&
626 !target instanceof DirectoryItem)) {
Ben Murdochca12bfa2013-07-23 11:17:05 +0100627 event.command.setHidden(true);
628 return;
629 }
630
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100631 var path = CommandUtil.getCommandPath(target);
632 var eligible = path && PathUtil.isEligibleForFolderShortcut(path);
Ben Murdochbbcdd452013-07-25 10:06:34 +0100633 var isShortcut = path && fileManager.folderShortcutExists(path);
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100634 event.canExecute = isShortcut && eligible;
Ben Murdochbb1529c2013-08-08 10:24:53 +0100635 event.command.setHidden(!event.canExecute);
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100636 }
637};
638
639/**
Ben Murdocheb525c52013-07-10 11:40:50 +0100640 * Zoom in to the Files.app.
641 */
642Commands.zoomInCommand = {
643 execute: function(event) {
644 chrome.fileBrowserPrivate.zoom('in');
645 },
646 canExecute: CommandUtil.canExecuteAlways
647};
648
649/**
650 * Zoom out from the Files.app.
651 */
652Commands.zoomOutCommand = {
653 execute: function(event) {
654 chrome.fileBrowserPrivate.zoom('out');
655 },
656 canExecute: CommandUtil.canExecuteAlways
657};
658
659/**
660 * Reset the zoom factor.
661 */
662Commands.zoomResetCommand = {
663 execute: function(event) {
664 chrome.fileBrowserPrivate.zoom('reset');
665 },
666 canExecute: CommandUtil.canExecuteAlways
667};