OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * Called from the main frame when unloading. | 8 * Called from the main frame when unloading. |
9 * @param {boolean=} opt_exiting True if the app is exiting. | 9 * @param {boolean=} opt_exiting True if the app is exiting. |
10 */ | 10 */ |
11 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); } | 11 function unload(opt_exiting) { Gallery.instance.onUnload(opt_exiting); } |
12 | 12 |
13 /** | 13 /** |
14 * Overrided metadata worker's path. | 14 * Overrided metadata worker's path. |
15 * @type {string} | 15 * @type {string} |
16 * @const | 16 * @const |
17 */ | 17 */ |
18 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; | 18 ContentProvider.WORKER_SCRIPT = '/js/metadata_worker.js'; |
19 | 19 |
20 /** | 20 /** |
21 * Data model for gallery. | 21 * Data model for gallery. |
22 * | 22 * |
23 * @param {MetadataCache} metadataCache Metadata cache. | 23 * @param {MetadataCache} metadataCache Metadata cache. |
24 * @constructor | 24 * @constructor |
25 * @extends {cr.ui.ArrayDataModel} | 25 * @extends {cr.ui.ArrayDataModel} |
26 */ | 26 */ |
27 function GalleryDataModel(metadataCache) { | 27 function GalleryDataModel(metadataCache) { |
28 cr.ui.ArrayDataModel.call(this, []); | 28 cr.ui.ArrayDataModel.call(this, []); |
29 | |
30 /** | |
31 * Metadata cache. | |
32 * @type {MetadataCache} | |
33 * @private | |
34 */ | |
29 this.metadataCache_ = metadataCache; | 35 this.metadataCache_ = metadataCache; |
36 | |
37 /** | |
38 * Directory where the image is saved if the image is located in a read-only | |
39 * volume. | |
40 * @type {DirectoryEntry} | |
41 */ | |
42 this.fallbackSaveDirectory = null; | |
30 } | 43 } |
31 | 44 |
32 /** | 45 /** |
33 * Maximum number of full size image cache. | 46 * Maximum number of full size image cache. |
34 * @type {number} | 47 * @type {number} |
35 * @const | 48 * @const |
36 * @private | 49 * @private |
37 */ | 50 */ |
38 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3; | 51 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3; |
39 | 52 |
(...skipping 25 matching lines...) Expand all Loading... | |
65 var newMetadata = ContentProvider.ConvertContentMetadata( | 78 var newMetadata = ContentProvider.ConvertContentMetadata( |
66 metadataEncoder.getMetadata(), | 79 metadataEncoder.getMetadata(), |
67 MetadataCache.cloneMetadata(item.getMetadata())); | 80 MetadataCache.cloneMetadata(item.getMetadata())); |
68 if (newMetadata.filesystem) | 81 if (newMetadata.filesystem) |
69 newMetadata.filesystem.modificationTime = new Date(); | 82 newMetadata.filesystem.modificationTime = new Date(); |
70 if (newMetadata.drive) | 83 if (newMetadata.drive) |
71 newMetadata.drive.present = true; | 84 newMetadata.drive.present = true; |
72 | 85 |
73 return new Promise(function(fulfill, reject) { | 86 return new Promise(function(fulfill, reject) { |
74 item.saveToFile( | 87 item.saveToFile( |
75 null, | 88 this.fallbackSaveDirectory, |
76 overwrite, | 89 overwrite, |
77 canvas, | 90 canvas, |
78 metadataEncoder, | 91 metadataEncoder, |
79 function(success) { | 92 function(success) { |
80 if (!success) { | 93 if (!success) { |
81 reject('Failed to save the image.'); | 94 reject('Failed to save the image.'); |
82 return; | 95 return; |
83 } | 96 } |
84 | 97 |
85 // The item's entry is updated to the latest entry. Update metadata. | 98 // The item's entry is updated to the latest entry. Update metadata. |
(...skipping 10 matching lines...) Expand all Loading... | |
96 if (util.isSameEntry(oldEntry, item.getEntry())) { | 109 if (util.isSameEntry(oldEntry, item.getEntry())) { |
97 // Need an update of metdataCache. | 110 // Need an update of metdataCache. |
98 this.metadataCache_.set( | 111 this.metadataCache_.set( |
99 item.getEntry(), | 112 item.getEntry(), |
100 Gallery.METADATA_TYPE, | 113 Gallery.METADATA_TYPE, |
101 newMetadata); | 114 newMetadata); |
102 } else { | 115 } else { |
103 // New entry is added and the item now tracks it. | 116 // New entry is added and the item now tracks it. |
104 // Add another item for the old entry. | 117 // Add another item for the old entry. |
105 var anotherItem = new Gallery.Item( | 118 var anotherItem = new Gallery.Item( |
106 oldEntry, oldMetadata, this.metadataCache_, item.isOriginal()); | 119 oldEntry, |
120 oldMetadata, | |
121 this.metadataCache_, | |
122 item.isOriginal(), | |
123 item.isReadOnly()); | |
107 // The item must be added behind the existing item so that it does | 124 // The item must be added behind the existing item so that it does |
108 // not change the index of the existing item. | 125 // not change the index of the existing item. |
109 // TODO(hirono): Update the item index of the selection model | 126 // TODO(hirono): Update the item index of the selection model |
110 // correctly. | 127 // correctly. |
111 this.splice(this.indexOf(item) + 1, 0, anotherItem); | 128 this.splice(this.indexOf(item) + 1, 0, anotherItem); |
112 } | 129 } |
113 | 130 |
114 fulfill(); | 131 fulfill(); |
115 }.bind(this)); | 132 }.bind(this)); |
116 }.bind(this)); | 133 }.bind(this)); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 }; | 201 }; |
185 this.container_ = document.querySelector('.gallery'); | 202 this.container_ = document.querySelector('.gallery'); |
186 this.document_ = document; | 203 this.document_ = document; |
187 this.metadataCache_ = this.context_.metadataCache; | 204 this.metadataCache_ = this.context_.metadataCache; |
188 this.volumeManager_ = volumeManager; | 205 this.volumeManager_ = volumeManager; |
189 this.selectedEntry_ = null; | 206 this.selectedEntry_ = null; |
190 this.metadataCacheObserverId_ = null; | 207 this.metadataCacheObserverId_ = null; |
191 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this); | 208 this.onExternallyUnmountedBound_ = this.onExternallyUnmounted_.bind(this); |
192 | 209 |
193 this.dataModel_ = new GalleryDataModel(this.context_.metadataCache); | 210 this.dataModel_ = new GalleryDataModel(this.context_.metadataCache); |
211 var downloadVolumeInfo = this.volumeManager_.getCurrentProfileVolumeInfo( | |
212 VolumeManagerCommon.VolumeType.DOWNLOADS); | |
213 downloadVolumeInfo.resolveDisplayRoot().then(function(entry) { | |
214 this.dataModel_.fallbackSaveDirectory = entry; | |
215 }.bind(this)).catch(function(error) { | |
216 console.error(error); | |
yoshiki
2014/08/15 03:37:14
Please show a short description of the error.
hirono
2014/08/15 08:04:15
Done.
| |
217 }); | |
194 this.selectionModel_ = new cr.ui.ListSelectionModel(); | 218 this.selectionModel_ = new cr.ui.ListSelectionModel(); |
195 | 219 |
196 this.initDom_(); | 220 this.initDom_(); |
197 this.initListeners_(); | 221 this.initListeners_(); |
198 } | 222 } |
199 | 223 |
200 /** | 224 /** |
201 * Gallery extends cr.EventTarget. | 225 * Gallery extends cr.EventTarget. |
202 */ | 226 */ |
203 Gallery.prototype.__proto__ = cr.EventTarget.prototype; | 227 Gallery.prototype.__proto__ = cr.EventTarget.prototype; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
331 this.filenameEdit_.addEventListener('focus', | 355 this.filenameEdit_.addEventListener('focus', |
332 this.onFilenameFocus_.bind(this)); | 356 this.onFilenameFocus_.bind(this)); |
333 | 357 |
334 this.filenameEdit_.addEventListener('keydown', | 358 this.filenameEdit_.addEventListener('keydown', |
335 this.onFilenameEditKeydown_.bind(this)); | 359 this.onFilenameEditKeydown_.bind(this)); |
336 | 360 |
337 var middleSpacer = this.filenameSpacer_ = | 361 var middleSpacer = this.filenameSpacer_ = |
338 this.toolbar_.querySelector('.middle-spacer'); | 362 this.toolbar_.querySelector('.middle-spacer'); |
339 var buttonSpacer = this.toolbar_.querySelector('button-spacer'); | 363 var buttonSpacer = this.toolbar_.querySelector('button-spacer'); |
340 | 364 |
341 this.prompt_ = new ImageEditor.Prompt(this.container_, str); | 365 this.prompt_ = new ImageEditor.Prompt(this.container_, strf); |
342 | 366 |
343 this.modeButton_ = this.toolbar_.querySelector('button.mode'); | 367 this.modeButton_ = this.toolbar_.querySelector('button.mode'); |
344 this.modeButton_.addEventListener('click', this.toggleMode_.bind(this, null)); | 368 this.modeButton_.addEventListener('click', this.toggleMode_.bind(this, null)); |
345 | 369 |
346 this.mosaicMode_ = new MosaicMode(content, | 370 this.mosaicMode_ = new MosaicMode(content, |
347 this.dataModel_, | 371 this.dataModel_, |
348 this.selectionModel_, | 372 this.selectionModel_, |
349 this.volumeManager_, | 373 this.volumeManager_, |
350 this.toggleMode_.bind(this, null)); | 374 this.toggleMode_.bind(this, null)); |
351 | 375 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 * @param {!Array.<Entry>} selectedEntries Array of selected entries. | 427 * @param {!Array.<Entry>} selectedEntries Array of selected entries. |
404 */ | 428 */ |
405 Gallery.prototype.load = function(entries, selectedEntries) { | 429 Gallery.prototype.load = function(entries, selectedEntries) { |
406 // Obtains max chank size. | 430 // Obtains max chank size. |
407 var maxChunkSize = 20; | 431 var maxChunkSize = 20; |
408 var volumeInfo = this.volumeManager_.getVolumeInfo(entries[0]); | 432 var volumeInfo = this.volumeManager_.getVolumeInfo(entries[0]); |
409 if (volumeInfo && | 433 if (volumeInfo && |
410 volumeInfo.volumeType === VolumeManagerCommon.VolumeType.MTP) { | 434 volumeInfo.volumeType === VolumeManagerCommon.VolumeType.MTP) { |
411 maxChunkSize = 1; | 435 maxChunkSize = 1; |
412 } | 436 } |
437 if (volumeInfo.isReadOnly) | |
438 this.context_.readonlyDirName = volumeInfo.label; | |
413 | 439 |
414 // Make loading list. | 440 // Make loading list. |
415 var entrySet = {}; | 441 var entrySet = {}; |
416 for (var i = 0; i < entries.length; i++) { | 442 for (var i = 0; i < entries.length; i++) { |
417 var entry = entries[i]; | 443 var entry = entries[i]; |
418 entrySet[entry.toURL()] = { | 444 entrySet[entry.toURL()] = { |
419 entry: entry, | 445 entry: entry, |
420 selected: false, | 446 selected: false, |
421 index: i | 447 index: i |
422 }; | 448 }; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 var entries = chunk.map(function(chunkItem) { | 480 var entries = chunk.map(function(chunkItem) { |
455 return chunkItem.entry; | 481 return chunkItem.entry; |
456 }); | 482 }); |
457 this.metadataCache_.get(entries, Gallery.METADATA_TYPE, fulfill); | 483 this.metadataCache_.get(entries, Gallery.METADATA_TYPE, fulfill); |
458 }.bind(this)).then(function(metadataList) { | 484 }.bind(this)).then(function(metadataList) { |
459 if (chunk.length !== metadataList.length) | 485 if (chunk.length !== metadataList.length) |
460 return Promise.reject('Failed to load metadata.'); | 486 return Promise.reject('Failed to load metadata.'); |
461 | 487 |
462 // Add items to the model. | 488 // Add items to the model. |
463 var items = chunk.map(function(chunkItem, index) { | 489 var items = chunk.map(function(chunkItem, index) { |
490 var volumeInfo = this.volumeManager_.getVolumeInfo(chunkItem.entry); | |
464 var clonedMetadata = MetadataCache.cloneMetadata(metadataList[index]); | 491 var clonedMetadata = MetadataCache.cloneMetadata(metadataList[index]); |
465 return new Gallery.Item( | 492 return new Gallery.Item( |
466 chunkItem.entry, | 493 chunkItem.entry, |
467 clonedMetadata, | 494 clonedMetadata, |
468 this.metadataCache_, | 495 this.metadataCache_, |
469 /* original */ true); | 496 /* original */ true, |
497 /* readonly */ !!(volumeInfo && volumeInfo.isReadOnly)); | |
470 }.bind(this)); | 498 }.bind(this)); |
471 this.dataModel_.push.apply(this.dataModel_, items); | 499 this.dataModel_.push.apply(this.dataModel_, items); |
472 | 500 |
473 // Apply the selection. | 501 // Apply the selection. |
474 var selectionUpdated = false; | 502 var selectionUpdated = false; |
475 for (var i = 0; i < chunk.length; i++) { | 503 for (var i = 0; i < chunk.length; i++) { |
476 if (!chunk[i].selected) | 504 if (!chunk[i].selected) |
477 continue; | 505 continue; |
478 var index = this.dataModel_.indexOf(items[i]); | 506 var index = this.dataModel_.indexOf(items[i]); |
479 if (index < 0) | 507 if (index < 0) |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
795 | 823 |
796 // Name box and rename support. | 824 // Name box and rename support. |
797 | 825 |
798 /** | 826 /** |
799 * Updates the UI related to the selected item and the persistent state. | 827 * Updates the UI related to the selected item and the persistent state. |
800 * | 828 * |
801 * @private | 829 * @private |
802 */ | 830 */ |
803 Gallery.prototype.updateSelectionAndState_ = function() { | 831 Gallery.prototype.updateSelectionAndState_ = function() { |
804 var numSelectedItems = this.selectionModel_.selectedIndexes.length; | 832 var numSelectedItems = this.selectionModel_.selectedIndexes.length; |
805 var displayName = ''; | |
806 var selectedEntryURL = null; | 833 var selectedEntryURL = null; |
807 | 834 |
808 // If it's selecting something, update the variable values. | 835 // If it's selecting something, update the variable values. |
809 if (numSelectedItems) { | 836 if (numSelectedItems) { |
810 // Obtains selected item. | 837 // Obtains selected item. |
811 var selectedItem = | 838 var selectedItem = |
812 this.dataModel_.item(this.selectionModel_.selectedIndex); | 839 this.dataModel_.item(this.selectionModel_.selectedIndex); |
813 this.selectedEntry_ = selectedItem.getEntry(); | 840 this.selectedEntry_ = selectedItem.getEntry(); |
814 selectedEntryURL = this.selectedEntry_.toURL(); | 841 selectedEntryURL = this.selectedEntry_.toURL(); |
815 | 842 |
816 // Update cache. | 843 // Update cache. |
817 selectedItem.touch(); | 844 selectedItem.touch(); |
818 this.dataModel_.evictCache(); | 845 this.dataModel_.evictCache(); |
819 | 846 |
820 // Update the title and the display name. | 847 // Update the title and the display name. |
821 if (numSelectedItems === 1) { | 848 if (numSelectedItems === 1) { |
822 window.top.document.title = this.selectedEntry_.name; | 849 window.top.document.title = this.selectedEntry_.name; |
823 displayName = ImageUtil.getDisplayNameFromName(this.selectedEntry_.name); | 850 this.filenameEdit_.disabled = selectedItem.isReadOnly(); |
851 this.filenameEdit_.value = | |
852 ImageUtil.getDisplayNameFromName(this.selectedEntry_.name); | |
824 } else if (this.context_.curDirEntry) { | 853 } else if (this.context_.curDirEntry) { |
825 // If the Gallery was opened on search results the search query will not | 854 // If the Gallery was opened on search results the search query will not |
826 // be recorded in the app state and the relaunch will just open the | 855 // be recorded in the app state and the relaunch will just open the |
827 // gallery in the curDirEntry directory. | 856 // gallery in the curDirEntry directory. |
828 window.top.document.title = this.context_.curDirEntry.name; | 857 window.top.document.title = this.context_.curDirEntry.name; |
829 displayName = strf('GALLERY_ITEMS_SELECTED', numSelectedItems); | 858 this.filenameEdit_.disabled = true; |
859 this.filenameEdit_.value = | |
860 strf('GALLERY_ITEMS_SELECTED', numSelectedItems); | |
830 } | 861 } |
831 } | 862 } |
832 | 863 |
833 window.top.util.updateAppState( | 864 window.top.util.updateAppState( |
834 null, // Keep the current directory. | 865 null, // Keep the current directory. |
835 selectedEntryURL, // Update the selection. | 866 selectedEntryURL, // Update the selection. |
836 {gallery: (this.currentMode_ === this.mosaicMode_ ? 'mosaic' : 'slide')}); | 867 {gallery: (this.currentMode_ === this.mosaicMode_ ? 'mosaic' : 'slide')}); |
837 | 868 |
838 // We can't rename files in readonly directory. | |
839 // We can only rename a single file. | |
840 this.filenameEdit_.disabled = numSelectedItems !== 1 || | |
841 this.context_.readonlyDirName; | |
842 this.filenameEdit_.value = displayName; | |
843 | |
844 // Update the share button. | 869 // Update the share button. |
845 var item = this.getSingleSelectedItem(); | 870 var item = this.getSingleSelectedItem(); |
846 this.shareButton_.hidden = !item || !item.isOnDrive(); | 871 this.shareButton_.hidden = !item || !item.isOnDrive(); |
847 }; | 872 }; |
848 | 873 |
849 /** | 874 /** |
850 * Click event handler on filename edit box | 875 * Click event handler on filename edit box |
851 * @private | 876 * @private |
852 */ | 877 */ |
853 Gallery.prototype.onFilenameFocus_ = function() { | 878 Gallery.prototype.onFilenameFocus_ = function() { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
981 window.loadTimeData.data = backgroundComponents.stringData; | 1006 window.loadTimeData.data = backgroundComponents.stringData; |
982 gallery = new Gallery(backgroundComponents.volumeManager); | 1007 gallery = new Gallery(backgroundComponents.volumeManager); |
983 }; | 1008 }; |
984 | 1009 |
985 /** | 1010 /** |
986 * Loads entries. | 1011 * Loads entries. |
987 */ | 1012 */ |
988 window.loadEntries = function(entries, selectedEntries) { | 1013 window.loadEntries = function(entries, selectedEntries) { |
989 gallery.load(entries, selectedEntries); | 1014 gallery.load(entries, selectedEntries); |
990 }; | 1015 }; |
OLD | NEW |