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
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_UI_COCOA_OMNIBOX_OMNIBOX_VIEW_MAC_H_
6#define CHROME_BROWSER_UI_COCOA_OMNIBOX_OMNIBOX_VIEW_MAC_H_
7
8#import <Cocoa/Cocoa.h>
9
10#include "base/memory/scoped_ptr.h"
11#include "base/strings/string16.h"
12#include "chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.h"
13#include "chrome/browser/ui/omnibox/omnibox_view.h"
14
15class OmniboxPopupView;
16
17namespace ui {
18class Clipboard;
19}
20
21// Implements OmniboxView on an AutocompleteTextField.
22class OmniboxViewMac : public OmniboxView,
23                       public AutocompleteTextFieldObserver {
24 public:
25  OmniboxViewMac(OmniboxEditController* controller,
26                 Profile* profile,
27                 CommandUpdater* command_updater,
28                 AutocompleteTextField* field);
29  virtual ~OmniboxViewMac();
30
31  // OmniboxView:
32  virtual void SaveStateToTab(content::WebContents* tab) OVERRIDE;
33  virtual void OnTabChanged(const content::WebContents* web_contents) OVERRIDE;
34  virtual void Update() OVERRIDE;
35  virtual void UpdatePlaceholderText() OVERRIDE;
36  virtual void OpenMatch(const AutocompleteMatch& match,
37                         WindowOpenDisposition disposition,
38                         const GURL& alternate_nav_url,
39                         const base::string16& pasted_text,
40                         size_t selected_line) OVERRIDE;
41  virtual base::string16 GetText() const OVERRIDE;
42  virtual void SetWindowTextAndCaretPos(const base::string16& text,
43                                        size_t caret_pos,
44                                        bool update_popup,
45                                        bool notify_text_changed) OVERRIDE;
46  virtual void SetForcedQuery() OVERRIDE;
47  virtual bool IsSelectAll() const OVERRIDE;
48  virtual bool DeleteAtEndPressed() OVERRIDE;
49  virtual void GetSelectionBounds(
50      base::string16::size_type* start,
51      base::string16::size_type* end) const OVERRIDE;
52  virtual void SelectAll(bool reversed) OVERRIDE;
53  virtual void RevertAll() OVERRIDE;
54  virtual void UpdatePopup() OVERRIDE;
55  virtual void CloseOmniboxPopup() OVERRIDE;
56  virtual void SetFocus() OVERRIDE;
57  virtual void ApplyCaretVisibility() OVERRIDE;
58  virtual void OnTemporaryTextMaybeChanged(
59      const base::string16& display_text,
60      bool save_original_selection,
61      bool notify_text_changed) OVERRIDE;
62  virtual bool OnInlineAutocompleteTextMaybeChanged(
63      const base::string16& display_text, size_t user_text_length) OVERRIDE;
64  virtual void OnInlineAutocompleteTextCleared() OVERRIDE;
65  virtual void OnRevertTemporaryText() OVERRIDE;
66  virtual void OnBeforePossibleChange() OVERRIDE;
67  virtual bool OnAfterPossibleChange() OVERRIDE;
68  virtual gfx::NativeView GetNativeView() const OVERRIDE;
69  virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE;
70  virtual void SetGrayTextAutocompletion(const base::string16& input) OVERRIDE;
71  virtual base::string16 GetGrayTextAutocompletion() const OVERRIDE;
72  virtual int GetTextWidth() const OVERRIDE;
73  virtual int GetWidth() const OVERRIDE;
74  virtual bool IsImeComposing() const OVERRIDE;
75
76  // Implement the AutocompleteTextFieldObserver interface.
77  virtual NSRange SelectionRangeForProposedRange(
78      NSRange proposed_range) OVERRIDE;
79  virtual void OnControlKeyChanged(bool pressed) OVERRIDE;
80  virtual bool CanCopy() OVERRIDE;
81  virtual void CopyToPasteboard(NSPasteboard* pboard) OVERRIDE;
82  virtual bool ShouldEnableShowURL() OVERRIDE;
83  virtual void ShowURL() OVERRIDE;
84  virtual void OnPaste() OVERRIDE;
85  virtual bool CanPasteAndGo() OVERRIDE;
86  virtual int GetPasteActionStringId() OVERRIDE;
87  virtual void OnPasteAndGo() OVERRIDE;
88  virtual void OnFrameChanged() OVERRIDE;
89  virtual void ClosePopup() OVERRIDE;
90  virtual void OnDidBeginEditing() OVERRIDE;
91  virtual void OnBeforeChange() OVERRIDE;
92  virtual void OnDidChange() OVERRIDE;
93  virtual void OnDidEndEditing() OVERRIDE;
94  virtual bool OnDoCommandBySelector(SEL cmd) OVERRIDE;
95  virtual void OnSetFocus(bool control_down) OVERRIDE;
96  virtual void OnKillFocus() OVERRIDE;
97  virtual void OnMouseDown(NSInteger button_number) OVERRIDE;
98  virtual bool ShouldSelectAllOnMouseDown() OVERRIDE;
99
100  // Helper for LocationBarViewMac.  Optionally selects all in |field_|.
101  void FocusLocation(bool select_all);
102
103  // Helper to get the font to use in the field, exposed for the
104  // popup.
105  // The style parameter specifies the new style for the font, and is a
106  // bitmask of the values: BOLD, ITALIC and UNDERLINE (see ui/gfx/font.h).
107  static NSFont* GetFieldFont(int style);
108
109  // If |resource_id| has a PDF image which can be used, return it.
110  // Otherwise return the PNG image from the resource bundle.
111  static NSImage* ImageForResource(int resource_id);
112
113  // Color used to draw suggest text.
114  static NSColor* SuggestTextColor();
115
116  AutocompleteTextField* field() const { return field_; }
117
118 private:
119  // Called when the user hits backspace in |field_|.  Checks whether
120  // keyword search is being terminated.  Returns true if the
121  // backspace should be intercepted (not forwarded on to the standard
122  // machinery).
123  bool OnBackspacePressed();
124
125  // Returns the field's currently selected range.  Only valid if the
126  // field has focus.
127  NSRange GetSelectedRange() const;
128
129  // Returns the field's currently marked range. Only valid if the field has
130  // focus.
131  NSRange GetMarkedRange() const;
132
133  // Returns true if |field_| is first-responder in the window.  Used
134  // in various DCHECKS to make sure code is running in appropriate
135  // situations.
136  bool IsFirstResponder() const;
137
138  // If |model_| believes it has focus, grab focus if needed and set
139  // the selection to |range|.  Otherwise does nothing.
140  void SetSelectedRange(const NSRange range);
141
142  // Update the field with |display_text| and highlight the host and scheme (if
143  // it's an URL or URL-fragment).  Resets any suggest text that may be present.
144  void SetText(const base::string16& display_text);
145
146  // Internal implementation of SetText.  Does not reset the suggest text before
147  // setting the display text.  Most callers should use |SetText()| instead.
148  void SetTextInternal(const base::string16& display_text);
149
150  // Update the field with |display_text| and set the selection.
151  void SetTextAndSelectedRange(const base::string16& display_text,
152                               const NSRange range);
153
154  // Pass the current content of |field_| to SetText(), maintaining
155  // any selection.  Named to be consistent with GTK and Windows,
156  // though here we cannot really do the in-place operation they do.
157  virtual void EmphasizeURLComponents() OVERRIDE;
158
159  // Calculates text attributes according to |display_text| and applies them
160  // to the given |as| object.
161  void ApplyTextAttributes(const base::string16& display_text,
162                           NSMutableAttributedString* as);
163
164  // Return the number of UTF-16 units in the current buffer, excluding the
165  // suggested text.
166  virtual int GetOmniboxTextLength() const OVERRIDE;
167  NSUInteger GetTextLength() const;
168
169  // Returns true if the caret is at the end of the content.
170  bool IsCaretAtEnd() const;
171
172  scoped_ptr<OmniboxPopupView> popup_view_;
173
174  AutocompleteTextField* field_;  // owned by tab controller
175
176  // Selection at the point where the user started using the
177  // arrows to move around in the popup.
178  NSRange saved_temporary_selection_;
179
180  // Tracking state before and after a possible change for reporting
181  // to model_.
182  NSRange selection_before_change_;
183  base::string16 text_before_change_;
184  NSRange marked_range_before_change_;
185
186  // Was delete pressed?
187  bool delete_was_pressed_;
188
189  // Was the delete key pressed with an empty selection at the end of the edit?
190  bool delete_at_end_pressed_;
191
192  base::string16 suggest_text_;
193
194  // State used to coalesce changes to text and selection to avoid drawing
195  // transient state.
196  bool in_coalesced_update_block_;
197  bool do_coalesced_text_update_;
198  base::string16 coalesced_text_update_;
199  bool do_coalesced_range_update_;
200  NSRange coalesced_range_update_;
201
202  DISALLOW_COPY_AND_ASSIGN(OmniboxViewMac);
203};
204
205#endif  // CHROME_BROWSER_UI_COCOA_OMNIBOX_OMNIBOX_VIEW_MAC_H_
206