| 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_view_mac.h" | 9 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" |
| 10 | 10 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 if (disposition != NEW_BACKGROUND_TAB) | 85 if (disposition != NEW_BACKGROUND_TAB) |
| 86 RevertAll(); // Revert the box to its unedited state. | 86 RevertAll(); // Revert the box to its unedited state. |
| 87 controller_->OnAutocompleteAccept(url, disposition, transition, | 87 controller_->OnAutocompleteAccept(url, disposition, transition, |
| 88 alternate_nav_url); | 88 alternate_nav_url); |
| 89 } | 89 } |
| 90 | 90 |
| 91 std::wstring AutocompleteEditViewMac::GetText() const { | 91 std::wstring AutocompleteEditViewMac::GetText() const { |
| 92 return base::SysNSStringToWide([field_ stringValue]); | 92 return base::SysNSStringToWide([field_ stringValue]); |
| 93 } | 93 } |
| 94 | 94 |
| 95 NSRange AutocompleteEditViewMac::GetSelectedRange() const { |
| 96 DCHECK([field_ currentEditor]); |
| 97 return [[field_ currentEditor] selectedRange]; |
| 98 } |
| 99 |
| 95 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text, | 100 void AutocompleteEditViewMac::SetWindowTextAndCaretPos(const std::wstring& text, |
| 96 size_t caret_pos) { | 101 size_t caret_pos) { |
| 97 UpdateAndStyleText(text, text.size()); | 102 UpdateAndStyleText(text, text.size()); |
| 98 } | 103 } |
| 99 | 104 |
| 100 void AutocompleteEditViewMac::SelectAll(bool reversed) { | 105 void AutocompleteEditViewMac::SelectAll(bool reversed) { |
| 101 // TODO(shess): Figure out what reversed implies. The gtk version | 106 // TODO(shess): Figure out what reversed implies. The gtk version |
| 102 // has it imply inverting the selection front to back, but I don't | 107 // has it imply inverting the selection front to back, but I don't |
| 103 // even know if that makes sense for Mac. | 108 // even know if that makes sense for Mac. |
| 104 UpdateAndStyleText(GetText(), 0); | 109 UpdateAndStyleText(GetText(), 0); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 | 212 |
| 208 UpdateAndStyleText(display_text, user_text_length); | 213 UpdateAndStyleText(display_text, user_text_length); |
| 209 return true; | 214 return true; |
| 210 } | 215 } |
| 211 | 216 |
| 212 void AutocompleteEditViewMac::OnRevertTemporaryText() { | 217 void AutocompleteEditViewMac::OnRevertTemporaryText() { |
| 213 UpdateAndStyleText(saved_temporary_text_, saved_temporary_text_.size()); | 218 UpdateAndStyleText(saved_temporary_text_, saved_temporary_text_.size()); |
| 214 saved_temporary_text_.clear(); | 219 saved_temporary_text_.clear(); |
| 215 } | 220 } |
| 216 | 221 |
| 222 void AutocompleteEditViewMac::OnBeforePossibleChange() { |
| 223 selection_before_change_ = GetSelectedRange(); |
| 224 text_before_change_ = GetText(); |
| 225 } |
| 226 |
| 227 bool AutocompleteEditViewMac::OnAfterPossibleChange() { |
| 228 NSRange new_selection(GetSelectedRange()); |
| 229 std::wstring new_text(GetText()); |
| 230 const size_t length = new_text.length(); |
| 231 |
| 232 bool selection_differs = !NSEqualRanges(new_selection, |
| 233 selection_before_change_); |
| 234 bool at_end_of_edit = (length == new_selection.location); |
| 235 bool text_differs = (new_text != text_before_change_); |
| 236 |
| 237 // When the user has deleted text, we don't allow inline |
| 238 // autocomplete. This is assumed if the text has gotten shorter AND |
| 239 // the selection has shifted towards the front of the text. During |
| 240 // normal typing the text will almost always be shorter (as the new |
| 241 // input replaces the autocomplete suggestion), but in that case the |
| 242 // selection point will have moved towards the end of the text. |
| 243 // TODO(shess): In our implementation, we can catch -deleteBackward: |
| 244 // and other methods to provide positive knowledge that a delete |
| 245 // occured, rather than intuiting it from context. Consider whether |
| 246 // that would be a stronger approach. |
| 247 bool just_deleted_text = |
| 248 (length < text_before_change_.length() && |
| 249 new_selection.location <= selection_before_change_.location); |
| 250 |
| 251 bool something_changed = model_->OnAfterPossibleChange(new_text, |
| 252 selection_differs, text_differs, just_deleted_text, at_end_of_edit); |
| 253 |
| 254 // TODO(shess): Restyle the text if something_changed. Not fixing |
| 255 // now because styling is currently broken. |
| 256 |
| 257 return something_changed; |
| 258 } |
| 259 |
| 217 void AutocompleteEditViewMac::OnUpOrDownKeyPressed(int dir) { | 260 void AutocompleteEditViewMac::OnUpOrDownKeyPressed(int dir) { |
| 218 model_->OnUpOrDownKeyPressed(dir); | 261 model_->OnUpOrDownKeyPressed(dir); |
| 219 } | 262 } |
| 220 void AutocompleteEditViewMac::OnEscapeKeyPressed() { | 263 void AutocompleteEditViewMac::OnEscapeKeyPressed() { |
| 221 model_->OnEscapeKeyPressed(); | 264 model_->OnEscapeKeyPressed(); |
| 222 } | 265 } |
| 223 void AutocompleteEditViewMac::OnSetFocus(bool f) { | 266 void AutocompleteEditViewMac::OnSetFocus(bool f) { |
| 224 model_->OnSetFocus(f); | 267 model_->OnSetFocus(f); |
| 225 } | 268 } |
| 226 void AutocompleteEditViewMac::OnKillFocus() { | 269 void AutocompleteEditViewMac::OnKillFocus() { |
| 227 model_->OnKillFocus(); | 270 model_->OnKillFocus(); |
| 228 } | 271 } |
| 229 void AutocompleteEditViewMac::AcceptInput( | 272 void AutocompleteEditViewMac::AcceptInput( |
| 230 WindowOpenDisposition disposition, bool for_drop) { | 273 WindowOpenDisposition disposition, bool for_drop) { |
| 231 model_->AcceptInput(disposition, for_drop); | 274 model_->AcceptInput(disposition, for_drop); |
| 232 } | 275 } |
| 233 void AutocompleteEditViewMac::OnAfterPossibleChange( | |
| 234 const std::wstring& new_text, | |
| 235 bool selection_differs, | |
| 236 bool text_differs, | |
| 237 bool just_deleted_text, | |
| 238 bool at_end_of_edit) { | |
| 239 model_->OnAfterPossibleChange(new_text, selection_differs, text_differs, | |
| 240 just_deleted_text, at_end_of_edit); | |
| 241 } | |
| 242 void AutocompleteEditViewMac::SetField(NSTextField* field) { | 276 void AutocompleteEditViewMac::SetField(NSTextField* field) { |
| 243 field_ = field; | 277 field_ = field; |
| 244 [field_ setDelegate:edit_helper_]; | 278 [field_ setDelegate:edit_helper_]; |
| 245 | 279 |
| 246 // The popup code needs the field for sizing and placement. | 280 // The popup code needs the field for sizing and placement. |
| 247 popup_view_->SetField(field_); | 281 popup_view_->SetField(field_); |
| 248 } | 282 } |
| 249 | 283 |
| 250 void AutocompleteEditViewMac::FocusLocation() { | 284 void AutocompleteEditViewMac::FocusLocation() { |
| 251 [[field_ window] makeFirstResponder:field_]; | 285 [[field_ window] makeFirstResponder:field_]; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 275 | 309 |
| 276 if (cmd == @selector(cancelOperation:)) { | 310 if (cmd == @selector(cancelOperation:)) { |
| 277 edit_view_->OnEscapeKeyPressed(); | 311 edit_view_->OnEscapeKeyPressed(); |
| 278 return YES; | 312 return YES; |
| 279 } | 313 } |
| 280 | 314 |
| 281 if (cmd == @selector(insertNewline:)) { | 315 if (cmd == @selector(insertNewline:)) { |
| 282 edit_view_->AcceptInput(CURRENT_TAB, false); | 316 edit_view_->AcceptInput(CURRENT_TAB, false); |
| 283 return YES; | 317 return YES; |
| 284 } | 318 } |
| 285 | 319 |
| 320 // Capture the state before the operation changes the content. |
| 321 // TODO(shess): Determine if this is always redundent WRT the call |
| 322 // in -controlTextDidChange:. |
| 323 edit_view_->OnBeforePossibleChange(); |
| 286 return NO; | 324 return NO; |
| 287 } | 325 } |
| 288 | 326 |
| 289 - (void)controlTextDidBeginEditing:(NSNotification*)aNotification { | 327 - (void)controlTextDidBeginEditing:(NSNotification*)aNotification { |
| 290 edit_view_->OnSetFocus(false); | 328 edit_view_->OnSetFocus(false); |
| 329 |
| 330 // Capture the current state. |
| 331 edit_view_->OnBeforePossibleChange(); |
| 291 } | 332 } |
| 292 | 333 |
| 293 - (void)controlTextDidChange:(NSNotification*)aNotification { | 334 - (void)controlTextDidChange:(NSNotification*)aNotification { |
| 294 // TODO(shess): Make this more efficient? Or not. For now, just | 335 // Figure out what changed and notify the model_. |
| 295 // pass in the current text, indicating that the text and | 336 edit_view_->OnAfterPossibleChange(); |
| 296 // selection differ, ignoring deletions, and assuming that we're | 337 |
| 297 // at the end of the text. | 338 // Then capture the new state. |
| 298 edit_view_->OnAfterPossibleChange(edit_view_->GetText(), | 339 edit_view_->OnBeforePossibleChange(); |
| 299 true, true, false, true); | |
| 300 } | 340 } |
| 301 | 341 |
| 302 - (void)controlTextDidEndEditing:(NSNotification*)aNotification { | 342 - (void)controlTextDidEndEditing:(NSNotification*)aNotification { |
| 303 edit_view_->OnKillFocus(); | 343 edit_view_->OnKillFocus(); |
| 304 | 344 |
| 305 // TODO(shess): Figure out where the selection belongs. On GTK, | 345 // TODO(shess): Figure out where the selection belongs. On GTK, |
| 306 // it's set to the start of the text. | 346 // it's set to the start of the text. |
| 307 } | 347 } |
| 308 | 348 |
| 309 @end | 349 @end |
| OLD | NEW |