OLD | NEW |
| (Empty) |
1 // 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 | |
5 'use strict'; | |
6 | |
7 /** | |
8 * TODO(dzvorygin): Here we use this hack, since 'hidden' is standard | |
9 * attribute and we can't use it's setter as usual. | |
10 * @param {boolean} value New value of hidden property. | |
11 */ | |
12 cr.ui.Command.prototype.setHidden = function(value) { | |
13 this.__lookupSetter__('hidden').call(this, value); | |
14 }; | |
15 | |
16 /** | |
17 * A command. | |
18 * @interface | |
19 */ | |
20 var Command = function() {}; | |
21 | |
22 /** | |
23 * Handles the execute event. | |
24 * @param {Event} event Command event. | |
25 * @param {FileManager} fileManager FileManager. | |
26 */ | |
27 Command.prototype.execute = function(event, fileManager) {}; | |
28 | |
29 /** | |
30 * Handles the can execute event. | |
31 * @param {Event} event Can execute event. | |
32 * @param {FileManager} fileManager FileManager. | |
33 */ | |
34 Command.prototype.canExecute = function(event, fileManager) {}; | |
35 | |
36 /** | |
37 * Utility for commands. | |
38 */ | |
39 var CommandUtil = {}; | |
40 | |
41 /** | |
42 * Extracts entry on which command event was dispatched. | |
43 * | |
44 * @param {DirectoryTree|DirectoryItem|NavigationList|HTMLLIElement|cr.ui.List} | |
45 * element Directory to extract a path from. | |
46 * @return {Entry} Entry of the found node. | |
47 */ | |
48 CommandUtil.getCommandEntry = function(element) { | |
49 if (element instanceof NavigationList) { | |
50 // element is a NavigationList. | |
51 /** @type {NavigationModelItem} */ | |
52 var item = element.selectedItem; | |
53 return element.selectedItem && | |
54 CommandUtil.getEntryFromNavigationModelItem_(item); | |
55 } else if (element instanceof NavigationListItem) { | |
56 // element is a subitem of NavigationList. | |
57 /** @type {NavigationList} */ | |
58 var navigationList = element.parentElement; | |
59 var index = navigationList.getIndexOfListItem(element); | |
60 /** @type {NavigationModelItem} */ | |
61 var item = (index != -1) ? navigationList.dataModel.item(index) : null; | |
62 return item && CommandUtil.getEntryFromNavigationModelItem_(item); | |
63 } else if (element instanceof DirectoryTree) { | |
64 // element is a DirectoryTree. | |
65 return element.selectedItem.entry; | |
66 } else if (element instanceof DirectoryItem) { | |
67 // element is a sub item in DirectoryTree. | |
68 return element.entry; | |
69 } else if (element instanceof cr.ui.List) { | |
70 // element is a normal List (eg. the file list on the right panel). | |
71 var entry = element.selectedItem; | |
72 // Check if it is Entry or not by checking for toURL(). | |
73 return entry && 'toURL' in entry ? entry : null; | |
74 } else { | |
75 console.warn('Unsupported element'); | |
76 return null; | |
77 } | |
78 }; | |
79 | |
80 /** | |
81 * Obtains an entry from the give navigation model item. | |
82 * @param {NavigationModelItem} item Navigation modle item. | |
83 * @return {Entry} Related entry. | |
84 * @private | |
85 */ | |
86 CommandUtil.getEntryFromNavigationModelItem_ = function(item) { | |
87 if (item.isVolume) | |
88 return item.volumeInfo.displayRoot; | |
89 if (item.isShortcut) | |
90 return item.entry; | |
91 return null; | |
92 }; | |
93 | |
94 /** | |
95 * Checks if command can be executed on drive. | |
96 * @param {Event} event Command event to mark. | |
97 * @param {FileManager} fileManager FileManager to use. | |
98 */ | |
99 CommandUtil.canExecuteEnabledOnDriveOnly = function(event, fileManager) { | |
100 event.canExecute = fileManager.isOnDrive(); | |
101 }; | |
102 | |
103 /** | |
104 * Sets the command as visible only when the current volume is drive and it's | |
105 * running as a normal app, not as a modal dialog. | |
106 * @param {Event} event Command event to mark. | |
107 * @param {FileManager} fileManager FileManager to use. | |
108 */ | |
109 CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly = | |
110 function(event, fileManager) { | |
111 var enabled = fileManager.isOnDrive() && | |
112 !DialogType.isModal(fileManager.dialogType); | |
113 event.canExecute = enabled; | |
114 event.command.setHidden(!enabled); | |
115 }; | |
116 | |
117 /** | |
118 * Sets as the command as always enabled. | |
119 * @param {Event} event Command event to mark. | |
120 */ | |
121 CommandUtil.canExecuteAlways = function(event) { | |
122 event.canExecute = true; | |
123 }; | |
124 | |
125 /** | |
126 * Returns a single selected/passed entry or null. | |
127 * @param {Event} event Command event. | |
128 * @param {FileManager} fileManager FileManager to use. | |
129 * @return {FileEntry} The entry or null. | |
130 */ | |
131 CommandUtil.getSingleEntry = function(event, fileManager) { | |
132 if (event.target.entry) { | |
133 return event.target.entry; | |
134 } | |
135 var selection = fileManager.getSelection(); | |
136 if (selection.totalCount == 1) { | |
137 return selection.entries[0]; | |
138 } | |
139 return null; | |
140 }; | |
141 | |
142 /** | |
143 * Obtains target entries that can be pinned from the selection. | |
144 * If directories are included in the selection, it just returns an empty | |
145 * array to avoid confusing because pinning directory is not supported | |
146 * currently. | |
147 * | |
148 * @return {Array.<Entry>} Target entries. | |
149 */ | |
150 CommandUtil.getPinTargetEntries = function() { | |
151 var hasDirectory = false; | |
152 var results = fileManager.getSelection().entries.filter(function(entry) { | |
153 hasDirectory = hasDirectory || entry.isDirectory; | |
154 if (!entry || hasDirectory) | |
155 return false; | |
156 var metadata = fileManager.metadataCache_.getCached(entry, 'drive'); | |
157 if (!metadata || metadata.hosted) | |
158 return false; | |
159 entry.pinned = metadata.pinned; | |
160 return true; | |
161 }); | |
162 return hasDirectory ? [] : results; | |
163 }; | |
164 | |
165 /** | |
166 * Sets the default handler for the commandId and prevents handling | |
167 * the keydown events for this command. Not doing that breaks relationship | |
168 * of original keyboard event and the command. WebKit would handle it | |
169 * differently in some cases. | |
170 * @param {Node} node to register command handler on. | |
171 * @param {string} commandId Command id to respond to. | |
172 */ | |
173 CommandUtil.forceDefaultHandler = function(node, commandId) { | |
174 var doc = node.ownerDocument; | |
175 var command = doc.querySelector('command[id="' + commandId + '"]'); | |
176 node.addEventListener('keydown', function(e) { | |
177 if (command.matchesEvent(e)) { | |
178 // Prevent cr.ui.CommandManager of handling it and leave it | |
179 // for the default handler. | |
180 e.stopPropagation(); | |
181 } | |
182 }); | |
183 node.addEventListener('command', function(event) { | |
184 if (event.command.id !== commandId) | |
185 return; | |
186 document.execCommand(event.command.id); | |
187 event.cancelBubble = true; | |
188 }); | |
189 node.addEventListener('canExecute', function(event) { | |
190 if (event.command.id === commandId) | |
191 event.canExecute = document.queryCommandEnabled(event.command.id); | |
192 }); | |
193 }; | |
194 | |
195 /** | |
196 * Default command. | |
197 * @type {Command} | |
198 */ | |
199 CommandUtil.defaultCommand = { | |
200 execute: function(event, fileManager) { | |
201 fileManager.document.execCommand(event.command.id); | |
202 }, | |
203 canExecute: function(event, fileManager) { | |
204 event.canExecute = fileManager.document.queryCommandEnabled( | |
205 event.command.id); | |
206 } | |
207 }; | |
208 | |
209 /** | |
210 * Creates the volume switch command with index. | |
211 * @param {number} index Volume index from 1 to 9. | |
212 * @return {Command} Volume switch command. | |
213 */ | |
214 CommandUtil.createVolumeSwitchCommand = function(index) { | |
215 return { | |
216 execute: function(event, fileManager) { | |
217 fileManager.navigationList.selectByIndex(index - 1); | |
218 }, | |
219 canExecute: function(event, fileManager) { | |
220 event.canExecute = index > 0 && | |
221 index <= fileManager.navigationList.dataModel.length; | |
222 } | |
223 }; | |
224 }; | |
225 | |
226 /** | |
227 * Handle of the command events. | |
228 * @param {FileManager} fileManager FileManager. | |
229 * @constructor | |
230 */ | |
231 var CommandHandler = function(fileManager) { | |
232 /** | |
233 * FileManager. | |
234 * @type {FileManager} | |
235 * @private | |
236 */ | |
237 this.fileManager_ = fileManager; | |
238 | |
239 /** | |
240 * Command elements. | |
241 * @type {Object.<string, cr.ui.Command>} | |
242 * @private | |
243 */ | |
244 this.commands_ = {}; | |
245 | |
246 Object.seal(this); | |
247 | |
248 // Decorate command tags in the document. | |
249 var commands = fileManager.document.querySelectorAll('command'); | |
250 for (var i = 0; i < commands.length; i++) { | |
251 cr.ui.Command.decorate(commands[i]); | |
252 this.commands_[commands[i].id] = commands[i]; | |
253 } | |
254 | |
255 // Register events. | |
256 fileManager.document.addEventListener('command', this.onCommand_.bind(this)); | |
257 fileManager.document.addEventListener('canExecute', | |
258 this.onCanExecute_.bind(this)); | |
259 }; | |
260 | |
261 /** | |
262 * Updates the availability of all commands. | |
263 */ | |
264 CommandHandler.prototype.updateAvailability = function() { | |
265 for (var id in this.commands_) { | |
266 this.commands_[id].canExecuteChange(); | |
267 } | |
268 }; | |
269 | |
270 /** | |
271 * Checks if the handler should ignore the current event, eg. since there is | |
272 * a popup dialog currently opened. | |
273 * | |
274 * @return {boolean} True if the event should be ignored, false otherwise. | |
275 * @private | |
276 */ | |
277 CommandHandler.prototype.shouldIgnoreEvents_ = function() { | |
278 // Do not handle commands, when a dialog is shown. | |
279 if (this.fileManager_.document.querySelector('.cr-dialog-container.shown')) | |
280 return true; | |
281 | |
282 return false; // Do not ignore. | |
283 }; | |
284 | |
285 /** | |
286 * Handles command events. | |
287 * @param {Event} event Command event. | |
288 * @private | |
289 */ | |
290 CommandHandler.prototype.onCommand_ = function(event) { | |
291 if (this.shouldIgnoreEvents_()) | |
292 return; | |
293 var handler = CommandHandler.COMMANDS_[event.command.id]; | |
294 handler.execute.call(this, event, this.fileManager_); | |
295 }; | |
296 | |
297 /** | |
298 * Handles canExecute events. | |
299 * @param {Event} event Can execute event. | |
300 * @private | |
301 */ | |
302 CommandHandler.prototype.onCanExecute_ = function(event) { | |
303 if (this.shouldIgnoreEvents_()) | |
304 return; | |
305 var handler = CommandHandler.COMMANDS_[event.command.id]; | |
306 handler.canExecute.call(this, event, this.fileManager_); | |
307 }; | |
308 | |
309 /** | |
310 * Commands. | |
311 * @type {Object.<string, Command>} | |
312 * @const | |
313 * @private | |
314 */ | |
315 CommandHandler.COMMANDS_ = {}; | |
316 | |
317 /** | |
318 * Unmounts external drive. | |
319 * @type {Command} | |
320 */ | |
321 CommandHandler.COMMANDS_['unmount'] = { | |
322 /** | |
323 * @param {Event} event Command event. | |
324 * @param {FileManager} fileManager The file manager instance. | |
325 */ | |
326 execute: function(event, fileManager) { | |
327 var root = CommandUtil.getCommandEntry(event.target); | |
328 if (!root) | |
329 return; | |
330 var errorCallback = function() { | |
331 fileManager.alert.showHtml('', str('UNMOUNT_FAILED')); | |
332 }; | |
333 var volumeInfo = fileManager.volumeManager.getVolumeInfo(root); | |
334 if (!volumeInfo) { | |
335 errorCallback(); | |
336 return; | |
337 } | |
338 fileManager.volumeManager_.unmount( | |
339 volumeInfo, | |
340 function() {}, | |
341 errorCallback); | |
342 }, | |
343 /** | |
344 * @param {Event} event Command event. | |
345 */ | |
346 canExecute: function(event, fileManager) { | |
347 var root = CommandUtil.getCommandEntry(event.target); | |
348 if (!root) | |
349 return; | |
350 var locationInfo = this.fileManager_.volumeManager.getLocationInfo(root); | |
351 var rootType = | |
352 locationInfo && locationInfo.isRootEntry && locationInfo.rootType; | |
353 | |
354 event.canExecute = (rootType == RootType.ARCHIVE || | |
355 rootType == RootType.REMOVABLE); | |
356 event.command.setHidden(!event.canExecute); | |
357 event.command.label = rootType == RootType.ARCHIVE ? | |
358 str('CLOSE_ARCHIVE_BUTTON_LABEL') : | |
359 str('UNMOUNT_DEVICE_BUTTON_LABEL'); | |
360 } | |
361 }; | |
362 | |
363 /** | |
364 * Formats external drive. | |
365 * @type {Command} | |
366 */ | |
367 CommandHandler.COMMANDS_['format'] = { | |
368 /** | |
369 * @param {Event} event Command event. | |
370 * @param {FileManager} fileManager The file manager instance. | |
371 */ | |
372 execute: function(event, fileManager) { | |
373 var directoryModel = fileManager.directoryModel; | |
374 var root = CommandUtil.getCommandEntry(event.target); | |
375 // If an entry is not found from the event target, use the current | |
376 // directory. This can happen for the format button for unsupported and | |
377 // unrecognized volumes. | |
378 if (!root) | |
379 root = directoryModel.getCurrentDirEntry(); | |
380 | |
381 var volumeInfo = fileManager.volumeManager.getVolumeInfo(root); | |
382 if (volumeInfo) { | |
383 fileManager.confirm.show( | |
384 loadTimeData.getString('FORMATTING_WARNING'), | |
385 chrome.fileBrowserPrivate.formatVolume.bind(null, | |
386 volumeInfo.volumeId)); | |
387 } | |
388 }, | |
389 /** | |
390 * @param {Event} event Command event. | |
391 * @param {FileManager} fileManager The file manager instance. | |
392 */ | |
393 canExecute: function(event, fileManager) { | |
394 var directoryModel = fileManager.directoryModel; | |
395 var root = CommandUtil.getCommandEntry(event.target); | |
396 // See the comment in execute() for why doing this. | |
397 if (!root) | |
398 root = directoryModel.getCurrentDirEntry(); | |
399 var location = root && fileManager.volumeManager.getLocationInfo(root); | |
400 var removable = location && location.rootType === RootType.REMOVABLE; | |
401 // Don't check if the volume is read-only. Unformatted volume is considered | |
402 // read-only per VolumeInfo.isReadOnly, but can be formatted. An error will | |
403 // be raised if formatting failed anyway. | |
404 event.canExecute = removable; | |
405 event.command.setHidden(!removable); | |
406 } | |
407 }; | |
408 | |
409 /** | |
410 * Initiates new folder creation. | |
411 * @type {Command} | |
412 */ | |
413 CommandHandler.COMMANDS_['new-folder'] = { | |
414 execute: function(event, fileManager) { | |
415 fileManager.createNewFolder(); | |
416 }, | |
417 canExecute: function(event, fileManager) { | |
418 var directoryModel = fileManager.directoryModel; | |
419 event.canExecute = !fileManager.isOnReadonlyDirectory() && | |
420 !fileManager.isRenamingInProgress() && | |
421 !directoryModel.isSearching() && | |
422 !directoryModel.isScanning(); | |
423 } | |
424 }; | |
425 | |
426 /** | |
427 * Initiates new window creation. | |
428 * @type {Command} | |
429 */ | |
430 CommandHandler.COMMANDS_['new-window'] = { | |
431 execute: function(event, fileManager) { | |
432 chrome.fileBrowserPrivate.getProfiles(function(profiles, | |
433 currentId, | |
434 displayedId) { | |
435 fileManager.backgroundPage.launchFileManager({ | |
436 currentDirectoryURL: fileManager.getCurrentDirectoryEntry() && | |
437 fileManager.getCurrentDirectoryEntry().toURL(), | |
438 displayedId: currentId !== displayedId ? displayedId : undefined | |
439 }); | |
440 }); | |
441 }, | |
442 canExecute: function(event, fileManager) { | |
443 event.canExecute = | |
444 fileManager.getCurrentDirectoryEntry() && | |
445 (fileManager.dialogType === DialogType.FULL_PAGE); | |
446 } | |
447 }; | |
448 | |
449 /** | |
450 * Deletes selected files. | |
451 * @type {Command} | |
452 */ | |
453 CommandHandler.COMMANDS_['delete'] = { | |
454 execute: function(event, fileManager) { | |
455 fileManager.deleteSelection(); | |
456 }, | |
457 canExecute: function(event, fileManager) { | |
458 var selection = fileManager.getSelection(); | |
459 event.canExecute = !fileManager.isOnReadonlyDirectory() && | |
460 selection && | |
461 selection.totalCount > 0; | |
462 } | |
463 }; | |
464 | |
465 /** | |
466 * Pastes files from clipboard. | |
467 * @type {Command} | |
468 */ | |
469 CommandHandler.COMMANDS_['paste'] = { | |
470 execute: function() { | |
471 document.execCommand(event.command.id); | |
472 }, | |
473 canExecute: function(event, fileManager) { | |
474 var document = fileManager.document; | |
475 var fileTransferController = fileManager.fileTransferController; | |
476 event.canExecute = (fileTransferController && | |
477 fileTransferController.queryPasteCommandEnabled()); | |
478 } | |
479 }; | |
480 | |
481 CommandHandler.COMMANDS_['cut'] = CommandUtil.defaultCommand; | |
482 CommandHandler.COMMANDS_['copy'] = CommandUtil.defaultCommand; | |
483 | |
484 /** | |
485 * Initiates file renaming. | |
486 * @type {Command} | |
487 */ | |
488 CommandHandler.COMMANDS_['rename'] = { | |
489 execute: function(event, fileManager) { | |
490 fileManager.initiateRename(); | |
491 }, | |
492 canExecute: function(event, fileManager) { | |
493 var selection = fileManager.getSelection(); | |
494 event.canExecute = !fileManager.isRenamingInProgress() && | |
495 !fileManager.isOnReadonlyDirectory() && | |
496 selection && | |
497 selection.totalCount == 1; | |
498 } | |
499 }; | |
500 | |
501 /** | |
502 * Opens drive help. | |
503 * @type {Command} | |
504 */ | |
505 CommandHandler.COMMANDS_['volume-help'] = { | |
506 execute: function(event, fileManager) { | |
507 if (fileManager.isOnDrive()) | |
508 util.visitURL(str('GOOGLE_DRIVE_HELP_URL')); | |
509 else | |
510 util.visitURL(str('FILES_APP_HELP_URL')); | |
511 }, | |
512 canExecute: function(event, fileManager) { | |
513 // Hides the help menu in modal dialog mode. It does not make much sense | |
514 // because after all, users cannot view the help without closing, and | |
515 // besides that the help page is about Files.app as an app, not about the | |
516 // dialog mode itself. It can also lead to hard-to-fix bug crbug.com/339089. | |
517 var hideHelp = DialogType.isModal(fileManager.dialogType); | |
518 event.canExecute = !hideHelp; | |
519 event.command.setHidden(hideHelp); | |
520 fileManager.document_.getElementById('help-separator').hidden = hideHelp; | |
521 }, | |
522 }; | |
523 | |
524 /** | |
525 * Opens drive buy-more-space url. | |
526 * @type {Command} | |
527 */ | |
528 CommandHandler.COMMANDS_['drive-buy-more-space'] = { | |
529 execute: function(event, fileManager) { | |
530 util.visitURL(str('GOOGLE_DRIVE_BUY_STORAGE_URL')); | |
531 }, | |
532 canExecute: CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly | |
533 }; | |
534 | |
535 /** | |
536 * Opens drive.google.com. | |
537 * @type {Command} | |
538 */ | |
539 CommandHandler.COMMANDS_['drive-go-to-drive'] = { | |
540 execute: function(event, fileManager) { | |
541 util.visitURL(str('GOOGLE_DRIVE_ROOT_URL')); | |
542 }, | |
543 canExecute: CommandUtil.canExecuteVisibleOnDriveInNormalAppModeOnly | |
544 }; | |
545 | |
546 /** | |
547 * Displays open with dialog for current selection. | |
548 * @type {Command} | |
549 */ | |
550 CommandHandler.COMMANDS_['open-with'] = { | |
551 execute: function(event, fileManager) { | |
552 var tasks = fileManager.getSelection().tasks; | |
553 if (tasks) { | |
554 tasks.showTaskPicker(fileManager.defaultTaskPicker, | |
555 str('OPEN_WITH_BUTTON_LABEL'), | |
556 '', | |
557 function(task) { | |
558 tasks.execute(task.taskId); | |
559 }); | |
560 } | |
561 }, | |
562 canExecute: function(event, fileManager) { | |
563 var tasks = fileManager.getSelection().tasks; | |
564 event.canExecute = tasks && tasks.size() > 1; | |
565 } | |
566 }; | |
567 | |
568 /** | |
569 * Focuses search input box. | |
570 * @type {Command} | |
571 */ | |
572 CommandHandler.COMMANDS_['search'] = { | |
573 execute: function(event, fileManager) { | |
574 var element = fileManager.document.querySelector('#search-box input'); | |
575 element.focus(); | |
576 element.select(); | |
577 }, | |
578 canExecute: function(event, fileManager) { | |
579 event.canExecute = !fileManager.isRenamingInProgress(); | |
580 } | |
581 }; | |
582 | |
583 /** | |
584 * Activates the n-th volume. | |
585 * @type {Command} | |
586 */ | |
587 CommandHandler.COMMANDS_['volume-switch-1'] = | |
588 CommandUtil.createVolumeSwitchCommand(1); | |
589 CommandHandler.COMMANDS_['volume-switch-2'] = | |
590 CommandUtil.createVolumeSwitchCommand(2); | |
591 CommandHandler.COMMANDS_['volume-switch-3'] = | |
592 CommandUtil.createVolumeSwitchCommand(3); | |
593 CommandHandler.COMMANDS_['volume-switch-4'] = | |
594 CommandUtil.createVolumeSwitchCommand(4); | |
595 CommandHandler.COMMANDS_['volume-switch-5'] = | |
596 CommandUtil.createVolumeSwitchCommand(5); | |
597 CommandHandler.COMMANDS_['volume-switch-6'] = | |
598 CommandUtil.createVolumeSwitchCommand(6); | |
599 CommandHandler.COMMANDS_['volume-switch-7'] = | |
600 CommandUtil.createVolumeSwitchCommand(7); | |
601 CommandHandler.COMMANDS_['volume-switch-8'] = | |
602 CommandUtil.createVolumeSwitchCommand(8); | |
603 CommandHandler.COMMANDS_['volume-switch-9'] = | |
604 CommandUtil.createVolumeSwitchCommand(9); | |
605 | |
606 /** | |
607 * Flips 'available offline' flag on the file. | |
608 * @type {Command} | |
609 */ | |
610 CommandHandler.COMMANDS_['toggle-pinned'] = { | |
611 execute: function(event, fileManager) { | |
612 var pin = !event.command.checked; | |
613 event.command.checked = pin; | |
614 var entries = CommandUtil.getPinTargetEntries(); | |
615 var currentEntry; | |
616 var error = false; | |
617 var steps = { | |
618 // Pick an entry and pin it. | |
619 start: function() { | |
620 // Check if all the entries are pinned or not. | |
621 if (entries.length == 0) | |
622 return; | |
623 currentEntry = entries.shift(); | |
624 chrome.fileBrowserPrivate.pinDriveFile( | |
625 currentEntry.toURL(), | |
626 pin, | |
627 steps.entryPinned); | |
628 }, | |
629 | |
630 // Check the result of pinning | |
631 entryPinned: function() { | |
632 // Convert to boolean. | |
633 error = !!chrome.runtime.lastError; | |
634 if (error && pin) { | |
635 fileManager.metadataCache_.get( | |
636 currentEntry, 'filesystem', steps.showError); | |
637 } | |
638 fileManager.metadataCache_.clear(currentEntry, 'drive'); | |
639 fileManager.metadataCache_.get( | |
640 currentEntry, 'drive', steps.updateUI.bind(this)); | |
641 }, | |
642 | |
643 // Update the user interface accoding to the cache state. | |
644 updateUI: function(drive) { | |
645 fileManager.updateMetadataInUI_( | |
646 'drive', [currentEntry.toURL()], [drive]); | |
647 if (!error) | |
648 steps.start(); | |
649 }, | |
650 | |
651 // Show the error | |
652 showError: function(filesystem) { | |
653 fileManager.alert.showHtml(str('DRIVE_OUT_OF_SPACE_HEADER'), | |
654 strf('DRIVE_OUT_OF_SPACE_MESSAGE', | |
655 unescape(currentEntry.name), | |
656 util.bytesToString(filesystem.size))); | |
657 } | |
658 }; | |
659 steps.start(); | |
660 }, | |
661 | |
662 canExecute: function(event, fileManager) { | |
663 var entries = CommandUtil.getPinTargetEntries(); | |
664 var checked = true; | |
665 for (var i = 0; i < entries.length; i++) { | |
666 checked = checked && entries[i].pinned; | |
667 } | |
668 if (entries.length > 0) { | |
669 event.canExecute = true; | |
670 event.command.setHidden(false); | |
671 event.command.checked = checked; | |
672 } else { | |
673 event.canExecute = false; | |
674 event.command.setHidden(true); | |
675 } | |
676 } | |
677 }; | |
678 | |
679 /** | |
680 * Creates zip file for current selection. | |
681 * @type {Command} | |
682 */ | |
683 CommandHandler.COMMANDS_['zip-selection'] = { | |
684 execute: function(event, fileManager) { | |
685 var dirEntry = fileManager.getCurrentDirectoryEntry(); | |
686 var selectionEntries = fileManager.getSelection().entries; | |
687 fileManager.fileOperationManager_.zipSelection(dirEntry, selectionEntries); | |
688 }, | |
689 canExecute: function(event, fileManager) { | |
690 var dirEntry = fileManager.getCurrentDirectoryEntry(); | |
691 var selection = fileManager.getSelection(); | |
692 event.canExecute = | |
693 dirEntry && | |
694 !fileManager.isOnReadonlyDirectory() && | |
695 !fileManager.isOnDrive() && | |
696 selection && selection.totalCount > 0; | |
697 } | |
698 }; | |
699 | |
700 /** | |
701 * Shows the share dialog for the current selection (single only). | |
702 * @type {Command} | |
703 */ | |
704 CommandHandler.COMMANDS_['share'] = { | |
705 execute: function(event, fileManager) { | |
706 fileManager.shareSelection(); | |
707 }, | |
708 canExecute: function(event, fileManager) { | |
709 var selection = fileManager.getSelection(); | |
710 var isDriveOffline = | |
711 fileManager.volumeManager.getDriveConnectionState().type === | |
712 util.DriveConnectionType.OFFLINE; | |
713 event.canExecute = fileManager.isOnDrive() && | |
714 !isDriveOffline && | |
715 selection && selection.totalCount == 1; | |
716 event.command.setHidden(!fileManager.isOnDrive()); | |
717 } | |
718 }; | |
719 | |
720 /** | |
721 * Creates a shortcut of the selected folder (single only). | |
722 * @type {Command} | |
723 */ | |
724 CommandHandler.COMMANDS_['create-folder-shortcut'] = { | |
725 /** | |
726 * @param {Event} event Command event. | |
727 * @param {FileManager} fileManager The file manager instance. | |
728 */ | |
729 execute: function(event, fileManager) { | |
730 var entry = CommandUtil.getCommandEntry(event.target); | |
731 if (entry) | |
732 fileManager.createFolderShortcut(entry); | |
733 }, | |
734 | |
735 /** | |
736 * @param {Event} event Command event. | |
737 * @param {FileManager} fileManager The file manager instance. | |
738 */ | |
739 canExecute: function(event, fileManager) { | |
740 var entry = CommandUtil.getCommandEntry(event.target); | |
741 var folderShortcutExists = entry && | |
742 fileManager.folderShortcutExists(entry); | |
743 | |
744 var onlyOneFolderSelected = true; | |
745 // Only on list, user can select multiple files. The command is enabled only | |
746 // when a single file is selected. | |
747 if (event.target instanceof cr.ui.List && | |
748 !(event.target instanceof NavigationList)) { | |
749 var items = event.target.selectedItems; | |
750 onlyOneFolderSelected = (items.length == 1 && items[0].isDirectory); | |
751 } | |
752 | |
753 var location = entry && fileManager.volumeManager.getLocationInfo(entry); | |
754 var eligible = location && location.isEligibleForFolderShortcut; | |
755 event.canExecute = | |
756 eligible && onlyOneFolderSelected && !folderShortcutExists; | |
757 event.command.setHidden(!eligible || !onlyOneFolderSelected); | |
758 } | |
759 }; | |
760 | |
761 /** | |
762 * Removes the folder shortcut. | |
763 * @type {Command} | |
764 */ | |
765 CommandHandler.COMMANDS_['remove-folder-shortcut'] = { | |
766 /** | |
767 * @param {Event} event Command event. | |
768 * @param {FileManager} fileManager The file manager instance. | |
769 */ | |
770 execute: function(event, fileManager) { | |
771 var entry = CommandUtil.getCommandEntry(event.target); | |
772 if (entry) | |
773 fileManager.removeFolderShortcut(entry); | |
774 }, | |
775 | |
776 /** | |
777 * @param {Event} event Command event. | |
778 * @param {FileManager} fileManager The file manager instance. | |
779 */ | |
780 canExecute: function(event, fileManager) { | |
781 var entry = CommandUtil.getCommandEntry(event.target); | |
782 var location = entry && fileManager.volumeManager.getLocationInfo(entry); | |
783 | |
784 var eligible = location && location.isEligibleForFolderShortcut; | |
785 var isShortcut = entry && fileManager.folderShortcutExists(entry); | |
786 event.canExecute = isShortcut && eligible; | |
787 event.command.setHidden(!event.canExecute); | |
788 } | |
789 }; | |
790 | |
791 /** | |
792 * Zoom in to the Files.app. | |
793 * @type {Command} | |
794 */ | |
795 CommandHandler.COMMANDS_['zoom-in'] = { | |
796 execute: function(event, fileManager) { | |
797 chrome.fileBrowserPrivate.zoom('in'); | |
798 }, | |
799 canExecute: CommandUtil.canExecuteAlways | |
800 }; | |
801 | |
802 /** | |
803 * Zoom out from the Files.app. | |
804 * @type {Command} | |
805 */ | |
806 CommandHandler.COMMANDS_['zoom-out'] = { | |
807 execute: function(event, fileManager) { | |
808 chrome.fileBrowserPrivate.zoom('out'); | |
809 }, | |
810 canExecute: CommandUtil.canExecuteAlways | |
811 }; | |
812 | |
813 /** | |
814 * Reset the zoom factor. | |
815 * @type {Command} | |
816 */ | |
817 CommandHandler.COMMANDS_['zoom-reset'] = { | |
818 execute: function(event, fileManager) { | |
819 chrome.fileBrowserPrivate.zoom('reset'); | |
820 }, | |
821 canExecute: CommandUtil.canExecuteAlways | |
822 }; | |
OLD | NEW |