// Copyright (c) 2010 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/plugin_exceptions_table_model.h" #include "app/l10n_util.h" #include "app/table_model_observer.h" #include "base/auto_reset.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/common/notification_service.h" #include "grit/generated_resources.h" PluginExceptionsTableModel::PluginExceptionsTableModel( HostContentSettingsMap* content_settings_map, HostContentSettingsMap* otr_content_settings_map) : map_(content_settings_map), otr_map_(otr_content_settings_map), updates_disabled_(false), observer_(NULL) { registrar_.Add(this, NotificationType::CONTENT_SETTINGS_CHANGED, NotificationService::AllSources()); } PluginExceptionsTableModel::~PluginExceptionsTableModel() {} bool PluginExceptionsTableModel::CanRemoveRows(const Rows& rows) const { return !rows.empty(); } void PluginExceptionsTableModel::RemoveRows(const Rows& rows) { AutoReset tmp(&updates_disabled_, true); bool reload_all = false; // Iterate in reverse over the rows to get the indexes right. for (Rows::const_reverse_iterator it = rows.rbegin(); it != rows.rend(); ++it) { DCHECK_LT(*it, settings_.size()); SettingsEntry& entry = settings_[*it]; HostContentSettingsMap* map = entry.is_otr ? otr_map_ : map_; map->SetContentSetting(entry.pattern, CONTENT_SETTINGS_TYPE_PLUGINS, resources_[entry.plugin_id], CONTENT_SETTING_DEFAULT); settings_.erase(settings_.begin() + *it); row_counts_[entry.plugin_id]--; if (!reload_all) { // If we remove the last exception for a plugin, recreate all groups // to get correct IDs. if (row_counts_[entry.plugin_id] == 0) { reload_all = true; } else { observer_->OnItemsRemoved(*it, 1); } } } if (reload_all) { // This also notifies the observer. ReloadSettings(); } } void PluginExceptionsTableModel::RemoveAll() { AutoReset tmp(&updates_disabled_, true); map_->ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS); if (otr_map_) otr_map_->ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS); ClearSettings(); if (observer_) observer_->OnModelChanged(); } int PluginExceptionsTableModel::RowCount() { return settings_.size(); } std::wstring PluginExceptionsTableModel::GetText(int row, int column_id) { DCHECK_GE(row, 0); DCHECK_LT(row, static_cast(settings_.size())); SettingsEntry& entry = settings_[row]; switch (column_id) { case IDS_EXCEPTIONS_PATTERN_HEADER: case IDS_EXCEPTIONS_HOSTNAME_HEADER: return UTF8ToWide(entry.pattern.AsString()); case IDS_EXCEPTIONS_ACTION_HEADER: switch (entry.setting) { case CONTENT_SETTING_ALLOW: return l10n_util::GetString(IDS_EXCEPTIONS_ALLOW_BUTTON); case CONTENT_SETTING_BLOCK: return l10n_util::GetString(IDS_EXCEPTIONS_BLOCK_BUTTON); default: NOTREACHED(); } break; default: NOTREACHED(); } return std::wstring(); } void PluginExceptionsTableModel::SetObserver(TableModelObserver* observer) { observer_ = observer; } TableModel::Groups PluginExceptionsTableModel::GetGroups() { return groups_; } int PluginExceptionsTableModel::GetGroupID(int row) { DCHECK_LT(row, static_cast(settings_.size())); return settings_[row].plugin_id; } void PluginExceptionsTableModel::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { if (!updates_disabled_) ReloadSettings(); } void PluginExceptionsTableModel::ClearSettings() { settings_.clear(); groups_.clear(); row_counts_.clear(); resources_.clear(); } void PluginExceptionsTableModel::GetPlugins( NPAPI::PluginList::PluginMap* plugins) { NPAPI::PluginList::Singleton()->GetPluginGroups(false, plugins); } void PluginExceptionsTableModel::LoadSettings() { int group_id = 0; NPAPI::PluginList::PluginMap plugins; GetPlugins(&plugins); for (NPAPI::PluginList::PluginMap::iterator it = plugins.begin(); it != plugins.end(); ++it) { std::string plugin = it->first; HostContentSettingsMap::SettingsForOneType settings; map_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, plugin, &settings); HostContentSettingsMap::SettingsForOneType otr_settings; if (otr_map_) { otr_map_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS, plugin, &otr_settings); } std::wstring title = UTF16ToWide(it->second->GetGroupName()); for (HostContentSettingsMap::SettingsForOneType::iterator setting_it = settings.begin(); setting_it != settings.end(); ++setting_it) { SettingsEntry entry = { setting_it->first, group_id, setting_it->second, false }; settings_.push_back(entry); } for (HostContentSettingsMap::SettingsForOneType::iterator setting_it = otr_settings.begin(); setting_it != otr_settings.end(); ++setting_it) { SettingsEntry entry = { setting_it->first, group_id, setting_it->second, true }; settings_.push_back(entry); } int num_plugins = settings.size() + otr_settings.size(); if (num_plugins > 0) { Group group = { title, group_id++ }; groups_.push_back(group); resources_.push_back(plugin); row_counts_.push_back(num_plugins); } } } void PluginExceptionsTableModel::ReloadSettings() { ClearSettings(); LoadSettings(); if (observer_) observer_->OnModelChanged(); }