1 // Copyright 2015 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.
6 * Data model for gallery.
8 * @param {!MetadataModel} metadataModel
9 * @param {!EntryListWatcher=} opt_watcher Entry list watcher.
11 * @extends {cr.ui.ArrayDataModel}
13 function GalleryDataModel(metadataModel, opt_watcher) {
14 cr.ui.ArrayDataModel.call(this, []);
17 * File system metadata.
18 * @private {!MetadataModel}
21 this.metadataModel_ = metadataModel;
24 * Directory where the image is saved if the image is located in a read-only
26 * @public {DirectoryEntry}
28 this.fallbackSaveDirectory = null;
30 // Start to watch file system entries.
31 var watcher = opt_watcher ? opt_watcher : new EntryListWatcher(this);
32 watcher.getEntry = function(item) { return item.getEntry(); };
36 * Maximum number of full size image cache.
41 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3;
44 * Maximum number of screen size image cache.
49 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5;
51 GalleryDataModel.prototype = {
52 __proto__: cr.ui.ArrayDataModel.prototype
58 * @param {!VolumeManager} volumeManager Volume manager instance.
59 * @param {!Gallery.Item} item Original gallery item.
60 * @param {!HTMLCanvasElement} canvas Canvas containing new image.
61 * @param {boolean} overwrite Whether to overwrite the image to the item or not.
62 * @return {!Promise} Promise to be fulfilled with when the operation completes.
64 GalleryDataModel.prototype.saveItem = function(
65 volumeManager, item, canvas, overwrite) {
66 var oldEntry = item.getEntry();
67 var oldMetadataItem = item.getMetadataItem();
68 var oldThumbnailMetadataItem = item.getThumbnailMetadataItem();
69 var oldLocationInfo = item.getLocationInfo();
70 return new Promise(function(fulfill, reject) {
74 this.fallbackSaveDirectory,
79 reject('Failed to save the image.');
83 // Current entry is updated.
85 var event = new Event('content');
87 event.oldEntry = oldEntry;
88 event.thumbnailChanged = true;
89 this.dispatchEvent(event);
91 if (!util.isSameEntry(oldEntry, item.getEntry())) {
92 // New entry is added and the item now tracks it.
93 // Add another item for the old entry.
94 var anotherItem = new Gallery.Item(
98 oldThumbnailMetadataItem,
100 // The item must be added behind the existing item so that it does
101 // not change the index of the existing item.
102 // TODO(hirono): Update the item index of the selection model
104 this.splice(this.indexOf(item) + 1, 0, anotherItem);
113 * Evicts image caches in the items.
115 GalleryDataModel.prototype.evictCache = function() {
116 // Sort the item by the last accessed date.
117 var sorted = this.slice().sort(function(a, b) {
118 return b.getLastAccessedDate() - a.getLastAccessedDate();
122 var contentCacheCount = 0;
123 var screenCacheCount = 0;
124 for (var i = 0; i < sorted.length; i++) {
125 if (sorted[i].contentImage) {
126 if (++contentCacheCount > GalleryDataModel.MAX_FULL_IMAGE_CACHE_) {
127 if (sorted[i].contentImage.parentNode) {
128 console.error('The content image has a parent node.');
130 // Force to free the buffer of the canvas by assigning zero size.
131 sorted[i].contentImage.width = 0;
132 sorted[i].contentImage.height = 0;
133 sorted[i].contentImage = null;
137 if (sorted[i].screenImage) {
138 if (++screenCacheCount > GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_) {
139 if (sorted[i].screenImage.parentNode) {
140 console.error('The screen image has a parent node.');
142 // Force to free the buffer of the canvas by assigning zero size.
143 sorted[i].screenImage.width = 0;
144 sorted[i].screenImage.height = 0;
145 sorted[i].screenImage = null;