| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 12 matching lines...) Expand all Loading... |
| 23 * end with a trailing slash if it represents a directory. | 23 * end with a trailing slash if it represents a directory. |
| 24 */ | 24 */ |
| 25 function FileManager(dialogDom, rootEntries, params) { | 25 function FileManager(dialogDom, rootEntries, params) { |
| 26 console.log('Init FileManager: ' + dialogDom); | 26 console.log('Init FileManager: ' + dialogDom); |
| 27 | 27 |
| 28 this.dialogDom_ = dialogDom; | 28 this.dialogDom_ = dialogDom; |
| 29 this.rootEntries_ = rootEntries; | 29 this.rootEntries_ = rootEntries; |
| 30 this.filesystem_ = rootEntries[0].filesystem; | 30 this.filesystem_ = rootEntries[0].filesystem; |
| 31 this.params_ = params || {}; | 31 this.params_ = params || {}; |
| 32 | 32 |
| 33 this.listType_ = null; |
| 34 |
| 33 this.document_ = dialogDom.ownerDocument; | 35 this.document_ = dialogDom.ownerDocument; |
| 34 this.dialogType_ = | 36 this.dialogType_ = |
| 35 this.params_.type || FileManager.DialogType.FULL_PAGE; | 37 this.params_.type || FileManager.DialogType.FULL_PAGE; |
| 36 | 38 |
| 37 this.defaultPath_ = this.params_.defaultPath || '/'; | 39 this.defaultPath_ = this.params_.defaultPath || '/'; |
| 38 | 40 |
| 39 // DirectoryEntry representing the current directory of the dialog. | 41 // DirectoryEntry representing the current directory of the dialog. |
| 40 this.currentDirEntry_ = null; | 42 this.currentDirEntry_ = null; |
| 41 | 43 |
| 42 this.addEventListener('directory-changed', | 44 this.addEventListener('directory-changed', |
| 43 this.onDirectoryChanged_.bind(this)); | 45 this.onDirectoryChanged_.bind(this)); |
| 44 this.addEventListener('selection-summarized', | 46 this.addEventListener('selection-summarized', |
| 45 this.onSelectionSummarized_.bind(this)); | 47 this.onSelectionSummarized_.bind(this)); |
| 46 | 48 |
| 47 this.initDom_(); | 49 this.initDom_(); |
| 48 this.initDialogType_(); | 50 this.initDialogType_(); |
| 49 | 51 |
| 50 this.onDetailSelectionChanged_(); | 52 this.onDetailSelectionChanged_(); |
| 51 | 53 |
| 52 chrome.fileBrowserPrivate.onDiskChanged.addListener( | 54 chrome.fileBrowserPrivate.onDiskChanged.addListener( |
| 53 this.onDiskChanged_.bind(this)); | 55 this.onDiskChanged_.bind(this)); |
| 54 | 56 |
| 55 this.table.querySelector('.list').focus(); | 57 // TODO(rginda) Add a focus() method to the various list classes to take care |
| 58 // of this. |
| 59 // this.currentList_.list_.focus(); |
| 56 } | 60 } |
| 57 | 61 |
| 58 FileManager.prototype = { | 62 FileManager.prototype = { |
| 59 __proto__: cr.EventTarget.prototype | 63 __proto__: cr.EventTarget.prototype |
| 60 }; | 64 }; |
| 61 | 65 |
| 62 // Anonymous "namespace". | 66 // Anonymous "namespace". |
| 63 (function() { | 67 (function() { |
| 64 | 68 |
| 65 // Private variables and helper functions. | 69 // Private variables and helper functions. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 } | 143 } |
| 140 | 144 |
| 141 /** | 145 /** |
| 142 * Get the icon type for a given Entry. | 146 * Get the icon type for a given Entry. |
| 143 * | 147 * |
| 144 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). | 148 * @param {Entry} entry An Entry subclass (FileEntry or DirectoryEntry). |
| 145 * @return {string} One of the keys from FileManager.iconTypes, or | 149 * @return {string} One of the keys from FileManager.iconTypes, or |
| 146 * 'unknown'. | 150 * 'unknown'. |
| 147 */ | 151 */ |
| 148 function getIconType(entry) { | 152 function getIconType(entry) { |
| 149 if (entry.isDirectory) | 153 if (entry.cachedIconType_) |
| 150 return 'folder'; | 154 return entry.cachedIconType_; |
| 151 | 155 |
| 152 for (var name in iconTypes) { | 156 var rv = 'unknown'; |
| 153 var value = iconTypes[name]; | |
| 154 | 157 |
| 155 if (value instanceof RegExp) { | 158 if (entry.isDirectory) { |
| 156 if (value.test(entry.name)) | 159 rv = 'folder'; |
| 157 return name; | 160 } else { |
| 158 } else if (typeof value == 'function') { | 161 for (var name in iconTypes) { |
| 159 try { | 162 var value = iconTypes[name]; |
| 160 if (value(entry)) | 163 |
| 161 return name; | 164 if (value instanceof RegExp) { |
| 162 } catch (ex) { | 165 if (value.test(entry.name)) { |
| 163 console.error('Caught exception while evaluating iconType: ' + | 166 rv = name; |
| 164 name, ex); | 167 break; |
| 168 } |
| 169 } else if (typeof value == 'function') { |
| 170 try { |
| 171 if (value(entry)) { |
| 172 rv = name; |
| 173 break; |
| 174 } |
| 175 } catch (ex) { |
| 176 console.error('Caught exception while evaluating iconType: ' + |
| 177 name, ex); |
| 178 } |
| 179 } else { |
| 180 console.log('Unexpected value in iconTypes[' + name + ']: ' + value); |
| 165 } | 181 } |
| 166 } else { | |
| 167 console.log('Unexpected value in iconTypes[' + name + ']: ' + value); | |
| 168 } | 182 } |
| 169 } | 183 } |
| 170 | 184 |
| 171 return 'unknown'; | 185 entry.cachedIconType_ = rv; |
| 186 return rv; |
| 172 } | 187 } |
| 173 | 188 |
| 174 /** | 189 /** |
| 175 * Call an asynchronous method on dirEntry, batching multiple callers. | 190 * Call an asynchronous method on dirEntry, batching multiple callers. |
| 176 * | 191 * |
| 177 * This batches multiple callers into a single invocation, calling all | 192 * This batches multiple callers into a single invocation, calling all |
| 178 * interested parties back when the async call completes. | 193 * interested parties back when the async call completes. |
| 179 * | 194 * |
| 180 * The Entry method to be invoked should take two callbacks as parameters | 195 * The Entry method to be invoked should take two callbacks as parameters |
| 181 * (one for success and one for failure), and it should invoke those | 196 * (one for success and one for failure), and it should invoke those |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 * | 336 * |
| 322 * The successCallback is always invoked synchronously, since this does not | 337 * The successCallback is always invoked synchronously, since this does not |
| 323 * actually require an async call. You should not depend on this, as it may | 338 * actually require an async call. You should not depend on this, as it may |
| 324 * change if we were to start reading magic numbers (for example). | 339 * change if we were to start reading magic numbers (for example). |
| 325 * | 340 * |
| 326 * @param {Entry} entry An HTML5 Entry object. | 341 * @param {Entry} entry An HTML5 Entry object. |
| 327 * @param {function(Entry)} successCallback The function to invoke once the | 342 * @param {function(Entry)} successCallback The function to invoke once the |
| 328 * icon type is known. | 343 * icon type is known. |
| 329 */ | 344 */ |
| 330 function cacheEntryIconType(entry, successCallback) { | 345 function cacheEntryIconType(entry, successCallback) { |
| 331 entry.cachedIconType_ = getIconType(entry); | 346 getIconType(entry); |
| 332 if (successCallback) | 347 if (successCallback) |
| 333 setTimeout(function() { successCallback(entry) }, 0); | 348 setTimeout(function() { successCallback(entry) }, 0); |
| 334 } | 349 } |
| 335 | 350 |
| 336 // Public statics. | 351 // Public statics. |
| 337 | 352 |
| 338 /** | 353 /** |
| 339 * List of dialog types. | 354 * List of dialog types. |
| 340 * | 355 * |
| 341 * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except | 356 * Keep this in sync with FileManagerDialog::GetDialogTypeAsString, except |
| 342 * FULL_PAGE which is specific to this code. | 357 * FULL_PAGE which is specific to this code. |
| 343 * | 358 * |
| 344 * @enum {string} | 359 * @enum {string} |
| 345 */ | 360 */ |
| 346 FileManager.DialogType = { | 361 FileManager.DialogType = { |
| 347 SELECT_FOLDER: 'folder', | 362 SELECT_FOLDER: 'folder', |
| 348 SELECT_SAVEAS_FILE: 'saveas-file', | 363 SELECT_SAVEAS_FILE: 'saveas-file', |
| 349 SELECT_OPEN_FILE: 'open-file', | 364 SELECT_OPEN_FILE: 'open-file', |
| 350 SELECT_OPEN_MULTI_FILE: 'open-multi-file', | 365 SELECT_OPEN_MULTI_FILE: 'open-multi-file', |
| 351 FULL_PAGE: 'full-page' | 366 FULL_PAGE: 'full-page' |
| 352 }; | 367 }; |
| 353 | 368 |
| 369 FileManager.ListType = { |
| 370 DETAIL: 'detail', |
| 371 THUMBNAIL: 'thumb' |
| 372 }; |
| 373 |
| 354 /** | 374 /** |
| 355 * Load translated strings. | 375 * Load translated strings. |
| 356 */ | 376 */ |
| 357 FileManager.initStrings = function(callback) { | 377 FileManager.initStrings = function(callback) { |
| 358 chrome.fileBrowserPrivate.getStrings(function(strings) { | 378 chrome.fileBrowserPrivate.getStrings(function(strings) { |
| 359 localStrings = new LocalStrings(strings); | 379 localStrings = new LocalStrings(strings); |
| 360 cr.initLocale(strings); | 380 cr.initLocale(strings); |
| 361 | 381 |
| 362 if (callback) | 382 if (callback) |
| 363 callback(); | 383 callback(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 var ary = this.dialogDom_.querySelectorAll('[visibleif]'); | 417 var ary = this.dialogDom_.querySelectorAll('[visibleif]'); |
| 398 for (var i = 0; i < ary.length; i++) { | 418 for (var i = 0; i < ary.length; i++) { |
| 399 var expr = ary[i].getAttribute('visibleif'); | 419 var expr = ary[i].getAttribute('visibleif'); |
| 400 if (!eval(expr)) | 420 if (!eval(expr)) |
| 401 ary[i].style.display = 'none'; | 421 ary[i].style.display = 'none'; |
| 402 } | 422 } |
| 403 | 423 |
| 404 // Populate the static localized strings. | 424 // Populate the static localized strings. |
| 405 i18nTemplate.process(this.document_, localStrings.templateData); | 425 i18nTemplate.process(this.document_, localStrings.templateData); |
| 406 | 426 |
| 407 // Set up the detail table. | 427 this.dataModel_ = new cr.ui.table.TableDataModel([]); |
| 408 var dataModel = new cr.ui.table.TableDataModel([]); | 428 this.dataModel_.sort('name'); |
| 409 dataModel.sort('name'); | 429 this.dataModel_.addEventListener('sorted', |
| 410 dataModel.addEventListener('sorted', | 430 this.onDataModelSorted_.bind(this)); |
| 411 this.onDataModelSorted_.bind(this)); | 431 this.dataModel_.prepareSort = this.prepareSort_.bind(this); |
| 412 dataModel.prepareSort = this.prepareSort_.bind(this); | |
| 413 | 432 |
| 433 this.initTable_(); |
| 434 this.initGrid_(); |
| 435 |
| 436 this.setListType(FileManager.ListType.DETAIL); |
| 437 |
| 438 this.onResize_(); |
| 439 this.dialogDom_.style.opacity = '1'; |
| 440 }; |
| 441 |
| 442 |
| 443 FileManager.prototype.setListType = function(type) { |
| 444 console.log('set list: ' + type); |
| 445 |
| 446 if (type && type == this.listType_) { |
| 447 console.log('no change: ' + type); |
| 448 return; |
| 449 } |
| 450 |
| 451 if (type == FileManager.ListType.DETAIL) { |
| 452 this.table_.style.display = ''; |
| 453 this.grid_.style.display = 'none'; |
| 454 this.currentList_ = this.table_; |
| 455 this.dialogDom_.querySelector('button.detail-view').disabled = true; |
| 456 this.dialogDom_.querySelector('button.thumbnail-view').disabled = false; |
| 457 } else if (type == FileManager.ListType.THUMBNAIL) { |
| 458 this.grid_.style.display = ''; |
| 459 this.table_.style.display = 'none'; |
| 460 this.currentList_ = this.grid_; |
| 461 this.dialogDom_.querySelector('button.thumbnail-view').disabled = true; |
| 462 this.dialogDom_.querySelector('button.detail-view').disabled = false; |
| 463 } else { |
| 464 throw new Error('Unknown list type: ' + type); |
| 465 } |
| 466 |
| 467 this.listType_ = type; |
| 468 this.onResize_(); |
| 469 this.currentList_.redraw(); |
| 470 |
| 471 console.log('type now: ' + this.listType_); |
| 472 }; |
| 473 |
| 474 /** |
| 475 * Initialize the file thumbnail grid. |
| 476 */ |
| 477 FileManager.prototype.initGrid_ = function() { |
| 478 this.grid_ = this.dialogDom_.querySelector('.thumbnail-grid'); |
| 479 cr.ui.Grid.decorate(this.grid_); |
| 480 this.grid_.dataModel = this.dataModel_; |
| 481 |
| 482 var self = this; |
| 483 this.grid_.itemConstructor = function(entry) { |
| 484 return self.renderThumbnail_(entry); |
| 485 }; |
| 486 |
| 487 if (this.dialogType_ != FileManager.DialogType.SELECT_OPEN_MULTI_FILE) { |
| 488 this.grid_.selectionModel = new cr.ui.ListSingleSelectionModel(); |
| 489 } |
| 490 |
| 491 this.grid_.addEventListener( |
| 492 'dblclick', this.onDetailDoubleClick_.bind(this)); |
| 493 this.grid_.selectionModel.addEventListener( |
| 494 'change', this.onDetailSelectionChanged_.bind(this)); |
| 495 }; |
| 496 |
| 497 /** |
| 498 * Initialize the file list table. |
| 499 */ |
| 500 FileManager.prototype.initTable_ = function() { |
| 414 var columns = [ | 501 var columns = [ |
| 415 new cr.ui.table.TableColumn('cachedIconType_', '', 5.4), | 502 new cr.ui.table.TableColumn('cachedIconType_', '', 5.4), |
| 416 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'), 64), | 503 new cr.ui.table.TableColumn('name', str('NAME_COLUMN_LABEL'), 64), |
| 417 new cr.ui.table.TableColumn('cachedSize_', | 504 new cr.ui.table.TableColumn('cachedSize_', |
| 418 str('SIZE_COLUMN_LABEL'), 15.5), | 505 str('SIZE_COLUMN_LABEL'), 15.5), |
| 419 new cr.ui.table.TableColumn('cachedMtime_', | 506 new cr.ui.table.TableColumn('cachedMtime_', |
| 420 str('DATE_COLUMN_LABEL'), 21) | 507 str('DATE_COLUMN_LABEL'), 21) |
| 421 ]; | 508 ]; |
| 422 | 509 |
| 423 columns[0].renderFunction = this.renderIconType_.bind(this); | 510 columns[0].renderFunction = this.renderIconType_.bind(this); |
| 424 columns[1].renderFunction = this.renderName_.bind(this); | 511 columns[1].renderFunction = this.renderName_.bind(this); |
| 425 columns[2].renderFunction = this.renderSize_.bind(this); | 512 columns[2].renderFunction = this.renderSize_.bind(this); |
| 426 columns[3].renderFunction = this.renderDate_.bind(this); | 513 columns[3].renderFunction = this.renderDate_.bind(this); |
| 427 | 514 |
| 428 this.table = this.dialogDom_.querySelector('.detail-table'); | 515 this.table_ = this.dialogDom_.querySelector('.detail-table'); |
| 429 cr.ui.Table.decorate(this.table); | 516 cr.ui.Table.decorate(this.table_); |
| 430 | 517 |
| 431 this.table.dataModel = dataModel; | 518 this.table_.dataModel = this.dataModel_; |
| 432 this.table.columnModel = new cr.ui.table.TableColumnModel(columns); | 519 this.table_.columnModel = new cr.ui.table.TableColumnModel(columns); |
| 433 | 520 |
| 434 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE || | 521 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE || |
| 435 this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FOLDER || | 522 this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FOLDER || |
| 436 this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { | 523 this.dialogType_ == FileManager.DialogType.SELECT_SAVEAS_FILE) { |
| 437 this.table.selectionModel = new cr.ui.table.TableSingleSelectionModel(); | 524 this.table_.selectionModel = new cr.ui.table.TableSingleSelectionModel(); |
| 438 } | 525 } |
| 439 | 526 |
| 440 this.table.addEventListener( | 527 this.table_.addEventListener( |
| 441 'dblclick', this.onDetailDoubleClick_.bind(this)); | 528 'dblclick', this.onDetailDoubleClick_.bind(this)); |
| 442 this.table.selectionModel.addEventListener( | 529 this.table_.selectionModel.addEventListener( |
| 443 'change', this.onDetailSelectionChanged_.bind(this)); | 530 'change', this.onDetailSelectionChanged_.bind(this)); |
| 444 | |
| 445 this.onResize_(); | |
| 446 this.dialogDom_.style.opacity = '1'; | |
| 447 }; | 531 }; |
| 448 | 532 |
| 449 FileManager.prototype.onResize_ = function() { | 533 FileManager.prototype.onResize_ = function() { |
| 450 // TODO(rginda): Remove this hack when cr.ui.List supports resizing. | 534 console.log('onResize'); |
| 451 this.table.list_.style.height = | 535 |
| 452 (this.table.clientHeight - this.table.header_.clientHeight) + 'px'; | 536 this.table_.style.height = this.grid_.style.height = |
| 453 this.table.redraw(); | 537 this.grid_.parentNode.clientHeight + 'px'; |
| 538 this.table_.style.width = this.grid_.style.width = |
| 539 this.grid_.parentNode.clientWidth + 'px'; |
| 540 |
| 541 this.table_.list_.style.width = this.table_.parentNode.clientWidth + 'px'; |
| 542 this.table_.list_.style.height = (this.table_.clientHeight - 1 - |
| 543 this.table_.header_.clientHeight) + 'px'; |
| 544 |
| 545 if (this.listType_ == FileManager.ListType.THUMBNAIL) { |
| 546 var self = this; |
| 547 setTimeout(function () { self.grid_.columns = 0 }, 100); |
| 548 } else { |
| 549 this.currentList_.redraw(); |
| 550 } |
| 454 }; | 551 }; |
| 455 | 552 |
| 456 /** | 553 /** |
| 457 * Tweak the UI to become a particular kind of dialog, as determined by the | 554 * Tweak the UI to become a particular kind of dialog, as determined by the |
| 458 * dialog type parameter passed to the constructor. | 555 * dialog type parameter passed to the constructor. |
| 459 */ | 556 */ |
| 460 FileManager.prototype.initDialogType_ = function() { | 557 FileManager.prototype.initDialogType_ = function() { |
| 461 var defaultTitle; | 558 var defaultTitle; |
| 462 var okLabel = str('OPEN_LABEL'); | 559 var okLabel = str('OPEN_LABEL'); |
| 463 | 560 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } | 656 } |
| 560 | 657 |
| 561 function checkCount() { | 658 function checkCount() { |
| 562 if (uncachedCount == 0) { | 659 if (uncachedCount == 0) { |
| 563 // Callback via a setTimeout so the sync/async semantics don't change | 660 // Callback via a setTimeout so the sync/async semantics don't change |
| 564 // based on whether or not the value is cached. | 661 // based on whether or not the value is cached. |
| 565 setTimeout(callback, 0); | 662 setTimeout(callback, 0); |
| 566 } | 663 } |
| 567 } | 664 } |
| 568 | 665 |
| 569 var dataModel = this.table.dataModel; | 666 var dataModel = this.dataModel_; |
| 570 var uncachedCount = dataModel.length; | 667 var uncachedCount = dataModel.length; |
| 571 | 668 |
| 572 for (var i = uncachedCount - 1; i >= 0 ; i--) { | 669 for (var i = uncachedCount - 1; i >= 0 ; i--) { |
| 573 var entry = dataModel.item(i); | 670 var entry = dataModel.item(i); |
| 574 if (field in entry) { | 671 if (field in entry) { |
| 575 uncachedCount--; | 672 uncachedCount--; |
| 576 } else { | 673 } else { |
| 577 cacheFunction(entry, function() { | 674 cacheFunction(entry, function() { |
| 578 uncachedCount--; | 675 uncachedCount--; |
| 579 checkCount(); | 676 checkCount(); |
| 580 }); | 677 }); |
| 581 } | 678 } |
| 582 } | 679 } |
| 583 | 680 |
| 584 checkCount(); | 681 checkCount(); |
| 585 } | 682 } |
| 586 | 683 |
| 684 FileManager.prototype.renderThumbnail_ = function(entry) { |
| 685 var li = this.document_.createElement('li'); |
| 686 li.className = 'thumbnail-item'; |
| 687 |
| 688 var img = this.document_.createElement('img'); |
| 689 this.setIconSrc(entry, img); |
| 690 li.appendChild(img); |
| 691 |
| 692 var div = this.document_.createElement('div'); |
| 693 div.textContent = entry.name; |
| 694 li.appendChild(div); |
| 695 |
| 696 cr.defineProperty(li, 'lead', cr.PropertyKind.BOOL_ATTR); |
| 697 cr.defineProperty(li, 'selected', cr.PropertyKind.BOOL_ATTR); |
| 698 |
| 699 return li; |
| 700 } |
| 701 |
| 587 /** | 702 /** |
| 588 * Render the type column of the detail table. | 703 * Render the type column of the detail table. |
| 589 * | 704 * |
| 590 * Invoked by cr.ui.Table when a file needs to be rendered. | 705 * Invoked by cr.ui.Table when a file needs to be rendered. |
| 591 * | 706 * |
| 592 * @param {Entry} entry The Entry object to render. | 707 * @param {Entry} entry The Entry object to render. |
| 593 * @param {string} columnId The id of the column to be rendered. | 708 * @param {string} columnId The id of the column to be rendered. |
| 594 * @param {cr.ui.Table} table The table doing the rendering. | 709 * @param {cr.ui.Table} table The table doing the rendering. |
| 595 */ | 710 */ |
| 596 FileManager.prototype.renderIconType_ = function(entry, columnId, table) { | 711 FileManager.prototype.renderIconType_ = function(entry, columnId, table) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 /** | 795 /** |
| 681 * Compute summary information about the current selection. | 796 * Compute summary information about the current selection. |
| 682 * | 797 * |
| 683 * This method dispatches the 'selection-summarized' event when it completes. | 798 * This method dispatches the 'selection-summarized' event when it completes. |
| 684 * Depending on how many of the selected files already have known sizes, the | 799 * Depending on how many of the selected files already have known sizes, the |
| 685 * dispatch may happen immediately, or after a number of async calls complete. | 800 * dispatch may happen immediately, or after a number of async calls complete. |
| 686 */ | 801 */ |
| 687 FileManager.prototype.summarizeSelection_ = function() { | 802 FileManager.prototype.summarizeSelection_ = function() { |
| 688 var selection = this.selection = { | 803 var selection = this.selection = { |
| 689 entries: [], | 804 entries: [], |
| 690 uris: [], | 805 urls: [], |
| 691 leadEntry: null, | 806 leadEntry: null, |
| 692 totalCount: 0, | 807 totalCount: 0, |
| 693 fileCount: 0, | 808 fileCount: 0, |
| 694 directoryCount: 0, | 809 directoryCount: 0, |
| 695 bytes: 0, | 810 bytes: 0, |
| 696 iconType: null, | 811 iconType: null, |
| 697 }; | 812 }; |
| 698 | 813 |
| 699 this.previewSummary_.textContent = str('COMPUTING_SELECTION'); | 814 this.previewSummary_.textContent = str('COMPUTING_SELECTION'); |
| 700 this.taskButtons_.innerHTML = ''; | 815 this.taskButtons_.innerHTML = ''; |
| 701 | 816 |
| 702 var selectedIndexes = this.table.selectionModel.selectedIndexes; | 817 var selectedIndexes = this.currentList_.selectionModel.selectedIndexes; |
| 703 if (!selectedIndexes.length) { | 818 if (!selectedIndexes.length) { |
| 704 cr.dispatchSimpleEvent(this, 'selection-summarized'); | 819 cr.dispatchSimpleEvent(this, 'selection-summarized'); |
| 705 return; | 820 return; |
| 706 } | 821 } |
| 707 | 822 |
| 708 var fileCount = 0; | 823 var fileCount = 0; |
| 709 var byteCount = 0; | 824 var byteCount = 0; |
| 710 var pendingFiles = []; | 825 var pendingFiles = []; |
| 711 | 826 |
| 712 for (var i = 0; i < selectedIndexes.length; i++) { | 827 for (var i = 0; i < selectedIndexes.length; i++) { |
| 713 var entry = this.table.dataModel.item(selectedIndexes[i]); | 828 var entry = this.dataModel_.item(selectedIndexes[i]); |
| 714 | 829 |
| 715 selection.entries.push(entry); | 830 selection.entries.push(entry); |
| 716 selection.uris.push(entry.toURI()); | 831 |
| 832 selection.urls.push(entry.toURL()); |
| 717 | 833 |
| 718 if (selection.iconType == null) { | 834 if (selection.iconType == null) { |
| 719 selection.iconType = getIconType(entry); | 835 selection.iconType = getIconType(entry); |
| 720 } else if (selection.iconType != 'unknown') { | 836 } else if (selection.iconType != 'unknown') { |
| 721 var iconType = getIconType(entry); | 837 var iconType = getIconType(entry); |
| 722 if (selection.iconType != iconType) | 838 if (selection.iconType != iconType) |
| 723 selection.iconType = 'unknown'; | 839 selection.iconType = 'unknown'; |
| 724 } | 840 } |
| 725 | 841 |
| 726 selection.totalCount++; | 842 selection.totalCount++; |
| 727 | 843 |
| 728 if (entry.isFile) { | 844 if (entry.isFile) { |
| 729 if (!('cachedSize_' in entry)) { | 845 if (!('cachedSize_' in entry)) { |
| 730 // Any file that hasn't been rendered may be missing its cachedSize_ | 846 // Any file that hasn't been rendered may be missing its cachedSize_ |
| 731 // property. For example, visit a large file list, and press ctrl-a | 847 // property. For example, visit a large file list, and press ctrl-a |
| 732 // to select all. In this case, we need to asynchronously get the | 848 // to select all. In this case, we need to asynchronously get the |
| 733 // sizes for these files before telling the world the selection has | 849 // sizes for these files before telling the world the selection has |
| 734 // been summarized. See the 'computeNextFile' logic below. | 850 // been summarized. See the 'computeNextFile' logic below. |
| 735 pendingFiles.push(entry); | 851 pendingFiles.push(entry); |
| 736 continue; | 852 continue; |
| 737 } else { | 853 } else { |
| 738 selection.bytes += entry.cachedSize_; | 854 selection.bytes += entry.cachedSize_; |
| 739 } | 855 } |
| 740 selection.fileCount += 1; | 856 selection.fileCount += 1; |
| 741 } else { | 857 } else { |
| 742 selection.directoryCount += 1; | 858 selection.directoryCount += 1; |
| 743 } | 859 } |
| 744 } | 860 } |
| 745 | 861 |
| 746 var leadIndex = this.table.selectionModel.leadIndex; | 862 var leadIndex = this.currentList_.selectionModel.leadIndex; |
| 747 if (leadIndex > -1) { | 863 if (leadIndex > -1) { |
| 748 selection.leadEntry = this.table.dataModel.item(leadIndex); | 864 selection.leadEntry = this.dataModel_.item(leadIndex); |
| 749 } else { | 865 } else { |
| 750 selection.leadEntry = selection.entries[0]; | 866 selection.leadEntry = selection.entries[0]; |
| 751 } | 867 } |
| 752 | 868 |
| 753 var self = this; | 869 var self = this; |
| 754 | 870 |
| 755 function cacheNextFile(fileEntry) { | 871 function cacheNextFile(fileEntry) { |
| 756 if (fileEntry) { | 872 if (fileEntry) { |
| 757 // We're careful to modify the 'selection', rather than 'self.selection' | 873 // We're careful to modify the 'selection', rather than 'self.selection' |
| 758 // here, just in case the selection has changed since this summarization | 874 // here, just in case the selection has changed since this summarization |
| 759 // began. | 875 // began. |
| 760 selection.bytes += fileEntry.cachedSize_; | 876 selection.bytes += fileEntry.cachedSize_; |
| 761 } | 877 } |
| 762 | 878 |
| 763 if (pendingFiles.length) { | 879 if (pendingFiles.length) { |
| 764 cacheEntrySize(pendingFiles.pop(), cacheNextFile); | 880 cacheEntrySize(pendingFiles.pop(), cacheNextFile); |
| 765 } else { | 881 } else { |
| 766 self.dispatchEvent(new cr.Event('selection-summarized')); | 882 self.dispatchEvent(new cr.Event('selection-summarized')); |
| 767 } | 883 } |
| 768 }; | 884 }; |
| 769 | 885 |
| 770 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { | 886 if (this.dialogType_ == FileManager.DialogType.FULL_PAGE) { |
| 771 chrome.fileBrowserPrivate.getFileTasks(selection.uris, | 887 chrome.fileBrowserPrivate.getFileTasks(selection.urls, |
| 772 this.onTasksFound_.bind(this)); | 888 this.onTasksFound_.bind(this)); |
| 773 } | 889 } |
| 774 | 890 |
| 775 cacheNextFile(); | 891 cacheNextFile(); |
| 776 }; | 892 }; |
| 777 | 893 |
| 778 FileManager.prototype.onTasksFound_ = function(tasksList) { | 894 FileManager.prototype.onTasksFound_ = function(tasksList) { |
| 779 for (var i = 0; i < tasksList.length; i++) { | 895 for (var i = 0; i < tasksList.length; i++) { |
| 780 var task = tasksList[i]; | 896 var task = tasksList[i]; |
| 781 | 897 |
| 782 var button = this.document_.createElement('button'); | 898 var button = this.document_.createElement('button'); |
| 783 button.addEventListener('click', this.onTaskButtonClicked_.bind(this)); | 899 button.addEventListener('click', this.onTaskButtonClicked_.bind(this)); |
| 784 button.className = 'task-button'; | 900 button.className = 'task-button'; |
| 785 button.task = task; | 901 button.task = task; |
| 786 | 902 |
| 787 var img = this.document_.createElement('img'); | 903 var img = this.document_.createElement('img'); |
| 788 img.src = task.iconUrl; | 904 img.src = task.iconUrl; |
| 789 | 905 |
| 790 button.appendChild(img); | 906 button.appendChild(img); |
| 791 button.appendChild(this.document_.createTextNode(task.title)); | 907 button.appendChild(this.document_.createTextNode(task.title)); |
| 792 | 908 |
| 793 this.taskButtons_.appendChild(button); | 909 this.taskButtons_.appendChild(button); |
| 794 } | 910 } |
| 795 }; | 911 }; |
| 796 | 912 |
| 797 FileManager.prototype.onTaskButtonClicked_ = function(event) { | 913 FileManager.prototype.onTaskButtonClicked_ = function(event) { |
| 798 chrome.fileBrowserPrivate.executeTask(event.srcElement.task.taskId, | 914 chrome.fileBrowserPrivate.executeTask(event.srcElement.task.taskId, |
| 799 this.selection.uris); | 915 this.selection.urls); |
| 800 } | 916 } |
| 801 | 917 |
| 802 /** | 918 /** |
| 803 * Update the breadcrumb display to reflect the current directory. | 919 * Update the breadcrumb display to reflect the current directory. |
| 804 */ | 920 */ |
| 805 FileManager.prototype.updateBreadcrumbs_ = function() { | 921 FileManager.prototype.updateBreadcrumbs_ = function() { |
| 806 var bc = this.dialogDom_.querySelector('.breadcrumbs'); | 922 var bc = this.dialogDom_.querySelector('.breadcrumbs'); |
| 807 bc.innerHTML = ''; | 923 bc.innerHTML = ''; |
| 808 | 924 |
| 809 var fullPath = this.currentDirEntry_.fullPath.replace(/\/$/, ''); | 925 var fullPath = this.currentDirEntry_.fullPath.replace(/\/$/, ''); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 this.previewFilename_.textContent = ''; | 976 this.previewFilename_.textContent = ''; |
| 861 return; | 977 return; |
| 862 } | 978 } |
| 863 | 979 |
| 864 var previewName = this.selection.leadEntry.name; | 980 var previewName = this.selection.leadEntry.name; |
| 865 if (this.currentDirEntry_.name == '') | 981 if (this.currentDirEntry_.name == '') |
| 866 previewName = this.getLabelForRootPath_(previewName); | 982 previewName = this.getLabelForRootPath_(previewName); |
| 867 | 983 |
| 868 this.previewFilename_.textContent = previewName; | 984 this.previewFilename_.textContent = previewName; |
| 869 | 985 |
| 870 var entry = this.selection.leadEntry; | 986 var iconType = getIconType(this.selection.leadEntry); |
| 987 if (iconType == 'image') { |
| 988 this.previewImage_.classList.add('transparent-background'); |
| 989 if (fileManager.selection.totalCount > 1) |
| 990 this.previewImage_.classList.add('multiple-selected'); |
| 991 } |
| 992 |
| 993 this.setIconSrc(this.selection.leadEntry, this.previewImage_); |
| 994 |
| 995 }; |
| 996 |
| 997 FileManager.prototype.setIconSrc = function(entry, img, callback) { |
| 871 var iconType = getIconType(entry); | 998 var iconType = getIconType(entry); |
| 872 if (iconType != 'image') { | 999 if (iconType != 'image') { |
| 873 // Not an image, display a canned clip-art graphic. | 1000 // Not an image, display a canned clip-art graphic. |
| 874 this.previewImage_.src = previewArt[iconType]; | 1001 img.src = previewArt[iconType]; |
| 875 } else { | 1002 } else { |
| 876 // File is an image, fetch the thumbnail. | 1003 // File is an image, fetch the thumbnail. |
| 877 | 1004 |
| 878 var fileManager = this; | 1005 img.src = entry.toURL(); |
| 879 | |
| 880 batchAsyncCall(entry, 'file', function(file) { | |
| 881 var reader = new FileReader(); | |
| 882 | |
| 883 reader.onerror = util.ferr('Error reading preview: ' + entry.fullPath); | |
| 884 reader.onloadend = function(e) { | |
| 885 fileManager.previewImage_.src = this.result; | |
| 886 fileManager.previewImage_.classList.add('transparent-background'); | |
| 887 if (fileManager.selection.totalCount > 1) | |
| 888 fileManager.previewImage_.classList.add('multiple-selected'); | |
| 889 }; | |
| 890 | |
| 891 reader.readAsDataURL(file); | |
| 892 }); | |
| 893 } | 1006 } |
| 1007 if (callback) |
| 1008 callback(); |
| 894 }; | 1009 }; |
| 895 | 1010 |
| 896 /** | 1011 /** |
| 897 * Change the current directory. | 1012 * Change the current directory. |
| 898 * | 1013 * |
| 899 * Dispatches the 'directory-changed' event when the directory is successfully | 1014 * Dispatches the 'directory-changed' event when the directory is successfully |
| 900 * changed. | 1015 * changed. |
| 901 * | 1016 * |
| 902 * @param {string} path The absolute path to the new directory. | 1017 * @param {string} path The absolute path to the new directory. |
| 903 */ | 1018 */ |
| (...skipping 28 matching lines...) Expand all Loading... |
| 932 } | 1047 } |
| 933 }); | 1048 }); |
| 934 }; | 1049 }; |
| 935 | 1050 |
| 936 /** | 1051 /** |
| 937 * Invoked by the table dataModel after a sort completes. | 1052 * Invoked by the table dataModel after a sort completes. |
| 938 * | 1053 * |
| 939 * We use this hook to make sure selected files stay visible after a sort. | 1054 * We use this hook to make sure selected files stay visible after a sort. |
| 940 */ | 1055 */ |
| 941 FileManager.prototype.onDataModelSorted_ = function() { | 1056 FileManager.prototype.onDataModelSorted_ = function() { |
| 942 var i = this.table.selectionModel.leadIndex; | 1057 var i = this.currentList_.selectionModel.leadIndex; |
| 943 this.table.scrollIntoView(i); | 1058 this.currentList_.scrollIntoView(i); |
| 944 } | 1059 } |
| 945 | 1060 |
| 946 /** | 1061 /** |
| 947 * Update the selection summary UI when the selection summarization completes. | 1062 * Update the selection summary UI when the selection summarization completes. |
| 948 */ | 1063 */ |
| 949 FileManager.prototype.onSelectionSummarized_ = function() { | 1064 FileManager.prototype.onSelectionSummarized_ = function() { |
| 950 if (this.selection.totalCount == 0) { | 1065 if (this.selection.totalCount == 0) { |
| 951 this.previewSummary_.textContent = str('NOTHING_SELECTED'); | 1066 this.previewSummary_.textContent = str('NOTHING_SELECTED'); |
| 952 | 1067 |
| 953 } else if (this.selection.totalCount == 1) { | 1068 } else if (this.selection.totalCount == 1) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 this.okButton_.disabled = !selectable; | 1120 this.okButton_.disabled = !selectable; |
| 1006 this.updatePreview_(); | 1121 this.updatePreview_(); |
| 1007 }; | 1122 }; |
| 1008 | 1123 |
| 1009 /** | 1124 /** |
| 1010 * Handle a double-click event on an entry in the detail list. | 1125 * Handle a double-click event on an entry in the detail list. |
| 1011 * | 1126 * |
| 1012 * @param {Event} event The click event. | 1127 * @param {Event} event The click event. |
| 1013 */ | 1128 */ |
| 1014 FileManager.prototype.onDetailDoubleClick_ = function(event) { | 1129 FileManager.prototype.onDetailDoubleClick_ = function(event) { |
| 1015 var i = this.table.selectionModel.leadIndex; | 1130 var i = this.currentList_.selectionModel.leadIndex; |
| 1016 var entry = this.table.dataModel.item(i); | 1131 var entry = this.dataModel_.item(i); |
| 1017 | 1132 |
| 1018 if (entry.isDirectory) | 1133 if (entry.isDirectory) |
| 1019 return this.changeDirectory(entry.fullPath); | 1134 return this.changeDirectory(entry.fullPath); |
| 1020 | 1135 |
| 1021 if (!this.okButton_.disabled) | 1136 if (!this.okButton_.disabled) |
| 1022 this.onOk_(); | 1137 this.onOk_(); |
| 1023 | 1138 |
| 1024 }; | 1139 }; |
| 1025 | 1140 |
| 1026 /** | 1141 /** |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1046 * | 1161 * |
| 1047 * @param {function()} opt_callback Optional function to invoke when the | 1162 * @param {function()} opt_callback Optional function to invoke when the |
| 1048 * rescan is complete. | 1163 * rescan is complete. |
| 1049 */ | 1164 */ |
| 1050 FileManager.prototype.rescanDirectory_ = function(opt_callback) { | 1165 FileManager.prototype.rescanDirectory_ = function(opt_callback) { |
| 1051 var self = this; | 1166 var self = this; |
| 1052 var reader; | 1167 var reader; |
| 1053 | 1168 |
| 1054 function onReadSome(entries) { | 1169 function onReadSome(entries) { |
| 1055 if (entries.length == 0) { | 1170 if (entries.length == 0) { |
| 1056 if (self.table.dataModel.sortStatus.field != 'name') | 1171 if (self.dataModel_.sortStatus.field != 'name') |
| 1057 self.table.dataModel.updateIndex(0); | 1172 self.dataModel_.updateIndex(0); |
| 1058 | 1173 |
| 1059 if (opt_callback) | 1174 if (opt_callback) |
| 1060 opt_callback(); | 1175 opt_callback(); |
| 1061 return; | 1176 return; |
| 1062 } | 1177 } |
| 1063 | 1178 |
| 1064 // Splice takes the to-be-spliced-in array as individual parameters, | 1179 // Splice takes the to-be-spliced-in array as individual parameters, |
| 1065 // rather than as an array, so we need to perform some acrobatics... | 1180 // rather than as an array, so we need to perform some acrobatics... |
| 1066 var spliceArgs = [].slice.call(entries); | 1181 var spliceArgs = [].slice.call(entries); |
| 1067 | 1182 |
| 1068 // Hide files that start with a dot ('.'). | 1183 // Hide files that start with a dot ('.'). |
| 1069 // TODO(rginda): User should be able to override this. Support for other | 1184 // TODO(rginda): User should be able to override this. Support for other |
| 1070 // commonly hidden patterns might be nice too. | 1185 // commonly hidden patterns might be nice too. |
| 1071 spliceArgs = spliceArgs.filter(function(e) { | 1186 spliceArgs = spliceArgs.filter(function(e) { |
| 1072 return e.name.substr(0, 1) != '.'; | 1187 return e.name.substr(0, 1) != '.'; |
| 1073 }); | 1188 }); |
| 1074 | 1189 |
| 1075 spliceArgs.unshift(0, 0); // index, deleteCount | 1190 spliceArgs.unshift(0, 0); // index, deleteCount |
| 1076 self.table.dataModel.splice.apply(self.table.dataModel, spliceArgs); | 1191 self.dataModel_.splice.apply(self.dataModel_, spliceArgs); |
| 1077 | 1192 |
| 1078 // Keep reading until entries.length is 0. | 1193 // Keep reading until entries.length is 0. |
| 1079 reader.readEntries(onReadSome); | 1194 reader.readEntries(onReadSome); |
| 1080 }; | 1195 }; |
| 1081 | 1196 |
| 1082 // Clear the table first. | 1197 // Clear the table first. |
| 1083 this.table.dataModel.splice(0, this.table.dataModel.length); | 1198 this.dataModel_.splice(0, this.dataModel_.length); |
| 1084 | 1199 |
| 1085 this.updateBreadcrumbs_(); | 1200 this.updateBreadcrumbs_(); |
| 1086 | 1201 |
| 1087 if (this.currentDirEntry_.fullPath != '/') { | 1202 if (this.currentDirEntry_.fullPath != '/') { |
| 1088 // If not the root directory, just read the contents. | 1203 // If not the root directory, just read the contents. |
| 1089 reader = this.currentDirEntry_.createReader(); | 1204 reader = this.currentDirEntry_.createReader(); |
| 1090 reader.readEntries(onReadSome); | 1205 reader.readEntries(onReadSome); |
| 1091 return; | 1206 return; |
| 1092 } | 1207 } |
| 1093 | 1208 |
| 1094 // Otherwise, use the provided list of root subdirectories, since the | 1209 // Otherwise, use the provided list of root subdirectories, since the |
| 1095 // real local filesystem root directory (the one we use outside the | 1210 // real local filesystem root directory (the one we use outside the |
| 1096 // harness) can't be enumerated yet. | 1211 // harness) can't be enumerated yet. |
| 1097 var spliceArgs = [].slice.call(this.rootEntries_); | 1212 var spliceArgs = [].slice.call(this.rootEntries_); |
| 1098 spliceArgs.unshift(0, 0); // index, deleteCount | 1213 spliceArgs.unshift(0, 0); // index, deleteCount |
| 1099 self.table.dataModel.splice.apply(self.table.dataModel, spliceArgs); | 1214 self.dataModel_.splice.apply(self.dataModel_, spliceArgs); |
| 1100 self.table.dataModel.updateIndex(0); | 1215 self.dataModel_.updateIndex(0); |
| 1101 | 1216 |
| 1102 if (opt_callback) | 1217 if (opt_callback) |
| 1103 opt_callback(); | 1218 opt_callback(); |
| 1104 }; | 1219 }; |
| 1105 | 1220 |
| 1106 FileManager.prototype.onFilenameInputKeyUp_ = function(event) { | 1221 FileManager.prototype.onFilenameInputKeyUp_ = function(event) { |
| 1107 this.okButton_.disabled = this.filenameInput_.value.length == 0; | 1222 this.okButton_.disabled = this.filenameInput_.value.length == 0; |
| 1108 | 1223 |
| 1109 if (event.keyCode == 13 /* Enter */ && !this.okButton_.disabled) | 1224 if (event.keyCode == 13 /* Enter */ && !this.okButton_.disabled) |
| 1110 this.onOk_(); | 1225 this.onOk_(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1138 if (name.indexOf('/') == -1) | 1253 if (name.indexOf('/') == -1) |
| 1139 break; | 1254 break; |
| 1140 | 1255 |
| 1141 alert(strf('ERROR_INVALID_FOLDER_CHARACTER', '/')); | 1256 alert(strf('ERROR_INVALID_FOLDER_CHARACTER', '/')); |
| 1142 } | 1257 } |
| 1143 | 1258 |
| 1144 var self = this; | 1259 var self = this; |
| 1145 | 1260 |
| 1146 function onSuccess(dirEntry) { | 1261 function onSuccess(dirEntry) { |
| 1147 self.rescanDirectory_(function () { | 1262 self.rescanDirectory_(function () { |
| 1148 for (var i = 0; i < self.table.dataModel.length; i++) { | 1263 for (var i = 0; i < self.dataModel_.length; i++) { |
| 1149 if (self.table.dataModel.item(i).name == dirEntry.name) { | 1264 if (self.dataModel_.item(i).name == dirEntry.name) { |
| 1150 self.table.selectionModel.selectedIndex = i; | 1265 self.currentList_.selectionModel.selectedIndex = i; |
| 1151 self.table.scrollIndexIntoView(i); | 1266 self.currentList_.scrollIndexIntoView(i); |
| 1152 self.table.focus(); | 1267 self.currentList_.focus(); |
| 1153 return; | 1268 return; |
| 1154 } | 1269 } |
| 1155 }; | 1270 }; |
| 1156 }); | 1271 }); |
| 1157 } | 1272 } |
| 1158 | 1273 |
| 1159 function onError(err) { | 1274 function onError(err) { |
| 1160 window.alert(strf('ERROR_CREATING_FOLDER', name, | 1275 window.alert(strf('ERROR_CREATING_FOLDER', name, |
| 1161 util.getFileErrorMnemonic(err.code))); | 1276 util.getFileErrorMnemonic(err.code))); |
| 1162 } | 1277 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 var filename = this.filenameInput_.value; | 1344 var filename = this.filenameInput_.value; |
| 1230 if (!filename) | 1345 if (!filename) |
| 1231 throw new Error('Missing filename!'); | 1346 throw new Error('Missing filename!'); |
| 1232 | 1347 |
| 1233 chrome.fileBrowserPrivate.selectFile(currentPath + filename, 0); | 1348 chrome.fileBrowserPrivate.selectFile(currentPath + filename, 0); |
| 1234 window.close(); | 1349 window.close(); |
| 1235 return; | 1350 return; |
| 1236 } | 1351 } |
| 1237 | 1352 |
| 1238 var ary = []; | 1353 var ary = []; |
| 1239 var selectedIndexes = this.table.selectionModel.selectedIndexes; | 1354 var selectedIndexes = this.currentList_.selectionModel.selectedIndexes; |
| 1240 | 1355 |
| 1241 // All other dialog types require at least one selected list item. | 1356 // All other dialog types require at least one selected list item. |
| 1242 // The logic to control whether or not the ok button is enabled should | 1357 // The logic to control whether or not the ok button is enabled should |
| 1243 // prevent us from ever getting here, but we sanity check to be sure. | 1358 // prevent us from ever getting here, but we sanity check to be sure. |
| 1244 if (!selectedIndexes.length) | 1359 if (!selectedIndexes.length) |
| 1245 throw new Error('Nothing selected!'); | 1360 throw new Error('Nothing selected!'); |
| 1246 | 1361 |
| 1247 for (var i = 0; i < selectedIndexes.length; i++) { | 1362 for (var i = 0; i < selectedIndexes.length; i++) { |
| 1248 var entry = this.table.dataModel.item(selectedIndexes[i]); | 1363 var entry = this.dataModel_.item(selectedIndexes[i]); |
| 1249 if (!entry) { | 1364 if (!entry) { |
| 1250 console.log('Error locating selected file at index: ' + i); | 1365 console.log('Error locating selected file at index: ' + i); |
| 1251 continue; | 1366 continue; |
| 1252 } | 1367 } |
| 1253 | 1368 |
| 1254 ary.push(currentPath + entry.name); | 1369 ary.push(currentPath + entry.name); |
| 1255 } | 1370 } |
| 1256 | 1371 |
| 1257 // Multi-file selection has no other restrictions. | 1372 // Multi-file selection has no other restrictions. |
| 1258 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_MULTI_FILE) { | 1373 if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_MULTI_FILE) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1271 } else if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE) { | 1386 } else if (this.dialogType_ == FileManager.DialogType.SELECT_OPEN_FILE) { |
| 1272 if (!this.selection.leadEntry.isFile) | 1387 if (!this.selection.leadEntry.isFile) |
| 1273 throw new Error('Selected entry is not a file!'); | 1388 throw new Error('Selected entry is not a file!'); |
| 1274 } | 1389 } |
| 1275 | 1390 |
| 1276 chrome.fileBrowserPrivate.selectFile(ary[0], 0); | 1391 chrome.fileBrowserPrivate.selectFile(ary[0], 0); |
| 1277 window.close(); | 1392 window.close(); |
| 1278 }; | 1393 }; |
| 1279 | 1394 |
| 1280 })(); | 1395 })(); |
| OLD | NEW |