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 | |
52 /** @type {NavigationModelItem} */ | |
53 var selectedItem = element.selectedItem; | |
54 return selectedItem && selectedItem.getCachedEntry(); | |
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 && item.getCachedEntry(); | |
63 } else if (element instanceof DirectoryTree) { | |
64 // element is a DirectoryTree. | |
65 return element.selectedItem; | |
66 } else if (element instanceof DirectoryItem) { | |
67 // element is a sub item in DirectoryTree. | |
68 | |
69 // DirectoryItem.fullPath is set on initialization, but entry is lazily. | |
70 // We may use fullPath just in case that the entry has not been set yet. | |
71 return element.entry; | |
72 } else if (element instanceof cr.ui.List) { | |
73 // element is a normal List (eg. the file list on the right panel). | |
74 var entry = element.selectedItem; | |
75 // Check if it is Entry or not by referring the fullPath member variable. | |
76 return entry && entry.fullPath ? entry : null; | |
77 } else { | |
78 console.warn('Unsupported element'); | |
79 return null; | |
80 } | |
81 }; | |
82 | |
83 /** | |
84 * @param {NavigationList} navigationList navigation list to extract root node. | |
85 * @return {?RootType} Type of the found root. | |
86 */ | |
87 CommandUtil.getCommandRootType = function(navigationList) { | |
88 var root = CommandUtil.getCommandEntry(navigationList); | |
89 return root && | |
90 PathUtil.isRootPath(root.fullPath) && | |
91 PathUtil.getRootType(root.fullPath); | |
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 * Checks if command should be visible on drive. | |
105 * @param {Event} event Command event to mark. | |
106 * @param {FileManager} fileManager FileManager to use. | |
107 */ | |
108 CommandUtil.canExecuteVisibleOnDriveOnly = function(event, fileManager) { | |
109 event.canExecute = fileManager.isOnDrive(); | |
110 event.command.setHidden(!fileManager.isOnDrive()); | |
111 }; | |
112 | |
113 /** | |
114 * Sets as the command as always enabled. | |
115 * @param {Event} event Command event to mark. | |
116 */ | |
117 CommandUtil.canExecuteAlways = function(event) { | |
118 event.canExecute = true; | |
119 }; | |
120 | |
121 /** | |
122 * Returns a single selected/passed entry or null. | |
123 * @param {Event} event Command event. | |
124 * @param {FileManager} fileManager FileManager to use. | |
125 * @return {FileEntry} The entry or null. | |
126 */ | |
127 CommandUtil.getSingleEntry = function(event, fileManager) { | |
128 if (event.target.entry) { | |
129 return event.target.entry; | |
130 } | |
131 var selection = fileManager.getSelection(); | |
132 if (selection.totalCount == 1) { | |
133 return selection.entries[0]; | |
134 } | |
135 return null; | |
136 }; | |
137 | |
138 /** | |
139 * Obtains target entries that can be pinned from the selection. | |
140 * If directories are included in the selection, it just returns an empty | |
141 * array to avoid confusing because pinning directory is not supported | |
142 * currently. | |
143 * | |
144 * @return {Array.<Entry>} Target entries. | |
145 */ | |
146 CommandUtil.getPinTargetEntries = function() { | |
147 var hasDirectory = false; | |
148 var results = fileManager.getSelection().entries.filter(function(entry) { | |
149 hasDirectory = hasDirectory || entry.isDirectory; | |
150 if (!entry || hasDirectory) | |
151 return false; | |
152 var metadata = fileManager.metadataCache_.getCached(entry, 'drive'); | |
153 if (!metadata || metadata.hosted) | |
154 return false; | |
155 entry.pinned = metadata.pinned; | |
156 return true; | |
157 }); | |
158 return hasDirectory ? [] : results; | |
159 }; | |
160 | |
161 /** | |
162 * Sets the default handler for the commandId and prevents handling | |
163 * the keydown events for this command. Not doing that breaks relationship | |
164 * of original keyboard event and the command. WebKit would handle it | |
165 * differently in some cases. | |
166 * @param {Node} node to register command handler on. | |
167 * @param {string} commandId Command id to respond to. | |
168 */ | |
169 CommandUtil.forceDefaultHandler = function(node, commandId) { | |
170 var doc = node.ownerDocument; | |
171 var command = doc.querySelector('command[id="' + commandId + '"]'); | |
172 node.addEventListener('keydown', function(e) { | |
173 if (command.matchesEvent(e)) { | |
174 // Prevent cr.ui.CommandManager of handling it and leave it | |
175 // for the default handler. | |
176 e.stopPropagation(); | |
177 } | |
178 }); | |
179 node.addEventListener('command', function(event) { | |
180 if (event.command.id !== commandId) | |
181 return; | |
182 document.execCommand(event.command.id); | |
183 event.cancelBubble = true; | |
184 }); | |
185 node.addEventListener('canExecute', function(event) { | |
186 if (event.command.id === commandId) | |
187 event.canExecute = document.queryCommandEnabled(event.command.id); | |
188 }); | |
189 }; | |
190 | |
191 /** | |
192 * Default command. | |
193 * @type {Command} | |
194 */ | |
195 CommandUtil.defaultCommand = { | |
196 execute: function(event, fileManager) { | |
197 fileManager.document.execCommand(event.command.id); | |
198 }, | |
199 canExecute: function(event, fileManager) { | |
200 event.canExecute = fileManager.document.queryCommandEnabled( | |
201 event.command.id); | |
202 } | |
203 }; | |
204 | |
205 /** | |
206 * Creates the volume switch command with index. | |
207 * @param {number} index Volume index from 1 to 9. | |
208 * @return {Command} Volume switch command. | |
209 */ | |
210 CommandUtil.createVolumeSwitchCommand = function(index) { | |
211 return { | |
212 execute: function(event, fileManager) { | |
213 fileManager.navigationList.selectByIndex(index - 1); | |
214 }, | |
215 canExecute: function(event, fileManager) { | |
216 event.canExecute = index > 0 && | |
217 index <= fileManager.navigationList.dataModel.length; | |
218 } | |
219 }; | |
220 }; | |
221 | |
222 /** | |
223 * Handle of the command events. | |
224 * @param {FileManager} fileManager FileManager. | |
225 * @constructor | |
226 */ | |
227 var CommandHandler = function(fileManager) { | |
228 /** | |
229 * FileManager. | |
230 * @type {FileManager} | |
231 * @private | |
232 */ | |
233 this.fileManager_ = fileManager; | |
234 | |
235 /** | |
236 * Command elements. | |
237 * @type {Object.<string, cr.ui.Command>} | |
238 * @private | |
239 */ | |
240 this.commands_ = {}; | |
241 | |
242 /** | |
243 * Whether the ctrl key is pressed or not. | |
244 * @type {boolean} | |
245 * @private | |
246 */ | |
247 this.ctrlKeyPressed_ = false; | |
248 | |
249 Object.seal(this); | |
250 | |
251 // Decorate command tags in the document. | |
252 var commands = fileManager.document.querySelectorAll('command'); | |
253 for (var i = 0; i < commands.length; i++) { | |
254 cr.ui.Command.decorate(commands[i]); | |
255 this.commands_[commands[i].id] = commands[i]; | |
256 } | |
257 | |
258 // Register events. | |
259 fileManager.document.addEventListener('command', this.onCommand_.bind(this)); | |
260 fileManager.document.addEventListener('canExecute', | |
261 this.onCanExecute_.bind(this)); | |
262 fileManager.document.addEventListener('keydown', this.onKeyDown_.bind(this)); | |
263 fileManager.document.addEventListener('keyup', this.onKeyUp_.bind(this)); | |
264 }; | |
265 | |
266 /** | |
267 * Updates the availability of all commands. | |
268 */ | |
269 CommandHandler.prototype.updateAvailability = function() { | |
270 for (var id in this.commands_) { | |
271 this.commands_[id].canExecuteChange(); | |
272 } | |
273 }; | |
274 | |
275 /** | |
276 * Handles command events. | |
277 * @param {Event} event Command event. | |
278 * @private | |
279 */ | |
280 CommandHandler.prototype.onCommand_ = function(event) { | |
281 var handler = CommandHandler.COMMANDS_[event.command.id]; | |
282 handler.execute.call(this, event, this.fileManager_); | |
283 }; | |
284 | |
285 /** | |
286 * Handles canExecute events. | |
287 * @param {Event} event Can execute event. | |
288 * @private | |
289 */ | |
290 CommandHandler.prototype.onCanExecute_ = function(event) { | |
291 var handler = CommandHandler.COMMANDS_[event.command.id]; | |
292 handler.canExecute.call(this, event, this.fileManager_); | |
293 }; | |
294 | |
295 /** | |
296 * Handle key down event. | |
297 * @param {Event} event Key down event. | |
298 * @private | |
299 */ | |
300 CommandHandler.prototype.onKeyDown_ = function(event) { | |
301 // 17 is the keycode of Ctrl key and it means the event is not for other keys | |
302 // with Ctrl modifier but for ctrl key itself. | |
303 if (util.getKeyModifiers(event) + event.keyCode == 'Ctrl-17') { | |
304 this.ctrlKeyPressed_ = true; | |
305 this.updateAvailability(); | |
306 } | |
307 }; | |
308 | |
309 /** | |
310 * Handle key up event. | |
311 * @param {Event} event Key up event. | |
312 * @private | |
313 */ | |
314 CommandHandler.prototype.onKeyUp_ = function(event) { | |
315 // 17 is the keycode of Ctrl key and it means the event is not for other keys | |
316 // with Ctrl modifier but for ctrl key itself. | |
317 if (util.getKeyModifiers(event) + event.keyCode == '17') { | |
318 this.ctrlKeyPressed_ = false; | |
319 this.updateAvailability(); | |
320 } | |
321 }; | |
322 | |
323 /** | |
324 * Commands. | |
325 * @type {Object.<string, Command>} | |
326 * @const | |
327 * @private | |
328 */ | |
329 CommandHandler.COMMANDS_ = {}; | |
330 | |
331 /** | |
332 * Unmounts external drive. | |
333 * @type {Command} | |
334 */ | |
335 CommandHandler.COMMANDS_['unmount'] = { | |
336 /** | |
337 * @param {Event} event Command event. | |
338 * @param {FileManager} fileManager The file manager instance. | |
339 */ | |
340 execute: function(event, fileManager) { | |
341 var root = CommandUtil.getCommandEntry(event.target); | |
342 if (root) | |
343 fileManager.unmountVolume(PathUtil.getRootPath(root.fullPath)); | |
344 }, | |
345 /** | |
346 * @param {Event} event Command event. | |
347 */ | |
348 canExecute: function(event, fileManager) { | |
349 var rootType = CommandUtil.getCommandRootType(event.target); | |
350 | |
351 event.canExecute = (rootType == RootType.ARCHIVE || | |
352 rootType == RootType.REMOVABLE); | |
353 event.command.setHidden(!event.canExecute); | |
354 event.command.label = rootType == RootType.ARCHIVE ? | |
355 str('CLOSE_ARCHIVE_BUTTON_LABEL') : | |
356 str('UNMOUNT_DEVICE_BUTTON_LABEL'); | |
357 } | |
358 }; | |
359 | |
360 /** | |
361 * Formats external drive. | |
362 * @type {Command} | |
363 */ | |
364 CommandHandler.COMMANDS_['format'] = { | |
365 /** | |
366 * @param {Event} event Command event. | |
367 * @param {FileManager} fileManager The file manager instance. | |
368 */ | |
369 execute: function(event, fileManager) { | |
370 var root = CommandUtil.getCommandEntry(event.target); | |
371 | |
372 if (root) { | |
373 var url = util.makeFilesystemUrl(PathUtil.getRootPath(root.fullPath)); | |
374 fileManager.confirm.show( | |
375 loadTimeData.getString('FORMATTING_WARNING'), | |
376 chrome.fileBrowserPrivate.formatDevice.bind(null, url)); | |
377 } | |
378 }, | |
379 /** | |
380 * @param {Event} event Command event. | |
381 * @param {FileManager} fileManager The file manager instance. | |
382 */ | |
383 canExecute: function(event, fileManager) { | |
384 var directoryModel = fileManager.directoryModel; | |
385 var root = CommandUtil.getCommandEntry(event.target); | |
386 var removable = root && | |
387 PathUtil.getRootType(root.fullPath) == RootType.REMOVABLE; | |
388 var isReadOnly = root && directoryModel.isPathReadOnly(root.fullPath); | |
389 event.canExecute = removable && !isReadOnly; | |
390 event.command.setHidden(!removable); | |
391 } | |
392 }; | |
393 | |
394 /** | |
395 * Imports photos from external drive. | |
396 * @type {Command} | |
397 */ | |
398 CommandHandler.COMMANDS_['import-photos'] = { | |
399 /** | |
400 * @param {Event} event Command event. | |
401 * @param {NavigationList} navigationList Target navigation list. | |
402 */ | |
403 execute: function(event, fileManager) { | |
404 var navigationList = fileManager.navigationList; | |
405 var root = CommandUtil.getCommandEntry(navigationList); | |
406 if (!root) | |
407 return; | |
408 | |
409 // TODO(mtomasz): Implement launching Photo Importer. | |
410 }, | |
411 /** | |
412 * @param {Event} event Command event. | |
413 * @param {NavigationList} navigationList Target navigation list. | |
414 */ | |
415 canExecute: function(event, fileManager) { | |
416 var navigationList = fileManager.navigationList; | |
417 var rootType = CommandUtil.getCommandRootType(navigationList); | |
418 event.canExecute = (rootType != RootType.DRIVE); | |
419 } | |
420 }; | |
421 | |
422 /** | |
423 * Initiates new folder creation. | |
424 * @type {Command} | |
425 */ | |
426 CommandHandler.COMMANDS_['new-folder'] = { | |
427 execute: function(event, fileManager) { | |
428 fileManager.createNewFolder(); | |
429 }, | |
430 canExecute: function(event, fileManager) { | |
431 var directoryModel = fileManager.directoryModel; | |
432 event.canExecute = !fileManager.isOnReadonlyDirectory() && | |
433 !fileManager.isRenamingInProgress() && | |
434 !directoryModel.isSearching() && | |
435 !directoryModel.isScanning(); | |
436 } | |
437 }; | |
438 | |
439 /** | |
440 * Initiates new window creation. | |
441 * @type {Command} | |
442 */ | |
443 CommandHandler.COMMANDS_['new-window'] = { | |
444 execute: function(event, fileManager) { | |
445 fileManager.backgroundPage.launchFileManager({ | |
446 defaultPath: fileManager.getCurrentDirectory() | |
447 }); | |
448 }, | |
449 canExecute: function(event, fileManager) { | |
450 event.canExecute = | |
451 fileManager.getCurrentDirectoryEntry() && | |
452 (fileManager.dialogType === DialogType.FULL_PAGE); | |
453 } | |
454 }; | |
455 | |
456 /** | |
457 * Changed the default app handling inserted media. | |
458 * @type {Command} | |
459 */ | |
460 CommandHandler.COMMANDS_['change-default-app'] = { | |
461 execute: function(event, fileManager) { | |
462 fileManager.showChangeDefaultAppPicker(); | |
463 }, | |
464 canExecute: CommandUtil.canExecuteAlways | |
465 }; | |
466 | |
467 /** | |
468 * Deletes selected files. | |
469 * @type {Command} | |
470 */ | |
471 CommandHandler.COMMANDS_['delete'] = { | |
472 execute: function(event, fileManager) { | |
473 fileManager.deleteSelection(); | |
474 }, | |
475 canExecute: function(event, fileManager) { | |
476 var selection = fileManager.getSelection(); | |
477 event.canExecute = !fileManager.isOnReadonlyDirectory() && | |
478 selection && | |
479 selection.totalCount > 0; | |
480 } | |
481 }; | |
482 | |
483 /** | |
484 * Pastes files from clipboard. | |
485 * @type {Command} | |
486 */ | |
487 CommandHandler.COMMANDS_['paste'] = { | |
488 execute: function() { | |
489 document.execCommand(event.command.id); | |
490 }, | |
491 canExecute: function(event, fileManager) { | |
492 var document = fileManager.document; | |
493 var fileTransferController = fileManager.fileTransferController; | |
494 event.canExecute = (fileTransferController && | |
495 fileTransferController.queryPasteCommandEnabled()); | |
496 } | |
497 }; | |
498 | |
499 CommandHandler.COMMANDS_['cut'] = CommandUtil.defaultCommand; | |
500 CommandHandler.COMMANDS_['copy'] = CommandUtil.defaultCommand; | |
501 | |
502 /** | |
503 * Initiates file renaming. | |
504 * @type {Command} | |
505 */ | |
506 CommandHandler.COMMANDS_['rename'] = { | |
507 execute: function(event, fileManager) { | |
508 fileManager.initiateRename(); | |
509 }, | |
510 canExecute: function(event, fileManager) { | |
511 var selection = fileManager.getSelection(); | |
512 event.canExecute = | |
513 !fileManager.isRenamingInProgress() && | |
514 !fileManager.isOnReadonlyDirectory() && | |
515 selection && | |
516 selection.totalCount == 1; | |
517 } | |
518 }; | |
519 | |
520 /** | |
521 * Opens drive help. | |
522 * @type {Command} | |
523 */ | |
524 CommandHandler.COMMANDS_['volume-help'] = { | |
525 execute: function(event, fileManager) { | |
526 if (fileManager.isOnDrive()) | |
527 util.visitURL(urlConstants.GOOGLE_DRIVE_HELP); | |
528 else | |
529 util.visitURL(urlConstants.FILES_APP_HELP); | |
530 }, | |
531 canExecute: CommandUtil.canExecuteAlways | |
532 }; | |
533 | |
534 /** | |
535 * Opens drive buy-more-space url. | |
536 * @type {Command} | |
537 */ | |
538 CommandHandler.COMMANDS_['drive-buy-more-space'] = { | |
539 execute: function(event, fileManager) { | |
540 util.visitURL(urlConstants.GOOGLE_DRIVE_BUY_STORAGE); | |
541 }, | |
542 canExecute: CommandUtil.canExecuteVisibleOnDriveOnly | |
543 }; | |
544 | |
545 /** | |
546 * Clears drive cache. | |
547 * @type {Command} | |
548 */ | |
549 CommandHandler.COMMANDS_['drive-clear-local-cache'] = { | |
550 execute: function(event, fileManager) { | |
551 chrome.fileBrowserPrivate.clearDriveCache(); | |
552 }, | |
553 canExecute: function(event, fileManager) { | |
554 event.canExecute = fileManager.isOnDrive() && this.ctrlKeyPressed_; | |
555 event.command.setHidden(!event.canExecute); | |
556 } | |
557 }; | |
558 | |
559 /** | |
560 * Opens drive.google.com. | |
561 * @type {Command} | |
562 */ | |
563 CommandHandler.COMMANDS_['drive-go-to-drive'] = { | |
564 execute: function(event, fileManager) { | |
565 util.visitURL(urlConstants.GOOGLE_DRIVE_ROOT); | |
566 }, | |
567 canExecute: CommandUtil.canExecuteVisibleOnDriveOnly | |
568 }; | |
569 | |
570 /** | |
571 * Displays open with dialog for current selection. | |
572 * @type {Command} | |
573 */ | |
574 CommandHandler.COMMANDS_['open-with'] = { | |
575 execute: function(event, fileManager) { | |
576 var tasks = fileManager.getSelection().tasks; | |
577 if (tasks) { | |
578 tasks.showTaskPicker(fileManager.defaultTaskPicker, | |
579 str('OPEN_WITH_BUTTON_LABEL'), | |
580 null, | |
581 function(task) { | |
582 tasks.execute(task.taskId); | |
583 }); | |
584 } | |
585 }, | |
586 canExecute: function(event, fileManager) { | |
587 var tasks = fileManager.getSelection().tasks; | |
588 event.canExecute = tasks && tasks.size() > 1; | |
589 } | |
590 }; | |
591 | |
592 /** | |
593 * Focuses search input box. | |
594 * @type {Command} | |
595 */ | |
596 CommandHandler.COMMANDS_['search'] = { | |
597 execute: function(event, fileManager) { | |
598 var element = fileManager.document.querySelector('#search-box input'); | |
599 element.focus(); | |
600 element.select(); | |
601 }, | |
602 canExecute: function(event, fileManager) { | |
603 event.canExecute = !fileManager.isRenamingInProgress(); | |
604 } | |
605 }; | |
606 | |
607 /** | |
608 * Activates the n-th volume. | |
609 * @type {Command} | |
610 */ | |
611 CommandHandler.COMMANDS_['volume-switch-1'] = | |
612 CommandUtil.createVolumeSwitchCommand(1); | |
613 CommandHandler.COMMANDS_['volume-switch-2'] = | |
614 CommandUtil.createVolumeSwitchCommand(2); | |
615 CommandHandler.COMMANDS_['volume-switch-3'] = | |
616 CommandUtil.createVolumeSwitchCommand(3); | |
617 CommandHandler.COMMANDS_['volume-switch-4'] = | |
618 CommandUtil.createVolumeSwitchCommand(4); | |
619 CommandHandler.COMMANDS_['volume-switch-5'] = | |
620 CommandUtil.createVolumeSwitchCommand(5); | |
621 CommandHandler.COMMANDS_['volume-switch-6'] = | |
622 CommandUtil.createVolumeSwitchCommand(6); | |
623 CommandHandler.COMMANDS_['volume-switch-7'] = | |
624 CommandUtil.createVolumeSwitchCommand(7); | |
625 CommandHandler.COMMANDS_['volume-switch-8'] = | |
626 CommandUtil.createVolumeSwitchCommand(8); | |
627 CommandHandler.COMMANDS_['volume-switch-9'] = | |
628 CommandUtil.createVolumeSwitchCommand(9); | |
629 | |
630 /** | |
631 * Flips 'available offline' flag on the file. | |
632 * @type {Command} | |
633 */ | |
634 CommandHandler.COMMANDS_['toggle-pinned'] = { | |
635 execute: function(event, fileManager) { | |
636 var pin = !event.command.checked; | |
637 event.command.checked = pin; | |
638 var entries = CommandUtil.getPinTargetEntries(); | |
639 var currentEntry; | |
640 var error = false; | |
641 var steps = { | |
642 // Pick an entry and pin it. | |
643 start: function() { | |
644 // Check if all the entries are pinned or not. | |
645 if (entries.length == 0) | |
646 return; | |
647 currentEntry = entries.shift(); | |
648 chrome.fileBrowserPrivate.pinDriveFile( | |
649 currentEntry.toURL(), | |
650 pin, | |
651 steps.entryPinned); | |
652 }, | |
653 | |
654 // Check the result of pinning | |
655 entryPinned: function() { | |
656 // Convert to boolean. | |
657 error = !!chrome.runtime.lastError; | |
658 if (error && pin) { | |
659 fileManager.metadataCache_.get( | |
660 currentEntry, 'filesystem', steps.showError); | |
661 } | |
662 fileManager.metadataCache_.clear(currentEntry, 'drive'); | |
663 fileManager.metadataCache_.get( | |
664 currentEntry, 'drive', steps.updateUI.bind(this)); | |
665 }, | |
666 | |
667 // Update the user interface accoding to the cache state. | |
668 updateUI: function(drive) { | |
669 fileManager.updateMetadataInUI_( | |
670 'drive', [currentEntry.toURL()], [drive]); | |
671 if (!error) | |
672 steps.start(); | |
673 }, | |
674 | |
675 // Show the error | |
676 showError: function(filesystem) { | |
677 fileManager.alert.showHtml(str('DRIVE_OUT_OF_SPACE_HEADER'), | |
678 strf('DRIVE_OUT_OF_SPACE_MESSAGE', | |
679 unescape(currentEntry.name), | |
680 util.bytesToString(filesystem.size))); | |
681 } | |
682 }; | |
683 steps.start(); | |
684 }, | |
685 | |
686 canExecute: function(event, fileManager) { | |
687 var entries = CommandUtil.getPinTargetEntries(); | |
688 var checked = true; | |
689 for (var i = 0; i < entries.length; i++) { | |
690 checked = checked && entries[i].pinned; | |
691 } | |
692 if (entries.length > 0) { | |
693 event.canExecute = true; | |
694 event.command.setHidden(false); | |
695 event.command.checked = checked; | |
696 } else { | |
697 event.canExecute = false; | |
698 event.command.setHidden(true); | |
699 } | |
700 } | |
701 }; | |
702 | |
703 /** | |
704 * Creates zip file for current selection. | |
705 * @type {Command} | |
706 */ | |
707 CommandHandler.COMMANDS_['zip-selection'] = { | |
708 execute: function(event, fileManager) { | |
709 var dirEntry = fileManager.getCurrentDirectoryEntry(); | |
710 var selectionEntries = fileManager.getSelection().entries; | |
711 fileManager.fileOperationManager_.zipSelection(dirEntry, selectionEntries); | |
712 }, | |
713 canExecute: function(event, fileManager) { | |
714 var dirEntry = fileManager.getCurrentDirectoryEntry(); | |
715 var selection = fileManager.getSelection(); | |
716 event.canExecute = | |
717 dirEntry && | |
718 !fileManager.isOnReadonlyDirectory() && | |
719 !fileManager.isOnDrive() && | |
720 selection && selection.totalCount > 0; | |
721 } | |
722 }; | |
723 | |
724 /** | |
725 * Shows the share dialog for the current selection (single only). | |
726 * @type {Command} | |
727 */ | |
728 CommandHandler.COMMANDS_['share'] = { | |
729 execute: function(event, fileManager) { | |
730 fileManager.shareSelection(); | |
731 }, | |
732 canExecute: function(event, fileManager) { | |
733 var selection = fileManager.getSelection(); | |
734 event.canExecute = fileManager.isOnDrive() && | |
735 !fileManager.isDriveOffline() && | |
736 selection && selection.totalCount == 1; | |
737 event.command.setHidden(!fileManager.isOnDrive()); | |
738 } | |
739 }; | |
740 | |
741 /** | |
742 * Creates a shortcut of the selected folder (single only). | |
743 * @type {Command} | |
744 */ | |
745 CommandHandler.COMMANDS_['create-folder-shortcut'] = { | |
746 /** | |
747 * @param {Event} event Command event. | |
748 * @param {FileManager} fileManager The file manager instance. | |
749 */ | |
750 execute: function(event, fileManager) { | |
751 var entry = CommandUtil.getCommandEntry(event.target); | |
752 if (entry) | |
753 fileManager.createFolderShortcut(entry.fullPath); | |
754 }, | |
755 | |
756 /** | |
757 * @param {Event} event Command event. | |
758 * @param {FileManager} fileManager The file manager instance. | |
759 */ | |
760 canExecute: function(event, fileManager) { | |
761 var target = event.target; | |
762 if (!(target instanceof NavigationListItem) && | |
763 !(target instanceof DirectoryItem)) { | |
764 event.command.setHidden(true); | |
765 return; | |
766 } | |
767 | |
768 var entry = CommandUtil.getCommandEntry(event.target); | |
769 var folderShortcutExists = entry && | |
770 fileManager.folderShortcutExists(entry.fullPath); | |
771 | |
772 var onlyOneFolderSelected = true; | |
773 // Only on list, user can select multiple files. The command is enabled only | |
774 // when a single file is selected. | |
775 if (event.target instanceof cr.ui.List && | |
776 !(event.target instanceof NavigationList)) { | |
777 var items = event.target.selectedItems; | |
778 onlyOneFolderSelected = (items.length == 1 && items[0].isDirectory); | |
779 } | |
780 | |
781 var eligible = entry && | |
782 PathUtil.isEligibleForFolderShortcut(entry.fullPath); | |
783 event.canExecute = | |
784 eligible && onlyOneFolderSelected && !folderShortcutExists; | |
785 event.command.setHidden(!eligible || !onlyOneFolderSelected); | |
786 } | |
787 }; | |
788 | |
789 /** | |
790 * Removes the folder shortcut. | |
791 * @type {Command} | |
792 */ | |
793 CommandHandler.COMMANDS_['remove-folder-shortcut'] = { | |
794 /** | |
795 * @param {Event} event Command event. | |
796 * @param {FileManager} fileManager The file manager instance. | |
797 */ | |
798 execute: function(event, fileManager) { | |
799 var entry = CommandUtil.getCommandEntry(event.target); | |
800 if (entry && entry.fullPath) | |
801 fileManager.removeFolderShortcut(entry.fullPath); | |
802 }, | |
803 | |
804 /** | |
805 * @param {Event} event Command event. | |
806 * @param {FileManager} fileManager The file manager instance. | |
807 */ | |
808 canExecute: function(event, fileManager) { | |
809 var target = event.target; | |
810 if (!target instanceof NavigationListItem && | |
811 !target instanceof DirectoryItem) { | |
812 event.command.setHidden(true); | |
813 return; | |
814 } | |
815 | |
816 var entry = CommandUtil.getCommandEntry(target); | |
817 var path = entry && entry.fullPath; | |
818 | |
819 var eligible = path && PathUtil.isEligibleForFolderShortcut(path); | |
820 var isShortcut = path && fileManager.folderShortcutExists(path); | |
821 event.canExecute = isShortcut && eligible; | |
822 event.command.setHidden(!event.canExecute); | |
823 } | |
824 }; | |
825 | |
826 /** | |
827 * Zoom in to the Files.app. | |
828 * @type {Command} | |
829 */ | |
830 CommandHandler.COMMANDS_['zoom-in'] = { | |
831 execute: function(event, fileManager) { | |
832 chrome.fileBrowserPrivate.zoom('in'); | |
833 }, | |
834 canExecute: CommandUtil.canExecuteAlways | |
835 }; | |
836 | |
837 /** | |
838 * Zoom out from the Files.app. | |
839 * @type {Command} | |
840 */ | |
841 CommandHandler.COMMANDS_['zoom-out'] = { | |
842 execute: function(event, fileManager) { | |
843 chrome.fileBrowserPrivate.zoom('out'); | |
844 }, | |
845 canExecute: CommandUtil.canExecuteAlways | |
846 }; | |
847 | |
848 /** | |
849 * Reset the zoom factor. | |
850 * @type {Command} | |
851 */ | |
852 CommandHandler.COMMANDS_['zoom-reset'] = { | |
853 execute: function(event, fileManager) { | |
854 chrome.fileBrowserPrivate.zoom('reset'); | |
855 }, | |
856 canExecute: CommandUtil.canExecuteAlways | |
857 }; | |
OLD | NEW |