| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/notifications/notification_exceptions_table_model.h" |
| |
| #include "base/auto_reset.h" |
| #include "chrome/common/content_settings.h" |
| #include "chrome/common/content_settings_helper.h" |
| #include "chrome/common/content_settings_types.h" |
| #include "chrome/common/url_constants.h" |
| #include "content/common/notification_service.h" |
| #include "content/common/notification_type.h" |
| #include "grit/generated_resources.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/models/table_model_observer.h" |
| |
| struct NotificationExceptionsTableModel::Entry { |
| Entry(const GURL& origin, ContentSetting setting); |
| bool operator<(const Entry& b) const; |
| |
| GURL origin; |
| ContentSetting setting; |
| }; |
| |
| NotificationExceptionsTableModel::NotificationExceptionsTableModel( |
| DesktopNotificationService* service) |
| : service_(service), |
| updates_disabled_(false), |
| observer_(NULL) { |
| registrar_.Add(this, NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED, |
| NotificationService::AllSources()); |
| LoadEntries(); |
| } |
| |
| NotificationExceptionsTableModel::~NotificationExceptionsTableModel() {} |
| |
| bool NotificationExceptionsTableModel::CanRemoveRows( |
| const Rows& rows) const { |
| return !rows.empty(); |
| } |
| |
| void NotificationExceptionsTableModel::RemoveRows(const Rows& rows) { |
| AutoReset<bool> tmp(&updates_disabled_, true); |
| // This is O(n^2) in rows.size(). Since n is small, that's ok. |
| for (Rows::const_reverse_iterator i(rows.rbegin()); i != rows.rend(); ++i) { |
| size_t row = *i; |
| Entry* entry = &entries_[row]; |
| if (entry->setting == CONTENT_SETTING_ALLOW) { |
| service_->ResetAllowedOrigin(entry->origin); |
| } else { |
| DCHECK_EQ(entry->setting, CONTENT_SETTING_BLOCK); |
| service_->ResetBlockedOrigin(entry->origin); |
| } |
| entries_.erase(entries_.begin() + row); // Note: |entry| is now garbage. |
| if (observer_) |
| observer_->OnItemsRemoved(row, 1); |
| } |
| } |
| |
| void NotificationExceptionsTableModel::RemoveAll() { |
| AutoReset<bool> tmp(&updates_disabled_, true); |
| entries_.clear(); |
| service_->ResetAllOrigins(); |
| if (observer_) |
| observer_->OnModelChanged(); |
| } |
| |
| int NotificationExceptionsTableModel::RowCount() { |
| return static_cast<int>(entries_.size()); |
| } |
| |
| string16 NotificationExceptionsTableModel::GetText(int row, |
| int column_id) { |
| const Entry& entry = entries_[row]; |
| if (column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) { |
| return content_settings_helper::OriginToString16(entry.origin); |
| } |
| |
| if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) { |
| switch (entry.setting) { |
| case CONTENT_SETTING_ALLOW: |
| return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_ALLOW_BUTTON); |
| case CONTENT_SETTING_BLOCK: |
| return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_BLOCK_BUTTON); |
| default: |
| break; |
| } |
| } |
| |
| NOTREACHED(); |
| return string16(); |
| } |
| |
| void NotificationExceptionsTableModel::SetObserver( |
| ui::TableModelObserver* observer) { |
| observer_ = observer; |
| } |
| |
| void NotificationExceptionsTableModel::Observe( |
| NotificationType type, |
| const NotificationSource& source, |
| const NotificationDetails& details) { |
| if (!updates_disabled_) { |
| DCHECK(type == NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED); |
| entries_.clear(); |
| LoadEntries(); |
| |
| if (observer_) |
| observer_->OnModelChanged(); |
| } |
| } |
| |
| void NotificationExceptionsTableModel::LoadEntries() { |
| std::vector<GURL> allowed(service_->GetAllowedOrigins()); |
| std::vector<GURL> blocked(service_->GetBlockedOrigins()); |
| entries_.reserve(allowed.size() + blocked.size()); |
| for (size_t i = 0; i < allowed.size(); ++i) |
| entries_.push_back(Entry(allowed[i], CONTENT_SETTING_ALLOW)); |
| for (size_t i = 0; i < blocked.size(); ++i) |
| entries_.push_back(Entry(blocked[i], CONTENT_SETTING_BLOCK)); |
| std::sort(entries_.begin(), entries_.end()); |
| } |
| |
| NotificationExceptionsTableModel::Entry::Entry( |
| const GURL& in_origin, |
| ContentSetting in_setting) |
| : origin(in_origin), |
| setting(in_setting) { |
| } |
| |
| bool NotificationExceptionsTableModel::Entry::operator<( |
| const NotificationExceptionsTableModel::Entry& b) const { |
| DCHECK_NE(origin, b.origin); |
| return origin < b.origin; |
| } |