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

Side by Side Diff: chrome/browser/bookmarks/bookmark_table_model.cc

Issue 1730015: Windows/Views: delete native bookmark manager code. (Closed)
Patch Set: Patch with fixed file perms. 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/bookmarks/bookmark_table_model.h"
6
7 #include <limits>
8
9 #include "app/l10n_util.h"
10 #include "app/resource_bundle.h"
11 #include "app/table_model_observer.h"
12 #include "base/i18n/rtl.h"
13 #include "base/i18n/time_formatting.h"
14 #include "base/string_util.h"
15 #include "chrome/browser/bookmarks/bookmark_model.h"
16 #include "chrome/browser/bookmarks/bookmark_utils.h"
17 #include "chrome/browser/pref_service.h"
18 #include "chrome/browser/profile.h"
19 #include "chrome/common/pref_names.h"
20 #include "googleurl/src/gurl.h"
21 #include "grit/app_resources.h"
22 #include "grit/generated_resources.h"
23 #include "grit/theme_resources.h"
24 #include "net/base/escape.h"
25 #include "net/base/net_util.h"
26
27 namespace {
28
29 // Number of bookmarks shown in recently bookmarked.
30 const int kRecentlyBookmarkedCount = 50;
31
32 // VectorBackedBookmarkTableModel ----------------------------------------------
33
34 class VectorBackedBookmarkTableModel : public BookmarkTableModel {
35 public:
36 explicit VectorBackedBookmarkTableModel(BookmarkModel* model)
37 : BookmarkTableModel(model) {
38 }
39
40 virtual const BookmarkNode* GetNodeForRow(int row) {
41 return nodes_[row];
42 }
43
44 virtual int RowCount() {
45 return static_cast<int>(nodes_.size());
46 }
47
48 virtual void BookmarkNodeMoved(BookmarkModel* model,
49 const BookmarkNode* old_parent,
50 int old_index,
51 const BookmarkNode* new_parent,
52 int new_index) {
53 NotifyObserverOfChange(new_parent->GetChild(new_index));
54 }
55
56 virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
57 const BookmarkNode* node) {
58 NotifyObserverOfChange(node);
59 }
60
61 virtual void BookmarkNodeChanged(BookmarkModel* model,
62 const BookmarkNode* node) {
63 NotifyObserverOfChange(node);
64 }
65
66 protected:
67 void NotifyObserverOfChange(const BookmarkNode* node) {
68 if (!observer())
69 return;
70
71 int index = IndexOfNode(node);
72 if (index != -1)
73 observer()->OnItemsChanged(index, 1);
74 }
75
76 typedef std::vector<const BookmarkNode*> Nodes;
77 Nodes& nodes() { return nodes_; }
78
79 private:
80 Nodes nodes_;
81
82 DISALLOW_COPY_AND_ASSIGN(VectorBackedBookmarkTableModel);
83 };
84
85 // FolderBookmarkTableModel ----------------------------------------------------
86
87 // FolderBookmarkTableModel is a TableModel implementation backed by the
88 // contents of a bookmark folder. FolderBookmarkTableModel caches the contents
89 // of the folder so that it can send out the correct events when a bookmark
90 // node is moved.
91 class FolderBookmarkTableModel : public VectorBackedBookmarkTableModel {
92 public:
93 FolderBookmarkTableModel(BookmarkModel* model, const BookmarkNode* root_node)
94 : VectorBackedBookmarkTableModel(model),
95 root_node_(root_node) {
96 PopulateNodesFromRoot();
97 }
98
99 virtual void BookmarkNodeMoved(BookmarkModel* model,
100 const BookmarkNode* old_parent,
101 int old_index,
102 const BookmarkNode* new_parent,
103 int new_index) {
104 if (old_parent == root_node_) {
105 nodes().erase(nodes().begin() + old_index);
106 if (observer())
107 observer()->OnItemsRemoved(old_index, 1);
108 }
109 if (new_parent == root_node_) {
110 nodes().insert(nodes().begin() + new_index,
111 root_node_->GetChild(new_index));
112 if (observer())
113 observer()->OnItemsAdded(new_index, 1);
114 }
115 }
116
117 virtual void BookmarkNodeAdded(BookmarkModel* model,
118 const BookmarkNode* parent,
119 int index) {
120 if (root_node_ == parent) {
121 nodes().insert(nodes().begin() + index, parent->GetChild(index));
122 if (observer())
123 observer()->OnItemsAdded(index, 1);
124 }
125 }
126
127 virtual void BookmarkNodeRemoved(BookmarkModel* model,
128 const BookmarkNode* parent,
129 int index,
130 const BookmarkNode* node) {
131 if (root_node_->HasAncestor(node)) {
132 // We, or one of our ancestors was removed.
133 root_node_ = NULL;
134 nodes().clear();
135 if (observer())
136 observer()->OnModelChanged();
137 return;
138 }
139 if (root_node_ == parent) {
140 nodes().erase(nodes().begin() + index);
141 if (observer())
142 observer()->OnItemsRemoved(index, 1);
143 }
144 }
145
146 virtual void BookmarkNodeChanged(BookmarkModel* model,
147 const BookmarkNode* node) {
148 NotifyChanged(node);
149 }
150
151 virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
152 const BookmarkNode* node) {
153 NotifyChanged(node);
154 }
155
156 virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
157 const BookmarkNode* node) {
158 if (node != root_node_)
159 return;
160
161 nodes().clear();
162 PopulateNodesFromRoot();
163
164 if (observer())
165 observer()->OnModelChanged();
166 }
167
168 private:
169 void NotifyChanged(const BookmarkNode* node) {
170 if (node->GetParent() == root_node_ && observer())
171 observer()->OnItemsChanged(node->GetParent()->IndexOfChild(node), 1);
172 }
173
174 void PopulateNodesFromRoot() {
175 for (int i = 0; i < root_node_->GetChildCount(); ++i)
176 nodes().push_back(root_node_->GetChild(i));
177 }
178
179 // The node we're showing the children of. This is set to NULL if the node
180 // (or one of its ancestors) is removed from the model.
181 const BookmarkNode* root_node_;
182
183 DISALLOW_COPY_AND_ASSIGN(FolderBookmarkTableModel);
184 };
185
186 // RecentlyBookmarkedTableModel ------------------------------------------------
187
188 class RecentlyBookmarkedTableModel : public VectorBackedBookmarkTableModel {
189 public:
190 explicit RecentlyBookmarkedTableModel(BookmarkModel* model)
191 : VectorBackedBookmarkTableModel(model) {
192 UpdateRecentlyBookmarked();
193 }
194
195 virtual void BookmarkNodeAdded(BookmarkModel* model,
196 const BookmarkNode* parent,
197 int index) {
198 if (parent->GetChild(index)->is_url())
199 UpdateRecentlyBookmarked();
200 }
201
202 virtual void BookmarkNodeRemoved(BookmarkModel* model,
203 const BookmarkNode* parent,
204 int old_index,
205 const BookmarkNode* old_node) {
206 if (old_node->is_url())
207 UpdateRecentlyBookmarked();
208 }
209
210 private:
211 void UpdateRecentlyBookmarked() {
212 nodes().clear();
213 bookmark_utils::GetMostRecentlyAddedEntries(model(),
214 kRecentlyBookmarkedCount,
215 &nodes());
216 if (observer())
217 observer()->OnModelChanged();
218 }
219
220 DISALLOW_COPY_AND_ASSIGN(RecentlyBookmarkedTableModel);
221 };
222
223 // BookmarkSearchTableModel ----------------------------------------------------
224
225 class BookmarkSearchTableModel : public VectorBackedBookmarkTableModel {
226 public:
227 BookmarkSearchTableModel(BookmarkModel* model,
228 const std::wstring& search_text,
229 const std::wstring& languages)
230 : VectorBackedBookmarkTableModel(model),
231 search_text_(search_text),
232 languages_(languages) {
233 bookmark_utils::GetBookmarksContainingText(
234 model, search_text, std::numeric_limits<int>::max(),
235 languages, &nodes());
236 }
237
238 virtual void BookmarkNodeAdded(BookmarkModel* model,
239 const BookmarkNode* parent,
240 int index) {
241 const BookmarkNode* node = parent->GetChild(index);
242 if (bookmark_utils::DoesBookmarkContainText(
243 node, search_text_, languages_)) {
244 nodes().push_back(node);
245 if (observer())
246 observer()->OnItemsAdded(static_cast<int>(nodes().size() - 1), 1);
247 }
248 }
249
250 virtual void BookmarkNodeRemoved(BookmarkModel* model,
251 const BookmarkNode* parent,
252 int index,
253 const BookmarkNode* node) {
254 int internal_index = IndexOfNode(node);
255 if (internal_index == -1)
256 return;
257
258 nodes().erase(nodes().begin() + static_cast<int>(internal_index));
259 if (observer())
260 observer()->OnItemsRemoved(internal_index, 1);
261 }
262
263 private:
264 const std::wstring search_text_;
265 const std::wstring languages_;
266
267 DISALLOW_COPY_AND_ASSIGN(BookmarkSearchTableModel);
268 };
269
270 } // namespace
271
272 // BookmarkTableModel ----------------------------------------------------------
273
274 // static
275 BookmarkTableModel* BookmarkTableModel::CreateRecentlyBookmarkedModel(
276 BookmarkModel* model) {
277 return new RecentlyBookmarkedTableModel(model);
278 }
279
280 // static
281 BookmarkTableModel* BookmarkTableModel::CreateBookmarkTableModelForFolder(
282 BookmarkModel* model, const BookmarkNode* node) {
283 return new FolderBookmarkTableModel(model, node);
284 }
285
286 // static
287 BookmarkTableModel* BookmarkTableModel::CreateSearchTableModel(
288 BookmarkModel* model,
289 const std::wstring& text,
290 const std::wstring& languages) {
291 return new BookmarkSearchTableModel(model, text, languages);
292 }
293
294 BookmarkTableModel::BookmarkTableModel(BookmarkModel* model)
295 : model_(model),
296 observer_(NULL) {
297 model_->AddObserver(this);
298 }
299
300 BookmarkTableModel::~BookmarkTableModel() {
301 if (model_)
302 model_->RemoveObserver(this);
303 }
304
305 std::wstring BookmarkTableModel::GetText(int row, int column_id) {
306 const BookmarkNode* node = GetNodeForRow(row);
307 switch (column_id) {
308 case IDS_BOOKMARK_TABLE_TITLE: {
309 std::wstring title = node->GetTitle();
310 // Adjust the text as well, for example, put LRE-PDF pair around LTR text
311 // in RTL enviroment, so that the ending punctuation in the text will not
312 // be rendered incorrectly (such as rendered as the leftmost character,
313 // and/or rendered as a mirrored punctuation character).
314 //
315 // TODO(xji): Consider adding a special case if the title text is a URL,
316 // since those should always be displayed LTR. Please refer to
317 // http://crbug.com/6726 for more information.
318 base::i18n::AdjustStringForLocaleDirection(title, &title);
319 return title;
320 }
321
322 case IDS_BOOKMARK_TABLE_URL: {
323 if (!node->is_url())
324 return std::wstring();
325 std::wstring languages = model_ && model_->profile()
326 ? model_->profile()->GetPrefs()->GetString(prefs::kAcceptLanguages)
327 : std::wstring();
328 std::wstring url_text = net::FormatUrl(node->GetURL(), languages,
329 net::kFormatUrlOmitAll, UnescapeRule::SPACES, NULL, NULL, NULL);
330 if (base::i18n::IsRTL())
331 base::i18n::WrapStringWithLTRFormatting(&url_text);
332 return url_text;
333 }
334
335 case IDS_BOOKMARK_TABLE_PATH: {
336 std::wstring path;
337 BuildPath(node->GetParent(), &path);
338 // Force path to have LTR directionality. The whole path (but not every
339 // single path component) is marked with LRE-PDF. For example,
340 // ALEPH/BET/GIMEL (using uppercase English for Hebrew) is supposed to
341 // appear (visually) as LEMIG/TEB/HPELA; foo/C/B/A.doc refers to file
342 // C.doc in directory B in directory A in directory foo, not to file
343 // A.doc in directory B in directory C in directory foo. The reason to
344 // mark the whole path, but not every single path component, as LTR is
345 // because paths need to get written in text documents, and that is how
346 // they will appear there. Being a saint and doing the tedious formatting
347 // to every single path component to get it to come out in the logical
348 // order will accomplish nothing but confuse people, since they will now
349 // see both formats being used, and will never know what anything means.
350 // Furthermore, doing the "logical" formatting with characters like LRM,
351 // LRE, and PDF to every single path component means that when someone
352 // copy/pastes your path, it will still contain those characters, and
353 // trying to access the file will fail because of them. Windows Explorer,
354 // Firefox, IE, Nautilus, gedit choose to format only the whole path as
355 // LTR too. The point here is to display the path the same way as it's
356 // displayed by other software.
357 if (base::i18n::IsRTL())
358 base::i18n::WrapStringWithLTRFormatting(&path);
359 return path;
360 }
361 }
362 NOTREACHED();
363 return std::wstring();
364 }
365
366 SkBitmap BookmarkTableModel::GetIcon(int row) {
367 static SkBitmap* folder_icon = ResourceBundle::GetSharedInstance().
368 GetBitmapNamed(IDR_BOOKMARK_BAR_FOLDER);
369 static SkBitmap* default_icon = ResourceBundle::GetSharedInstance().
370 GetBitmapNamed(IDR_DEFAULT_FAVICON);
371
372 const BookmarkNode* node = GetNodeForRow(row);
373 if (node->is_folder())
374 return *folder_icon;
375
376 if (model_->GetFavIcon(node).empty())
377 return *default_icon;
378
379 return model_->GetFavIcon(node);
380 }
381
382 void BookmarkTableModel::BookmarkModelBeingDeleted(BookmarkModel* model) {
383 model_->RemoveObserver(this);
384 model_ = NULL;
385 }
386
387 int BookmarkTableModel::IndexOfNode(const BookmarkNode* node) {
388 for (int i = RowCount() - 1; i >= 0; --i) {
389 if (GetNodeForRow(i) == node)
390 return i;
391 }
392 return -1;
393 }
394
395 void BookmarkTableModel::BuildPath(const BookmarkNode* node,
396 std::wstring* path) {
397 if (!node) {
398 NOTREACHED();
399 return;
400 }
401 if (node == model()->GetBookmarkBarNode()) {
402 *path = l10n_util::GetString(IDS_BOOKMARK_TABLE_BOOKMARK_BAR_PATH);
403 return;
404 }
405 if (node == model()->other_node()) {
406 *path = l10n_util::GetString(IDS_BOOKMARK_TABLE_OTHER_BOOKMARKS_PATH);
407 return;
408 }
409 BuildPath(node->GetParent(), path);
410 path->append(l10n_util::GetString(IDS_BOOKMARK_TABLE_PATH_SEPARATOR));
411 path->append(node->GetTitle());
412 }
OLDNEW
« no previous file with comments | « chrome/browser/bookmarks/bookmark_table_model.h ('k') | chrome/browser/bookmarks/bookmark_table_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698