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