| Index: chrome/browser/importer/importer.cc
|
| ===================================================================
|
| --- chrome/browser/importer/importer.cc (revision 4885)
|
| +++ chrome/browser/importer/importer.cc (working copy)
|
| @@ -5,6 +5,7 @@
|
| #include "chrome/browser/importer/importer.h"
|
|
|
| #include <map>
|
| +#include <set>
|
|
|
| #include "base/file_util.h"
|
| #include "base/gfx/image_operations.h"
|
| @@ -81,10 +82,15 @@
|
|
|
| void ProfileWriter::AddBookmarkEntry(
|
| const std::vector<BookmarkEntry>& bookmark,
|
| - bool check_uniqueness) {
|
| + const std::wstring& first_folder_name,
|
| + int options) {
|
| BookmarkModel* model = profile_->GetBookmarkModel();
|
| DCHECK(model->IsLoaded());
|
|
|
| + bool first_run = (options & FIRST_RUN) != 0;
|
| + std::wstring real_first_folder = first_run ? first_folder_name :
|
| + GenerateUniqueFolderName(model, first_folder_name);
|
| +
|
| bool show_bookmark_toolbar = false;
|
| std::set<BookmarkNode*> groups_added_to;
|
| for (std::vector<BookmarkEntry>::const_iterator it = bookmark.begin();
|
| @@ -92,49 +98,13 @@
|
| // Don't insert this url if it isn't valid.
|
| if (!it->url.is_valid())
|
| continue;
|
| -
|
| +
|
| // We suppose that bookmarks are unique by Title, URL, and Folder. Since
|
| // checking for uniqueness may not be always the user's intention we have
|
| // this as an option.
|
| - if (check_uniqueness) {
|
| - std::vector<BookmarkModel::TitleMatch> matches;
|
| - model->GetBookmarksMatchingText((*it).title, 32, &matches); // 32 enough?
|
| - if (!matches.empty()) {
|
| - bool found_match = false;
|
| - for (std::vector<BookmarkModel::TitleMatch>::iterator match_it =
|
| - matches.begin();
|
| - match_it != matches.end() && !found_match;
|
| - ++match_it) {
|
| - if ((*it).title != (*match_it).node->GetTitle())
|
| - continue;
|
| - if ((*it).url != (*match_it).node->GetURL())
|
| - continue;
|
| -
|
| - // Check the folder path for uniqueness as well
|
| - found_match = true;
|
| - BookmarkNode* node = (*match_it).node->GetParent();
|
| - for(std::vector<std::wstring>::const_reverse_iterator path_it =
|
| - (*it).path.rbegin();
|
| - (path_it != (*it).path.rend()) && found_match;
|
| - ++path_it) {
|
| - if (NULL == node || (*path_it != node->GetTitle()))
|
| - found_match = false;
|
| - if (found_match)
|
| - node = node->GetParent();
|
| - }
|
| -
|
| - // We need a post test to differentiate checks such as
|
| - // /home/hello and /hello. Note that here the current parent
|
| - // should be the "Other bookmarks" node, its parent should be the
|
| - // root with title "", and it's parent is finally NULL.
|
| - if (NULL == node->GetParent() ||
|
| - NULL != node->GetParent()->GetParent())
|
| - found_match = false;
|
| - }
|
| -
|
| - if (found_match)
|
| - continue;
|
| - }
|
| + if (options & ADD_IF_UNIQUE &&
|
| + DoesBookmarkExist(model, *it, real_first_folder, first_run)) {
|
| + continue;
|
| }
|
|
|
| // Set up groups in BookmarkModel in such a way that path[i] is
|
| @@ -146,17 +116,21 @@
|
| for (std::vector<std::wstring>::const_iterator i = it->path.begin();
|
| i != it->path.end(); ++i) {
|
| BookmarkNode* child = NULL;
|
| + const std::wstring& folder_name =
|
| + (!first_run && !it->in_toolbar && (i == it->path.begin())) ?
|
| + real_first_folder : *i;
|
| +
|
| for (int index = 0; index < parent->GetChildCount(); ++index) {
|
| BookmarkNode* node = parent->GetChild(index);
|
| if ((node->GetType() == history::StarredEntry::BOOKMARK_BAR ||
|
| node->GetType() == history::StarredEntry::USER_GROUP) &&
|
| - node->GetTitle() == *i) {
|
| + node->GetTitle() == folder_name) {
|
| child = node;
|
| break;
|
| }
|
| }
|
| if (child == NULL)
|
| - child = model->AddGroup(parent, parent->GetChildCount(), *i);
|
| + child = model->AddGroup(parent, parent->GetChildCount(), folder_name);
|
| parent = child;
|
| }
|
| groups_added_to.insert(parent);
|
| @@ -321,6 +295,79 @@
|
| }
|
| }
|
|
|
| +std::wstring ProfileWriter::GenerateUniqueFolderName(
|
| + BookmarkModel* model,
|
| + const std::wstring& folder_name) {
|
| + // Build a set containing the folder names of the other folder.
|
| + std::set<std::wstring> other_folder_names;
|
| + BookmarkNode* other = model->other_node();
|
| + for (int i = 0; i < other->GetChildCount(); ++i) {
|
| + BookmarkNode* node = other->GetChild(i);
|
| + if (node->is_folder())
|
| + other_folder_names.insert(node->GetTitle());
|
| + }
|
| +
|
| + if (other_folder_names.find(folder_name) == other_folder_names.end())
|
| + return folder_name; // Name is unique, use it.
|
| +
|
| + // Otherwise iterate until we find a unique name.
|
| + for (int i = 1; i < 100; ++i) {
|
| + std::wstring name = folder_name + StringPrintf(L" (%d)", i);
|
| + if (other_folder_names.find(name) == other_folder_names.end())
|
| + return name;
|
| + }
|
| +
|
| + return folder_name;
|
| +}
|
| +
|
| +bool ProfileWriter::DoesBookmarkExist(
|
| + BookmarkModel* model,
|
| + const BookmarkEntry& entry,
|
| + const std::wstring& first_folder_name,
|
| + bool first_run) {
|
| + std::vector<BookmarkNode*> nodes_with_same_url;
|
| + model->GetNodesByURL(entry.url, &nodes_with_same_url);
|
| + if (nodes_with_same_url.empty())
|
| + return false;
|
| +
|
| + for (size_t i = 0; i < nodes_with_same_url.size(); ++i) {
|
| + BookmarkNode* node = nodes_with_same_url[i];
|
| + if (entry.title != node->GetTitle())
|
| + continue;
|
| +
|
| + // Does the path match?
|
| + bool found_match = true;
|
| + BookmarkNode* parent = node->GetParent();
|
| + for (std::vector<std::wstring>::const_reverse_iterator path_it =
|
| + entry.path.rbegin();
|
| + (path_it != entry.path.rend()) && found_match; ++path_it) {
|
| + const std::wstring& folder_name =
|
| + (!first_run && path_it + 1 == entry.path.rend()) ?
|
| + first_folder_name : *path_it;
|
| + if (NULL == parent || *path_it != folder_name)
|
| + found_match = false;
|
| + else
|
| + parent = parent->GetParent();
|
| + }
|
| +
|
| + // We need a post test to differentiate checks such as
|
| + // /home/hello and /hello. The parent should either by the other folder
|
| + // node, or the bookmarks bar, depending upon first_run and
|
| + // entry.in_toolbar.
|
| + if (found_match &&
|
| + ((first_run && entry.in_toolbar && parent !=
|
| + model->GetBookmarkBarNode()) ||
|
| + ((!first_run || !entry.in_toolbar) &&
|
| + parent != model->other_node()))) {
|
| + found_match = false;
|
| + }
|
| +
|
| + if (found_match)
|
| + return true; // Found a match with the same url path and title.
|
| + }
|
| + return false;
|
| +}
|
| +
|
| // Importer.
|
|
|
| // static
|
| @@ -539,6 +586,7 @@
|
| switch (type) {
|
| case MS_IE:
|
| return new IEImporter();
|
| + case BOOKMARKS_HTML:
|
| case FIREFOX2:
|
| return new Firefox2Importer();
|
| case FIREFOX3:
|
|
|