Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: chrome/browser/geolocation/geolocation_content_settings_table_model.cc

Issue 1539021: Geolocation exceptions window, Windows.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/geolocation/geolocation_content_settings_table_model.h" 5 #include "chrome/browser/geolocation/geolocation_content_settings_table_model.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/l10n_util_collator.h"
8 #include "app/table_model_observer.h" 9 #include "app/table_model_observer.h"
9 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/common/url_constants.h"
10 #include "grit/generated_resources.h" 12 #include "grit/generated_resources.h"
11 13
14 namespace {
15 // Return -1, 0, or 1 depending on whether |origin1| should be sorted before,
16 // equal to, or after |origin2|.
17 int CompareOrigins(const GURL& origin1, const GURL& origin2) {
18 if (origin1 == origin2)
19 return 0;
20
21 // Sort alphabetically by host name.
22 std::string origin1_host(origin1.host());
23 std::string origin2_host(origin2.host());
24 if (origin1_host != origin2_host)
25 return origin1_host < origin2_host ? -1 : 1;
26
27 // We'll show non-HTTP schemes, so sort them alphabetically, but put HTTP
28 // first.
29 std::string origin1_scheme(origin1.scheme());
30 std::string origin2_scheme(origin2.scheme());
31 if (origin1_scheme != origin2_scheme) {
32 if (origin1_scheme == chrome::kHttpScheme)
33 return -1;
34 if (origin2_scheme == chrome::kHttpScheme)
35 return 1;
36 return origin1_scheme < origin2_scheme ? -1 : 1;
37 }
38
39 // Sort by port number. This has to differ if the origins are really origins
40 // (and not longer URLs). An unspecified port will be -1 and thus
41 // automatically come first (which is what we want).
42 int origin1_port = origin1.IntPort();
43 int origin2_port = origin2.IntPort();
44 DCHECK(origin1_port != origin2_port);
45 return origin1_port < origin2_port ? -1 : 1;
46 }
47 } // namespace
48
12 GeolocationContentSettingsTableModel::GeolocationContentSettingsTableModel( 49 GeolocationContentSettingsTableModel::GeolocationContentSettingsTableModel(
13 GeolocationContentSettingsMap* map) 50 GeolocationContentSettingsMap* map)
14 : map_(map), 51 : map_(map),
15 observer_(NULL) { 52 observer_(NULL) {
16 GeolocationContentSettingsMap::AllOriginsSettings settings( 53 GeolocationContentSettingsMap::AllOriginsSettings settings(
17 map_->GetAllOriginsSettings()); 54 map_->GetAllOriginsSettings());
18 GeolocationContentSettingsMap::AllOriginsSettings::const_iterator i; 55 GeolocationContentSettingsMap::AllOriginsSettings::const_iterator i;
19 for (i = settings.begin(); i != settings.end(); ++i) 56 for (i = settings.begin(); i != settings.end(); ++i)
20 AddEntriesForOrigin(i->first, i->second); 57 AddEntriesForOrigin(i->first, i->second);
21 } 58 }
22 59
23 bool GeolocationContentSettingsTableModel::CanRemoveException(int row) const { 60 bool GeolocationContentSettingsTableModel::CanRemoveExceptions(
24 const Entry& entry = entries_[row]; 61 const Rows& rows) const {
25 return !(entry.origin == entry.embedding_origin && 62 for (Rows::const_iterator i(rows.begin()); i != rows.end(); ++i) {
26 static_cast<size_t>(row + 1) < entries_.size() && 63 const Entry& entry = entries_[*i];
27 entries_[row + 1].origin == entry.origin && 64 if ((entry.origin == entry.embedding_origin) &&
28 entry.setting == CONTENT_SETTING_DEFAULT); 65 (entry.setting == CONTENT_SETTING_DEFAULT)) {
66 for (size_t j = (*i) + 1;
67 (j < entries_.size()) && (entries_[j].origin == entry.origin); ++j) {
68 if (!rows.count(j))
69 return false;
70 }
71 }
72 }
73 return true;
29 } 74 }
30 75
31 void GeolocationContentSettingsTableModel::RemoveException(int row) { 76 void GeolocationContentSettingsTableModel::RemoveExceptions(const Rows& rows) {
32 Entry& entry = entries_[row]; 77 for (Rows::const_reverse_iterator i(rows.rbegin()); i != rows.rend(); ++i) {
33 bool next_has_same_origin = static_cast<size_t>(row + 1) < entries_.size() && 78 size_t row = *i;
34 entries_[row + 1].origin == entry.origin; 79 Entry* entry = &entries_[row];
35 bool has_children = entry.origin == entry.embedding_origin && 80 GURL entry_origin(entry->origin); // Copy, not reference, since we'll erase
36 next_has_same_origin; 81 // |entry| before we're done with this.
37 map_->SetContentSetting(entry.origin, entry.embedding_origin, 82 bool next_has_same_origin = ((row + 1) < entries_.size()) &&
38 CONTENT_SETTING_DEFAULT); 83 (entries_[row + 1].origin == entry_origin);
39 if (has_children) { 84 bool has_children = (entry_origin == entry->embedding_origin) &&
40 entry.setting = CONTENT_SETTING_DEFAULT; 85 next_has_same_origin;
41 if (observer_) 86 map_->SetContentSetting(entry_origin, entry->embedding_origin,
42 observer_->OnItemsChanged(row, 1); 87 CONTENT_SETTING_DEFAULT);
43 } else if (!next_has_same_origin && 88 if (has_children) {
44 row > 0 && 89 entry->setting = CONTENT_SETTING_DEFAULT;
45 entries_[row - 1].origin == entry.origin && 90 if (observer_)
46 entries_[row - 1].setting == CONTENT_SETTING_DEFAULT) { 91 observer_->OnItemsChanged(row, 1);
47 // If we remove the last non-default child of a default parent, we should 92 continue;
48 // remove the parent too. 93 }
49 entries_.erase(entries_.begin() + row - 1, entries_.begin() + row + 1); 94 do {
50 if (observer_) 95 entries_.erase(entries_.begin() + row); // Note: |entry| is now garbage.
51 observer_->OnItemsRemoved(row - 1, 2); 96 if (observer_)
52 } else { 97 observer_->OnItemsRemoved(row, 1);
53 entries_.erase(entries_.begin() + row); 98 // If we remove the last non-default child of a default parent, we
54 if (observer_) 99 // should remove the parent too. We do these removals one-at-a-time
55 observer_->OnItemsRemoved(row, 1); 100 // because the table view will end up being called back as each row is
101 // removed, in turn calling back to CanRemoveExceptions(), and if we've
102 // already removed more entries than the view has, we'll have problems.
103 if ((row == 0) || rows.count(row - 1))
104 break;
105 entry = &entries_[--row];
106 } while (!next_has_same_origin && (entry->origin == entry_origin) &&
107 (entry->origin == entry->embedding_origin) &&
108 (entry->setting == CONTENT_SETTING_DEFAULT));
56 } 109 }
57 } 110 }
58 111
59 void GeolocationContentSettingsTableModel::RemoveAll() { 112 void GeolocationContentSettingsTableModel::RemoveAll() {
60 int old_row_count = RowCount(); 113 int old_row_count = RowCount();
61 entries_.clear(); 114 entries_.clear();
62 map_->ResetToDefault(); 115 map_->ResetToDefault();
63 if (observer_) 116 if (observer_)
64 observer_->OnItemsRemoved(0, old_row_count); 117 observer_->OnItemsRemoved(0, old_row_count);
65 } 118 }
66 119
67 int GeolocationContentSettingsTableModel::RowCount() { 120 int GeolocationContentSettingsTableModel::RowCount() {
68 return entries_.size(); 121 return entries_.size();
69 } 122 }
70 123
71 std::wstring GeolocationContentSettingsTableModel::GetText(int row, 124 std::wstring GeolocationContentSettingsTableModel::GetText(int row,
72 int column_id) { 125 int column_id) {
73 const Entry& entry = entries_[row]; 126 const Entry& entry = entries_[row];
74 if (column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) { 127 if (column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) {
75 if (entry.origin == entry.embedding_origin) 128 if (entry.origin == entry.embedding_origin) {
76 return UTF8ToWide( 129 return UTF8ToWide(GeolocationContentSettingsMap::OriginToString(
77 GeolocationContentSettingsMap::OriginToString(entry.origin)); 130 entry.origin));
78 if (entry.embedding_origin.is_empty()) 131 }
79 return ASCIIToWide(" ") + 132 std::wstring indent(L" ");
133 if (entry.embedding_origin.is_empty()) {
134 // NOTE: As long as the user cannot add/edit entries from the exceptions
135 // dialog, it's impossible to actually have a non-default setting for some
136 // origin "embedded on any other site", so this row will never appear. If
137 // we add the ability to add/edit exceptions, we'll need to decide when to
138 // display this and how "removing" it will function.
139 return indent +
80 l10n_util::GetString(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER); 140 l10n_util::GetString(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ANY_OTHER);
81 return ASCIIToWide(" ") + 141 }
82 l10n_util::GetStringF(IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST, 142 return indent + l10n_util::GetStringF(
83 UTF8ToWide(GeolocationContentSettingsMap::OriginToString( 143 IDS_EXCEPTIONS_GEOLOCATION_EMBEDDED_ON_HOST,
84 entry.embedding_origin))); 144 UTF8ToWide(GeolocationContentSettingsMap::OriginToString(
85 } else if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) { 145 entry.embedding_origin)));
146 }
147
148 if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
86 switch (entry.setting) { 149 switch (entry.setting) {
87 case CONTENT_SETTING_ALLOW: 150 case CONTENT_SETTING_ALLOW:
88 return l10n_util::GetString(IDS_EXCEPTIONS_ALLOW_BUTTON); 151 return l10n_util::GetString(IDS_EXCEPTIONS_ALLOW_BUTTON);
89 case CONTENT_SETTING_BLOCK: 152 case CONTENT_SETTING_BLOCK:
90 return l10n_util::GetString(IDS_EXCEPTIONS_BLOCK_BUTTON); 153 return l10n_util::GetString(IDS_EXCEPTIONS_BLOCK_BUTTON);
91 case CONTENT_SETTING_ASK: 154 case CONTENT_SETTING_ASK:
92 return l10n_util::GetString(IDS_EXCEPTIONS_ASK_BUTTON); 155 return l10n_util::GetString(IDS_EXCEPTIONS_ASK_BUTTON);
93 case CONTENT_SETTING_DEFAULT: 156 case CONTENT_SETTING_DEFAULT:
94 return l10n_util::GetString(IDS_EXCEPTIONS_NOT_SET_BUTTON); 157 return l10n_util::GetString(IDS_EXCEPTIONS_NOT_SET_BUTTON);
95 default: 158 default:
96 NOTREACHED(); 159 break;
97 } 160 }
98 } else {
99 NOTREACHED();
100 } 161 }
162
163 NOTREACHED();
101 return std::wstring(); 164 return std::wstring();
102 } 165 }
103 166
104 void GeolocationContentSettingsTableModel::SetObserver( 167 void GeolocationContentSettingsTableModel::SetObserver(
105 TableModelObserver* observer) { 168 TableModelObserver* observer) {
106 observer_ = observer; 169 observer_ = observer;
107 } 170 }
108 171
172 int GeolocationContentSettingsTableModel::CompareValues(int row1,
173 int row2,
174 int column_id) {
175 DCHECK(row1 >= 0 && row1 < RowCount() &&
176 row2 >= 0 && row2 < RowCount());
177
178 const Entry& entry1 = entries_[row1];
179 const Entry& entry2 = entries_[row2];
180
181 // Sort top-level requesting origins, keeping all embedded (child) rules
182 // together.
183 int origin_comparison = CompareOrigins(entry1.origin, entry2.origin);
184 if (origin_comparison == 0) {
185 // The non-embedded rule comes before all embedded rules.
186 bool entry1_origins_same = entry1.origin == entry1.embedding_origin;
187 bool entry2_origins_same = entry2.origin == entry2.embedding_origin;
188 if (entry1_origins_same != entry2_origins_same)
189 return entry1_origins_same ? -1 : 1;
190
191 // The "default" embedded rule comes after all other embedded rules.
192 bool embedding_origin1_empty = entry1.embedding_origin.is_empty();
193 bool embedding_origin2_empty = entry2.embedding_origin.is_empty();
194 if (embedding_origin1_empty != embedding_origin2_empty)
195 return embedding_origin2_empty ? -1 : 1;
196
197 origin_comparison =
198 CompareOrigins(entry1.embedding_origin, entry2.embedding_origin);
199 } else if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
200 // The rows are in different origins. We need to find out how the top-level
201 // origins will compare.
202 while (entries_[row1].origin != entries_[row1].embedding_origin)
203 --row1;
204 while (entries_[row2].origin != entries_[row2].embedding_origin)
205 --row2;
206 }
207
208 // The entries are at the same "scope". If we're sorting by action, then do
209 // that now.
210 if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
211 int compare_text = l10n_util::CompareStringWithCollator(
212 GetCollator(), GetText(row1, column_id), GetText(row2, column_id));
213 if (compare_text != 0)
214 return compare_text;
215 }
216
217 // Sort by the relevant origin.
218 return origin_comparison;
219 }
220
109 void GeolocationContentSettingsTableModel::AddEntriesForOrigin( 221 void GeolocationContentSettingsTableModel::AddEntriesForOrigin(
110 const GURL& origin, 222 const GURL& origin,
111 const GeolocationContentSettingsMap::OneOriginSettings& settings) { 223 const GeolocationContentSettingsMap::OneOriginSettings& settings) {
112 GeolocationContentSettingsMap::OneOriginSettings::const_iterator parent = 224 GeolocationContentSettingsMap::OneOriginSettings::const_iterator parent =
113 settings.find(origin); 225 settings.find(origin);
114 226
115 // Add the "parent" entry for the non-embedded setting. 227 // Add the "parent" entry for the non-embedded setting.
116 entries_.push_back(Entry(origin, origin, 228 entries_.push_back(Entry(origin, origin,
117 (parent == settings.end()) ? CONTENT_SETTING_DEFAULT : parent->second)); 229 (parent == settings.end()) ? CONTENT_SETTING_DEFAULT : parent->second));
118 230
119 // Add the "children" for any embedded settings. 231 // Add the "children" for any embedded settings.
120 GeolocationContentSettingsMap::OneOriginSettings::const_iterator i; 232 GeolocationContentSettingsMap::OneOriginSettings::const_iterator i;
121 for (i = settings.begin(); i != settings.end(); ++i) { 233 for (i = settings.begin(); i != settings.end(); ++i) {
122 // Skip the non-embedded setting which we already added above. 234 // Skip the non-embedded setting which we already added above.
123 if (i == parent) 235 if (i == parent)
124 continue; 236 continue;
125 237
126 entries_.push_back(Entry(origin, i->first, i->second)); 238 entries_.push_back(Entry(origin, i->first, i->second));
127 } 239 }
128 } 240 }
129 241
130 // static 242 // static
131 GeolocationContentSettingsTableModel::Entry::Entry( 243 GeolocationContentSettingsTableModel::Entry::Entry(
132 const GURL& in_origin, const GURL& in_embedding_origin, 244 const GURL& in_origin, const GURL& in_embedding_origin,
133 ContentSetting in_setting) 245 ContentSetting in_setting)
134 : origin(in_origin), 246 : origin(in_origin),
135 embedding_origin(in_embedding_origin), 247 embedding_origin(in_embedding_origin),
136 setting(in_setting) { 248 setting(in_setting) {
137 } 249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698