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 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 case 'delete': | 1027 case 'delete': |
1028 return (// Initialized to the point where we have a current directory | 1028 return (// Initialized to the point where we have a current directory |
1029 !readonly && | 1029 !readonly && |
1030 // Rename not in progress. | 1030 // Rename not in progress. |
1031 !this.isRenamingInProgress() && | 1031 !this.isRenamingInProgress() && |
1032 this.selection && | 1032 this.selection && |
1033 this.selection.totalCount > 0); | 1033 this.selection.totalCount > 0); |
1034 | 1034 |
1035 case 'newfolder': | 1035 case 'newfolder': |
1036 return !readonly && | 1036 return !readonly && |
| 1037 !this.directoryModel_.isSearching() && |
1037 (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE || | 1038 (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE || |
1038 this.dialogType_ == FileManager.DialogType.FULL_PAGE); | 1039 this.dialogType_ == FileManager.DialogType.FULL_PAGE); |
1039 | 1040 |
1040 case 'unmount': | 1041 case 'unmount': |
1041 return true; | 1042 return true; |
1042 | 1043 |
1043 case 'format': | 1044 case 'format': |
1044 var entry = this.directoryModel_.getCurrentRootDirEntry(); | 1045 var entry = this.directoryModel_.getCurrentRootDirEntry(); |
1045 | 1046 |
1046 return entry && DirectoryModel.getRootType(entry.fullPath) == | 1047 return entry && DirectoryModel.getRootType(entry.fullPath) == |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 } | 1281 } |
1281 } | 1282 } |
1282 }; | 1283 }; |
1283 | 1284 |
1284 /** | 1285 /** |
1285 * Handler of file manager operations. Update directory model | 1286 * Handler of file manager operations. Update directory model |
1286 * to reflect operation result iimediatelly (not waiting directory | 1287 * to reflect operation result iimediatelly (not waiting directory |
1287 * update event). | 1288 * update event). |
1288 */ | 1289 */ |
1289 FileManager.prototype.onCopyManagerOperationComplete_ = function(event) { | 1290 FileManager.prototype.onCopyManagerOperationComplete_ = function(event) { |
1290 var currentPath = this.directoryModel_.getCurrentDirEntry().fullPath; | 1291 var currentPath = |
| 1292 this.directoryModel_.getCurrentDirPath(); |
| 1293 if (this.isOnGData() && this.directoryModel_.isSearching()) |
| 1294 return; |
| 1295 |
1291 function inCurrentDirectory(entry) { | 1296 function inCurrentDirectory(entry) { |
1292 var fullPath = entry.fullPath; | 1297 var fullPath = entry.fullPath; |
1293 var dirPath = fullPath.substr(0, fullPath.length - | 1298 var dirPath = fullPath.substr(0, fullPath.length - |
1294 entry.name.length - 1); | 1299 entry.name.length - 1); |
1295 return dirPath == currentPath; | 1300 return dirPath == currentPath; |
1296 } | 1301 } |
1297 for (var i = 0; i < event.affectedEntries.length; i++) { | 1302 for (var i = 0; i < event.affectedEntries.length; i++) { |
1298 entry = event.affectedEntries[i]; | 1303 entry = event.affectedEntries[i]; |
1299 if (inCurrentDirectory(entry)) | 1304 if (inCurrentDirectory(entry)) |
1300 this.directoryModel_.onEntryChanged(entry.name); | 1305 this.directoryModel_.onEntryChanged(entry.name); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1518 defaultTitle = str('SELECT_OPEN_FILE_TITLE'); | 1523 defaultTitle = str('SELECT_OPEN_FILE_TITLE'); |
1519 break; | 1524 break; |
1520 | 1525 |
1521 case FileManager.DialogType.SELECT_OPEN_MULTI_FILE: | 1526 case FileManager.DialogType.SELECT_OPEN_MULTI_FILE: |
1522 defaultTitle = str('SELECT_OPEN_MULTI_FILE_TITLE'); | 1527 defaultTitle = str('SELECT_OPEN_MULTI_FILE_TITLE'); |
1523 break; | 1528 break; |
1524 | 1529 |
1525 case FileManager.DialogType.SELECT_SAVEAS_FILE: | 1530 case FileManager.DialogType.SELECT_SAVEAS_FILE: |
1526 defaultTitle = str('SELECT_SAVEAS_FILE_TITLE'); | 1531 defaultTitle = str('SELECT_SAVEAS_FILE_TITLE'); |
1527 okLabel = str('SAVE_LABEL'); | 1532 okLabel = str('SAVE_LABEL'); |
| 1533 // We don't want search enabled in save as dialog. |
| 1534 this.dialogDom_.querySelector('#search-box').style.display = 'none'; |
1528 break; | 1535 break; |
1529 | 1536 |
1530 case FileManager.DialogType.FULL_PAGE: | 1537 case FileManager.DialogType.FULL_PAGE: |
1531 break; | 1538 break; |
1532 | 1539 |
1533 default: | 1540 default: |
1534 throw new Error('Unknown dialog type: ' + this.dialogType_); | 1541 throw new Error('Unknown dialog type: ' + this.dialogType_); |
1535 } | 1542 } |
1536 | 1543 |
1537 this.okButton_.textContent = okLabel; | 1544 this.okButton_.textContent = okLabel; |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1863 * @param {Entry} entry The Entry object to render. | 1870 * @param {Entry} entry The Entry object to render. |
1864 * @return {HTMLDivElement} The label. | 1871 * @return {HTMLDivElement} The label. |
1865 */ | 1872 */ |
1866 FileManager.prototype.renderFileNameLabel_ = function(entry) { | 1873 FileManager.prototype.renderFileNameLabel_ = function(entry) { |
1867 // Filename need to be in a '.filename-label' container for correct | 1874 // Filename need to be in a '.filename-label' container for correct |
1868 // work of inplace renaming. | 1875 // work of inplace renaming. |
1869 var fileName = this.document_.createElement('div'); | 1876 var fileName = this.document_.createElement('div'); |
1870 fileName.className = 'filename-label'; | 1877 fileName.className = 'filename-label'; |
1871 | 1878 |
1872 fileName.textContent = | 1879 fileName.textContent = |
1873 this.directoryModel_.getCurrentDirEntry().name == '' ? | 1880 this.directoryModel_.getDisplayName(entry.fullPath, entry.name); |
1874 this.getRootLabel_(entry.name) : entry.name; | 1881 |
1875 return fileName; | 1882 return fileName; |
1876 }; | 1883 }; |
1877 | 1884 |
1878 /** | 1885 /** |
1879 * Render the Size column of the detail table. | 1886 * Render the Size column of the detail table. |
1880 * | 1887 * |
1881 * @param {Entry} entry The Entry object to render. | 1888 * @param {Entry} entry The Entry object to render. |
1882 * @param {string} columnId The id of the column to be rendered. | 1889 * @param {string} columnId The id of the column to be rendered. |
1883 * @param {cr.ui.Table} table The table doing the rendering. | 1890 * @param {cr.ui.Table} table The table doing the rendering. |
1884 */ | 1891 */ |
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2697 this.setupCurrentDirectoryPostponed_(true /* cancel */); | 2704 this.setupCurrentDirectoryPostponed_(true /* cancel */); |
2698 // Change to unmounted GData root. | 2705 // Change to unmounted GData root. |
2699 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY; | 2706 changeDirectoryTo = '/' + DirectoryModel.GDATA_DIRECTORY; |
2700 } | 2707 } |
2701 } | 2708 } |
2702 } | 2709 } |
2703 | 2710 |
2704 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { | 2711 chrome.fileBrowserPrivate.getMountPoints(function(mountPoints) { |
2705 this.setMountPoints_(mountPoints); | 2712 this.setMountPoints_(mountPoints); |
2706 | 2713 |
2707 if (event.eventType == 'mount') { | 2714 if (event.eventType == 'mount' && event.mountType != 'gdata') { |
2708 // Mount request finished - remove it. | 2715 // Mount request finished - remove it. |
2709 // Currently we only request mounts for archive files. | 2716 // Currently we only request mounts for archive files. |
2710 var index = this.mountRequests_.indexOf(event.sourcePath); | 2717 var index = this.mountRequests_.indexOf(event.sourcePath); |
2711 if (index != -1) { | 2718 if (index != -1) { |
2712 this.mountRequests_.splice(index, 1); | 2719 this.mountRequests_.splice(index, 1); |
2713 if (event.status == 'success') { | 2720 if (event.status == 'success') { |
2714 // Successful mount requested from this tab, go to the drive root. | 2721 // Successful mount requested from this tab, go to the drive root. |
2715 changeDirectoryTo = event.mountPath; | 2722 changeDirectoryTo = event.mountPath; |
2716 } else { | 2723 } else { |
2717 // Request initiated from this tab failed, report the error. | 2724 // Request initiated from this tab failed, report the error. |
2718 var fileName = event.sourcePath.split('/').pop(); | 2725 var fileName = event.sourcePath.split('/').pop(); |
2719 this.alert.show( | 2726 this.alert.show( |
2720 strf('ARCHIVE_MOUNT_FAILED', fileName, event.status)); | 2727 strf('ARCHIVE_MOUNT_FAILED', fileName, event.status)); |
2721 } | 2728 } |
2722 } | 2729 } |
2723 } | 2730 } |
2724 | 2731 |
2725 if (event.eventType == 'unmount') { | 2732 if (event.eventType == 'unmount' && event.mountType != 'gdata') { |
2726 // Unmount request finished - remove it. | 2733 // Unmount request finished - remove it. |
2727 var index = this.unmountRequests_.indexOf(event.mountPath); | 2734 var index = this.unmountRequests_.indexOf(event.mountPath); |
2728 if (index != -1) { | 2735 if (index != -1) { |
2729 this.unmountRequests_.splice(index, 1); | 2736 this.unmountRequests_.splice(index, 1); |
2730 if (event.status != 'success') | 2737 if (event.status != 'success') |
2731 this.alert.show(strf('UNMOUNT_FAILED', event.status)); | 2738 this.alert.show(strf('UNMOUNT_FAILED', event.status)); |
2732 } | 2739 } |
2733 | 2740 |
2734 if (event.status == 'success' && | 2741 if (event.status == 'success' && |
2735 event.mountPath == this.directoryModel_.getCurrentRootPath()) { | 2742 event.mountPath == this.directoryModel_.getCurrentRootPath()) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2855 if (task.taskId != this.getExtensionId_() + '|gallery') { | 2862 if (task.taskId != this.getExtensionId_() + '|gallery') { |
2856 // Add callback, so gallery can execute the task. | 2863 // Add callback, so gallery can execute the task. |
2857 task.execute = this.dispatchFileTask_.bind(this, task.taskId); | 2864 task.execute = this.dispatchFileTask_.bind(this, task.taskId); |
2858 shareActions.push(task); | 2865 shareActions.push(task); |
2859 } | 2866 } |
2860 } | 2867 } |
2861 callback(shareActions); | 2868 callback(shareActions); |
2862 }.bind(this)); | 2869 }.bind(this)); |
2863 }; | 2870 }; |
2864 | 2871 |
| 2872 /** |
| 2873 * Does preprocessing of url list to open before calling |doOpenGallery_|. |
| 2874 * |
| 2875 * @param {Array.<string>} urls List of urls to open in the gallery. |
| 2876 */ |
2865 FileManager.prototype.openGallery_ = function(urls) { | 2877 FileManager.prototype.openGallery_ = function(urls) { |
2866 var self = this; | |
2867 | |
2868 var galleryFrame = this.document_.createElement('iframe'); | |
2869 galleryFrame.className = 'overlay-pane'; | |
2870 galleryFrame.scrolling = 'no'; | |
2871 galleryFrame.setAttribute('webkitallowfullscreen', true); | |
2872 | |
2873 var singleSelection = urls.length == 1; | 2878 var singleSelection = urls.length == 1; |
2874 var selectedUrl; | 2879 var selectedUrl; |
2875 if (singleSelection && FileType.isImage(urls[0])) { | 2880 if (singleSelection && FileType.isImage(urls[0])) { |
2876 // Single image item selected. Pass to the Gallery as a selected. | 2881 // Single image item selected. Pass to the Gallery as a selected. |
2877 selectedUrl = urls[0]; | 2882 selectedUrl = urls[0]; |
2878 // Pass along every image and video in the directory so that it shows up | 2883 // Pass along every image and video in the directory so that it shows up |
2879 // in the ribbon. | 2884 // in the ribbon. |
2880 // We do not do that if a single video is selected because the UI is | 2885 // We do not do that if a single video is selected because the UI is |
2881 // cleaner without the ribbon. | 2886 // cleaner without the ribbon. |
2882 urls = this.getAllUrlsInCurrentDirectory_().filter( | 2887 urls = this.getAllUrlsInCurrentDirectory_().filter( |
2883 FileType.isImageOrVideo); | 2888 FileType.isImageOrVideo); |
2884 } else { | 2889 } else { |
2885 // Pass just the selected items, select the first entry. | 2890 // Pass just the selected items, select the first entry. |
2886 selectedUrl = urls[0]; | 2891 selectedUrl = urls[0]; |
2887 } | 2892 } |
2888 | 2893 |
| 2894 // TODO(tbarzic): There's probably a better way to do this. |
| 2895 if (this.directoryModel_.isOnGDataSearchDir()) { |
| 2896 var self = this; |
| 2897 var gdataRootUrl = this.directoryModel_.getCurrentRootDirEntry().toURL(); |
| 2898 util.resolveGDataSearchUrls([selectedUrl], gdataRootUrl, |
| 2899 function(resolved) { |
| 2900 util.resolveGDataSearchUrls(urls, gdataRootUrl, |
| 2901 self.doOpenGallery_.bind(self, singleSelection, resolved[0])); |
| 2902 }); |
| 2903 return; |
| 2904 } |
| 2905 this.doOpenGallery_(singleSelection, selectedUrl, urls); |
| 2906 }; |
| 2907 |
| 2908 /** |
| 2909 * Opens provided urls in the gallery. |
| 2910 * |
| 2911 * @param {string} selectedUrl Url of the item that should initially be |
| 2912 * selected. |
| 2913 * @param {Array.<string>} urls List of all the urls that will be shown in |
| 2914 * the gallery. |
| 2915 */ |
| 2916 FileManager.prototype.doOpenGallery_ = function(singleSelection, |
| 2917 selectedUrl, |
| 2918 urls) { |
| 2919 var self = this; |
| 2920 |
| 2921 var galleryFrame = this.document_.createElement('iframe'); |
| 2922 galleryFrame.className = 'overlay-pane'; |
| 2923 galleryFrame.scrolling = 'no'; |
| 2924 galleryFrame.setAttribute('webkitallowfullscreen', true); |
| 2925 |
2889 var dirPath = this.directoryModel_.getCurrentDirEntry().fullPath; | 2926 var dirPath = this.directoryModel_.getCurrentDirEntry().fullPath; |
2890 | |
2891 // Push a temporary state which will be replaced every time an individual | 2927 // Push a temporary state which will be replaced every time an individual |
2892 // item is selected in the Gallery. | 2928 // item is selected in the Gallery. |
2893 this.updateLocation_(false /*push*/, dirPath); | 2929 this.updateLocation_(false /*push*/, dirPath); |
2894 | 2930 |
2895 galleryFrame.onload = function() { | 2931 galleryFrame.onload = function() { |
2896 galleryFrame.contentWindow.ImageUtil.metrics = metrics; | 2932 galleryFrame.contentWindow.ImageUtil.metrics = metrics; |
2897 galleryFrame.contentWindow.FileType = FileType; | 2933 galleryFrame.contentWindow.FileType = FileType; |
2898 galleryFrame.contentWindow.util = util; | 2934 galleryFrame.contentWindow.util = util; |
2899 | 2935 |
2900 // Gallery shoud treat GData folder as readonly even when online | 2936 // Gallery shoud treat GData folder as readonly even when online |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2968 | 3004 |
2969 path = path + '/'; | 3005 path = path + '/'; |
2970 div.path = path; | 3006 div.path = path; |
2971 | 3007 |
2972 bc.appendChild(div); | 3008 bc.appendChild(div); |
2973 | 3009 |
2974 if (i == pathNames.length - 1) { | 3010 if (i == pathNames.length - 1) { |
2975 div.classList.add('breadcrumb-last'); | 3011 div.classList.add('breadcrumb-last'); |
2976 } else { | 3012 } else { |
2977 div.addEventListener('click', this.onBreadcrumbClick_.bind(this)); | 3013 div.addEventListener('click', this.onBreadcrumbClick_.bind(this)); |
2978 | |
2979 var spacer = doc.createElement('div'); | 3014 var spacer = doc.createElement('div'); |
2980 spacer.className = 'separator'; | 3015 spacer.className = 'separator'; |
2981 bc.appendChild(spacer); | 3016 bc.appendChild(spacer); |
2982 } | 3017 } |
2983 } | 3018 } |
2984 this.truncateBreadcrumbs_(); | 3019 this.truncateBreadcrumbs_(); |
2985 }; | 3020 }; |
2986 | 3021 |
2987 FileManager.prototype.isRenamingInProgress = function() { | 3022 FileManager.prototype.isRenamingInProgress = function() { |
2988 return !!this.renameInput_.currentEntry; | 3023 return !!this.renameInput_.currentEntry; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3119 }; | 3154 }; |
3120 | 3155 |
3121 /** | 3156 /** |
3122 * Return URL of the current directory or null. | 3157 * Return URL of the current directory or null. |
3123 */ | 3158 */ |
3124 FileManager.prototype.getCurrentDirectoryURL = function() { | 3159 FileManager.prototype.getCurrentDirectoryURL = function() { |
3125 return this.directoryModel_ && | 3160 return this.directoryModel_ && |
3126 this.directoryModel_.getCurrentDirEntry().toURL(); | 3161 this.directoryModel_.getCurrentDirEntry().toURL(); |
3127 }; | 3162 }; |
3128 | 3163 |
| 3164 /** |
| 3165 * Return URL of the search directory, current directory or null. |
| 3166 */ |
| 3167 FileManager.prototype.getSearchOrCurrentDirectoryURL = function() { |
| 3168 return this.directoryModel_ && |
| 3169 this.directoryModel_.getSearchOrCurrentDirEntry().toURL(); |
| 3170 }; |
| 3171 |
3129 FileManager.prototype.deleteEntries = function(entries, force, opt_callback) { | 3172 FileManager.prototype.deleteEntries = function(entries, force, opt_callback) { |
3130 if (!force) { | 3173 if (!force) { |
3131 var self = this; | 3174 var self = this; |
3132 var msg; | 3175 var msg; |
3133 if (entries.length == 1) { | 3176 if (entries.length == 1) { |
3134 msg = strf('CONFIRM_DELETE_ONE', entries[0].name); | 3177 var entryName = this.directoryModel_.getDisplayName(entries[0].fullPath, |
| 3178 entries[0].name); |
| 3179 msg = strf('CONFIRM_DELETE_ONE', entryName); |
3135 } else { | 3180 } else { |
3136 msg = strf('CONFIRM_DELETE_SOME', entries.length); | 3181 msg = strf('CONFIRM_DELETE_SOME', entries.length); |
3137 } | 3182 } |
3138 | 3183 |
3139 this.confirm.show(msg, this.deleteEntries.bind( | 3184 this.confirm.show(msg, this.deleteEntries.bind( |
3140 this, entries, true, opt_callback)); | 3185 this, entries, true, opt_callback)); |
3141 return; | 3186 return; |
3142 } | 3187 } |
3143 | 3188 |
3144 this.directoryModel_.deleteEntries(entries, opt_callback); | 3189 this.directoryModel_.deleteEntries(entries, opt_callback); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3401 this.dispatchDefaultTask_(); | 3446 this.dispatchDefaultTask_(); |
3402 return true; | 3447 return true; |
3403 } | 3448 } |
3404 if (!this.okButton_.disabled) { | 3449 if (!this.okButton_.disabled) { |
3405 this.onOk_(); | 3450 this.onOk_(); |
3406 return true; | 3451 return true; |
3407 } | 3452 } |
3408 return false; | 3453 return false; |
3409 }; | 3454 }; |
3410 | 3455 |
| 3456 /** |
| 3457 * Executes directory action (i.e. changes directory). If new directory is a |
| 3458 * search result directory, we'll have to calculate its real path before we |
| 3459 * actually do the operation. |
| 3460 * |
| 3461 * @param {DirectoryEntry} entry Directory entry to which directory should be |
| 3462 * changed. |
| 3463 */ |
3411 FileManager.prototype.onDirectoryAction = function(entry) { | 3464 FileManager.prototype.onDirectoryAction = function(entry) { |
3412 var deviceNumber = this.getDeviceNumber(entry); | 3465 if (!DirectoryModel.isGDataSearchPath(entry.fullPath)) |
3413 if (deviceNumber != undefined && | |
3414 this.mountPoints_[deviceNumber].mountCondition == | |
3415 'unknown_filesystem') { | |
3416 return this.showButter(str('UNKNOWN_FILESYSTEM_WARNING')); | |
3417 } else if (deviceNumber != undefined && | |
3418 this.mountPoints_[deviceNumber].mountCondition == | |
3419 'unsupported_filesystem') { | |
3420 return this.showButter(str('UNSUPPORTED_FILESYSTEM_WARNING')); | |
3421 } else { | |
3422 return this.directoryModel_.changeDirectory(entry.fullPath); | 3466 return this.directoryModel_.changeDirectory(entry.fullPath); |
3423 } | 3467 |
| 3468 // If we are under gdata search path, the real entries file path may be |
| 3469 // different from |entry.fullPath|. |
| 3470 var self = this; |
| 3471 chrome.fileBrowserPrivate.getPathForDriveSearchResult(entry.toURL(), |
| 3472 function(path) { |
| 3473 // |path| may be undefined if there was an error. If that is the case, |
| 3474 // change to the original file path. |
| 3475 var changeToPath = path; |
| 3476 self.directoryModel_.changeDirectory(changeToPath); |
| 3477 }); |
3424 }; | 3478 }; |
3425 | 3479 |
3426 /** | 3480 /** |
3427 * Show or hide the "Low disk space" warning. | 3481 * Show or hide the "Low disk space" warning. |
3428 * @param {boolean} show True if the box need to be shown. | 3482 * @param {boolean} show True if the box need to be shown. |
3429 */ | 3483 */ |
3430 FileManager.prototype.showLowDiskSpaceWarning_ = function(show) { | 3484 FileManager.prototype.showLowDiskSpaceWarning_ = function(show) { |
3431 var box = this.dialogDom_.querySelector('.downloads-warning'); | 3485 var box = this.dialogDom_.querySelector('.downloads-warning'); |
3432 if (show) { | 3486 if (show) { |
3433 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); | 3487 var html = util.htmlUnescape(str('DOWNLOADS_DIRECTORY_WARNING')); |
(...skipping 30 matching lines...) Expand all Loading... |
3464 /** | 3518 /** |
3465 * Update the tab title. | 3519 * Update the tab title. |
3466 */ | 3520 */ |
3467 FileManager.prototype.updateTitle_ = function() { | 3521 FileManager.prototype.updateTitle_ = function() { |
3468 this.document_.title = this.getCurrentDirectory().substr(1).replace( | 3522 this.document_.title = this.getCurrentDirectory().substr(1).replace( |
3469 new RegExp('^' + DirectoryModel.GDATA_DIRECTORY), | 3523 new RegExp('^' + DirectoryModel.GDATA_DIRECTORY), |
3470 str('GDATA_PRODUCT_NAME')); | 3524 str('GDATA_PRODUCT_NAME')); |
3471 }, | 3525 }, |
3472 | 3526 |
3473 /** | 3527 /** |
| 3528 * Updates search box value when directory gets changed. |
| 3529 */ |
| 3530 FileManager.prototype.updateSearchBoxOnDirChange_ = function() { |
| 3531 var searchBox = this.dialogDom_.querySelector('#search-box'); |
| 3532 if (!searchBox.disabled) |
| 3533 searchBox.value = ''; |
| 3534 }, |
| 3535 |
| 3536 /** |
3474 * Update the UI when the current directory changes. | 3537 * Update the UI when the current directory changes. |
3475 * | 3538 * |
3476 * @param {cr.Event} event The directory-changed event. | 3539 * @param {cr.Event} event The directory-changed event. |
3477 */ | 3540 */ |
3478 FileManager.prototype.onDirectoryChanged_ = function(event) { | 3541 FileManager.prototype.onDirectoryChanged_ = function(event) { |
3479 this.updateCommonActionButtons_(); | 3542 this.updateCommonActionButtons_(); |
3480 this.updateOkButton_(); | 3543 this.updateOkButton_(); |
3481 this.updateBreadcrumbs_(); | 3544 this.updateBreadcrumbs_(); |
3482 this.updateColumnModel_(); | 3545 this.updateColumnModel_(); |
| 3546 this.updateSearchBoxOnDirChange_(); |
3483 | 3547 |
3484 // Sometimes we rescan the same directory (when mounting GData lazily first, | 3548 // Sometimes we rescan the same directory (when mounting GData lazily first, |
3485 // then for real). Do not update the location then. | 3549 // then for real). Do not update the location then. |
3486 if (event.newDirEntry.fullPath != event.previousDirEntry.fullPath) { | 3550 if (event.newDirEntry.fullPath != event.previousDirEntry.fullPath) { |
3487 this.updateLocation_(event.initial, event.newDirEntry.fullPath); | 3551 this.updateLocation_(event.initial, event.newDirEntry.fullPath); |
3488 } | 3552 } |
3489 | 3553 |
3490 this.checkFreeSpace_(this.getCurrentDirectory()); | 3554 this.checkFreeSpace_(this.getCurrentDirectory()); |
3491 | 3555 |
3492 this.updateTitle_(); | 3556 this.updateTitle_(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3581 if (!result) { | 3645 if (!result) { |
3582 console.log('Failed to remove file watch'); | 3646 console.log('Failed to remove file watch'); |
3583 } | 3647 } |
3584 }); | 3648 }); |
3585 this.watchedDirectoryUrl_ = null; | 3649 this.watchedDirectoryUrl_ = null; |
3586 } | 3650 } |
3587 }; | 3651 }; |
3588 | 3652 |
3589 FileManager.prototype.onFileChanged_ = function(event) { | 3653 FileManager.prototype.onFileChanged_ = function(event) { |
3590 // We receive a lot of events even in folders we are not interested in. | 3654 // We receive a lot of events even in folders we are not interested in. |
3591 if (encodeURI(event.fileUrl) == this.getCurrentDirectoryURL()) | 3655 if (encodeURI(event.fileUrl) == this.getSearchOrCurrentDirectoryURL()) |
3592 this.directoryModel_.rescanLater(); | 3656 this.directoryModel_.rescanLater(); |
3593 }; | 3657 }; |
3594 | 3658 |
3595 FileManager.prototype.initiateRename_ = function() { | 3659 FileManager.prototype.initiateRename_ = function() { |
3596 var item = this.currentList_.ensureLeadItemExists(); | 3660 var item = this.currentList_.ensureLeadItemExists(); |
3597 if (!item) | 3661 if (!item) |
3598 return; | 3662 return; |
3599 var label = item.querySelector('.filename-label'); | 3663 var label = item.querySelector('.filename-label'); |
3600 var input = this.renameInput_; | 3664 var input = this.renameInput_; |
3601 | 3665 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3661 input.validation_ = false; | 3725 input.validation_ = false; |
3662 // Alert dialog restores focus unless the item removed from DOM. | 3726 // Alert dialog restores focus unless the item removed from DOM. |
3663 if (this.document_.activeElement != input) | 3727 if (this.document_.activeElement != input) |
3664 this.cancelRename_(); | 3728 this.cancelRename_(); |
3665 } | 3729 } |
3666 | 3730 |
3667 if (!this.validateFileName_(newName, validationDone.bind(this))) | 3731 if (!this.validateFileName_(newName, validationDone.bind(this))) |
3668 return; | 3732 return; |
3669 | 3733 |
3670 function onError(err) { | 3734 function onError(err) { |
3671 nameNode.textContent = entry.name; | 3735 var entryName = |
3672 this.alert.show(strf('ERROR_RENAMING', entry.name, | 3736 this.directoryModel_.getDisplayName(entry.fullPath, entry.name); |
| 3737 nameNode.textContent = entryName; |
| 3738 this.alert.show(strf('ERROR_RENAMING', entryName, |
3673 getFileErrorString(err.code))); | 3739 getFileErrorString(err.code))); |
3674 } | 3740 } |
3675 | 3741 |
3676 this.cancelRename_(); | 3742 this.cancelRename_(); |
3677 // Optimistically apply new name immediately to avoid flickering in | 3743 // Optimistically apply new name immediately to avoid flickering in |
3678 // case of success. | 3744 // case of success. |
3679 nameNode.textContent = newName; | 3745 nameNode.textContent = newName; |
3680 | 3746 |
3681 this.directoryModel_.doesExist(newName, function(exists, isFile) { | 3747 this.directoryModel_.doesExist(entry, newName, function(exists, isFile) { |
3682 if (!exists) { | 3748 if (!exists) { |
3683 this.directoryModel_.renameEntry(entry, newName, onError.bind(this)); | 3749 this.directoryModel_.renameEntry(entry, newName, onError.bind(this)); |
3684 } else { | 3750 } else { |
3685 nameNode.textContent = entry.name; | 3751 nameNode.textContent = |
| 3752 this.directoryModel_.getDisplayName(entry.fullPath, entry.name); |
3686 var message = isFile ? 'FILE_ALREADY_EXISTS' : | 3753 var message = isFile ? 'FILE_ALREADY_EXISTS' : |
3687 'DIRECTORY_ALREADY_EXISTS'; | 3754 'DIRECTORY_ALREADY_EXISTS'; |
3688 this.alert.show(strf(message, newName)); | 3755 this.alert.show(strf(message, newName)); |
3689 } | 3756 } |
3690 }.bind(this)); | 3757 }.bind(this)); |
3691 }; | 3758 }; |
3692 | 3759 |
3693 FileManager.prototype.cancelRename_ = function() { | 3760 FileManager.prototype.cancelRename_ = function() { |
3694 this.renameInput_.currentEntry = null; | 3761 this.renameInput_.currentEntry = null; |
3695 | 3762 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4043 } | 4110 } |
4044 this.onUnload_(); | 4111 this.onUnload_(); |
4045 window.close(); | 4112 window.close(); |
4046 }; | 4113 }; |
4047 | 4114 |
4048 /** | 4115 /** |
4049 * Tries to close this modal dialog with some files selected. | 4116 * Tries to close this modal dialog with some files selected. |
4050 * Performs preprocessing if needed (e.g. for GData). | 4117 * Performs preprocessing if needed (e.g. for GData). |
4051 * @param {Object} selection Contains urls, filterIndex and multiple fields. | 4118 * @param {Object} selection Contains urls, filterIndex and multiple fields. |
4052 */ | 4119 */ |
4053 FileManager.prototype.selectFilesAndClose_ = function(selection) { | 4120 FileManager.prototype.doSelectFilesAndClose_ = function(selection) { |
4054 if (!this.isOnGData()) { | 4121 if (!this.isOnGData()) { |
4055 setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0); | 4122 setTimeout(this.callSelectFilesApiAndClose_.bind(this, selection), 0); |
4056 return; | 4123 return; |
4057 } | 4124 } |
4058 | 4125 |
4059 var shade = this.document_.createElement('div'); | 4126 var shade = this.document_.createElement('div'); |
4060 shade.className = 'shade'; | 4127 shade.className = 'shade'; |
4061 var footer = this.document_.querySelector('.dialog-footer'); | 4128 var footer = this.document_.querySelector('.dialog-footer'); |
4062 var progress = footer.querySelector('.progress-track'); | 4129 var progress = footer.querySelector('.progress-track'); |
4063 progress.style.width = '0%'; | 4130 progress.style.width = '0%'; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4145 } | 4212 } |
4146 } | 4213 } |
4147 this.resolveSelectResults_(selection.urls, onResolved); | 4214 this.resolveSelectResults_(selection.urls, onResolved); |
4148 }.bind(this); | 4215 }.bind(this); |
4149 | 4216 |
4150 setup(); | 4217 setup(); |
4151 this.metadataCache_.get(selection.urls, 'gdata', onProperties); | 4218 this.metadataCache_.get(selection.urls, 'gdata', onProperties); |
4152 }; | 4219 }; |
4153 | 4220 |
4154 /** | 4221 /** |
| 4222 * Does selection urls list preprocessing and calls |doSelectFilesAndClose_|. |
| 4223 * |
| 4224 * @param {Object} selection Contains urls, filterIndex and multiple fields. |
| 4225 */ |
| 4226 FileManager.prototype.selectFilesAndClose_ = function(selection) { |
| 4227 if (this.directoryModel_.isOnGDataSearchDir()) { |
| 4228 var self = this; |
| 4229 var gdataRootUrl = this.directoryModel_.getCurrentRootDirEntry().toURL(); |
| 4230 util.resolveGDataSearchUrls(selection.urls, gdataRootUrl, |
| 4231 function(resolved) { |
| 4232 selection.urls = resolved; |
| 4233 self.doSelectFilesAndClose_(selection); |
| 4234 }); |
| 4235 return; |
| 4236 } |
| 4237 this.doSelectFilesAndClose_(selection); |
| 4238 }; |
| 4239 |
| 4240 /** |
4155 * Handle a click of the ok button. | 4241 * Handle a click of the ok button. |
4156 * | 4242 * |
4157 * The ok button has different UI labels depending on the type of dialog, but | 4243 * The ok button has different UI labels depending on the type of dialog, but |
4158 * in code it's always referred to as 'ok'. | 4244 * in code it's always referred to as 'ok'. |
4159 * | 4245 * |
4160 * @param {Event} event The click event. | 4246 * @param {Event} event The click event. |
4161 */ | 4247 */ |
4162 FileManager.prototype.onOk_ = function(event) { | 4248 FileManager.prototype.onOk_ = function(event) { |
4163 var currentDirUrl = this.getCurrentDirectoryURL(); | 4249 var currentDirUrl = this.getSearchOrCurrentDirectoryURL(); |
4164 | 4250 |
4165 if (currentDirUrl.charAt(currentDirUrl.length - 1) != '/') | 4251 if (currentDirUrl.charAt(currentDirUrl.length - 1) != '/') |
4166 currentDirUrl += '/'; | 4252 currentDirUrl += '/'; |
4167 | 4253 |
4168 var self = this; | 4254 var self = this; |
4169 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 4255 if (this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
4170 // Save-as doesn't require a valid selection from the list, since | 4256 // Save-as doesn't require a valid selection from the list, since |
4171 // we're going to take the filename from the text input. | 4257 // we're going to take the filename from the text input. |
4172 var filename = this.filenameInput_.value; | 4258 var filename = this.filenameInput_.value; |
4173 if (!filename) | 4259 if (!filename) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4215 throw new Error('Nothing selected!'); | 4301 throw new Error('Nothing selected!'); |
4216 | 4302 |
4217 var dm = this.directoryModel_.getFileList(); | 4303 var dm = this.directoryModel_.getFileList(); |
4218 for (var i = 0; i < selectedIndexes.length; i++) { | 4304 for (var i = 0; i < selectedIndexes.length; i++) { |
4219 var entry = dm.item(selectedIndexes[i]); | 4305 var entry = dm.item(selectedIndexes[i]); |
4220 if (!entry) { | 4306 if (!entry) { |
4221 console.log('Error locating selected file at index: ' + i); | 4307 console.log('Error locating selected file at index: ' + i); |
4222 continue; | 4308 continue; |
4223 } | 4309 } |
4224 | 4310 |
4225 files.push(currentDirUrl + encodeURIComponent(entry.name)); | 4311 files.push(entry.toURL()); |
4226 } | 4312 } |
4227 | 4313 |
4228 // Multi-file selection has no other restrictions. | 4314 // Multi-file selection has no other restrictions. |
4229 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_MULTI_FILE) { | 4315 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_MULTI_FILE) { |
4230 var multipleSelection = { | 4316 var multipleSelection = { |
4231 urls: files, | 4317 urls: files, |
4232 multiple: true | 4318 multiple: true |
4233 }; | 4319 }; |
4234 this.selectFilesAndClose_(multipleSelection); | 4320 this.selectFilesAndClose_(multipleSelection); |
4235 return; | 4321 return; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4360 else | 4446 else |
4361 event.target.removeAttribute('checked'); | 4447 event.target.removeAttribute('checked'); |
4362 | 4448 |
4363 var changeInfo = {}; | 4449 var changeInfo = {}; |
4364 changeInfo[pref] = inverted ? !newValue : newValue; | 4450 changeInfo[pref] = inverted ? !newValue : newValue; |
4365 chrome.fileBrowserPrivate.setGDataPreferences(changeInfo); | 4451 chrome.fileBrowserPrivate.setGDataPreferences(changeInfo); |
4366 }; | 4452 }; |
4367 | 4453 |
4368 FileManager.prototype.onSearchBoxUpdate_ = function(event) { | 4454 FileManager.prototype.onSearchBoxUpdate_ = function(event) { |
4369 var searchString = this.document_.getElementById('search-box').value; | 4455 var searchString = this.document_.getElementById('search-box').value; |
4370 var searchStringLC = searchString.toLowerCase(); | |
4371 var noResultsDiv = this.document_.getElementById('no-search-results'); | 4456 var noResultsDiv = this.document_.getElementById('no-search-results'); |
4372 if (searchString) { | |
4373 this.directoryModel_.addFilter( | |
4374 'searchbox', | |
4375 function(e) { | |
4376 return e.name.toLowerCase().indexOf(searchStringLC) > -1; | |
4377 }); | |
4378 | 4457 |
4379 this.reportEmptySearchResults_ = function() { | 4458 function reportEmptySearchResults() { |
4380 if (this.directoryModel_.getFileList().length === 0) { | 4459 if (this.directoryModel_.getFileList().length === 0) { |
4381 var text = strf('SEARCH_NO_MATCHING_FILES', searchString); | 4460 var text = strf('SEARCH_NO_MATCHING_FILES', searchString); |
4382 noResultsDiv.innerHTML = text; | 4461 noResultsDiv.innerHTML = text; |
4383 noResultsDiv.hidden = false; | 4462 noResultsDiv.hidden = false; |
4384 } | 4463 } else { |
4385 }.bind(this); | 4464 noResultsDiv.hidden = true; |
| 4465 } |
| 4466 } |
4386 | 4467 |
4387 this.directoryModel_.addEventListener( | 4468 function hideNoResultsDiv() { |
4388 'rescan-completed', this.reportEmptySearchResults_); | |
4389 } else { | |
4390 this.directoryModel_.removeFilter('searchbox'); | |
4391 noResultsDiv.hidden = true; | 4469 noResultsDiv.hidden = true; |
4392 this.directoryModel_.removeEventListener( | |
4393 'rescan-completed', this.reportEmptySearchResults_); | |
4394 } | 4470 } |
| 4471 |
| 4472 this.directoryModel_.search(searchString, |
| 4473 reportEmptySearchResults.bind(this), |
| 4474 hideNoResultsDiv.bind(this)); |
4395 }; | 4475 }; |
4396 | 4476 |
4397 FileManager.prototype.decorateSplitter = function(splitterElement) { | 4477 FileManager.prototype.decorateSplitter = function(splitterElement) { |
4398 var self = this; | 4478 var self = this; |
4399 | 4479 |
4400 var Splitter = cr.ui.Splitter; | 4480 var Splitter = cr.ui.Splitter; |
4401 | 4481 |
4402 var customSplitter = cr.ui.define('div'); | 4482 var customSplitter = cr.ui.define('div'); |
4403 | 4483 |
4404 customSplitter.prototype = { | 4484 customSplitter.prototype = { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4546 | 4626 |
4547 function closeBanner() { | 4627 function closeBanner() { |
4548 self.cleanupGDataWelcome_(); | 4628 self.cleanupGDataWelcome_(); |
4549 // Stop showing the welcome banner. | 4629 // Stop showing the welcome banner. |
4550 localStorage[WELCOME_HEADER_COUNTER_KEY] = WELCOME_HEADER_COUNTER_LIMIT; | 4630 localStorage[WELCOME_HEADER_COUNTER_KEY] = WELCOME_HEADER_COUNTER_LIMIT; |
4551 } | 4631 } |
4552 | 4632 |
4553 return maybeShowBanner; | 4633 return maybeShowBanner; |
4554 }; | 4634 }; |
4555 })(); | 4635 })(); |
OLD | NEW |