summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_install_ui.cc16
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc22
-rw-r--r--chrome/browser/tab_contents/tab_contents.h4
-rw-r--r--chrome/browser/views/infobars/infobar_container.cc37
-rw-r--r--chrome/browser/views/infobars/infobar_container.h14
-rw-r--r--chrome/common/notification_type.h7
6 files changed, 84 insertions, 16 deletions
diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc
index 7d879c5..cfc5e54 100644
--- a/chrome/browser/extensions/extension_install_ui.cc
+++ b/chrome/browser/extensions/extension_install_ui.cc
@@ -112,16 +112,22 @@ void ExtensionInstallUI::ShowThemeInfoBar(Extension* extension) {
if (!tab_contents)
return;
- // First remove any previous theme preview infobar.
+ // First find any previous theme preview infobars.
+ InfoBarDelegate* old_delegate = NULL;
for (int i = 0; i < tab_contents->infobar_delegate_count(); ++i) {
InfoBarDelegate* delegate = tab_contents->GetInfoBarDelegateAt(i);
if (delegate->AsThemePreviewInfobarDelegate()) {
- tab_contents->RemoveInfoBar(delegate);
+ old_delegate = delegate;
break;
}
}
- // Now add the new one.
- tab_contents->AddInfoBar(new ThemePreviewInfobarDelegate(
- tab_contents, extension->name()));
+ // Then either replace that old one or add a new one.
+ InfoBarDelegate* new_delegate = new ThemePreviewInfobarDelegate(tab_contents,
+ extension->name());
+
+ if (old_delegate)
+ tab_contents->ReplaceInfoBar(old_delegate, new_delegate);
+ else
+ tab_contents->AddInfoBar(new_delegate);
}
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 5b816f19..5f6de7c 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -890,6 +890,28 @@ void TabContents::RemoveInfoBar(InfoBarDelegate* delegate) {
}
}
+void TabContents::ReplaceInfoBar(InfoBarDelegate* old_delegate,
+ InfoBarDelegate* new_delegate) {
+ std::vector<InfoBarDelegate*>::iterator it =
+ find(infobar_delegates_.begin(), infobar_delegates_.end(), old_delegate);
+ DCHECK(it != infobar_delegates_.end());
+
+ // Notify the container about the change of plans.
+ scoped_ptr<std::pair<InfoBarDelegate*, InfoBarDelegate*> > details(
+ new std::pair<InfoBarDelegate*, InfoBarDelegate*>(
+ old_delegate, new_delegate));
+ NotificationService::current()->Notify(
+ NotificationType::TAB_CONTENTS_INFOBAR_REPLACED,
+ Source<TabContents>(this),
+ Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> >(details.get()));
+
+ // Remove the old one.
+ infobar_delegates_.erase(it);
+
+ // Add the new one.
+ infobar_delegates_.push_back(new_delegate);
+}
+
bool TabContents::IsBookmarkBarAlwaysVisible() {
// See GetDOMUIForCurrentState() comment for more info. This case is very
// similar, but for non-first loads, we want to use the committed entry. This
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index 0536436..e8f7d14 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -401,6 +401,10 @@ class TabContents : public PageNavigator,
// Removes the InfoBar for the specified |delegate|.
void RemoveInfoBar(InfoBarDelegate* delegate);
+ // Replaces one infobar with another, without any animation in between.
+ void ReplaceInfoBar(InfoBarDelegate* old_delegate,
+ InfoBarDelegate* new_delegate);
+
// Enumeration and access functions.
int infobar_delegate_count() const { return infobar_delegates_.size(); }
InfoBarDelegate* GetInfoBarDelegateAt(int index) {
diff --git a/chrome/browser/views/infobars/infobar_container.cc b/chrome/browser/views/infobars/infobar_container.cc
index 530236c..792729b 100644
--- a/chrome/browser/views/infobars/infobar_container.cc
+++ b/chrome/browser/views/infobars/infobar_container.cc
@@ -38,6 +38,8 @@ void InfoBarContainer::ChangeTabContents(TabContents* contents) {
tc_source);
registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED,
tc_source);
+ registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REPLACED,
+ tc_source);
}
}
@@ -109,9 +111,13 @@ void InfoBarContainer::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
if (type == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) {
- AddInfoBar(Details<InfoBarDelegate>(details).ptr());
+ AddInfoBar(Details<InfoBarDelegate>(details).ptr(), true); // animated
} else if (type == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED) {
- RemoveInfoBar(Details<InfoBarDelegate>(details).ptr());
+ RemoveInfoBar(Details<InfoBarDelegate>(details).ptr(), true); // animated
+ } else if (type == NotificationType::TAB_CONTENTS_INFOBAR_REPLACED) {
+ std::pair<InfoBarDelegate*, InfoBarDelegate*>* delegates =
+ Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> >(details).ptr();
+ ReplaceInfoBar(delegates->first, delegates->second);
} else {
NOTREACHED();
}
@@ -129,20 +135,37 @@ void InfoBarContainer::UpdateInfoBars() {
}
}
-void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate) {
+void InfoBarContainer::AddInfoBar(InfoBarDelegate* delegate,
+ bool use_animation) {
InfoBar* infobar = delegate->CreateInfoBar();
infobar->set_container(this);
- infobar->AnimateOpen();
AddChildView(infobar);
+
+ if (use_animation)
+ infobar->AnimateOpen();
+ else
+ infobar->Open();
}
-void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate) {
+void InfoBarContainer::RemoveInfoBar(InfoBarDelegate* delegate,
+ bool use_animation) {
int index = 0;
for (; index < tab_contents_->infobar_delegate_count(); ++index) {
if (tab_contents_->GetInfoBarDelegateAt(index) == delegate)
break;
}
- // The View will be removed once the Close animation completes.
- static_cast<InfoBar*>(GetChildViewAt(index))->AnimateClose();
+ InfoBar* infobar = static_cast<InfoBar*>(GetChildViewAt(index));
+ if (use_animation) {
+ // The View will be removed once the Close animation completes.
+ infobar->AnimateClose();
+ } else {
+ infobar->Close();
+ }
+}
+
+void InfoBarContainer::ReplaceInfoBar(InfoBarDelegate* old_delegate,
+ InfoBarDelegate* new_delegate) {
+ RemoveInfoBar(old_delegate, false); // no animation
+ AddInfoBar(new_delegate, false); // no animation
}
diff --git a/chrome/browser/views/infobars/infobar_container.h b/chrome/browser/views/infobars/infobar_container.h
index 063ba26..b5ea0f0 100644
--- a/chrome/browser/views/infobars/infobar_container.h
+++ b/chrome/browser/views/infobars/infobar_container.h
@@ -57,13 +57,19 @@ class InfoBarContainer : public views::View,
void UpdateInfoBars();
// Adds an InfoBar for the specified delegate, in response to a notification
- // from the selected TabContents. The InfoBar's appearance will be animated.
- void AddInfoBar(InfoBarDelegate* delegate);
+ // from the selected TabContents. The InfoBar's appearance will be animated
+ // if |use_animation| is true.
+ void AddInfoBar(InfoBarDelegate* delegate, bool use_animation);
// Removes an InfoBar for the specified delegate, in response to a
// notification from the selected TabContents. The InfoBar's disappearance
- // will be animated.
- void RemoveInfoBar(InfoBarDelegate* delegate);
+ // will be animated if |use_animation| is true.
+ void RemoveInfoBar(InfoBarDelegate* delegate, bool use_animation);
+
+ // Replaces an InfoBar for the specified delegate with a new one. There is no
+ // animation.
+ void ReplaceInfoBar(InfoBarDelegate* old_delegate,
+ InfoBarDelegate* new_delegate);
NotificationRegistrar registrar_;
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 7a95f9a..2a04ffe 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -280,6 +280,13 @@ class NotificationType {
// InfoBarDelegate interface for the InfoBar that was removed.
TAB_CONTENTS_INFOBAR_REMOVED,
+ // This message is sent when an InfoBar is replacing another infobar in a
+ // TabContents. The source is a Source<TabContents> with a pointer to the
+ // TabContents the InfoBar was removed from. The details is a
+ // Details<std::pair<InfoBarDelegate*, InfoBarDelegate*> > with a pointer
+ // to the old and new InfoBarDelegates, respectively.
+ TAB_CONTENTS_INFOBAR_REPLACED,
+
// This is sent when an externally hosted tab is created. The details
// contain the ExternalTabContainer that contains the tab
EXTERNAL_TAB_CREATED,