1// Copyright 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#include "chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h"
6
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/browser/autocomplete/shortcuts_backend.h"
9#include "chrome/browser/autocomplete/shortcuts_backend_factory.h"
10#include "chrome/browser/history/history_service.h"
11#include "chrome/browser/history/history_service_factory.h"
12#include "chrome/browser/infobars/infobar_service.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/grit/generated_resources.h"
15#include "components/infobars/core/infobar.h"
16#include "content/public/browser/web_contents.h"
17#include "grit/theme_resources.h"
18#include "ui/base/l10n/l10n_util.h"
19
20
21AlternateNavInfoBarDelegate::~AlternateNavInfoBarDelegate() {
22}
23
24// static
25void AlternateNavInfoBarDelegate::Create(
26    content::WebContents* web_contents,
27    const base::string16& text,
28    const AutocompleteMatch& match,
29    const GURL& search_url) {
30  InfoBarService* infobar_service =
31      InfoBarService::FromWebContents(web_contents);
32  infobar_service->AddInfoBar(AlternateNavInfoBarDelegate::CreateInfoBar(
33      scoped_ptr<AlternateNavInfoBarDelegate>(new AlternateNavInfoBarDelegate(
34          Profile::FromBrowserContext(web_contents->GetBrowserContext()), text,
35          match, search_url))));
36}
37
38AlternateNavInfoBarDelegate::AlternateNavInfoBarDelegate(
39    Profile* profile,
40    const base::string16& text,
41    const AutocompleteMatch& match,
42    const GURL& search_url)
43    : infobars::InfoBarDelegate(),
44      profile_(profile),
45      text_(text),
46      match_(match),
47      search_url_(search_url) {
48  DCHECK(match_.destination_url.is_valid());
49  DCHECK(search_url_.is_valid());
50}
51
52// AlternateNavInfoBarDelegate::CreateInfoBar() is implemented in
53// platform-specific files.
54
55base::string16 AlternateNavInfoBarDelegate::GetMessageTextWithOffset(
56    size_t* link_offset) const {
57  const base::string16 label = l10n_util::GetStringFUTF16(
58      IDS_ALTERNATE_NAV_URL_VIEW_LABEL, base::string16(), link_offset);
59  return label;
60}
61
62base::string16 AlternateNavInfoBarDelegate::GetLinkText() const {
63  return base::UTF8ToUTF16(match_.destination_url.spec());
64}
65
66bool AlternateNavInfoBarDelegate::LinkClicked(
67    WindowOpenDisposition disposition) {
68  // Tell the shortcuts backend to remove the shortcut it added for the original
69  // search and instead add one reflecting this navigation.
70  scoped_refptr<ShortcutsBackend> shortcuts_backend(
71      ShortcutsBackendFactory::GetForProfile(profile_));
72  if (shortcuts_backend.get()) {  // May be NULL in incognito.
73    shortcuts_backend->DeleteShortcutsWithURL(search_url_);
74    shortcuts_backend->AddOrUpdateShortcut(text_, match_);
75  }
76
77  // Tell the history system to remove any saved search term for the search.
78  HistoryService* const history_service =
79      HistoryServiceFactory::GetForProfile(profile_, Profile::IMPLICIT_ACCESS);
80  if (history_service)
81    history_service->DeleteKeywordSearchTermForURL(search_url_);
82
83  // Pretend the user typed this URL, so that navigating to it will be the
84  // default action when it's typed again in the future.
85  InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL(
86      content::OpenURLParams(match_.destination_url, content::Referrer(),
87                             disposition, ui::PAGE_TRANSITION_TYPED,
88                             false));
89
90  // We should always close, even if the navigation did not occur within this
91  // WebContents.
92  return true;
93}
94
95int AlternateNavInfoBarDelegate::GetIconID() const {
96  return IDR_INFOBAR_ALT_NAV_URL;
97}
98
99infobars::InfoBarDelegate::Type AlternateNavInfoBarDelegate::GetInfoBarType()
100    const {
101  return PAGE_ACTION_TYPE;
102}
103