<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/bookmark_bubble_gtk.h"

#include <gtk/gtk.h>

#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "chrome/browser/bookmarks/bookmark_editor.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/info_bubble_gtk.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/profile.h"
#include "chrome/common/gtk_util.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"

namespace {

// We basically have a singleton, since a bubble is sort of app-modal.  This
// keeps track of the currently open bubble, or NULL if none is open.
BookmarkBubbleGtk* g_bubble = NULL;

// Max number of most recently used folders.
const size_t kMaxMRUFolders = 5;

std::vector<const BookmarkNode*> PopulateFolderCombo(BookmarkModel* model,
                                                     const GURL& url,
                                                     GtkWidget* folder_combo) {
  const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url);
  const BookmarkNode* parent = node->GetParent();
  const BookmarkNode* bookmark_bar = model->GetBookmarkBarNode();
  const BookmarkNode* other = model->other_node();

  // Use + 2 to account for bookmark bar and other node.
  std::vector<const BookmarkNode*> recent_nodes =
      bookmark_utils::GetMostRecentlyModifiedGroups(model, kMaxMRUFolders + 2);

  std::vector<const BookmarkNode*> nodes;
  // Make the parent the first item, unless it's the bookmark bar or other node.
  if (parent != bookmark_bar && parent != other)
    nodes.push_back(parent);

  for (size_t i = 0; i < recent_nodes.size(); ++i) {
    if (recent_nodes[i] != parent &&
        recent_nodes[i] != bookmark_bar &&
        recent_nodes[i] != other) {
      nodes.push_back(recent_nodes[i]);
    }
    // Make sure we only have kMaxMRUFolders in the first chunk.
    if (nodes.size() == kMaxMRUFolders)
      break;
  }

  // And put the bookmark bar and other nodes at the end of the list.
  nodes.push_back(bookmark_bar);
  nodes.push_back(other);

  // We always have nodes + 1 entries in the combo.  The last entry will be
  // the 'Select another folder...' entry that opens the bookmark editor.
  for (size_t i = 0; i < nodes.size(); ++i) {
    gtk_combo_box_append_text(GTK_COMBO_BOX(folder_combo),
                              WideToUTF8(nodes[i]->GetTitle()).c_str());
  }
  gtk_combo_box_append_text(GTK_COMBO_BOX(folder_combo),
      l10n_util::GetStringUTF8(
          IDS_BOOMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER).c_str());

  int parent_index = static_cast<int>(
      std::find(nodes.begin(), nodes.end(), parent) - nodes.begin());
  gtk_combo_box_set_active(GTK_COMBO_BOX(folder_combo), parent_index);

  return nodes;
}

}  // namespace

// static
void BookmarkBubbleGtk::Show(GtkWindow* toplevel_window,
                             const gfx::Rect& rect,
                             Profile* profile,
                             const GURL& url,
                             bool newly_bookmarked) {
  // TODO(deanm): The Views code deals with the possibility of a bubble already
  // being open, and then it just does nothing.  I am not sure how this could
  // happen with the style of our GTK bubble since it has a grab.  I would also
  // think that closing the previous bubble and opening the new one would make
  // more sense, but I guess then you would commit the bubble's changes.
  DCHECK(!g_bubble);
  g_bubble = new BookmarkBubbleGtk(toplevel_window, rect, profile,
                                   url, newly_bookmarked);
}

void BookmarkBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble,<commit_msg>Add a check for NULL in PopulateFolderCombo.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/bookmark_bubble_gtk.h"

#include <gtk/gtk.h>

#include "app/gfx/gtk_util.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "chrome/browser/bookmarks/bookmark_editor.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/info_bubble_gtk.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/profile.h"
#include "chrome/common/gtk_util.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"

namespace {

// We basically have a singleton, since a bubble is sort of app-modal.  This
// keeps track of the currently open bubble, or NULL if none is open.
BookmarkBubbleGtk* g_bubble = NULL;

// Max number of most recently used folders.
const size_t kMaxMRUFolders = 5;

std::vector<const BookmarkNode*> PopulateFolderCombo(BookmarkModel* model,
                                                     const GURL& url,
                                                     GtkWidget* folder_combo) {
  const BookmarkNode* bookmark_bar = model->GetBookmarkBarNode();
  const BookmarkNode* other = model->other_node();
  const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url);
  const BookmarkNode* parent = node ? node->GetParent() : NULL;

  // Use + 2 to account for bookmark bar and other node.
  std::vector<const BookmarkNode*> recent_nodes =
      bookmark_utils::GetMostRecentlyModifiedGroups(model, kMaxMRUFolders + 2);

  std::vector<const BookmarkNode*> nodes;
  // Make the parent the first item, unless it's the bookmark bar or other node.
  if (parent && parent != bookmark_bar && parent != other)
    nodes.push_back(parent);

  for (size_t i = 0; i < recent_nodes.size(); ++i) {
    if (recent_nodes[i] != parent &&
        recent_nodes[i] != bookmark_bar &&
        recent_nodes[i] != other) {
      nodes.push_back(recent_nodes[i]);
    }
    // Make sure we only have kMaxMRUFolders in the first chunk.
    if (nodes.size() == kMaxMRUFolders)
      break;
  }

  // And put the bookmark bar and other nodes at the end of the list.
  nodes.push_back(bookmark_bar);
  nodes.push_back(other);

  // We always have nodes + 1 entries in the combo.  The last entry will be
  // the 'Select another folder...' entry that opens the bookmark editor.
  for (size_t i = 0; i < nodes.size(); ++i) {
    gtk_combo_box_append_text(GTK_COMBO_BOX(folder_combo),
                              WideToUTF8(nodes[i]->GetTitle()).c_str());
  }
  gtk_combo_box_append_text(GTK_COMBO_BOX(folder_combo),
      l10n_util::GetStringUTF8(
          IDS_BOOMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER).c_str());

  gint parent_index = 0;
  if (parent) {
    parent_index = static_cast<gint>(
        std::find(nodes.begin(), nodes.end(), parent) - nodes.begin());
  }
  gtk_combo_box_set_active(GTK_COMBO_BOX(folder_combo), parent_index);

  return nodes;
}

}  // namespace

// static
void BookmarkBubbleGtk::Show(GtkWindow* toplevel_window,
                             const gfx::Rect& rect,
                             Profile* profile,
                             const GURL& url,
                             bool newly_bookmarked) {
  // TODO(deanm): The Views code deals with the possibility of a bubble already
  // being open, and then it just does nothing.  I am not sure how this could
  // happen with the style of our GTK bubble since it has a grab.  I would also
  // think that closing the previous bubble and opening the new one would make
  // more sense, but I guess then you would commit the bubble's changes.
  DCHECK(!g_bubble);
  g_bubble = new BookmarkBubbleGtk(toplevel_window, rect, profile,
                                   url, newly_bookmarked);
}

void BookmarkBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble,
{'fraction_non_alphanumeric': 0.1042287075640262, 'fraction_numerical': 0.003930911256700417, 'mean_word_length': 3.158494304110946, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3820011', 'n_tokens_mistral': 2720, 'n_tokens_neox': 2623, 'n_words': 728}