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/clipboard.h" |
| 8 #include "base/string_util.h" |
7 #include "base/sys_string_conversions.h" | 9 #include "base/sys_string_conversions.h" |
8 #include "chrome/browser/autocomplete/autocomplete_edit.h" | 10 #include "chrome/browser/autocomplete/autocomplete_edit.h" |
9 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" | 11 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" |
10 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" | 12 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" |
| 13 #include "chrome/browser/browser_process.h" |
11 #include "chrome/browser/cocoa/autocomplete_text_field.h" | 14 #include "chrome/browser/cocoa/autocomplete_text_field.h" |
12 #include "chrome/browser/tab_contents/tab_contents.h" | 15 #include "chrome/browser/tab_contents/tab_contents.h" |
13 | 16 |
14 // Focus-handling between |field_| and |model_| is a bit subtle. | 17 // Focus-handling between |field_| and |model_| is a bit subtle. |
15 // Other platforms detect change of focus, which is inconvenient | 18 // Other platforms detect change of focus, which is inconvenient |
16 // without subclassing NSTextField (even with a subclass, the use of a | 19 // without subclassing NSTextField (even with a subclass, the use of a |
17 // field editor may complicate things). | 20 // field editor may complicate things). |
18 // | 21 // |
19 // |model_| doesn't actually do anything when it gains focus, it just | 22 // |model_| doesn't actually do anything when it gains focus, it just |
20 // initializes. Visible activity happens only after the user edits. | 23 // initializes. Visible activity happens only after the user edits. |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 ClosePopup(); | 544 ClosePopup(); |
542 | 545 |
543 // Tell the model to reset itself. | 546 // Tell the model to reset itself. |
544 model_->OnKillFocus(); | 547 model_->OnKillFocus(); |
545 } | 548 } |
546 | 549 |
547 void AutocompleteEditViewMac::OnDidResignKey() { | 550 void AutocompleteEditViewMac::OnDidResignKey() { |
548 ClosePopup(); | 551 ClosePopup(); |
549 } | 552 } |
550 | 553 |
| 554 void AutocompleteEditViewMac::OnPaste() { |
| 555 // This code currently expects |field_| to be focussed. |
| 556 DCHECK([field_ currentEditor]); |
| 557 |
| 558 std::wstring text = GetClipboardText(g_browser_process->clipboard()); |
| 559 if (text.empty()) { |
| 560 return; |
| 561 } |
| 562 |
| 563 // If this paste will be replacing all the text, record that, so we |
| 564 // can do different behaviors in such a case. |
| 565 const NSRange allRange = NSMakeRange(0, [[field_ stringValue] length]); |
| 566 const NSRange selectedRange = GetSelectedRange(); |
| 567 if (NSEqualRanges(allRange, selectedRange)) { |
| 568 model_->on_paste_replacing_all(); |
| 569 } |
| 570 |
| 571 // Force a Paste operation to trigger the text_changed code in |
| 572 // OnAfterPossibleChange(), even if identical contents are pasted into the |
| 573 // text box. |
| 574 text_before_change_.clear(); |
| 575 |
| 576 NSString* s = base::SysWideToNSString(text); |
| 577 [[field_ currentEditor] replaceCharactersInRange:selectedRange withString:s]; |
| 578 |
| 579 OnAfterPossibleChange(); |
| 580 } |
| 581 |
551 void AutocompleteEditViewMac::AcceptInput( | 582 void AutocompleteEditViewMac::AcceptInput( |
552 WindowOpenDisposition disposition, bool for_drop) { | 583 WindowOpenDisposition disposition, bool for_drop) { |
553 model_->AcceptInput(disposition, for_drop); | 584 model_->AcceptInput(disposition, for_drop); |
554 } | 585 } |
555 | 586 |
556 void AutocompleteEditViewMac::FocusLocation() { | 587 void AutocompleteEditViewMac::FocusLocation() { |
557 [[field_ window] makeFirstResponder:field_]; | 588 [[field_ window] makeFirstResponder:field_]; |
558 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]); | 589 DCHECK_EQ([field_ currentEditor], [[field_ window] firstResponder]); |
559 } | 590 } |
560 | 591 |
| 592 // TODO(shess): Copied from autocomplete_edit_view_win.cc. Could this |
| 593 // be pushed into the model? |
| 594 std::wstring AutocompleteEditViewMac::GetClipboardText(Clipboard* clipboard) { |
| 595 // autocomplete_edit_view_win.cc assumes this can never happen, we |
| 596 // will too. |
| 597 DCHECK(clipboard); |
| 598 |
| 599 if (clipboard->IsFormatAvailable(Clipboard::GetPlainTextWFormatType())) { |
| 600 string16 text16; |
| 601 clipboard->ReadText(&text16); |
| 602 |
| 603 // Note: Unlike in the find popup and textfield view, here we completely |
| 604 // remove whitespace strings containing newlines. We assume users are |
| 605 // most likely pasting in URLs that may have been split into multiple |
| 606 // lines in terminals, email programs, etc., and so linebreaks indicate |
| 607 // completely bogus whitespace that would just cause the input to be |
| 608 // invalid. |
| 609 return CollapseWhitespace(UTF16ToWide(text16), true); |
| 610 } |
| 611 |
| 612 // Try bookmark format. |
| 613 // |
| 614 // It is tempting to try bookmark format first, but the URL we get out of a |
| 615 // bookmark has been cannonicalized via GURL. This means if a user copies |
| 616 // and pastes from the URL bar to itself, the text will get fixed up and |
| 617 // cannonicalized, which is not what the user expects. By pasting in this |
| 618 // order, we are sure to paste what the user copied. |
| 619 if (clipboard->IsFormatAvailable(Clipboard::GetUrlWFormatType())) { |
| 620 std::string url_str; |
| 621 clipboard->ReadBookmark(NULL, &url_str); |
| 622 // pass resulting url string through GURL to normalize |
| 623 GURL url(url_str); |
| 624 if (url.is_valid()) { |
| 625 return UTF8ToWide(url.spec()); |
| 626 } |
| 627 } |
| 628 |
| 629 return std::wstring(); |
| 630 } |
| 631 |
561 @implementation AutocompleteFieldDelegate | 632 @implementation AutocompleteFieldDelegate |
562 | 633 |
563 - initWithEditView:(AutocompleteEditViewMac*)view { | 634 - initWithEditView:(AutocompleteEditViewMac*)view { |
564 self = [super init]; | 635 self = [super init]; |
565 if (self) { | 636 if (self) { |
566 edit_view_ = view; | 637 edit_view_ = view; |
567 } | 638 } |
568 return self; | 639 return self; |
569 } | 640 } |
570 | 641 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 | 692 |
622 - (BOOL)control:(NSControl*)control textShouldEndEditing:(NSText*)fieldEditor { | 693 - (BOOL)control:(NSControl*)control textShouldEndEditing:(NSText*)fieldEditor { |
623 edit_view_->OnDidEndEditing(); | 694 edit_view_->OnDidEndEditing(); |
624 | 695 |
625 return YES; | 696 return YES; |
626 | 697 |
627 // TODO(shess): Figure out where the selection belongs. On GTK, | 698 // TODO(shess): Figure out where the selection belongs. On GTK, |
628 // it's set to the start of the text. | 699 // it's set to the start of the text. |
629 } | 700 } |
630 | 701 |
| 702 - (BOOL)control:(NSControl*)control textShouldPaste:(NSText*)fieldEditor { |
| 703 edit_view_->OnPaste(); |
| 704 |
| 705 // Caller shouldn't also paste. |
| 706 return NO; |
| 707 } |
| 708 |
631 // Signal that we've lost focus when the window resigns key. | 709 // Signal that we've lost focus when the window resigns key. |
632 - (void)windowDidResignKey:(NSNotification*)notification { | 710 - (void)windowDidResignKey:(NSNotification*)notification { |
633 edit_view_->OnDidResignKey(); | 711 edit_view_->OnDidResignKey(); |
634 } | 712 } |
635 | 713 |
636 @end | 714 @end |
OLD | NEW |