Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm

Issue 9310074: Switch to using WebIntentPickerModel, and bring picker closer to mocks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed unit tests Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/ui/cocoa/web_intent_picker_cocoa.h" 5 #include "chrome/browser/ui/cocoa/web_intent_picker_cocoa.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include "base/bind.h"
10 #include "base/message_loop.h"
9 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/browser_window.h" 13 #include "chrome/browser/ui/browser_window.h"
12 #import "chrome/browser/ui/cocoa/browser_window_controller.h" 14 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
13 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" 15 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
14 #import "chrome/browser/ui/cocoa/web_intent_bubble_controller.h" 16 #import "chrome/browser/ui/cocoa/web_intent_bubble_controller.h"
15 #include "chrome/browser/ui/intents/web_intent_picker.h" 17 #include "chrome/browser/ui/intents/web_intent_picker.h"
16 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" 18 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
17 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
18 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents.h"
(...skipping 26 matching lines...) Expand all
45 TabContentsWrapper* wrapper, 47 TabContentsWrapper* wrapper,
46 WebIntentPickerDelegate* delegate, 48 WebIntentPickerDelegate* delegate,
47 WebIntentPickerModel* model) { 49 WebIntentPickerModel* model) {
48 return new WebIntentPickerCocoa(browser, wrapper, delegate, model); 50 return new WebIntentPickerCocoa(browser, wrapper, delegate, model);
49 } 51 }
50 52
51 WebIntentPickerCocoa::WebIntentPickerCocoa() 53 WebIntentPickerCocoa::WebIntentPickerCocoa()
52 : delegate_(NULL), 54 : delegate_(NULL),
53 model_(NULL), 55 model_(NULL),
54 browser_(NULL), 56 browser_(NULL),
55 controller_(NULL) { 57 controller_(nil),
58 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
Nico 2012/02/03 23:27:07 this macro is only needed for msvc i think
groby-ooo-7-16 2012/02/06 22:30:19 Done.
56 } 59 }
57 60
58 61
59 WebIntentPickerCocoa::WebIntentPickerCocoa(Browser* browser, 62 WebIntentPickerCocoa::WebIntentPickerCocoa(Browser* browser,
60 TabContentsWrapper* wrapper, 63 TabContentsWrapper* wrapper,
61 WebIntentPickerDelegate* delegate, 64 WebIntentPickerDelegate* delegate,
62 WebIntentPickerModel* model) 65 WebIntentPickerModel* model)
63 : delegate_(delegate), 66 : delegate_(delegate),
64 model_(model), 67 model_(model),
65 browser_(browser), 68 browser_(browser),
66 controller_(NULL) { 69 controller_(nil),
70 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
67 model_->set_observer(this); 71 model_->set_observer(this);
68 72
69 DCHECK(browser); 73 DCHECK(browser);
70 DCHECK(delegate); 74 DCHECK(delegate);
71 NSWindow* parentWindow = browser->window()->GetNativeHandle(); 75 NSWindow* parentWindow = browser->window()->GetNativeHandle();
72 76
73 // Compute the anchor point, relative to location bar. 77 // Compute the anchor point, relative to location bar.
74 BrowserWindowController* controller = [parentWindow windowController]; 78 BrowserWindowController* controller = [parentWindow windowController];
75 LocationBarViewMac* locationBar = [controller locationBarBridge]; 79 LocationBarViewMac* locationBar = [controller locationBarBridge];
76 NSPoint anchor = locationBar->GetPageInfoBubblePoint(); 80 NSPoint anchor = locationBar->GetPageInfoBubblePoint();
77 anchor = [browser->window()->GetNativeHandle() convertBaseToScreen:anchor]; 81 anchor = [browser->window()->GetNativeHandle() convertBaseToScreen:anchor];
78 82
79 // The controller is deallocated when the window is closed, so no need to 83 // The controller is deallocated when the window is closed, so no need to
80 // worry about it here. 84 // worry about it here.
81 [[WebIntentBubbleController alloc] initWithPicker:this 85 [[WebIntentBubbleController alloc] initWithPicker:this
82 parentWindow:parentWindow 86 parentWindow:parentWindow
83 anchoredAt:anchor]; 87 anchoredAt:anchor];
84 } 88 }
85 89
86 WebIntentPickerCocoa::~WebIntentPickerCocoa() { 90 WebIntentPickerCocoa::~WebIntentPickerCocoa() {
87 if (model_ != NULL) 91 if (model_ != NULL)
88 model_->set_observer(NULL); 92 model_->set_observer(NULL);
89 } 93 }
90 94
91 void WebIntentPickerCocoa::Close() { 95 void WebIntentPickerCocoa::Close() {
92 } 96 }
93 97
98 void WebIntentPickerCocoa::PerformDelayedLayout() {
99 // Check to see if a layout has already been scheduled.
Nico 2012/02/03 23:27:07 indent only 2
groby-ooo-7-16 2012/02/06 22:30:19 Done.
100 if (weak_ptr_factory_.HasWeakPtrs())
101 return;
102
103 // Delay performing layout by a second so that all the animations from
104 // InfoBubbleWindow and origin updates from BaseBubbleController finish, so
105 // that we don't all race trying to change the frame's origin.
106 //
107 // Using MessageLoop is superior here to |-performSelector:| because it will
108 // not retain its target; if the child outlives its parent, zombies get left
109 // behind (http://crbug.com/59619). This will cancel the scheduled task if
110 // the controller get destroyed before the message
111 // can be delivered.
Nico 2012/02/03 23:27:07 This looks familiar. Can this code be factored out
groby-ooo-7-16 2012/02/06 22:30:19 It _is_ familiar. The PageInfoBubble does _almost_
Nico 2012/02/06 22:39:38 :-/
112 MessageLoop::current()->PostDelayedTask(FROM_HERE,
113 base::Bind(&WebIntentPickerCocoa::PerformLayout,
114 weak_ptr_factory_.GetWeakPtr()),
115 100 /* milliseconds */);
116 }
117
118 void WebIntentPickerCocoa::PerformLayout() {
119 DCHECK(controller_);
120 // If the window is animating closed when this is called, the
121 // animation could be holding the last reference to |controller_|
122 // (and thus |this|). Pin it until the task is completed.
123 scoped_nsobject<WebIntentBubbleController> keep_alive([controller_ retain]);
124 [controller_ performLayoutWithModel:model_];
125 }
126
94 void WebIntentPickerCocoa::OnModelChanged(WebIntentPickerModel* model) { 127 void WebIntentPickerCocoa::OnModelChanged(WebIntentPickerModel* model) {
95 DCHECK(controller_); 128 PerformDelayedLayout();
96 scoped_nsobject<NSMutableArray> urlArray(
97 [[NSMutableArray alloc] initWithCapacity:model->GetItemCount()]);
98
99 for (size_t i = 0; i < model->GetItemCount(); ++i) {
100 const WebIntentPickerModel::Item& item = model->GetItemAt(i);
101
102 [urlArray addObject:
103 [NSString stringWithUTF8String:item.url.spec().c_str()]];
104 [controller_ replaceImageAtIndex:i withImage:item.favicon.ToNSImage()];
105 }
106
107 [controller_ setServiceURLs:urlArray];
108 } 129 }
109 130
110 void WebIntentPickerCocoa::OnFaviconChanged(WebIntentPickerModel* model, 131 void WebIntentPickerCocoa::OnFaviconChanged(WebIntentPickerModel* model,
111 size_t index) { 132 size_t index) {
112 DCHECK(controller_); 133 // We don't handle individual icon changes - just redo the whole model.
113 134 PerformDelayedLayout();
114 const WebIntentPickerModel::Item& item = model->GetItemAt(index);
115 [controller_ replaceImageAtIndex:index withImage:item.favicon.ToNSImage()];
116 } 135 }
117 136
118 void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) { 137 void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) {
119 const WebIntentPickerModel::Item& item = model->GetItemAt( 138 const WebIntentPickerModel::Item& item = model->GetItemAt(
120 model->inline_disposition_index()); 139 model->inline_disposition_index());
121 140
122 content::WebContents* web_contents = content::WebContents::Create( 141 content::WebContents* web_contents = content::WebContents::Create(
123 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); 142 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
124 inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents)); 143 inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents));
125 inline_disposition_delegate_.reset(new InlineHtmlContentDelegate); 144 inline_disposition_delegate_.reset(new InlineHtmlContentDelegate);
126 web_contents->SetDelegate(inline_disposition_delegate_.get()); 145 web_contents->SetDelegate(inline_disposition_delegate_.get());
127 146
128 inline_disposition_tab_contents_->web_contents()->GetController().LoadURL( 147 inline_disposition_tab_contents_->web_contents()->GetController().LoadURL(
129 item.url, 148 item.url,
130 content::Referrer(), 149 content::Referrer(),
131 content::PAGE_TRANSITION_START_PAGE, 150 content::PAGE_TRANSITION_START_PAGE,
132 std::string()); 151 std::string());
133 152
134 [controller_ setInlineDispositionTabContents: 153 [controller_ setInlineDispositionTabContents:
135 inline_disposition_tab_contents_.get()]; 154 inline_disposition_tab_contents_.get()];
155 PerformDelayedLayout();
136 156
137 delegate_->OnInlineDispositionWebContentsCreated(web_contents); 157 delegate_->OnInlineDispositionWebContentsCreated(web_contents);
138 } 158 }
139 159
140 void WebIntentPickerCocoa::OnCancelled() { 160 void WebIntentPickerCocoa::OnCancelled() {
141 DCHECK(delegate_); 161 DCHECK(delegate_);
142 delegate_->OnCancelled(); 162 delegate_->OnCancelled();
143 controller_ = NULL; // Controller will be unusable soon, abandon. 163 controller_ = NULL; // Controller will be unusable soon, abandon.
144 } 164 }
145 165
146 void WebIntentPickerCocoa::OnServiceChosen(size_t index) { 166 void WebIntentPickerCocoa::OnServiceChosen(size_t index) {
147 DCHECK(delegate_); 167 DCHECK(delegate_);
148 const WebIntentPickerModel::Item& item = model_->GetItemAt(index); 168 const WebIntentPickerModel::Item& item = model_->GetItemAt(index);
149 delegate_->OnServiceChosen(index, item.disposition); 169 delegate_->OnServiceChosen(index, item.disposition);
150 } 170 }
151 171
152 void WebIntentPickerCocoa::set_controller( 172 void WebIntentPickerCocoa::set_controller(
153 WebIntentBubbleController* controller) { 173 WebIntentBubbleController* controller) {
154 controller_ = controller; 174 controller_ = controller;
155 } 175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698