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.h"
13 #include "chrome/browser/infobars/infobar_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/themes/theme_service.h"
16 #include "chrome/browser/themes/theme_service_factory.h"
17 #include "chrome/browser/ui/browser_finder.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.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
<InfoBar
> new_infobar(ConfirmInfoBarDelegate::CreateInfoBar(
52 scoped_ptr
<ConfirmInfoBarDelegate
>(new ThemeInstalledInfoBarDelegate(
53 profile
->GetExtensionService(), theme_service
, new_theme
,
54 previous_theme_id
, previous_using_native_theme
))));
56 // If there's a previous theme infobar, just replace that instead of adding a
58 for (size_t i
= 0; i
< infobar_service
->infobar_count(); ++i
) {
59 InfoBar
* old_infobar
= infobar_service
->infobar_at(i
);
60 ThemeInstalledInfoBarDelegate
* theme_infobar
=
61 old_infobar
->delegate()->AsThemePreviewInfobarDelegate();
63 // If the user installed the same theme twice, ignore the second install
64 // and keep the first install info bar, so that they can easily undo to
65 // get back the previous theme.
66 if (theme_infobar
->theme_id_
!= new_theme
->id()) {
67 infobar_service
->ReplaceInfoBar(old_infobar
, new_infobar
.Pass());
68 theme_service
->OnInfobarDisplayed();
74 // No previous theme infobar, so add this.
75 infobar_service
->AddInfoBar(new_infobar
.Pass());
76 theme_service
->OnInfobarDisplayed();
79 ThemeInstalledInfoBarDelegate::ThemeInstalledInfoBarDelegate(
80 ExtensionService
* extension_service
,
81 ThemeService
* theme_service
,
82 const extensions::Extension
* new_theme
,
83 const std::string
& previous_theme_id
,
84 bool previous_using_native_theme
)
85 : ConfirmInfoBarDelegate(),
86 extension_service_(extension_service
),
87 theme_service_(theme_service
),
88 name_(new_theme
->name()),
89 theme_id_(new_theme
->id()),
90 previous_theme_id_(previous_theme_id
),
91 previous_using_native_theme_(previous_using_native_theme
) {
92 registrar_
.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED
,
93 content::Source
<ThemeService
>(theme_service_
));
96 ThemeInstalledInfoBarDelegate::~ThemeInstalledInfoBarDelegate() {
97 // We don't want any notifications while we're running our destructor.
98 registrar_
.RemoveAll();
100 theme_service_
->OnInfobarDestroyed();
103 int ThemeInstalledInfoBarDelegate::GetIconID() const {
104 // TODO(aa): Reply with the theme's icon, but this requires reading it
105 // asynchronously from disk.
106 return IDR_INFOBAR_THEME
;
109 InfoBarDelegate::Type
ThemeInstalledInfoBarDelegate::GetInfoBarType() const {
110 return PAGE_ACTION_TYPE
;
113 ThemeInstalledInfoBarDelegate
*
114 ThemeInstalledInfoBarDelegate::AsThemePreviewInfobarDelegate() {
118 base::string16
ThemeInstalledInfoBarDelegate::GetMessageText() const {
119 return l10n_util::GetStringFUTF16(IDS_THEME_INSTALL_INFOBAR_LABEL
,
120 base::UTF8ToUTF16(name_
));
123 int ThemeInstalledInfoBarDelegate::GetButtons() const {
124 return BUTTON_CANCEL
;
127 base::string16
ThemeInstalledInfoBarDelegate::GetButtonLabel(
128 InfoBarButton button
) const {
129 DCHECK_EQ(BUTTON_CANCEL
, button
);
130 return l10n_util::GetStringUTF16(IDS_THEME_INSTALL_INFOBAR_UNDO_BUTTON
);
133 bool ThemeInstalledInfoBarDelegate::Cancel() {
134 if (!previous_theme_id_
.empty()) {
135 const extensions::Extension
* previous_theme
=
136 extension_service_
->GetExtensionById(previous_theme_id_
, true);
137 if (previous_theme
) {
138 theme_service_
->SetTheme(previous_theme
);
139 return false; // The theme change will close us.
143 if (previous_using_native_theme_
)
144 theme_service_
->SetNativeTheme();
146 theme_service_
->UseDefaultTheme();
147 return false; // The theme change will close us.
150 void ThemeInstalledInfoBarDelegate::Observe(
152 const content::NotificationSource
& source
,
153 const content::NotificationDetails
& details
) {
154 DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED
, type
);
155 // If the new theme is different from what this info bar is associated with,
156 // close this info bar since it is no longer relevant.
157 if (theme_id_
!= theme_service_
->GetThemeID())
158 infobar()->RemoveSelf();