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 "components/infobars/core/infobar.h"
19 #include "content/public/browser/notification_source.h"
20 #include "extensions/common/extension.h"
21 #include "grit/generated_resources.h"
22 #include "grit/theme_resources.h"
23 #include "ui/base/l10n/l10n_util.h"
27 void ThemeInstalledInfoBarDelegate::Create(
28 const extensions::Extension
* new_theme
,
30 const std::string
& previous_theme_id
,
31 bool previous_using_native_theme
) {
33 if (!new_theme
->is_theme())
36 // Create the new infobar.
37 // FindTabbedBrowser() is called with |match_original_profiles| true because a
38 // theme install in either a normal or incognito window for a profile affects
39 // all normal and incognito windows for that profile.
41 chrome::FindTabbedBrowser(profile
, true, chrome::GetActiveDesktop());
44 content::WebContents
* web_contents
=
45 browser
->tab_strip_model()->GetActiveWebContents();
48 InfoBarService
* infobar_service
=
49 InfoBarService::FromWebContents(web_contents
);
50 ThemeService
* theme_service
= ThemeServiceFactory::GetForProfile(profile
);
51 scoped_ptr
<infobars::InfoBar
> new_infobar(
52 ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr
<ConfirmInfoBarDelegate
>(
53 new ThemeInstalledInfoBarDelegate(
54 profile
->GetExtensionService(), theme_service
, new_theme
,
55 previous_theme_id
, previous_using_native_theme
))));
57 // If there's a previous theme infobar, just replace that instead of adding a
59 for (size_t i
= 0; i
< infobar_service
->infobar_count(); ++i
) {
60 infobars::InfoBar
* old_infobar
= infobar_service
->infobar_at(i
);
61 ThemeInstalledInfoBarDelegate
* theme_infobar
=
62 old_infobar
->delegate()->AsThemePreviewInfobarDelegate();
64 // If the user installed the same theme twice, ignore the second install
65 // and keep the first install info bar, so that they can easily undo to
66 // get back the previous theme.
67 if (theme_infobar
->theme_id_
!= new_theme
->id()) {
68 infobar_service
->ReplaceInfoBar(old_infobar
, new_infobar
.Pass());
69 theme_service
->OnInfobarDisplayed();
75 // No previous theme infobar, so add this.
76 infobar_service
->AddInfoBar(new_infobar
.Pass());
77 theme_service
->OnInfobarDisplayed();
80 ThemeInstalledInfoBarDelegate::ThemeInstalledInfoBarDelegate(
81 ExtensionService
* extension_service
,
82 ThemeService
* theme_service
,
83 const extensions::Extension
* new_theme
,
84 const std::string
& previous_theme_id
,
85 bool previous_using_native_theme
)
86 : ConfirmInfoBarDelegate(),
87 extension_service_(extension_service
),
88 theme_service_(theme_service
),
89 name_(new_theme
->name()),
90 theme_id_(new_theme
->id()),
91 previous_theme_id_(previous_theme_id
),
92 previous_using_native_theme_(previous_using_native_theme
) {
93 registrar_
.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED
,
94 content::Source
<ThemeService
>(theme_service_
));
97 ThemeInstalledInfoBarDelegate::~ThemeInstalledInfoBarDelegate() {
98 // We don't want any notifications while we're running our destructor.
99 registrar_
.RemoveAll();
101 theme_service_
->OnInfobarDestroyed();
104 int ThemeInstalledInfoBarDelegate::GetIconID() const {
105 // TODO(aa): Reply with the theme's icon, but this requires reading it
106 // asynchronously from disk.
107 return IDR_INFOBAR_THEME
;
110 infobars::InfoBarDelegate::Type
ThemeInstalledInfoBarDelegate::GetInfoBarType()
112 return PAGE_ACTION_TYPE
;
115 ThemeInstalledInfoBarDelegate
*
116 ThemeInstalledInfoBarDelegate::AsThemePreviewInfobarDelegate() {
120 base::string16
ThemeInstalledInfoBarDelegate::GetMessageText() const {
121 return l10n_util::GetStringFUTF16(IDS_THEME_INSTALL_INFOBAR_LABEL
,
122 base::UTF8ToUTF16(name_
));
125 int ThemeInstalledInfoBarDelegate::GetButtons() const {
126 return BUTTON_CANCEL
;
129 base::string16
ThemeInstalledInfoBarDelegate::GetButtonLabel(
130 InfoBarButton button
) const {
131 DCHECK_EQ(BUTTON_CANCEL
, button
);
132 return l10n_util::GetStringUTF16(IDS_THEME_INSTALL_INFOBAR_UNDO_BUTTON
);
135 bool ThemeInstalledInfoBarDelegate::Cancel() {
136 if (!previous_theme_id_
.empty()) {
137 const extensions::Extension
* previous_theme
=
138 extension_service_
->GetExtensionById(previous_theme_id_
, true);
139 if (previous_theme
) {
140 theme_service_
->SetTheme(previous_theme
);
141 return false; // The theme change will close us.
145 if (previous_using_native_theme_
)
146 theme_service_
->SetNativeTheme();
148 theme_service_
->UseDefaultTheme();
149 return false; // The theme change will close us.
152 void ThemeInstalledInfoBarDelegate::Observe(
154 const content::NotificationSource
& source
,
155 const content::NotificationDetails
& details
) {
156 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED
, type
);
157 // If the new theme is different from what this info bar is associated with,
158 // close this info bar since it is no longer relevant.
159 if (theme_id_
!= theme_service_
->GetThemeID())
160 infobar()->RemoveSelf();