apps_search_results_model_bridge.mm revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import "ui/app_list/cocoa/apps_search_results_model_bridge.h" 6 7#import <Cocoa/Cocoa.h> 8 9#include "base/strings/sys_string_conversions.h" 10#include "ui/app_list/app_list_model.h" 11#import "ui/app_list/cocoa/apps_search_results_controller.h" 12#include "ui/app_list/search_result.h" 13#include "ui/app_list/search_result_observer.h" 14#import "ui/base/cocoa/menu_controller.h" 15 16namespace app_list { 17 18class AppsSearchResultsModelBridge::ItemObserver : public SearchResultObserver { 19 public: 20 ItemObserver(AppsSearchResultsModelBridge* bridge, size_t index) 21 : bridge_(bridge), row_in_view_(index) { 22 // Cache the result, because the results array is updated before notifying 23 // observers (which happens before deleting the SearchResult). 24 result_ = [bridge_->parent_ results]->GetItemAt(index); 25 result_->AddObserver(this); 26 } 27 28 virtual ~ItemObserver() { 29 result_->RemoveObserver(this); 30 } 31 32 NSMenu* GetContextMenu() { 33 if (!context_menu_controller_) { 34 context_menu_controller_.reset( 35 [[MenuController alloc] initWithModel:result_->GetContextMenuModel() 36 useWithPopUpButtonCell:NO]); 37 } 38 return [context_menu_controller_ menu]; 39 } 40 41 // SearchResultObserver overrides: 42 virtual void OnIconChanged() OVERRIDE { 43 bridge_->ReloadDataForItems(row_in_view_, 1); 44 } 45 virtual void OnActionsChanged() OVERRIDE {} 46 virtual void OnIsInstallingChanged() OVERRIDE {} 47 virtual void OnPercentDownloadedChanged() OVERRIDE {} 48 virtual void OnItemInstalled() OVERRIDE {} 49 virtual void OnItemUninstalled() OVERRIDE; 50 51 private: 52 AppsSearchResultsModelBridge* bridge_; // Weak. Owns us. 53 SearchResult* result_; // Weak. Owned by AppListModel::SearchResults. 54 size_t row_in_view_; 55 base::scoped_nsobject<MenuController> context_menu_controller_; 56 57 DISALLOW_COPY_AND_ASSIGN(ItemObserver); 58}; 59 60void AppsSearchResultsModelBridge::ItemObserver::OnItemUninstalled() { 61 // Performing the search again will destroy |this|, so post a task. This also 62 // ensures that the AppSearchProvider has observed the uninstall before 63 // performing the search again, otherwise it will provide a NULL result. 64 [[bridge_->parent_ delegate] performSelector:@selector(redoSearch) 65 withObject:nil 66 afterDelay:0]; 67} 68 69AppsSearchResultsModelBridge::AppsSearchResultsModelBridge( 70 AppsSearchResultsController* results_controller) 71 : parent_(results_controller) { 72 UpdateItemObservers(); 73 [parent_ results]->AddObserver(this); 74} 75 76AppsSearchResultsModelBridge::~AppsSearchResultsModelBridge() { 77 [parent_ results]->RemoveObserver(this); 78} 79 80NSMenu* AppsSearchResultsModelBridge::MenuForItem(size_t index) { 81 DCHECK_LT(index, item_observers_.size()); 82 return item_observers_[index]->GetContextMenu(); 83} 84 85void AppsSearchResultsModelBridge::UpdateItemObservers() { 86 DCHECK(item_observers_.empty()); 87 const size_t itemCount = [parent_ results]->item_count(); 88 for (size_t i = 0 ; i < itemCount; ++i) 89 item_observers_.push_back(new ItemObserver(this, i)); 90} 91 92void AppsSearchResultsModelBridge::ReloadDataForItems( 93 size_t start, size_t count) const { 94 NSIndexSet* column = [NSIndexSet indexSetWithIndex:0]; 95 NSIndexSet* rows = 96 [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(start, count)]; 97 [[parent_ tableView] reloadDataForRowIndexes:rows 98 columnIndexes:column]; 99} 100 101void AppsSearchResultsModelBridge::ListItemsAdded( 102 size_t start, size_t count) { 103 item_observers_.clear(); 104 if (start == static_cast<size_t>([[parent_ tableView] numberOfRows])) 105 [[parent_ tableView] noteNumberOfRowsChanged]; 106 else 107 [[parent_ tableView] reloadData]; 108 UpdateItemObservers(); 109} 110 111void AppsSearchResultsModelBridge::ListItemsRemoved( 112 size_t start, size_t count) { 113 item_observers_.clear(); 114 if (start == [parent_ results]->item_count()) 115 [[parent_ tableView] noteNumberOfRowsChanged]; 116 else 117 [[parent_ tableView] reloadData]; 118 UpdateItemObservers(); 119} 120 121void AppsSearchResultsModelBridge::ListItemMoved( 122 size_t index, size_t target_index) { 123 NOTREACHED(); 124} 125 126void AppsSearchResultsModelBridge::ListItemsChanged( 127 size_t start, size_t count) { 128 item_observers_.clear(); 129 ReloadDataForItems(start, count); 130 UpdateItemObservers(); 131} 132 133} // namespace app_list 134