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.
5 #include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/infobars/infobar_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/themes/theme_service.h"
15 #include "chrome/browser/themes/theme_service_factory.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "components/infobars/core/infobar.h"
20 #include "content/public/browser/notification_source.h"
21 #include "extensions/browser/extension_system.h"
22 #include "extensions/common/extension.h"
23 #include "grit/theme_resources.h"
24 #include "ui/base/l10n/l10n_util.h"
28 void ThemeInstalledInfoBarDelegate::Create(
29 const extensions::Extension
* new_theme
,
31 const std::string
& previous_theme_id
,
32 bool previous_using_system_theme
) {
34 if (!new_theme
->is_theme())
37 // Create the new infobar.
38 // FindTabbedBrowser() is called with |match_original_profiles| true because a
39 // theme install in either a normal or incognito window for a profile affects
40 // all normal and incognito windows for that profile.
42 chrome::FindTabbedBrowser(profile
, true, chrome::GetActiveDesktop());
45 content::WebContents
* web_contents
=
46 browser
->tab_strip_model()->GetActiveWebContents();
49 InfoBarService
* infobar_service
=
50 InfoBarService::FromWebContents(web_contents
);
51 ThemeService
* theme_service
= ThemeServiceFactory::GetForProfile(profile
);
52 scoped_ptr
<infobars::InfoBar
> new_infobar(
53 infobar_service
->CreateConfirmInfoBar(
54 scoped_ptr
<ConfirmInfoBarDelegate
>(new ThemeInstalledInfoBarDelegate(
55 extensions::ExtensionSystem::Get(profile
)->extension_service(),
56 theme_service
, new_theme
, previous_theme_id
,
57 previous_using_system_theme
))));
59 // If there's a previous theme infobar, just replace that instead of adding a
61 for (size_t i
= 0; i
< infobar_service
->infobar_count(); ++i
) {
62 infobars::InfoBar
* old_infobar
= infobar_service
->infobar_at(i
);
63 ThemeInstalledInfoBarDelegate
* theme_infobar
=
64 old_infobar
->delegate()->AsThemePreviewInfobarDelegate();
66 // If the user installed the same theme twice, ignore the second install
67 // and keep the first install info bar, so that they can easily undo to
68 // get back the previous theme.
69 if (theme_infobar
->theme_id_
!= new_theme
->id()) {
70 infobar_service
->ReplaceInfoBar(old_infobar
, new_infobar
.Pass());
71 theme_service
->OnInfobarDisplayed();
77 // No previous theme infobar, so add this.
78 infobar_service
->AddInfoBar(new_infobar
.Pass());
79 theme_service
->OnInfobarDisplayed();
82 ThemeInstalledInfoBarDelegate::ThemeInstalledInfoBarDelegate(
83 ExtensionService
* extension_service
,
84 ThemeService
* theme_service
,
85 const extensions::Extension
* new_theme
,
86 const std::string
& previous_theme_id
,
87 bool previous_using_system_theme
)
88 : ConfirmInfoBarDelegate(),
89 extension_service_(extension_service
),
90 theme_service_(theme_service
),
91 name_(new_theme
->name()),
92 theme_id_(new_theme
->id()),
93 previous_theme_id_(previous_theme_id
),
94 previous_using_system_theme_(previous_using_system_theme
) {
95 registrar_
.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED
,
96 content::Source
<ThemeService
>(theme_service_
));
99 ThemeInstalledInfoBarDelegate::~ThemeInstalledInfoBarDelegate() {
100 // We don't want any notifications while we're running our destructor.
101 registrar_
.RemoveAll();
103 theme_service_
->OnInfobarDestroyed();
106 infobars::InfoBarDelegate::Type
107 ThemeInstalledInfoBarDelegate::GetInfoBarType() const {
108 return PAGE_ACTION_TYPE
;
111 int ThemeInstalledInfoBarDelegate::GetIconID() const {
112 // TODO(aa): Reply with the theme's icon, but this requires reading it
113 // asynchronously from disk.
114 return IDR_INFOBAR_THEME
;
117 ThemeInstalledInfoBarDelegate
*
118 ThemeInstalledInfoBarDelegate::AsThemePreviewInfobarDelegate() {
122 base::string16
ThemeInstalledInfoBarDelegate::GetMessageText() const {
123 return l10n_util::GetStringFUTF16(IDS_THEME_INSTALL_INFOBAR_LABEL
,
124 base::UTF8ToUTF16(name_
));
127 int ThemeInstalledInfoBarDelegate::GetButtons() const {
128 return BUTTON_CANCEL
;
131 base::string16
ThemeInstalledInfoBarDelegate::GetButtonLabel(
132 InfoBarButton button
) const {
133 DCHECK_EQ(BUTTON_CANCEL
, button
);
134 return l10n_util::GetStringUTF16(IDS_THEME_INSTALL_INFOBAR_UNDO_BUTTON
);
137 bool ThemeInstalledInfoBarDelegate::Cancel() {
138 if (!previous_theme_id_
.empty()) {
139 const extensions::Extension
* previous_theme
=
140 extension_service_
->GetExtensionById(previous_theme_id_
, true);
141 if (previous_theme
) {
142 theme_service_
->SetTheme(previous_theme
);
143 return false; // The theme change will close us.
147 if (previous_using_system_theme_
)
148 theme_service_
->UseSystemTheme();
150 theme_service_
->UseDefaultTheme();
151 return false; // The theme change will close us.
154 void ThemeInstalledInfoBarDelegate::Observe(
156 const content::NotificationSource
& source
,
157 const content::NotificationDetails
& details
) {
158 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED
, type
);
159 // If the new theme is different from what this info bar is associated with,
160 // close this info bar since it is no longer relevant.
161 if (theme_id_
!= theme_service_
->GetThemeID())
162 infobar()->RemoveSelf();