1// Copyright (c) 2011 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_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/compiler_specific.h"
13#include "base/task.h"
14#include "chrome/browser/autocomplete/autocomplete_edit.h"
15#include "chrome/browser/extensions/extension_context_menu_model.h"
16#include "chrome/browser/first_run/first_run.h"
17#include "chrome/browser/prefs/pref_member.h"
18#include "chrome/browser/search_engines/template_url_model_observer.h"
19#include "chrome/browser/ui/omnibox/location_bar.h"
20#include "chrome/browser/ui/toolbar/toolbar_model.h"
21#include "chrome/browser/ui/views/extensions/extension_popup.h"
22#include "ui/gfx/font.h"
23#include "ui/gfx/rect.h"
24#include "views/controls/native/native_view_host.h"
25
26#if defined(OS_WIN)
27#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h"
28#elif defined(OS_LINUX)
29#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
30#endif
31
32class CommandUpdater;
33class ContentSettingImageView;
34class EVBubbleView;
35class ExtensionAction;
36class GURL;
37class InstantController;
38class KeywordHintView;
39class LocationIconView;
40class PageActionWithBadgeView;
41class Profile;
42class SelectedKeywordView;
43class StarView;
44class TabContents;
45class TabContentsWrapper;
46class TemplateURLModel;
47
48namespace views {
49class HorizontalPainter;
50class Label;
51};
52
53#if defined(OS_WIN)
54class SuggestedTextView;
55#endif
56
57/////////////////////////////////////////////////////////////////////////////
58//
59// LocationBarView class
60//
61//   The LocationBarView class is a View subclass that paints the background
62//   of the URL bar strip and contains its content.
63//
64/////////////////////////////////////////////////////////////////////////////
65class LocationBarView : public LocationBar,
66                        public LocationBarTesting,
67                        public views::View,
68                        public views::DragController,
69                        public AutocompleteEditController,
70                        public TemplateURLModelObserver,
71                        public NotificationObserver {
72 public:
73  // The location bar view's class name.
74  static const char kViewClassName[];
75
76  class Delegate {
77   public:
78    // Should return the current tab contents.
79    virtual TabContentsWrapper* GetTabContentsWrapper() const = 0;
80
81    // Returns the InstantController, or NULL if there isn't one.
82    virtual InstantController* GetInstant() = 0;
83
84    // Called by the location bar view when the user starts typing in the edit.
85    // This forces our security style to be UNKNOWN for the duration of the
86    // editing.
87    virtual void OnInputInProgress(bool in_progress) = 0;
88  };
89
90  enum ColorKind {
91    BACKGROUND = 0,
92    TEXT,
93    SELECTED_TEXT,
94    DEEMPHASIZED_TEXT,
95    SECURITY_TEXT,
96  };
97
98  // The modes reflect the different scenarios where a location bar can be used.
99  // The normal mode is the mode used in a regular browser window.
100  // In popup mode, the location bar view is read only and has a slightly
101  // different presentation (font size / color).
102  // In app launcher mode, the location bar is empty and no security states or
103  // page/browser actions are displayed.
104  enum Mode {
105    NORMAL = 0,
106    POPUP,
107    APP_LAUNCHER
108  };
109
110  LocationBarView(Profile* profile,
111                  CommandUpdater* command_updater,
112                  ToolbarModel* model,
113                  Delegate* delegate,
114                  Mode mode);
115  virtual ~LocationBarView();
116
117  void Init();
118
119  // True if this instance has been initialized by calling Init, which can only
120  // be called when the receiving instance is attached to a view container.
121  bool IsInitialized() const;
122
123  // Returns the appropriate color for the desired kind, based on the user's
124  // system theme.
125  static SkColor GetColor(ToolbarModel::SecurityLevel security_level,
126                          ColorKind kind);
127
128  // Updates the location bar.  We also reset the bar's permanent text and
129  // security style, and, if |tab_for_state_restoring| is non-NULL, also restore
130  // saved state that the tab holds.
131  void Update(const TabContents* tab_for_state_restoring);
132
133  void SetProfile(Profile* profile);
134  Profile* profile() const { return profile_; }
135
136  // Sets |preview_enabled| for the PageAction View associated with this
137  // |page_action|. If |preview_enabled| is true, the view will display the
138  // PageActions icon even though it has not been activated by the extension.
139  // This is used by the ExtensionInstalledBubble to preview what the icon
140  // will look like for the user upon installation of the extension.
141  void SetPreviewEnabledPageAction(ExtensionAction *page_action,
142                                   bool preview_enabled);
143
144  // Retrieves the PageAction View which is associated with |page_action|.
145  views::View* GetPageActionView(ExtensionAction* page_action);
146
147  // Toggles the star on or off.
148  void SetStarToggled(bool on);
149
150  // Shows the bookmark bubble.
151  void ShowStarBubble(const GURL& url, bool newly_bookmarked);
152
153  // Returns the screen coordinates of the location entry (where the URL text
154  // appears, not where the icons are shown).
155  gfx::Point GetLocationEntryOrigin() const;
156
157#if defined(OS_WIN)
158  // Invoked from AutocompleteEditViewWin to show the instant suggestion.
159  void SetInstantSuggestion(const string16& text,
160                            bool animate_to_complete);
161
162  // Returns the current instant suggestion text.
163  string16 GetInstantSuggestion() const;
164#endif
165
166  // Sizing functions
167  virtual gfx::Size GetPreferredSize() OVERRIDE;
168
169  // Layout and Painting functions
170  virtual void Layout() OVERRIDE;
171  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
172
173  // No focus border for the location bar, the caret is enough.
174  virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE { }
175
176  // Set if we should show a focus rect while the location entry field is
177  // focused. Used when the toolbar is in full keyboard accessibility mode.
178  // Repaints if necessary.
179  virtual void SetShowFocusRect(bool show);
180
181  // Select all of the text. Needed when the user tabs through controls
182  // in the toolbar in full keyboard accessibility mode.
183  virtual void SelectAll();
184
185#if defined(OS_WIN)
186  // Event Handlers
187  virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE;
188  virtual bool OnMouseDragged(const views::MouseEvent& event) OVERRIDE;
189  virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE;
190  virtual void OnMouseCaptureLost() OVERRIDE;
191#endif
192
193  const LocationIconView* location_icon_view() const {
194    return location_icon_view_;
195  }
196
197  // AutocompleteEditController
198  virtual void OnAutocompleteAccept(const GURL& url,
199                                    WindowOpenDisposition disposition,
200                                    PageTransition::Type transition,
201                                    const GURL& alternate_nav_url) OVERRIDE;
202  virtual void OnChanged() OVERRIDE;
203  virtual void OnSelectionBoundsChanged() OVERRIDE;
204  virtual void OnInputInProgress(bool in_progress) OVERRIDE;
205  virtual void OnKillFocus() OVERRIDE;
206  virtual void OnSetFocus() OVERRIDE;
207  virtual SkBitmap GetFavicon() const OVERRIDE;
208  virtual string16 GetTitle() const OVERRIDE;
209  virtual InstantController* GetInstant() OVERRIDE;
210  virtual TabContentsWrapper* GetTabContentsWrapper() const OVERRIDE;
211
212  // Overridden from views::View:
213  virtual std::string GetClassName() const OVERRIDE;
214  virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& event)
215      OVERRIDE;
216  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
217
218  // Overridden from views::DragController:
219  virtual void WriteDragDataForView(View* sender,
220                                    const gfx::Point& press_pt,
221                                    OSExchangeData* data) OVERRIDE;
222  virtual int GetDragOperationsForView(View* sender,
223                                       const gfx::Point& p) OVERRIDE;
224  virtual bool CanStartDragForView(View* sender,
225                                   const gfx::Point& press_pt,
226                                   const gfx::Point& p) OVERRIDE;
227
228  // Overridden from LocationBar:
229  virtual void ShowFirstRunBubble(FirstRun::BubbleType bubble_type) OVERRIDE;
230  virtual void SetSuggestedText(const string16& text,
231                                InstantCompleteBehavior behavior) OVERRIDE;
232  virtual std::wstring GetInputString() const OVERRIDE;
233  virtual WindowOpenDisposition GetWindowOpenDisposition() const OVERRIDE;
234  virtual PageTransition::Type GetPageTransition() const OVERRIDE;
235  virtual void AcceptInput() OVERRIDE;
236  virtual void FocusLocation(bool select_all) OVERRIDE;
237  virtual void FocusSearch() OVERRIDE;
238  virtual void UpdateContentSettingsIcons() OVERRIDE;
239  virtual void UpdatePageActions() OVERRIDE;
240  virtual void InvalidatePageActions() OVERRIDE;
241  virtual void SaveStateToContents(TabContents* contents) OVERRIDE;
242  virtual void Revert() OVERRIDE;
243  virtual const AutocompleteEditView* location_entry() const OVERRIDE;
244  virtual AutocompleteEditView* location_entry() OVERRIDE;
245  virtual LocationBarTesting* GetLocationBarForTesting() OVERRIDE;
246
247  // Overridden from LocationBarTesting:
248  virtual int PageActionCount() OVERRIDE;
249  virtual int PageActionVisibleCount() OVERRIDE;
250  virtual ExtensionAction* GetPageAction(size_t index) OVERRIDE;
251  virtual ExtensionAction* GetVisiblePageAction(size_t index) OVERRIDE;
252  virtual void TestPageActionPressed(size_t index) OVERRIDE;
253
254  // Overridden from TemplateURLModelObserver
255  virtual void OnTemplateURLModelChanged() OVERRIDE;
256
257  // Overridden from NotificationObserver
258  virtual void Observe(NotificationType type,
259                       const NotificationSource& source,
260                       const NotificationDetails& details) OVERRIDE;
261
262  // Thickness of the left and right edges of the omnibox, in normal mode.
263  static const int kNormalHorizontalEdgeThickness;
264  // Thickness of the top and bottom edges of the omnibox.
265  static const int kVerticalEdgeThickness;
266  // Space between items in the location bar.
267  static const int kItemPadding;
268  // Amount of padding built into the standard omnibox icons.
269  static const int kIconInternalPadding;
270  // Space between the edges and the items next to them.
271  static const int kEdgeItemPadding;
272  // Space between the edge and a bubble.
273  static const int kBubbleHorizontalPadding;
274
275 protected:
276  virtual void OnFocus() OVERRIDE;
277
278 private:
279  typedef std::vector<ContentSettingImageView*> ContentSettingViews;
280
281  friend class PageActionImageView;
282  friend class PageActionWithBadgeView;
283  typedef std::vector<PageActionWithBadgeView*> PageActionViews;
284
285  // Returns the amount of horizontal space (in pixels) out of
286  // |location_bar_width| that is not taken up by the actual text in
287  // location_entry_.
288  int AvailableWidth(int location_bar_width);
289
290  // If |view| fits in |available_width|, it is made visible and positioned at
291  // the leading or trailing end of |bounds|, which are then shrunk
292  // appropriately.  Otherwise |view| is made invisible.
293  // Note: |view| is expected to have already been positioned and sized
294  // vertically.
295  void LayoutView(views::View* view,
296                  int padding,
297                  int available_width,
298                  bool leading,
299                  gfx::Rect* bounds);
300
301  // Update the visibility state of the Content Blocked icons to reflect what is
302  // actually blocked on the current page.
303  void RefreshContentSettingViews();
304
305  // Delete all page action views that we have created.
306  void DeletePageActionViews();
307
308  // Update the views for the Page Actions, to reflect state changes for
309  // PageActions.
310  void RefreshPageActionViews();
311
312  // Sets the visibility of view to new_vis.
313  void ToggleVisibility(bool new_vis, views::View* view);
314
315#if defined(OS_WIN)
316  // Helper for the Mouse event handlers that does all the real work.
317  void OnMouseEvent(const views::MouseEvent& event, UINT msg);
318
319  // Returns true if the suggest text is valid.
320  bool HasValidSuggestText() const;
321#endif
322
323  // Helper to show the first run info bubble.
324  void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type);
325
326  // Current profile. Not owned by us.
327  Profile* profile_;
328
329  // The Autocomplete Edit field.
330#if defined(OS_WIN)
331  scoped_ptr<AutocompleteEditViewWin> location_entry_;
332#else
333  scoped_ptr<AutocompleteEditView> location_entry_;
334#endif
335
336  // The CommandUpdater for the Browser object that corresponds to this View.
337  CommandUpdater* command_updater_;
338
339  // The model.
340  ToolbarModel* model_;
341
342  // Our delegate.
343  Delegate* delegate_;
344
345  // This is the string of text from the autocompletion session that the user
346  // entered or selected.
347  std::wstring location_input_;
348
349  // The user's desired disposition for how their input should be opened
350  WindowOpenDisposition disposition_;
351
352  // The transition type to use for the navigation
353  PageTransition::Type transition_;
354
355  // Font used by edit and some of the hints.
356  gfx::Font font_;
357
358  // An object used to paint the normal-mode background.
359  scoped_ptr<views::HorizontalPainter> painter_;
360
361  // An icon to the left of the edit field.
362  LocationIconView* location_icon_view_;
363
364  // A bubble displayed for EV HTTPS sites.
365  EVBubbleView* ev_bubble_view_;
366
367  // Location_entry view
368  views::View* location_entry_view_;
369
370  // The following views are used to provide hints and remind the user as to
371  // what is going in the edit. They are all added a children of the
372  // LocationBarView. At most one is visible at a time. Preference is
373  // given to the keyword_view_, then hint_view_.
374  // These autocollapse when the edit needs the room.
375
376  // Shown if the user has selected a keyword.
377  SelectedKeywordView* selected_keyword_view_;
378
379#if defined(OS_WIN)
380  // View responsible for showing suggested text. This is NULL when there is no
381  // suggested text.
382  SuggestedTextView* suggested_text_view_;
383#endif
384
385  // Shown if the selected url has a corresponding keyword.
386  KeywordHintView* keyword_hint_view_;
387
388  // The content setting views.
389  ContentSettingViews content_setting_views_;
390
391  // The page action icon views.
392  PageActionViews page_action_views_;
393
394  // The star.
395  StarView* star_view_;
396
397  // The mode that dictates how the bar shows.
398  Mode mode_;
399
400  // True if we should show a focus rect while the location entry field is
401  // focused. Used when the toolbar is in full keyboard accessibility mode.
402  bool show_focus_rect_;
403
404  // Whether bubble text is short or long.
405  FirstRun::BubbleType bubble_type_;
406
407  // This is in case we're destroyed before the model loads. We store the model
408  // because calling profile_->GetTemplateURLModel() in the destructor causes a
409  // crash.
410  TemplateURLModel* template_url_model_;
411
412  // Tracks this preference to determine whether bookmark editing is allowed.
413  BooleanPrefMember edit_bookmarks_enabled_;
414
415  DISALLOW_IMPLICIT_CONSTRUCTORS(LocationBarView);
416};
417
418#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
419