OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/autocomplete/autocomplete_edit_view_mac.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" |
6 | 6 |
7 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
8 #include "chrome/browser/autocomplete/autocomplete_edit.h" | 8 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
9 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" | 9 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" |
10 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" | 10 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 // after destruction. | 172 // after destruction. |
173 [field_ setDelegate:nil]; | 173 [field_ setDelegate:nil]; |
174 | 174 |
175 // Disconnect notifications so they don't signal a dead object. | 175 // Disconnect notifications so they don't signal a dead object. |
176 [[NSNotificationCenter defaultCenter] removeObserver:edit_helper_]; | 176 [[NSNotificationCenter defaultCenter] removeObserver:edit_helper_]; |
177 } | 177 } |
178 | 178 |
179 void AutocompleteEditViewMac::SaveStateToTab(TabContents* tab) { | 179 void AutocompleteEditViewMac::SaveStateToTab(TabContents* tab) { |
180 DCHECK(tab); | 180 DCHECK(tab); |
181 | 181 |
| 182 const bool hasFocus = [field_ currentEditor] ? true : false; |
| 183 |
182 NSRange range; | 184 NSRange range; |
183 if (model_->has_focus()) { | 185 if (hasFocus) { |
184 range = GetSelectedRange(); | 186 range = GetSelectedRange(); |
185 } else { | 187 } else { |
186 // If we are not focussed, there is no selection. Manufacture | 188 // If we are not focussed, there is no selection. Manufacture |
187 // something reasonable in case it starts to matter in the future. | 189 // something reasonable in case it starts to matter in the future. |
188 range = NSMakeRange(0, [[field_ stringValue] length]); | 190 range = NSMakeRange(0, [[field_ stringValue] length]); |
189 } | 191 } |
190 | 192 |
191 AutocompleteEditViewMacState state(model_->GetStateForTabSwitch(), | 193 AutocompleteEditViewMacState state(model_->GetStateForTabSwitch(), |
192 model_->has_focus(), range); | 194 hasFocus, range); |
193 StoreStateToTab(tab, state); | 195 StoreStateToTab(tab, state); |
194 } | 196 } |
195 | 197 |
196 void AutocompleteEditViewMac::Update( | 198 void AutocompleteEditViewMac::Update( |
197 const TabContents* tab_for_state_restoring) { | 199 const TabContents* tab_for_state_restoring) { |
198 // TODO(shess): It seems like if the tab is non-NULL, then this code | 200 // TODO(shess): It seems like if the tab is non-NULL, then this code |
199 // shouldn't need to be called at all. When coded that way, I find | 201 // shouldn't need to be called at all. When coded that way, I find |
200 // that the field isn't always updated correctly. Figure out why | 202 // that the field isn't always updated correctly. Figure out why |
201 // this is. Maybe this method should be refactored into more | 203 // this is. Maybe this method should be refactored into more |
202 // specific cases. | 204 // specific cases. |
203 const std::wstring text = toolbar_model_->GetText(); | 205 const std::wstring text = toolbar_model_->GetText(); |
204 const bool user_visible = model_->UpdatePermanentText(text); | 206 const bool user_visible = model_->UpdatePermanentText(text); |
205 | 207 |
206 if (tab_for_state_restoring) { | 208 if (tab_for_state_restoring) { |
207 RevertAll(); | 209 RevertAll(); |
208 | 210 |
209 const AutocompleteEditViewMacState* state = | 211 const AutocompleteEditViewMacState* state = |
210 GetStateFromTab(tab_for_state_restoring); | 212 GetStateFromTab(tab_for_state_restoring); |
211 if (state) { | 213 if (state) { |
212 // Should restore the user's text via SetUserText(). | 214 // Should restore the user's text via SetUserText(). |
213 model_->RestoreState(state->model_state); | 215 model_->RestoreState(state->model_state); |
214 | 216 |
215 // Restore user's selection. | 217 // Restore focus and selection if they were present when the tab |
216 // TODO(shess): The model_ does not restore the focus state. If | 218 // was switched away. |
217 // field_ was in focus when we switched away, I presume it | |
218 // should be in focus when we switch back. Figure out if model_ | |
219 // not restoring focus is an oversight, or intentional for some | |
220 // subtle reason. | |
221 if (state->has_focus) { | 219 if (state->has_focus) { |
222 SetSelectedRange(state->selection); | 220 // TODO(shess): Unfortunately, there is no safe way to update |
| 221 // this because TabStripController -selectTabWithContents:* is |
| 222 // also messing with focus. Both parties need to agree to |
| 223 // store existing state before anyone tries to setup the new |
| 224 // state. Anyhow, it would look something like this. |
| 225 #if 0 |
| 226 FocusLocation(); |
| 227 |
| 228 // Must restore directly to evade model_->has_focus() guard. |
| 229 [[field_ currentEditor] setSelectedRange:state->selection]; |
| 230 #endif |
223 } | 231 } |
224 } | 232 } |
225 } else if (user_visible) { | 233 } else if (user_visible) { |
226 // Restore everything to the baseline look. | 234 // Restore everything to the baseline look. |
227 RevertAll(); | 235 RevertAll(); |
228 // TODO(shess): Figure out how this case is used, to make sure | 236 // TODO(shess): Figure out how this case is used, to make sure |
229 // we're getting the selection and popup right. | 237 // we're getting the selection and popup right. |
230 | 238 |
231 } else { | 239 } else { |
232 // TODO(shess): Figure out how this case is used, to make sure | 240 // TODO(shess): Figure out how this case is used, to make sure |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 UpdatePopup(); | 279 UpdatePopup(); |
272 } | 280 } |
273 } | 281 } |
274 | 282 |
275 NSRange AutocompleteEditViewMac::GetSelectedRange() const { | 283 NSRange AutocompleteEditViewMac::GetSelectedRange() const { |
276 DCHECK([field_ currentEditor]); | 284 DCHECK([field_ currentEditor]); |
277 return [[field_ currentEditor] selectedRange]; | 285 return [[field_ currentEditor] selectedRange]; |
278 } | 286 } |
279 | 287 |
280 void AutocompleteEditViewMac::SetSelectedRange(const NSRange range) { | 288 void AutocompleteEditViewMac::SetSelectedRange(const NSRange range) { |
281 // TODO(shess): Check if we should steal focus or not. We can't set | 289 if (model_->has_focus()) { |
282 // the selection without focus, though. | 290 // TODO(shess): This should not be necessary. Try to convert to |
283 FocusLocation(); | 291 // DCHECK(IsFirstResponder()). |
| 292 FocusLocation(); |
284 | 293 |
285 // TODO(shess): What if it didn't get first responder, and there is | 294 // TODO(shess): What if it didn't get first responder, and there is |
286 // no field editor? This will do nothing. Well, at least it won't | 295 // no field editor? This will do nothing. Well, at least it won't |
287 // crash. Think of something more productive to do, or prove that | 296 // crash. Think of something more productive to do, or prove that |
288 // it cannot occur and DCHECK appropriately. | 297 // it cannot occur and DCHECK appropriately. |
289 [[field_ currentEditor] setSelectedRange:range]; | 298 [[field_ currentEditor] setSelectedRange:range]; |
| 299 } |
290 } | 300 } |
291 | 301 |
292 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text, | 302 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text, |
293 size_t caret_pos) { | 303 size_t caret_pos) { |
294 DCHECK_LE(caret_pos, text.size()); | 304 DCHECK_LE(caret_pos, text.size()); |
295 UpdateAndStyleText(text); | 305 UpdateAndStyleText(text); |
296 SetSelectedRange(NSMakeRange(caret_pos, caret_pos)); | 306 SetSelectedRange(NSMakeRange(caret_pos, caret_pos)); |
297 } | 307 } |
298 | 308 |
299 void AutocompleteEditViewMac::SelectAll(bool reversed) { | 309 void AutocompleteEditViewMac::SelectAll(bool reversed) { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 // TODO(shess): Figure out where the selection belongs. On GTK, | 616 // TODO(shess): Figure out where the selection belongs. On GTK, |
607 // it's set to the start of the text. | 617 // it's set to the start of the text. |
608 } | 618 } |
609 | 619 |
610 // Signal that we've lost focus when the window resigns key. | 620 // Signal that we've lost focus when the window resigns key. |
611 - (void)windowDidResignKey:(NSNotification*)notification { | 621 - (void)windowDidResignKey:(NSNotification*)notification { |
612 edit_view_->OnDidResignKey(); | 622 edit_view_->OnDidResignKey(); |
613 } | 623 } |
614 | 624 |
615 @end | 625 @end |
OLD | NEW |