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 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 FileManager.prototype.initRootsList_ = function() { | 791 FileManager.prototype.initRootsList_ = function() { |
792 this.rootsList_ = this.dialogDom_.querySelector('.roots-list'); | 792 this.rootsList_ = this.dialogDom_.querySelector('.roots-list'); |
793 cr.ui.List.decorate(this.rootsList_); | 793 cr.ui.List.decorate(this.rootsList_); |
794 this.rootsList_.startBatchUpdates(); | 794 this.rootsList_.startBatchUpdates(); |
795 | 795 |
796 var self = this; | 796 var self = this; |
797 this.rootsList_.itemConstructor = function(entry) { | 797 this.rootsList_.itemConstructor = function(entry) { |
798 return self.renderRoot_(entry); | 798 return self.renderRoot_(entry); |
799 }; | 799 }; |
800 | 800 |
801 this.rootsList_.selectionModel = this.directoryModel_.rootsListSelection; | 801 this.rootsList_.selectionModel = |
| 802 this.directoryModel_.getRootsListSelectionModel(); |
802 | 803 |
803 // TODO(dgozman): add "Add a drive" item. | 804 // TODO(dgozman): add "Add a drive" item. |
804 this.rootsList_.dataModel = this.directoryModel_.rootsList; | 805 this.rootsList_.dataModel = this.directoryModel_.getRootsList(); |
805 this.directoryModel_.updateRoots(function() { | 806 this.directoryModel_.updateRoots(function() { |
806 self.rootsList_.endBatchUpdates(); | 807 self.rootsList_.endBatchUpdates(); |
807 }, false); | 808 }, false); |
808 }; | 809 }; |
809 | 810 |
810 /** | 811 /** |
811 * @param {boolean} dirChanged True if we just changed to GData directory, | 812 * @param {boolean} dirChanged True if we just changed to GData directory, |
812 * False if "Retry" button clicked. | 813 * False if "Retry" button clicked. |
813 */ | 814 */ |
814 FileManager.prototype.initGData_ = function(dirChanged) { | 815 FileManager.prototype.initGData_ = function(dirChanged) { |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 | 1215 |
1215 case 'newfolder': | 1216 case 'newfolder': |
1216 return !readonly && | 1217 return !readonly && |
1217 (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE || | 1218 (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE || |
1218 this.dialogType_ == FileManager.DialogType.FULL_PAGE); | 1219 this.dialogType_ == FileManager.DialogType.FULL_PAGE); |
1219 | 1220 |
1220 case 'unmount': | 1221 case 'unmount': |
1221 return true; | 1222 return true; |
1222 | 1223 |
1223 case 'format': | 1224 case 'format': |
1224 var entry = | 1225 var entry = this.directoryModel_.getCurrentRootDirEntry(); |
1225 this.getRootEntry_(this.rootsList_.selectionModel.selectedIndex); | |
1226 | 1226 |
1227 return entry && DirectoryModel.getRootType(entry.fullPath) == | 1227 return entry && DirectoryModel.getRootType(entry.fullPath) == |
1228 DirectoryModel.RootType.REMOVABLE; | 1228 DirectoryModel.RootType.REMOVABLE; |
1229 } | 1229 } |
1230 }; | 1230 }; |
1231 | 1231 |
1232 FileManager.prototype.getRootEntry_ = function(index) { | 1232 FileManager.prototype.getRootEntry_ = function(index) { |
1233 if (index == -1) | 1233 if (index == -1) |
1234 return null; | 1234 return null; |
1235 | 1235 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 | 1502 |
1503 case 'delete': | 1503 case 'delete': |
1504 this.deleteEntries(this.selection.entries); | 1504 this.deleteEntries(this.selection.entries); |
1505 return; | 1505 return; |
1506 | 1506 |
1507 case 'newfolder': | 1507 case 'newfolder': |
1508 this.onNewFolderCommand_(event); | 1508 this.onNewFolderCommand_(event); |
1509 return; | 1509 return; |
1510 | 1510 |
1511 case 'unmount': | 1511 case 'unmount': |
1512 var entry = | 1512 this.unmountVolume_(this.directoryModel_.getCurrentRootDirEntry()); |
1513 this.getRootEntry_(this.rootsList_.selectionModel.selectedIndex); | |
1514 | |
1515 this.unmountVolume_(entry); | |
1516 return; | 1513 return; |
1517 | 1514 |
1518 case 'format': | 1515 case 'format': |
1519 var entry = | 1516 var entry = this.directoryModel_.getCurrentRootDirEntry(); |
1520 this.getRootEntry_(this.rootsList_.selectionModel.selectedIndex); | |
1521 | |
1522 this.confirm.show(str('FORMATTING_WARNING'), function() { | 1517 this.confirm.show(str('FORMATTING_WARNING'), function() { |
1523 chrome.fileBrowserPrivate.formatDevice(entry.toURL()); | 1518 chrome.fileBrowserPrivate.formatDevice(entry.toURL()); |
1524 }); | 1519 }); |
1525 | 1520 |
1526 return; | 1521 return; |
1527 } | 1522 } |
1528 }; | 1523 }; |
1529 | 1524 |
1530 /** | 1525 /** |
1531 * Respond to the back and forward buttons. | 1526 * Respond to the back and forward buttons. |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1919 | 1914 |
1920 if (path == '/' + DirectoryModel.GDATA_DIRECTORY) | 1915 if (path == '/' + DirectoryModel.GDATA_DIRECTORY) |
1921 return str('GDATA_DIRECTORY_LABEL'); | 1916 return str('GDATA_DIRECTORY_LABEL'); |
1922 | 1917 |
1923 return path; | 1918 return path; |
1924 }; | 1919 }; |
1925 | 1920 |
1926 FileManager.prototype.renderRoot_ = function(entry) { | 1921 FileManager.prototype.renderRoot_ = function(entry) { |
1927 var li = this.document_.createElement('li'); | 1922 var li = this.document_.createElement('li'); |
1928 li.className = 'root-item'; | 1923 li.className = 'root-item'; |
1929 li.addEventListener('click', this.onRootClick_.bind(this, entry)); | 1924 this.directoryModel_.registerRootClickListener_(li, entry); |
1930 | 1925 |
1931 var rootType = DirectoryModel.getRootType(entry.fullPath); | 1926 var rootType = DirectoryModel.getRootType(entry.fullPath); |
1932 | 1927 |
1933 var div = this.document_.createElement('div'); | 1928 var div = this.document_.createElement('div'); |
1934 div.className = 'root-label'; | 1929 div.className = 'root-label'; |
1935 | 1930 |
1936 var icon = rootType; | 1931 var icon = rootType; |
1937 var deviceNumber = this.getDeviceNumber(entry); | 1932 var deviceNumber = this.getDeviceNumber(entry); |
1938 | 1933 |
1939 if (deviceNumber != undefined) { | 1934 if (deviceNumber != undefined) { |
(...skipping 23 matching lines...) Expand all Loading... |
1963 | 1958 |
1964 cr.ui.contextMenuHandler.setContextMenu(li, this.rootsContextMenu_); | 1959 cr.ui.contextMenuHandler.setContextMenu(li, this.rootsContextMenu_); |
1965 } | 1960 } |
1966 | 1961 |
1967 cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR); | 1962 cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR); |
1968 cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR); | 1963 cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR); |
1969 return li; | 1964 return li; |
1970 }; | 1965 }; |
1971 | 1966 |
1972 /** | 1967 /** |
1973 * Handler for root item being clicked. | |
1974 * @param {Entry} entry to navigate to. | |
1975 * @param {Event} event The event. | |
1976 */ | |
1977 FileManager.prototype.onRootClick_ = function(entry, event) { | |
1978 var path = this.directoryModel_.currentEntry.fullPath; | |
1979 if (path.indexOf(entry.fullPath) == 0 && path != entry.fullPath) { | |
1980 this.directoryModel_.changeDirectory(entry.fullPath); | |
1981 } | |
1982 }; | |
1983 | |
1984 /** | |
1985 * Unmounts device. | 1968 * Unmounts device. |
1986 * @param {string} url The url of removable storage to unmount. | 1969 * @param {string} url The url of removable storage to unmount. |
1987 */ | 1970 */ |
1988 FileManager.prototype.unmountVolume_ = function(entry) { | 1971 FileManager.prototype.unmountVolume_ = function(entry) { |
1989 this.unmountRequests_.push(entry.fullPath); | 1972 this.unmountRequests_.push(entry.fullPath); |
1990 chrome.fileBrowserPrivate.removeMount(entry.toURL()); | 1973 chrome.fileBrowserPrivate.removeMount(entry.toURL()); |
1991 }; | 1974 }; |
1992 | 1975 |
1993 FileManager.prototype.styleGDataItem_ = function(entry, listItem) { | 1976 FileManager.prototype.styleGDataItem_ = function(entry, listItem) { |
1994 if (!this.isOnGData()) | 1977 if (!this.isOnGData()) |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2450 } | 2433 } |
2451 | 2434 |
2452 function setVisibility(visibility) { | 2435 function setVisibility(visibility) { |
2453 panel.setAttribute('visibility', visibility); | 2436 panel.setAttribute('visibility', visibility); |
2454 } | 2437 } |
2455 }; | 2438 }; |
2456 | 2439 |
2457 | 2440 |
2458 FileManager.prototype.isOnGData = function() { | 2441 FileManager.prototype.isOnGData = function() { |
2459 return this.directoryModel_ && | 2442 return this.directoryModel_ && |
2460 this.directoryModel_.rootPath == '/' + DirectoryModel.GDATA_DIRECTORY; | 2443 this.directoryModel_.getCurrentRootPath() == |
| 2444 '/' + DirectoryModel.GDATA_DIRECTORY; |
2461 }; | 2445 }; |
2462 | 2446 |
2463 FileManager.prototype.getMetadataProvider = function() { | 2447 FileManager.prototype.getMetadataProvider = function() { |
2464 return this.metadataProvider_; | 2448 return this.metadataProvider_; |
2465 }; | 2449 }; |
2466 | 2450 |
2467 /** | 2451 /** |
2468 * Callback called when tasks for selected files are determined. | 2452 * Callback called when tasks for selected files are determined. |
2469 * @param {Object} selection Selection is passed here, since this.selection | 2453 * @param {Object} selection Selection is passed here, since this.selection |
2470 * can change before tasks were found, and we should be accurate. | 2454 * can change before tasks were found, and we should be accurate. |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2712 }; | 2696 }; |
2713 // Not calling clearGDataLoadingTimer_ here because we want to keep | 2697 // Not calling clearGDataLoadingTimer_ here because we want to keep |
2714 // "Loading Google Docs" message until the directory loads. It is OK if | 2698 // "Loading Google Docs" message until the directory loads. It is OK if |
2715 // the timer fires after the mount because onDirectoryChanged_ will hide | 2699 // the timer fires after the mount because onDirectoryChanged_ will hide |
2716 // the unmounted panel. | 2700 // the unmounted panel. |
2717 if (this.setupCurrentDirectoryPostponed_) { | 2701 if (this.setupCurrentDirectoryPostponed_) { |
2718 this.setupCurrentDirectoryPostponed_(false /* execute */); | 2702 this.setupCurrentDirectoryPostponed_(false /* execute */); |
2719 } else if (this.isOnGData() && | 2703 } else if (this.isOnGData() && |
2720 this.directoryModel_.currentEntry.unmounted) { | 2704 this.directoryModel_.currentEntry.unmounted) { |
2721 // We are currently on an unmounted GData directory, force a rescan. | 2705 // We are currently on an unmounted GData directory, force a rescan. |
2722 changeDirectoryTo = this.directoryModel_.rootPath; | 2706 changeDirectoryTo = this.directoryModel_.getCurrentRootPath(); |
2723 } | 2707 } |
2724 } else { | 2708 } else { |
2725 this.gdataMounted_ = false; | 2709 this.gdataMounted_ = false; |
2726 this.gdataMountInfo_ = null; | 2710 this.gdataMountInfo_ = null; |
2727 this.clearGDataLoadingTimer_(); | 2711 this.clearGDataLoadingTimer_(); |
2728 this.onGDataUnreachable_('GData mount failed: ' + event.status); | 2712 this.onGDataUnreachable_('GData mount failed: ' + event.status); |
2729 if (this.setupCurrentDirectoryPostponed_) { | 2713 if (this.setupCurrentDirectoryPostponed_) { |
2730 this.setupCurrentDirectoryPostponed_(true /* cancel */); | 2714 this.setupCurrentDirectoryPostponed_(true /* cancel */); |
2731 // Change to unmounted GData root. | 2715 // Change to unmounted GData root. |
2732 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY; | 2716 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY; |
(...skipping 25 matching lines...) Expand all Loading... |
2758 if (event.eventType == 'unmount') { | 2742 if (event.eventType == 'unmount') { |
2759 // Unmount request finished - remove it. | 2743 // Unmount request finished - remove it. |
2760 var index = self.unmountRequests_.indexOf(event.mountPath); | 2744 var index = self.unmountRequests_.indexOf(event.mountPath); |
2761 if (index != -1) { | 2745 if (index != -1) { |
2762 self.unmountRequests_.splice(index, 1); | 2746 self.unmountRequests_.splice(index, 1); |
2763 if (event.status != 'success') | 2747 if (event.status != 'success') |
2764 self.alert.show(strf('UNMOUNT_FAILED', event.status)); | 2748 self.alert.show(strf('UNMOUNT_FAILED', event.status)); |
2765 } | 2749 } |
2766 | 2750 |
2767 if (event.status == 'success' && | 2751 if (event.status == 'success' && |
2768 event.mountPath == self.directoryModel_.rootPath) { | 2752 event.mountPath == self.directoryModel_.getCurrentRootPath()) { |
2769 if (self.params_.mountTriggered && index == -1) { | 2753 if (self.params_.mountTriggered && index == -1) { |
2770 // This device mount was the reason this File Manager instance was | 2754 // This device mount was the reason this File Manager instance was |
2771 // created. Now the device is unmounted from another instance | 2755 // created. Now the device is unmounted from another instance |
2772 // or the user removed the device manually. Close this instance. | 2756 // or the user removed the device manually. Close this instance. |
2773 // window.close() sometimes doesn't work. | 2757 // window.close() sometimes doesn't work. |
2774 chrome.tabs.getCurrent(function(tab) { | 2758 chrome.tabs.getCurrent(function(tab) { |
2775 chrome.tabs.remove(tab.id); | 2759 chrome.tabs.remove(tab.id); |
2776 }); | 2760 }); |
2777 return; | 2761 return; |
2778 } | 2762 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2910 | 2894 |
2911 galleryFrame.onload = function() { | 2895 galleryFrame.onload = function() { |
2912 galleryFrame.contentWindow.ImageUtil.metrics = metrics; | 2896 galleryFrame.contentWindow.ImageUtil.metrics = metrics; |
2913 galleryFrame.contentWindow.FileType = FileType; | 2897 galleryFrame.contentWindow.FileType = FileType; |
2914 galleryFrame.contentWindow.util = util; | 2898 galleryFrame.contentWindow.util = util; |
2915 | 2899 |
2916 // Gallery shoud treat GData folder as readonly even when online | 2900 // Gallery shoud treat GData folder as readonly even when online |
2917 // until we learn to save files directly to GData. | 2901 // until we learn to save files directly to GData. |
2918 var readonly = self.isOnReadonlyDirectory() || self.isOnGData(); | 2902 var readonly = self.isOnReadonlyDirectory() || self.isOnGData(); |
2919 var currentDir = self.directoryModel_.currentEntry; | 2903 var currentDir = self.directoryModel_.currentEntry; |
2920 var downloadsDir = self.directoryModel_.rootsList.item(0); | 2904 var downloadsDir = self.directoryModel_.getRootsList().item(0); |
2921 | 2905 |
2922 var context = { | 2906 var context = { |
2923 // We show the root label in readonly warning (e.g. archive name). | 2907 // We show the root label in readonly warning (e.g. archive name). |
2924 readonlyDirName: | 2908 readonlyDirName: |
2925 readonly ? | 2909 readonly ? |
2926 (self.isOnGData() ? | 2910 (self.isOnGData() ? |
2927 self.getRootLabel_(currentDir.fullPath) : | 2911 self.getRootLabel_(currentDir.fullPath) : |
2928 self.directoryModel_.rootName) : | 2912 self.directoryModel_.rootName) : |
2929 null, | 2913 null, |
2930 saveDirEntry: readonly ? downloadsDir : currentDir, | 2914 saveDirEntry: readonly ? downloadsDir : currentDir, |
(...skipping 15 matching lines...) Expand all Loading... |
2946 this.openFilePopup_(galleryFrame); | 2930 this.openFilePopup_(galleryFrame); |
2947 }; | 2931 }; |
2948 | 2932 |
2949 /** | 2933 /** |
2950 * Update the breadcrumb display to reflect the current directory. | 2934 * Update the breadcrumb display to reflect the current directory. |
2951 */ | 2935 */ |
2952 FileManager.prototype.updateBreadcrumbs_ = function() { | 2936 FileManager.prototype.updateBreadcrumbs_ = function() { |
2953 var bc = this.dialogDom_.querySelector('.breadcrumbs'); | 2937 var bc = this.dialogDom_.querySelector('.breadcrumbs'); |
2954 removeChildren(bc); | 2938 removeChildren(bc); |
2955 | 2939 |
2956 var rootPath = this.directoryModel_.rootPath; | 2940 var rootPath = this.directoryModel_.getCurrentRootPath(); |
2957 var relativePath = this.directoryModel_.currentEntry.fullPath. | 2941 var relativePath = this.directoryModel_.currentEntry.fullPath. |
2958 substring(rootPath.length).replace(/\/$/, ''); | 2942 substring(rootPath.length).replace(/\/$/, ''); |
2959 | 2943 |
2960 var pathNames = relativePath.replace(/\/$/, '').split('/'); | 2944 var pathNames = relativePath.replace(/\/$/, '').split('/'); |
2961 if (pathNames[0] == '') | 2945 if (pathNames[0] == '') |
2962 pathNames.splice(0, 1); | 2946 pathNames.splice(0, 1); |
2963 | 2947 |
2964 // We need a first breadcrumb for root, so placing last name from | 2948 // We need a first breadcrumb for root, so placing last name from |
2965 // rootPath as first name of relativePath. | 2949 // rootPath as first name of relativePath. |
2966 var rootPathNames = rootPath.replace(/\/$/, '').split('/'); | 2950 var rootPathNames = rootPath.replace(/\/$/, '').split('/'); |
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4381 | 4365 |
4382 handleSplitterDragEnd: function(e) { | 4366 handleSplitterDragEnd: function(e) { |
4383 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments); | 4367 Splitter.prototype.handleSplitterDragEnd.apply(this, arguments); |
4384 this.ownerDocument.documentElement.classList.remove('col-resize'); | 4368 this.ownerDocument.documentElement.classList.remove('col-resize'); |
4385 } | 4369 } |
4386 }; | 4370 }; |
4387 | 4371 |
4388 customSplitter.decorate(splitterElement); | 4372 customSplitter.decorate(splitterElement); |
4389 }; | 4373 }; |
4390 })(); | 4374 })(); |
OLD | NEW |