OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/importer/importer.h" | 5 #include "chrome/browser/importer/importer.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
| 8 #include <set> |
8 | 9 |
9 #include "base/file_util.h" | 10 #include "base/file_util.h" |
10 #include "base/gfx/image_operations.h" | 11 #include "base/gfx/image_operations.h" |
11 #include "base/gfx/png_encoder.h" | 12 #include "base/gfx/png_encoder.h" |
12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
13 #include "chrome/browser/bookmarks/bookmark_model.h" | 14 #include "chrome/browser/bookmarks/bookmark_model.h" |
14 #include "chrome/browser/browser.h" | 15 #include "chrome/browser/browser.h" |
15 #include "chrome/browser/browser_list.h" | 16 #include "chrome/browser/browser_list.h" |
16 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
17 #include "chrome/browser/first_run.h" | 18 #include "chrome/browser/first_run.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 DCHECK(profile_); | 75 DCHECK(profile_); |
75 | 76 |
76 PrefService* prefs = profile_->GetPrefs(); | 77 PrefService* prefs = profile_->GetPrefs(); |
77 // NOTE: We set the kHomePage value, but keep the NewTab page as the homepage. | 78 // NOTE: We set the kHomePage value, but keep the NewTab page as the homepage. |
78 prefs->SetString(prefs::kHomePage, ASCIIToWide(home_page.spec())); | 79 prefs->SetString(prefs::kHomePage, ASCIIToWide(home_page.spec())); |
79 prefs->ScheduleSavePersistentPrefs(g_browser_process->file_thread()); | 80 prefs->ScheduleSavePersistentPrefs(g_browser_process->file_thread()); |
80 } | 81 } |
81 | 82 |
82 void ProfileWriter::AddBookmarkEntry( | 83 void ProfileWriter::AddBookmarkEntry( |
83 const std::vector<BookmarkEntry>& bookmark, | 84 const std::vector<BookmarkEntry>& bookmark, |
84 bool check_uniqueness) { | 85 const std::wstring& first_folder_name, |
| 86 int options) { |
85 BookmarkModel* model = profile_->GetBookmarkModel(); | 87 BookmarkModel* model = profile_->GetBookmarkModel(); |
86 DCHECK(model->IsLoaded()); | 88 DCHECK(model->IsLoaded()); |
87 | 89 |
| 90 bool first_run = (options & FIRST_RUN) != 0; |
| 91 std::wstring real_first_folder = first_run ? first_folder_name : |
| 92 GenerateUniqueFolderName(model, first_folder_name); |
| 93 |
88 bool show_bookmark_toolbar = false; | 94 bool show_bookmark_toolbar = false; |
89 std::set<BookmarkNode*> groups_added_to; | 95 std::set<BookmarkNode*> groups_added_to; |
90 for (std::vector<BookmarkEntry>::const_iterator it = bookmark.begin(); | 96 for (std::vector<BookmarkEntry>::const_iterator it = bookmark.begin(); |
91 it != bookmark.end(); ++it) { | 97 it != bookmark.end(); ++it) { |
92 // Don't insert this url if it isn't valid. | 98 // Don't insert this url if it isn't valid. |
93 if (!it->url.is_valid()) | 99 if (!it->url.is_valid()) |
94 continue; | 100 continue; |
95 | 101 |
96 // We suppose that bookmarks are unique by Title, URL, and Folder. Since | 102 // We suppose that bookmarks are unique by Title, URL, and Folder. Since |
97 // checking for uniqueness may not be always the user's intention we have | 103 // checking for uniqueness may not be always the user's intention we have |
98 // this as an option. | 104 // this as an option. |
99 if (check_uniqueness) { | 105 if (options & ADD_IF_UNIQUE && |
100 std::vector<BookmarkModel::TitleMatch> matches; | 106 DoesBookmarkExist(model, *it, real_first_folder, first_run)) { |
101 model->GetBookmarksMatchingText((*it).title, 32, &matches); // 32 enough? | 107 continue; |
102 if (!matches.empty()) { | |
103 bool found_match = false; | |
104 for (std::vector<BookmarkModel::TitleMatch>::iterator match_it = | |
105 matches.begin(); | |
106 match_it != matches.end() && !found_match; | |
107 ++match_it) { | |
108 if ((*it).title != (*match_it).node->GetTitle()) | |
109 continue; | |
110 if ((*it).url != (*match_it).node->GetURL()) | |
111 continue; | |
112 | |
113 // Check the folder path for uniqueness as well | |
114 found_match = true; | |
115 BookmarkNode* node = (*match_it).node->GetParent(); | |
116 for(std::vector<std::wstring>::const_reverse_iterator path_it = | |
117 (*it).path.rbegin(); | |
118 (path_it != (*it).path.rend()) && found_match; | |
119 ++path_it) { | |
120 if (NULL == node || (*path_it != node->GetTitle())) | |
121 found_match = false; | |
122 if (found_match) | |
123 node = node->GetParent(); | |
124 } | |
125 | |
126 // We need a post test to differentiate checks such as | |
127 // /home/hello and /hello. Note that here the current parent | |
128 // should be the "Other bookmarks" node, its parent should be the | |
129 // root with title "", and it's parent is finally NULL. | |
130 if (NULL == node->GetParent() || | |
131 NULL != node->GetParent()->GetParent()) | |
132 found_match = false; | |
133 } | |
134 | |
135 if (found_match) | |
136 continue; | |
137 } | |
138 } | 108 } |
139 | 109 |
140 // Set up groups in BookmarkModel in such a way that path[i] is | 110 // Set up groups in BookmarkModel in such a way that path[i] is |
141 // the subgroup of path[i-1]. Finally they construct a path in the | 111 // the subgroup of path[i-1]. Finally they construct a path in the |
142 // model: | 112 // model: |
143 // path[0] \ path[1] \ ... \ path[size() - 1] | 113 // path[0] \ path[1] \ ... \ path[size() - 1] |
144 BookmarkNode* parent = | 114 BookmarkNode* parent = |
145 (it->in_toolbar ? model->GetBookmarkBarNode() : model->other_node()); | 115 (it->in_toolbar ? model->GetBookmarkBarNode() : model->other_node()); |
146 for (std::vector<std::wstring>::const_iterator i = it->path.begin(); | 116 for (std::vector<std::wstring>::const_iterator i = it->path.begin(); |
147 i != it->path.end(); ++i) { | 117 i != it->path.end(); ++i) { |
148 BookmarkNode* child = NULL; | 118 BookmarkNode* child = NULL; |
| 119 const std::wstring& folder_name = |
| 120 (!first_run && !it->in_toolbar && (i == it->path.begin())) ? |
| 121 real_first_folder : *i; |
| 122 |
149 for (int index = 0; index < parent->GetChildCount(); ++index) { | 123 for (int index = 0; index < parent->GetChildCount(); ++index) { |
150 BookmarkNode* node = parent->GetChild(index); | 124 BookmarkNode* node = parent->GetChild(index); |
151 if ((node->GetType() == history::StarredEntry::BOOKMARK_BAR || | 125 if ((node->GetType() == history::StarredEntry::BOOKMARK_BAR || |
152 node->GetType() == history::StarredEntry::USER_GROUP) && | 126 node->GetType() == history::StarredEntry::USER_GROUP) && |
153 node->GetTitle() == *i) { | 127 node->GetTitle() == folder_name) { |
154 child = node; | 128 child = node; |
155 break; | 129 break; |
156 } | 130 } |
157 } | 131 } |
158 if (child == NULL) | 132 if (child == NULL) |
159 child = model->AddGroup(parent, parent->GetChildCount(), *i); | 133 child = model->AddGroup(parent, parent->GetChildCount(), folder_name); |
160 parent = child; | 134 parent = child; |
161 } | 135 } |
162 groups_added_to.insert(parent); | 136 groups_added_to.insert(parent); |
163 model->AddURLWithCreationTime(parent, parent->GetChildCount(), | 137 model->AddURLWithCreationTime(parent, parent->GetChildCount(), |
164 it->title, it->url, it->creation_time); | 138 it->title, it->url, it->creation_time); |
165 | 139 |
166 // If some items are put into toolbar, it looks like the user was using | 140 // If some items are put into toolbar, it looks like the user was using |
167 // it in their last browser. We turn on the bookmarks toolbar. | 141 // it in their last browser. We turn on the bookmarks toolbar. |
168 if (it->in_toolbar) | 142 if (it->in_toolbar) |
169 show_bookmark_toolbar = true; | 143 show_bookmark_toolbar = true; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 // Set the pref and notify the notification service. | 288 // Set the pref and notify the notification service. |
315 prefs->SetBoolean(prefs::kShowBookmarkBar, true); | 289 prefs->SetBoolean(prefs::kShowBookmarkBar, true); |
316 prefs->ScheduleSavePersistentPrefs(g_browser_process->file_thread()); | 290 prefs->ScheduleSavePersistentPrefs(g_browser_process->file_thread()); |
317 Source<Profile> source(profile_); | 291 Source<Profile> source(profile_); |
318 NotificationService::current()->Notify( | 292 NotificationService::current()->Notify( |
319 NOTIFY_BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, source, | 293 NOTIFY_BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, source, |
320 NotificationService::NoDetails()); | 294 NotificationService::NoDetails()); |
321 } | 295 } |
322 } | 296 } |
323 | 297 |
| 298 std::wstring ProfileWriter::GenerateUniqueFolderName( |
| 299 BookmarkModel* model, |
| 300 const std::wstring& folder_name) { |
| 301 // Build a set containing the folder names of the other folder. |
| 302 std::set<std::wstring> other_folder_names; |
| 303 BookmarkNode* other = model->other_node(); |
| 304 for (int i = 0; i < other->GetChildCount(); ++i) { |
| 305 BookmarkNode* node = other->GetChild(i); |
| 306 if (node->is_folder()) |
| 307 other_folder_names.insert(node->GetTitle()); |
| 308 } |
| 309 |
| 310 if (other_folder_names.find(folder_name) == other_folder_names.end()) |
| 311 return folder_name; // Name is unique, use it. |
| 312 |
| 313 // Otherwise iterate until we find a unique name. |
| 314 for (int i = 1; i < 100; ++i) { |
| 315 std::wstring name = folder_name + StringPrintf(L" (%d)", i); |
| 316 if (other_folder_names.find(name) == other_folder_names.end()) |
| 317 return name; |
| 318 } |
| 319 |
| 320 return folder_name; |
| 321 } |
| 322 |
| 323 bool ProfileWriter::DoesBookmarkExist( |
| 324 BookmarkModel* model, |
| 325 const BookmarkEntry& entry, |
| 326 const std::wstring& first_folder_name, |
| 327 bool first_run) { |
| 328 std::vector<BookmarkNode*> nodes_with_same_url; |
| 329 model->GetNodesByURL(entry.url, &nodes_with_same_url); |
| 330 if (nodes_with_same_url.empty()) |
| 331 return false; |
| 332 |
| 333 for (size_t i = 0; i < nodes_with_same_url.size(); ++i) { |
| 334 BookmarkNode* node = nodes_with_same_url[i]; |
| 335 if (entry.title != node->GetTitle()) |
| 336 continue; |
| 337 |
| 338 // Does the path match? |
| 339 bool found_match = true; |
| 340 BookmarkNode* parent = node->GetParent(); |
| 341 for (std::vector<std::wstring>::const_reverse_iterator path_it = |
| 342 entry.path.rbegin(); |
| 343 (path_it != entry.path.rend()) && found_match; ++path_it) { |
| 344 const std::wstring& folder_name = |
| 345 (!first_run && path_it + 1 == entry.path.rend()) ? |
| 346 first_folder_name : *path_it; |
| 347 if (NULL == parent || *path_it != folder_name) |
| 348 found_match = false; |
| 349 else |
| 350 parent = parent->GetParent(); |
| 351 } |
| 352 |
| 353 // We need a post test to differentiate checks such as |
| 354 // /home/hello and /hello. The parent should either by the other folder |
| 355 // node, or the bookmarks bar, depending upon first_run and |
| 356 // entry.in_toolbar. |
| 357 if (found_match && |
| 358 ((first_run && entry.in_toolbar && parent != |
| 359 model->GetBookmarkBarNode()) || |
| 360 ((!first_run || !entry.in_toolbar) && |
| 361 parent != model->other_node()))) { |
| 362 found_match = false; |
| 363 } |
| 364 |
| 365 if (found_match) |
| 366 return true; // Found a match with the same url path and title. |
| 367 } |
| 368 return false; |
| 369 } |
| 370 |
324 // Importer. | 371 // Importer. |
325 | 372 |
326 // static | 373 // static |
327 bool Importer::ReencodeFavicon(const unsigned char* src_data, size_t src_len, | 374 bool Importer::ReencodeFavicon(const unsigned char* src_data, size_t src_len, |
328 std::vector<unsigned char>* png_data) { | 375 std::vector<unsigned char>* png_data) { |
329 // Decode the favicon using WebKit's image decoder. | 376 // Decode the favicon using WebKit's image decoder. |
330 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize)); | 377 webkit_glue::ImageDecoder decoder(gfx::Size(kFavIconSize, kFavIconSize)); |
331 SkBitmap decoded = decoder.Decode(src_data, src_len); | 378 SkBitmap decoded = decoder.Decode(src_data, src_len); |
332 if (decoded.empty()) | 379 if (decoded.empty()) |
333 return false; // Unable to decode. | 380 return false; // Unable to decode. |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 firefox_lock_.reset(); // Release the Firefox profile lock. | 579 firefox_lock_.reset(); // Release the Firefox profile lock. |
533 if (observer_) | 580 if (observer_) |
534 observer_->ImportEnded(); | 581 observer_->ImportEnded(); |
535 Release(); | 582 Release(); |
536 } | 583 } |
537 | 584 |
538 Importer* ImporterHost::CreateImporterByType(ProfileType type) { | 585 Importer* ImporterHost::CreateImporterByType(ProfileType type) { |
539 switch (type) { | 586 switch (type) { |
540 case MS_IE: | 587 case MS_IE: |
541 return new IEImporter(); | 588 return new IEImporter(); |
| 589 case BOOKMARKS_HTML: |
542 case FIREFOX2: | 590 case FIREFOX2: |
543 return new Firefox2Importer(); | 591 return new Firefox2Importer(); |
544 case FIREFOX3: | 592 case FIREFOX3: |
545 return new Firefox3Importer(); | 593 return new Firefox3Importer(); |
546 case GOOGLE_TOOLBAR5: | 594 case GOOGLE_TOOLBAR5: |
547 return new Toolbar5Importer(); | 595 return new Toolbar5Importer(); |
548 } | 596 } |
549 NOTREACHED(); | 597 NOTREACHED(); |
550 return NULL; | 598 return NULL; |
551 } | 599 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 ProfileInfo* google_toolbar = new ProfileInfo(); | 709 ProfileInfo* google_toolbar = new ProfileInfo(); |
662 google_toolbar->browser_type = GOOGLE_TOOLBAR5; | 710 google_toolbar->browser_type = GOOGLE_TOOLBAR5; |
663 google_toolbar->description = l10n_util::GetString( | 711 google_toolbar->description = l10n_util::GetString( |
664 IDS_IMPORT_FROM_GOOGLE_TOOLBAR); | 712 IDS_IMPORT_FROM_GOOGLE_TOOLBAR); |
665 google_toolbar->source_path.clear(); | 713 google_toolbar->source_path.clear(); |
666 google_toolbar->app_path.clear(); | 714 google_toolbar->app_path.clear(); |
667 google_toolbar->services_supported = FAVORITES; | 715 google_toolbar->services_supported = FAVORITES; |
668 source_profiles_.push_back(google_toolbar); | 716 source_profiles_.push_back(google_toolbar); |
669 } | 717 } |
670 } | 718 } |
OLD | NEW |