1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/notifications/notification_exceptions_table_model.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/auto_reset.h"
8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/content_settings.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/content_settings_helper.h"
10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/content_settings_types.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/models/table_model_observer.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstruct NotificationExceptionsTableModel::Entry {
19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Entry(const GURL& origin, ContentSetting setting);
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool operator<(const Entry& b) const;
21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GURL origin;
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ContentSetting setting;
24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNotificationExceptionsTableModel::NotificationExceptionsTableModel(
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DesktopNotificationService* service)
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : service_(service),
29201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      updates_disabled_(false),
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer_(NULL) {
31201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  registrar_.Add(this, NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
32201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 NotificationService::AllSources());
33201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  LoadEntries();
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickNotificationExceptionsTableModel::~NotificationExceptionsTableModel() {}
37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NotificationExceptionsTableModel::CanRemoveRows(
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const Rows& rows) const {
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !rows.empty();
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NotificationExceptionsTableModel::RemoveRows(const Rows& rows) {
44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AutoReset<bool> tmp(&updates_disabled_, true);
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is O(n^2) in rows.size(). Since n is small, that's ok.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (Rows::const_reverse_iterator i(rows.rbegin()); i != rows.rend(); ++i) {
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t row = *i;
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Entry* entry = &entries_[row];
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (entry->setting == CONTENT_SETTING_ALLOW) {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service_->ResetAllowedOrigin(entry->origin);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(entry->setting, CONTENT_SETTING_BLOCK);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service_->ResetBlockedOrigin(entry->origin);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    entries_.erase(entries_.begin() + row);  // Note: |entry| is now garbage.
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (observer_)
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      observer_->OnItemsRemoved(row, 1);
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NotificationExceptionsTableModel::RemoveAll() {
62201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AutoReset<bool> tmp(&updates_disabled_, true);
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  entries_.clear();
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->ResetAllOrigins();
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (observer_)
66201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    observer_->OnModelChanged();
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint NotificationExceptionsTableModel::RowCount() {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return static_cast<int>(entries_.size());
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstring16 NotificationExceptionsTableModel::GetText(int row,
743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                   int column_id) {
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = entries_[row];
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) {
773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return content_settings_helper::OriginToString16(entry.origin);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (entry.setting) {
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CONTENT_SETTING_ALLOW:
833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_ALLOW_BUTTON);
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CONTENT_SETTING_BLOCK:
853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_BLOCK_BUTTON);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NOTREACHED();
923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return string16();
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NotificationExceptionsTableModel::SetObserver(
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui::TableModelObserver* observer) {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observer_ = observer;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid NotificationExceptionsTableModel::Observe(
101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    NotificationType type,
102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const NotificationSource& source,
103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const NotificationDetails& details) {
104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!updates_disabled_) {
105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DCHECK(type == NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED);
106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    entries_.clear();
107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    LoadEntries();
108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (observer_)
110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      observer_->OnModelChanged();
111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid NotificationExceptionsTableModel::LoadEntries() {
115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::vector<GURL> allowed(service_->GetAllowedOrigins());
116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::vector<GURL> blocked(service_->GetBlockedOrigins());
117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  entries_.reserve(allowed.size() + blocked.size());
118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (size_t i = 0; i < allowed.size(); ++i)
119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    entries_.push_back(Entry(allowed[i], CONTENT_SETTING_ALLOW));
120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (size_t i = 0; i < blocked.size(); ++i)
121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    entries_.push_back(Entry(blocked[i], CONTENT_SETTING_BLOCK));
122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::sort(entries_.begin(), entries_.end());
123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNotificationExceptionsTableModel::Entry::Entry(
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& in_origin,
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ContentSetting in_setting)
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : origin(in_origin),
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      setting(in_setting) {
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool NotificationExceptionsTableModel::Entry::operator<(
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationExceptionsTableModel::Entry& b) const {
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_NE(origin, b.origin);
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return origin < b.origin;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
137