Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / app_list / cocoa / apps_search_results_model_bridge.mm
blob69a3205ef06bde137fa4495cb440776b61d1d066
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.
5 #import "ui/app_list/cocoa/apps_search_results_model_bridge.h"
7 #import <Cocoa/Cocoa.h>
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"
16 namespace app_list {
18 class 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   }
28   virtual ~ItemObserver() {
29     result_->RemoveObserver(this);
30   }
32   NSMenu* GetContextMenu() {
33     if (!context_menu_controller_) {
34       ui::MenuModel* menu_model = result_->GetContextMenuModel();
35       if (!menu_model)
36         return nil;
38       context_menu_controller_.reset(
39           [[MenuController alloc] initWithModel:menu_model
40                          useWithPopUpButtonCell:NO]);
41     }
42     return [context_menu_controller_ menu];
43   }
45   // SearchResultObserver overrides:
46   virtual void OnIconChanged() OVERRIDE {
47     bridge_->ReloadDataForItems(row_in_view_, 1);
48   }
49   virtual void OnActionsChanged() OVERRIDE {}
50   virtual void OnIsInstallingChanged() OVERRIDE {}
51   virtual void OnPercentDownloadedChanged() OVERRIDE {}
52   virtual void OnItemInstalled() OVERRIDE {}
53   virtual void OnItemUninstalled() OVERRIDE;
55  private:
56   AppsSearchResultsModelBridge* bridge_;  // Weak. Owns us.
57   SearchResult* result_;  // Weak. Owned by AppListModel::SearchResults.
58   size_t row_in_view_;
59   base::scoped_nsobject<MenuController> context_menu_controller_;
61   DISALLOW_COPY_AND_ASSIGN(ItemObserver);
64 void AppsSearchResultsModelBridge::ItemObserver::OnItemUninstalled() {
65   // Performing the search again will destroy |this|, so post a task. This also
66   // ensures that the AppSearchProvider has observed the uninstall before
67   // performing the search again, otherwise it will provide a NULL result.
68   [[bridge_->parent_ delegate] performSelector:@selector(redoSearch)
69                                     withObject:nil
70                                     afterDelay:0];
73 AppsSearchResultsModelBridge::AppsSearchResultsModelBridge(
74     AppsSearchResultsController* results_controller)
75     : parent_(results_controller) {
76   UpdateItemObservers();
77   [parent_ results]->AddObserver(this);
80 AppsSearchResultsModelBridge::~AppsSearchResultsModelBridge() {
81   [parent_ results]->RemoveObserver(this);
84 NSMenu* AppsSearchResultsModelBridge::MenuForItem(size_t index) {
85   DCHECK_LT(index, item_observers_.size());
86   return item_observers_[index]->GetContextMenu();
89 void AppsSearchResultsModelBridge::UpdateItemObservers() {
90   DCHECK(item_observers_.empty());
91   const size_t itemCount = [parent_ results]->item_count();
92   for (size_t i = 0 ; i < itemCount; ++i)
93     item_observers_.push_back(new ItemObserver(this, i));
96 void AppsSearchResultsModelBridge::ReloadDataForItems(
97     size_t start, size_t count) const {
98   NSIndexSet* column = [NSIndexSet indexSetWithIndex:0];
99   NSIndexSet* rows =
100       [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(start, count)];
101   [[parent_ tableView] reloadDataForRowIndexes:rows
102                                  columnIndexes:column];
105 void AppsSearchResultsModelBridge::ListItemsAdded(
106     size_t start, size_t count) {
107   item_observers_.clear();
108   if (start == static_cast<size_t>([[parent_ tableView] numberOfRows]))
109     [[parent_ tableView] noteNumberOfRowsChanged];
110   else
111     [[parent_ tableView] reloadData];
112   UpdateItemObservers();
115 void AppsSearchResultsModelBridge::ListItemsRemoved(
116     size_t start, size_t count) {
117   item_observers_.clear();
118   if (start == [parent_ results]->item_count())
119     [[parent_ tableView] noteNumberOfRowsChanged];
120   else
121     [[parent_ tableView] reloadData];
122   UpdateItemObservers();
125 void AppsSearchResultsModelBridge::ListItemMoved(
126     size_t index, size_t target_index) {
127   NOTREACHED();
130 void AppsSearchResultsModelBridge::ListItemsChanged(
131     size_t start, size_t count) {
132   item_observers_.clear();
133   ReloadDataForItems(start, count);
134   UpdateItemObservers();
137 }  // namespace app_list