bookmark_utils.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "apps/app_launcher.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_editor.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/search/search.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/simple_message_box.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/url_constants.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/user_prefs.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_util.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int num_bookmark_urls_before_prompting = 15;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Iterator that iterates through a set of BookmarkNodes returning the URLs
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// for nodes that are urls, or the URLs for the children of non-url urls.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This does not recurse through all descendants, only immediate children.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The following illustrates
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// typical usage:
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OpenURLIterator iterator(nodes);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// while (iterator.has_next()) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   const GURL* url = iterator.NextURL();
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   // do something with |urll|.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// }
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class OpenURLIterator {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit OpenURLIterator(const std::vector<const BookmarkNode*>& nodes)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : child_index_(0),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        next_(NULL),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        parent_(nodes.begin()),
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        end_(nodes.end()) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FindNext();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_next() { return next_ != NULL;}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL* NextURL() {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!has_next()) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL* next = next_;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FindNext();
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return next;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Seach next node which has URL.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FindNext() {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (; parent_ < end_; ++parent_, child_index_ = 0) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if ((*parent_)->is_url()) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        next_ = &(*parent_)->url();
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ++parent_;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        child_index_ = 0;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (; child_index_ < (*parent_)->child_count(); ++child_index_) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          const BookmarkNode* child = (*parent_)->GetChild(child_index_);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          if (child->is_url()) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            next_ = &child->url();
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ++child_index_;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    next_ = NULL;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int child_index_;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL* next_;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<const BookmarkNode*>::const_iterator parent_;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::vector<const BookmarkNode*>::const_iterator end_;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OpenURLIterator);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldOpenAll(gfx::NativeWindow parent,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const std::vector<const BookmarkNode*>& nodes) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int child_count = 0;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenURLIterator iterator(nodes);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (iterator.has_next()) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    iterator.NextURL();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child_count++;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (child_count < num_bookmark_urls_before_prompting)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ShowMessageBox(parent,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOULD_OPEN_ALL,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 base::IntToString16(child_count)),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MESSAGE_BOX_TYPE_QUESTION) == MESSAGE_BOX_RESULT_YES;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the total number of descendants nodes.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChildURLCountTotal(const BookmarkNode* node) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = 0;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < node->child_count(); ++i) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BookmarkNode* child = node->GetChild(i);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result++;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (child->is_folder())
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result += ChildURLCountTotal(child);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns in |urls|, the url and title pairs for each open tab in browser.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetURLsForOpenTabs(Browser* browser,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        std::vector<std::pair<GURL, string16> >* urls) {
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < browser->tab_strip_model()->count(); ++i) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::pair<GURL, string16> entry;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetURLAndTitleToBookmark(browser->tab_strip_model()->GetWebContentsAt(i),
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             &(entry.first), &(entry.second));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    urls->push_back(entry);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenAll(gfx::NativeWindow parent,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             content::PageNavigator* navigator,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const std::vector<const BookmarkNode*>& nodes,
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             WindowOpenDisposition initial_disposition,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             content::BrowserContext* browser_context) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ShouldOpenAll(parent, nodes))
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Opens all |nodes| of type URL and any children of |nodes| that are of type
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // URL. |navigator| is the PageNavigator used to open URLs. After the first
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // url is opened |opened_first_url| is set to true and |navigator| is set to
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the PageNavigator of the last active tab. This is done to handle a window
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // disposition of new window, in which case we want subsequent tabs to open in
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that window.
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool opened_first_url = false;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WindowOpenDisposition disposition = initial_disposition;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenURLIterator iterator(nodes);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (iterator.has_next()) {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL* url = iterator.NextURL();
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When |initial_disposition| is OFF_THE_RECORD, a node which can't be
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // opened in incognito window, it is detected using |browser_context|, is
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // not opened.
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (initial_disposition == OFF_THE_RECORD &&
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !IsURLAllowedInIncognito(*url, browser_context))
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents* opened_tab = navigator->OpenURL(
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        content::OpenURLParams(*url, content::Referrer(), disposition,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               content::PAGE_TRANSITION_AUTO_BOOKMARK, false));
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!opened_first_url) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      opened_first_url = true;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      disposition = NEW_BACKGROUND_TAB;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // We opened the first URL which may have opened a new window or clobbered
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // the current page, reset the navigator just to be sure. |opened_tab| may
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // be NULL in tests.
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (opened_tab)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        navigator = opened_tab;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OpenAll(gfx::NativeWindow parent,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             content::PageNavigator* navigator,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             const BookmarkNode* node,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             WindowOpenDisposition initial_disposition,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             content::BrowserContext* browser_context) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<const BookmarkNode*> nodes;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nodes.push_back(node);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenAll(parent, navigator, nodes, initial_disposition, browser_context);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ConfirmDeleteBookmarkNode(const BookmarkNode* node,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               gfx::NativeWindow window) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(node && node->is_folder() && !node->empty());
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ShowMessageBox(window,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringFUTF16Int(IDS_BOOKMARK_EDITOR_CONFIRM_DELETE,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ChildURLCountTotal(node)),
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MESSAGE_BOX_TYPE_QUESTION) == MESSAGE_BOX_RESULT_YES;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowBookmarkAllTabsDialog(Browser* browser) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = browser->profile();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(model && model->IsLoaded());
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const BookmarkNode* parent = model->GetParentForNewNodes();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkEditor::EditDetails details =
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BookmarkEditor::EditDetails::AddFolder(parent, parent->child_count());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetURLsForOpenTabs(browser, &(details.urls));
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!details.urls.empty());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkEditor::Show(browser->window()->GetNativeWindow(), profile, details,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BookmarkEditor::SHOW_TREE);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasBookmarkURLs(const std::vector<const BookmarkNode*>& selection) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenURLIterator iterator(selection);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return iterator.has_next();
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasBookmarkURLsAllowedInIncognitoMode(
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<const BookmarkNode*>& selection,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::BrowserContext* browser_context) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  OpenURLIterator iterator(selection);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (iterator.has_next()) {
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL* url = iterator.NextURL();
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (IsURLAllowedInIncognito(*url, browser_context))
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GURL GetURLToBookmark(content::WebContents* web_contents) {
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(web_contents);
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return IsInstantNTP(web_contents) ?
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GURL(kChromeUINewTabURL) : web_contents->GetURL();
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetURLAndTitleToBookmark(content::WebContents* web_contents,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              GURL* url,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              string16* title) {
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *url = GetURLToBookmark(web_contents);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *title = web_contents->GetTitle();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ToggleBookmarkBarWhenVisible(content::BrowserContext* browser_context) {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = components::UserPrefs::Get(browser_context);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool always_show = !prefs->GetBoolean(prefs::kShowBookmarkBar);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The user changed when the bookmark bar is shown, update the preferences.
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->SetBoolean(prefs::kShowBookmarkBar, always_show);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)string16 FormatBookmarkURLForDisplay(const GURL& url,
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const PrefService* prefs) {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string languages;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (prefs)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    languages = prefs->GetString(prefs::kAcceptLanguages);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Because this gets re-parsed by FixupURL(), it's safe to omit the scheme
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and trailing slash, and unescape most characters.  However, it's
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // important not to drop any username/password, or unescape anything that
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // changes the URL's meaning.
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return net::FormatUrl(
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url, languages,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      net::kFormatUrlOmitAll & ~net::kFormatUrlOmitUsernamePassword,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      net::UnescapeRule::SPACES, NULL, NULL, NULL);
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IsAppsShortcutEnabled(const Profile* profile) {
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_ASH)
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Don't show the apps shortcut in ash when the app launcher is enabled.
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (apps::WasAppLauncherEnabled())
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chrome::IsInstantExtendedAPIEnabled() && !profile->IsOffTheRecord();
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ShouldShowAppsShortcutInBookmarkBar(Profile* profile) {
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return IsAppsShortcutEnabled(profile) &&
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile->GetPrefs()->GetBoolean(prefs::kShowAppsShortcutInBookmarkBar);
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
292