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(); };
34 this.addEventListener('splice', this.onSplice_.bind(this));
38 * Maximum number of full size image cache.
43 GalleryDataModel.MAX_FULL_IMAGE_CACHE_ = 3;
46 * Maximum number of screen size image cache.
51 GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_ = 5;
53 GalleryDataModel.prototype = {
54 __proto__: cr.ui.ArrayDataModel.prototype
60 * @param {!VolumeManagerWrapper} volumeManager Volume manager instance.
61 * @param {!Gallery.Item} item Original gallery item.
62 * @param {!HTMLCanvasElement} canvas Canvas containing new image.
63 * @param {boolean} overwrite Set true to overwrite original if it's possible.
64 * @return {!Promise} Promise to be fulfilled with when the operation completes.
66 GalleryDataModel.prototype.saveItem = function(
67 volumeManager, item, canvas, overwrite) {
68 var oldEntry = item.getEntry();
69 var oldLocationInfo = item.getLocationInfo();
70 var oldIsOriginal = item.isOriginal();
71 return new Promise(function(fulfill, reject) {
75 this.fallbackSaveDirectory,
80 reject('Failed to save the image.');
84 // Current entry is updated.
86 var event = new Event('content');
88 event.oldEntry = oldEntry;
89 event.thumbnailChanged = true;
90 this.dispatchEvent(event);
92 if (!util.isSameEntry(oldEntry, item.getEntry())) {
94 this.metadataModel_.get(
95 [oldEntry], Gallery.PREFETCH_PROPERTY_NAMES),
96 new ThumbnailModel(this.metadataModel_).get([oldEntry])
97 ]).then(function(itemLists) {
98 // New entry is added and the item now tracks it.
99 // Add another item for the old entry.
100 var anotherItem = new Gallery.Item(
106 // The item must be added behind the existing item so that it does
107 // not change the index of the existing item.
108 // TODO(hirono): Update the item index of the selection model
110 this.splice(this.indexOf(item) + 1, 0, anotherItem);
111 }.bind(this)).then(fulfill, reject);
120 * Evicts image caches in the items.
122 GalleryDataModel.prototype.evictCache = function() {
123 // Sort the item by the last accessed date.
124 var sorted = this.slice().sort(function(a, b) {
125 return b.getLastAccessedDate() - a.getLastAccessedDate();
129 var contentCacheCount = 0;
130 var screenCacheCount = 0;
131 for (var i = 0; i < sorted.length; i++) {
132 if (sorted[i].contentImage) {
133 if (++contentCacheCount > GalleryDataModel.MAX_FULL_IMAGE_CACHE_) {
134 if (sorted[i].contentImage.parentNode) {
135 console.error('The content image has a parent node.');
137 // Force to free the buffer of the canvas by assigning zero size.
138 sorted[i].contentImage.width = 0;
139 sorted[i].contentImage.height = 0;
140 sorted[i].contentImage = null;
144 if (sorted[i].screenImage) {
145 if (++screenCacheCount > GalleryDataModel.MAX_SCREEN_IMAGE_CACHE_) {
146 if (sorted[i].screenImage.parentNode) {
147 console.error('The screen image has a parent node.');
149 // Force to free the buffer of the canvas by assigning zero size.
150 sorted[i].screenImage.width = 0;
151 sorted[i].screenImage.height = 0;
152 sorted[i].screenImage = null;
160 * Handles entry delete.
161 * @param {!Event} event
164 GalleryDataModel.prototype.onSplice_ = function(event) {
165 if (!event.removed || !event.removed.length)
167 var removedURLs = event.removed.map(function(item) {
168 return item.getEntry().toURL();
170 this.metadataModel_.notifyEntriesRemoved(removedURLs);