OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 /** | 5 /** |
6 * FileManager constructor. | 6 * FileManager constructor. |
7 * | 7 * |
8 * FileManager objects encapsulate the functionality of the file selector | 8 * FileManager objects encapsulate the functionality of the file selector |
9 * dialogs, as well as the full screen file manager application (though the | 9 * dialogs, as well as the full screen file manager application (though the |
10 * latter is not yet implemented). | 10 * latter is not yet implemented). |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 this.copyManager_.addEventListener('copy-progress', | 402 this.copyManager_.addEventListener('copy-progress', |
403 this.onCopyProgress_.bind(this)); | 403 this.onCopyProgress_.bind(this)); |
404 this.copyManager_.addEventListener('copy-operation-complete', | 404 this.copyManager_.addEventListener('copy-operation-complete', |
405 this.onCopyManagerOperationComplete_.bind(this)); | 405 this.onCopyManagerOperationComplete_.bind(this)); |
406 | 406 |
407 var controller = this.fileTransferController_ = new FileTransferController( | 407 var controller = this.fileTransferController_ = new FileTransferController( |
408 this.directoryModel_.getFileList(), | 408 this.directoryModel_.getFileList(), |
409 this.directoryModel_.getFileListSelection(), | 409 this.directoryModel_.getFileListSelection(), |
410 GridItem.bind(null, this), | 410 GridItem.bind(null, this), |
411 this.copyManager_, | 411 this.copyManager_, |
412 this.directoryModel_); | 412 this.directoryModel_, |
| 413 this.metadataCache_); |
413 controller.attachDragSource(this.table_.list); | 414 controller.attachDragSource(this.table_.list); |
414 controller.attachDropTarget(this.table_.list); | 415 controller.attachDropTarget(this.table_.list); |
415 controller.attachDragSource(this.grid_); | 416 controller.attachDragSource(this.grid_); |
416 controller.attachDropTarget(this.grid_); | 417 controller.attachDropTarget(this.grid_); |
417 controller.attachDropTarget(this.rootsList_, true); | 418 controller.attachDropTarget(this.rootsList_, true); |
418 controller.attachCopyPasteHandlers(this.document_); | 419 controller.attachCopyPasteHandlers(this.document_); |
419 controller.addEventListener('selection-copied', | 420 controller.addEventListener('selection-copied', |
420 this.blinkSelection.bind(this)); | 421 this.blinkSelection.bind(this)); |
421 controller.addEventListener('selection-cut', | 422 controller.addEventListener('selection-cut', |
422 this.blinkSelection.bind(this)); | 423 this.blinkSelection.bind(this)); |
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1982 var url = urls[index]; | 1983 var url = urls[index]; |
1983 if (!(url in items)) continue; | 1984 if (!(url in items)) continue; |
1984 var listItem = items[url]; | 1985 var listItem = items[url]; |
1985 var entry = entries[url]; | 1986 var entry = entries[url]; |
1986 var props = properties[index]; | 1987 var props = properties[index]; |
1987 if (type == 'filesystem') { | 1988 if (type == 'filesystem') { |
1988 this.displayDateInDiv_(listItem.querySelector('.date'), props); | 1989 this.displayDateInDiv_(listItem.querySelector('.date'), props); |
1989 this.displaySizeInDiv_(listItem.querySelector('.size'), props); | 1990 this.displaySizeInDiv_(listItem.querySelector('.size'), props); |
1990 this.displayTypeInDiv_(listItem.querySelector('.type'), props); | 1991 this.displayTypeInDiv_(listItem.querySelector('.type'), props); |
1991 } else if (type == 'gdata') { | 1992 } else if (type == 'gdata') { |
1992 this.displayOfflineInDiv_(listItem.querySelector('.offline'), props); | 1993 var offline = listItem.querySelector('.offline'); |
| 1994 if (offline) // This column is only present in full page mode. |
| 1995 this.displayOfflineInDiv_(offline, props); |
1993 this.displayGDataStyleInItem_(listItem, entry, props); | 1996 this.displayGDataStyleInItem_(listItem, entry, props); |
1994 } | 1997 } |
1995 } | 1998 } |
1996 }; | 1999 }; |
1997 | 2000 |
1998 /** | 2001 /** |
1999 * Restore the item which is being renamed while refreshing the file list. Do | 2002 * Restore the item which is being renamed while refreshing the file list. Do |
2000 * nothing if no item is being renamed or such an item disappeared. | 2003 * nothing if no item is being renamed or such an item disappeared. |
2001 * | 2004 * |
2002 * While refreshing file list it gets repopulated with new file entries. | 2005 * While refreshing file list it gets repopulated with new file entries. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2034 */ | 2037 */ |
2035 FileManager.prototype.summarizeSelection_ = function() { | 2038 FileManager.prototype.summarizeSelection_ = function() { |
2036 var selection = this.selection = { | 2039 var selection = this.selection = { |
2037 entries: [], | 2040 entries: [], |
2038 urls: [], | 2041 urls: [], |
2039 totalCount: 0, | 2042 totalCount: 0, |
2040 fileCount: 0, | 2043 fileCount: 0, |
2041 directoryCount: 0, | 2044 directoryCount: 0, |
2042 bytes: 0, | 2045 bytes: 0, |
2043 showBytes: false, | 2046 showBytes: false, |
| 2047 allGDataFilesPresent: false, |
2044 iconType: null, | 2048 iconType: null, |
2045 indexes: this.currentList_.selectionModel.selectedIndexes | 2049 indexes: this.currentList_.selectionModel.selectedIndexes |
2046 }; | 2050 }; |
2047 | 2051 |
2048 if (!selection.indexes.length) { | 2052 if (!selection.indexes.length) { |
2049 this.updateCommonActionButtons_(); | 2053 this.updateCommonActionButtons_(); |
2050 this.updatePreviewPanelVisibility_(); | 2054 this.updatePreviewPanelVisibility_(); |
2051 cr.dispatchSimpleEvent(this, 'selection-summarized'); | 2055 cr.dispatchSimpleEvent(this, 'selection-summarized'); |
2052 return; | 2056 return; |
2053 } | 2057 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2148 } | 2152 } |
2149 | 2153 |
2150 if (entry.isFile) { | 2154 if (entry.isFile) { |
2151 selection.bytes += filesystem.size; | 2155 selection.bytes += filesystem.size; |
2152 selection.showBytes |= filesystem.fileType.type != 'hosted'; | 2156 selection.showBytes |= filesystem.fileType.type != 'hosted'; |
2153 } | 2157 } |
2154 } | 2158 } |
2155 | 2159 |
2156 this.dispatchEvent(new cr.Event('selection-summarized')); | 2160 this.dispatchEvent(new cr.Event('selection-summarized')); |
2157 }.bind(this)); | 2161 }.bind(this)); |
| 2162 |
| 2163 if (this.isOnGData()) { |
| 2164 this.metadataCache_.get(selection.urls, 'gdata', function(props) { |
| 2165 selection.allGDataFilesPresent = |
| 2166 props.filter(function(p) {return !p.availableOffline}).length == 0; |
| 2167 this.updateOkButton_(); |
| 2168 }.bind(this)); |
| 2169 } |
2158 }; | 2170 }; |
2159 | 2171 |
2160 /** | 2172 /** |
| 2173 * Check if all the files in the current selection are available. The only |
| 2174 * case when files might be not available is when the selection contains |
| 2175 * uncached GData files and the browser is offline. |
| 2176 * @return {boolean} True if all files in the current selection are |
| 2177 * available. |
| 2178 */ |
| 2179 FileManager.prototype.isSelectionAvailable = function() { |
| 2180 return !this.isOnGDataOffline() || this.selection.allGDataFilesPresent; |
| 2181 }; |
| 2182 |
| 2183 /** |
2161 * Initialize a thumbnail in the bottom pannel to pop up on mouse over. | 2184 * Initialize a thumbnail in the bottom pannel to pop up on mouse over. |
2162 * Image's assumed to be just loaded and not inserted into the DOM. | 2185 * Image's assumed to be just loaded and not inserted into the DOM. |
2163 * | 2186 * |
2164 * @param {HTMLElement} box Element what's going to contain the image. | 2187 * @param {HTMLElement} box Element what's going to contain the image. |
2165 * @param {HTMLElement} img Loaded image. | 2188 * @param {HTMLElement} img Loaded image. |
2166 */ | 2189 */ |
2167 FileManager.prototype.initThumbnailZoom_ = function(box, img, transform) { | 2190 FileManager.prototype.initThumbnailZoom_ = function(box, img, transform) { |
2168 var width = img.width; | 2191 var width = img.width; |
2169 var height = img.height; | 2192 var height = img.height; |
2170 var THUMBNAIL_SIZE = 45; | 2193 var THUMBNAIL_SIZE = 45; |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2459 // handling the same task instance from multiple tabs. | 2482 // handling the same task instance from multiple tabs. |
2460 // So, we manually execute the task. | 2483 // So, we manually execute the task. |
2461 this.onFileTaskExecute_(task_parts[1], urls); | 2484 this.onFileTaskExecute_(task_parts[1], urls); |
2462 } | 2485 } |
2463 }.bind(this)); | 2486 }.bind(this)); |
2464 }; | 2487 }; |
2465 | 2488 |
2466 FileManager.prototype.executeIfAvailable_ = function(urls, callback) { | 2489 FileManager.prototype.executeIfAvailable_ = function(urls, callback) { |
2467 if (this.isOnGDataOffline()) { | 2490 if (this.isOnGDataOffline()) { |
2468 this.metadataCache_.get(urls, 'gdata', function(props) { | 2491 this.metadataCache_.get(urls, 'gdata', function(props) { |
2469 for (var i = 0; i != props.length; i++) { | 2492 if (props.filter(function(p) {return !p.availableOffline}).length) { |
2470 if (!props[i].availableOffline) { | 2493 this.alert.showHtml( |
2471 this.alert.showHtml( | 2494 str('OFFLINE_HEADER'), |
2472 str('OFFLINE_HEADER'), | 2495 strf( |
2473 strf( | 2496 urls.length == 1 ? |
2474 urls.length == 1 ? | 2497 'OFFLINE_MESSAGE' : |
2475 'OFFLINE_MESSAGE' : | 2498 'OFFLINE_MESSAGE_PLURAL', |
2476 'OFFLINE_MESSAGE_PLURAL', | 2499 str('OFFLINE_COLUMN_LABEL'))); |
2477 str('OFFLINE_COLUMN_LABEL'))); | 2500 return; |
2478 return; | |
2479 } | |
2480 } | 2501 } |
2481 callback(urls); | 2502 callback(urls); |
2482 }.bind(this)); | 2503 }.bind(this)); |
2483 } else { | 2504 } else { |
2484 callback(urls); | 2505 callback(urls); |
2485 } | 2506 } |
2486 }; | 2507 }; |
2487 | 2508 |
2488 FileManager.prototype.isOffline = function() { | |
2489 return !navigator.onLine; | |
2490 }; | |
2491 | |
2492 FileManager.prototype.onOnlineOffline_ = function() { | 2509 FileManager.prototype.onOnlineOffline_ = function() { |
2493 if (this.isOffline()) { | 2510 if (util.isOffline()) { |
2494 console.log('OFFLINE'); | 2511 console.log('OFFLINE'); |
2495 this.dialogContainer_.setAttribute('offline', true); | 2512 this.dialogContainer_.setAttribute('offline', true); |
2496 } else { | 2513 } else { |
2497 console.log('ONLINE'); | 2514 console.log('ONLINE'); |
2498 this.dialogContainer_.removeAttribute('offline'); | 2515 this.dialogContainer_.removeAttribute('offline'); |
2499 } | 2516 } |
2500 }; | 2517 }; |
2501 | 2518 |
2502 FileManager.prototype.isOnGDataOffline = function() { | 2519 FileManager.prototype.isOnGDataOffline = function() { |
2503 return this.isOnGData() && this.isOffline(); | 2520 return this.isOnGData() && util.isOffline(); |
2504 }; | 2521 }; |
2505 | 2522 |
2506 FileManager.prototype.isOnReadonlyDirectory = function() { | 2523 FileManager.prototype.isOnReadonlyDirectory = function() { |
2507 return this.directoryModel_.isReadOnly(); | 2524 return this.directoryModel_.isReadOnly(); |
2508 }; | 2525 }; |
2509 | 2526 |
2510 /** | 2527 /** |
2511 * Event handler called when some volume was mounted or unmouted. | 2528 * Event handler called when some volume was mounted or unmouted. |
2512 */ | 2529 */ |
2513 FileManager.prototype.onMountCompleted_ = function(event) { | 2530 FileManager.prototype.onMountCompleted_ = function(event) { |
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3069 strf('GDATA_OUT_OF_SPACE_MESSAGE', | 3086 strf('GDATA_OUT_OF_SPACE_MESSAGE', |
3070 util.bytesToSi(filesystem.size))); | 3087 util.bytesToSi(filesystem.size))); |
3071 }); | 3088 }); |
3072 } | 3089 } |
3073 // We don't have update events yet, so clear the cached data. | 3090 // We don't have update events yet, so clear the cached data. |
3074 self.metadataCache_.clear(entry, 'gdata'); | 3091 self.metadataCache_.clear(entry, 'gdata'); |
3075 checkbox.checked = props[0].isPinned; | 3092 checkbox.checked = props[0].isPinned; |
3076 } | 3093 } |
3077 var pin = checkbox.checked; | 3094 var pin = checkbox.checked; |
3078 this.metadataCache_.get(entry, 'gdata', function(gdata) { | 3095 this.metadataCache_.get(entry, 'gdata', function(gdata) { |
3079 if (self.isOffline() && pin && !gdata.present) { | 3096 if (util.isOffline() && pin && !gdata.present) { |
3080 // If we are offline, we cannot pin a file that is not already present. | 3097 // If we are offline, we cannot pin a file that is not already present. |
3081 checkbox.checked = false; // Revert the default action. | 3098 checkbox.checked = false; // Revert the default action. |
3082 self.alert.showHtml( | 3099 self.alert.showHtml( |
3083 str('OFFLINE_HEADER'), | 3100 str('OFFLINE_HEADER'), |
3084 strf('OFFLINE_MESSAGE', str('OFFLINE_COLUMN_LABEL'))); | 3101 strf('OFFLINE_MESSAGE', str('OFFLINE_COLUMN_LABEL'))); |
3085 return; | 3102 return; |
3086 } | 3103 } |
3087 chrome.fileBrowserPrivate.pinGDataFile([entry.toURL()], pin, callback); | 3104 chrome.fileBrowserPrivate.pinGDataFile([entry.toURL()], pin, callback); |
3088 }); | 3105 }); |
3089 event.preventDefault(); | 3106 event.preventDefault(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3182 this.updateSelectAllCheckboxState_(selectAllCheckbox); | 3199 this.updateSelectAllCheckboxState_(selectAllCheckbox); |
3183 }; | 3200 }; |
3184 | 3201 |
3185 FileManager.prototype.updateOkButton_ = function(event) { | 3202 FileManager.prototype.updateOkButton_ = function(event) { |
3186 var selectable; | 3203 var selectable; |
3187 | 3204 |
3188 if (this.dialogType_ == FileManager.DialogType.SELECT_FOLDER) { | 3205 if (this.dialogType_ == FileManager.DialogType.SELECT_FOLDER) { |
3189 selectable = this.selection.directoryCount == 1 && | 3206 selectable = this.selection.directoryCount == 1 && |
3190 this.selection.fileCount == 0; | 3207 this.selection.fileCount == 0; |
3191 } else if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE) { | 3208 } else if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE) { |
3192 selectable = (this.selection.directoryCount == 0 && | 3209 selectable = (this.isSelectionAvailable() && |
| 3210 this.selection.directoryCount == 0 && |
3193 this.selection.fileCount == 1); | 3211 this.selection.fileCount == 1); |
3194 } else if (this.dialogType_ == | 3212 } else if (this.dialogType_ == |
3195 FileManager.DialogType.SELECT_OPEN_MULTI_FILE) { | 3213 FileManager.DialogType.SELECT_OPEN_MULTI_FILE) { |
3196 selectable = (this.selection.directoryCount == 0 && | 3214 selectable = (this.isSelectionAvailable() && |
| 3215 this.selection.directoryCount == 0 && |
3197 this.selection.fileCount >= 1); | 3216 this.selection.fileCount >= 1); |
3198 } else if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 3217 } else if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
3199 if (this.isOnReadonlyDirectory()) { | 3218 if (this.isOnReadonlyDirectory()) { |
3200 selectable = false; | 3219 selectable = false; |
3201 } else { | 3220 } else { |
3202 selectable = !!this.filenameInput_.value; | 3221 selectable = !!this.filenameInput_.value; |
3203 } | 3222 } |
3204 } else if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { | 3223 } else if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { |
3205 // No "select" buttons on the full page UI. | 3224 // No "select" buttons on the full page UI. |
3206 selectable = true; | 3225 selectable = true; |
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4226 | 4245 |
4227 handleSplitterDragEnd: function(e) { | 4246 handleSplitterDragEnd: function(e) { |
4228 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments); | 4247 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments); |
4229 this.ownerDocument.documentElement.classList.remove('col-resize'); | 4248 this.ownerDocument.documentElement.classList.remove('col-resize'); |
4230 } | 4249 } |
4231 }; | 4250 }; |
4232 | 4251 |
4233 customSplitter.decorate(splitterElement); | 4252 customSplitter.decorate(splitterElement); |
4234 }; | 4253 }; |
4235 })(); | 4254 })(); |
OLD | NEW |