<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/views/about_chrome_view.h"

#include "app/gfx/canvas.h"
#include "app/gfx/color_utils.h"
#include "base/i18n/word_iterator.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/file_version_info.h"
#include "base/string_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/url_constants.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
#include "views/controls/textfield/textfield.h"
#include "views/controls/throbber.h"
#include "views/standard_layout.h"
#include "views/widget/widget.h"
#include "views/window/window.h"
#include "webkit/glue/webkit_glue.h"

#if defined(OS_WIN)
#include <commdlg.h>

#include "base/win_util.h"
#include "chrome/browser/views/restart_message_box.h"
#include "chrome/installer/util/install_util.h"
#endif

namespace {
// The pixel width of the version text field. Ideally, we'd like to have the
// bounds set to the edge of the icon. However, the icon is not a view but a
// part of the background, so we have to hard code the width to make sure
// the version field doesn't overlap it.
const int kVersionFieldWidth = 195;

// These are used as placeholder text around the links in the text in the about
// dialog.
const wchar_t* kBeginLink = L"BEGIN_LINK";
const wchar_t* kEndLink = L"END_LINK";
const wchar_t* kBeginLinkChr = L"BEGIN_LINK_CHR";
const wchar_t* kBeginLinkOss = L"BEGIN_LINK_OSS";
const wchar_t* kEndLinkChr = L"END_LINK_CHR";
const wchar_t* kEndLinkOss = L"END_LINK_OSS";

// The background bitmap used to draw the background color for the About box
// and the separator line (this is the image we will draw the logo on top of).
static const SkBitmap* kBackgroundBmp = NULL;

// Returns a substring from |text| between start and end.
std::wstring StringSubRange(const std::wstring& text, size_t start,
                            size_t end) {
  DCHECK(end > start);
  return text.substr(start, end - start);
}

}  // namespace

namespace browser {

// Declared in browser_dialogs.h so that others don't need to depend on our .h.
void ShowAboutChromeView(gfx::NativeWindow parent,
                         Profile* profile) {
  views::Window::CreateChromeWindow(parent,
                                    gfx::Rect(),
                                    new AboutChromeView(profile))->Show();
}

}  // namespace browser

////////////////////////////////////////////////////////////////////////////////
// AboutChromeView, public:

AboutChromeView::AboutChromeView(Profile* profile)
    : profile_(profile),
      about_dlg_background_logo_(NULL),
      about_title_label_(NULL),
      version_label_(NULL),
#if defined(OS_CHROMEOS)
      os_version_label_(NULL),
#endif
      copyright_label_(NULL),
      main_text_label_(NULL),
      main_text_label_height_(0),
      chromium_url_(NULL),
      open_source_url_(NULL),
      terms_of_service_url_(NULL),
      check_button_status_(CHECKBUTTON_HIDDEN),
      chromium_url_appears_first_(true),
      text_direction_is_rtl_(false) {
  DCHECK(profile);
#if defined(OS_CHROMEOS)
  loader_.GetVersion(&consumer_,
      NewCallback(this, &AboutChromeView::OnOSVersion));
#endif
  Init();

#if defined(OS_WIN)
  google_updater_ = new GoogleUpdate();
  google_updater_->AddStatusChangeListener(this);
#endif

  if (kBackgroundBmp == NULL) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    kBackgroundBmp = rb.GetBitmapNamed(IDR_ABOUT_BACKGROUND_COLOR);
  }
}

AboutChromeView::~AboutChromeView() {
#if defined(OS_WIN)
  // The Google Updater will hold a pointer to us until it reports status, so we
  // need to let it know that we will no longer be listening.
  if (google_updater_)
    google_updater_->RemoveStatusChangeListener();
#endif
}

void AboutChromeView::Init() {
  text_direction_is_rtl_ =
      l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();

  scoped_ptr<FileVersionInfo> version_info(
      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
  if (version_info.get() == NULL) {
    NOTREACHED() << L"Failed to initialize about window";
    return;
  }

  current_version_ = version_info->file_version();
#if !defined(GOOGLE_CHROME_BUILD)
  current_version_ += L" (";
  current_version_ += version_info->last_change();
  current_version_ += L")";
#endif

  // Views we will add to the *parent* of this dialog, since it will display
  // next to the buttons which we don't draw ourselves.
  throbber_.reset(new views::Throbber(50, true));
  throbber_->set_parent_owned(false);
  throbber_->SetVisible(false);

  SkBitmap* success_image = rb.GetBitmapNamed(IDR_UPDATE_UPTODATE);
  success_indicator_.SetImage(*success_image);
  success_indicator_.set_parent_owned(false);

  SkBitmap* update_available_image = rb.GetBitmapNamed(IDR_UPDATE_AVAILABLE);
  update_available_indicator_.SetImage(*update_available_image);
  update_available_indicator_.set_parent_owned(false);

  SkBitmap* timeout_image = rb.GetBitmapNamed(IDR_UPDATE_FAIL);
  timeout_indicator_.SetImage(*timeout_image);
  timeout_indicator_.set_parent_owned(false);

  update_label_.SetVisible(false);<commit_msg>Display channel in about box after version.  Windows.<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/views/about_chrome_view.h"

#include "app/gfx/canvas.h"
#include "app/gfx/color_utils.h"
#include "base/i18n/word_iterator.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/file_version_info.h"
#include "base/string_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/url_constants.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
#include "views/controls/textfield/textfield.h"
#include "views/controls/throbber.h"
#include "views/standard_layout.h"
#include "views/widget/widget.h"
#include "views/window/window.h"
#include "webkit/glue/webkit_glue.h"

#if defined(OS_WIN)
#include <commdlg.h>

#include "base/registry.h"
#include "base/win_util.h"
#include "chrome/browser/views/restart_message_box.h"
#include "chrome/installer/util/install_util.h"
#endif

namespace {
// The pixel width of the version text field. Ideally, we'd like to have the
// bounds set to the edge of the icon. However, the icon is not a view but a
// part of the background, so we have to hard code the width to make sure
// the version field doesn't overlap it.
const int kVersionFieldWidth = 195;

// These are used as placeholder text around the links in the text in the about
// dialog.
const wchar_t* kBeginLink = L"BEGIN_LINK";
const wchar_t* kEndLink = L"END_LINK";
const wchar_t* kBeginLinkChr = L"BEGIN_LINK_CHR";
const wchar_t* kBeginLinkOss = L"BEGIN_LINK_OSS";
const wchar_t* kEndLinkChr = L"END_LINK_CHR";
const wchar_t* kEndLinkOss = L"END_LINK_OSS";

// The background bitmap used to draw the background color for the About box
// and the separator line (this is the image we will draw the logo on top of).
static const SkBitmap* kBackgroundBmp = NULL;

// Returns a substring from |text| between start and end.
std::wstring StringSubRange(const std::wstring& text, size_t start,
                            size_t end) {
  DCHECK(end > start);
  return text.substr(start, end - start);
}

#if defined(GOOGLE_CHROME_BUILD) && defined(OS_WIN)

// Constants copied from src/tools/channel_changer/channel_changer.cc.

// The Google Update key to read to find out which branch you are on.
const wchar_t* const kChromeClientStateKey =
    L"Software\\Google\\Update\\ClientState\\"
    L"{8A69D345-D564-463C-AFF1-A69D9E530F96}";

// The Google Client key to read to find out which branch you are on.
const wchar_t* const kChromeClientsKey =
    L"Software\\Google\\Update\\Clients\\"
    L"{8A69D345-D564-463C-AFF1-A69D9E530F96}";

// The Google Update value that defines which branch you are on.
const wchar_t* const kBranchKey = L"ap";

// The suffix Google Update sometimes adds to the channel name (channel names
// are defined in kBranchStrings), indicating that a full install is needed. We
// strip this out (if present) for the purpose of determining which channel you
// are on.
const wchar_t* const kChannelSuffix = L"-full";

// See DetectBranch() in src/tools/channel_changer/channel_changer.cc.
std::wstring CurrentChromeChannel() {
  std::wstring update_branch = L"stable";  // default if we get confused.

  // See if we can find the Clients key on the HKLM branch.
  HKEY registry_hive = HKEY_LOCAL_MACHINE;
  RegKey google_update_hklm(registry_hive, kChromeClientsKey, KEY_READ);
  if (!google_update_hklm.Valid()) {
    // HKLM failed us, try the same for the HKCU branch.
    registry_hive = HKEY_CURRENT_USER;
    RegKey google_update_hkcu(registry_hive, kChromeClientsKey, KEY_READ);
    if (!google_update_hkcu.Valid()) {
      // Unknown.
      registry_hive = 0;
    }
  }

  if (registry_hive != 0) {
    // Now that we know which hive to use, read the 'ap' key from it.
    RegKey client_state(registry_hive, kChromeClientStateKey, KEY_READ);
    client_state.ReadValue(kBranchKey, &update_branch);

    // We look for '1.1-beta' or '1.1-dev', but Google Update might have added
    // '-full' to the channel name, which we need to strip out to determine what
    // channel you are on.
    std::wstring suffix = kChannelSuffix;
    if (update_branch.length() > suffix.length()) {
      size_t index = update_branch.rfind(suffix);
      if (index != std::wstring::npos &&
          index == update_branch.length() - suffix.length()) {
        update_branch = update_branch.substr(0, index);
      }
    }
  }

  // Map to something pithy for human consumption.
  if ((update_branch == L"2.0-dev") ||(update_branch == L"1.1-dev"))
    update_branch = L"dev";
  else if (update_branch == L"1.1-beta")
    update_branch = L"beta";

  return update_branch;
}
#endif  /* GOOGLE_CHROME_BUILD && OS_WIN */

}  // namespace

namespace browser {

// Declared in browser_dialogs.h so that others don't need to depend on our .h.
void ShowAboutChromeView(gfx::NativeWindow parent,
                         Profile* profile) {
  views::Window::CreateChromeWindow(parent,
                                    gfx::Rect(),
                                    new AboutChromeView(profile))->Show();
}

}  // namespace browser

////////////////////////////////////////////////////////////////////////////////
// AboutChromeView, public:

AboutChromeView::AboutChromeView(Profile* profile)
    : profile_(profile),
      about_dlg_background_logo_(NULL),
      about_title_label_(NULL),
      version_label_(NULL),
#if defined(OS_CHROMEOS)
      os_version_label_(NULL),
#endif
      copyright_label_(NULL),
      main_text_label_(NULL),
      main_text_label_height_(0),
      chromium_url_(NULL),
      open_source_url_(NULL),
      terms_of_service_url_(NULL),
      check_button_status_(CHECKBUTTON_HIDDEN),
      chromium_url_appears_first_(true),
      text_direction_is_rtl_(false) {
  DCHECK(profile);
#if defined(OS_CHROMEOS)
  loader_.GetVersion(&consumer_,
      NewCallback(this, &AboutChromeView::OnOSVersion));
#endif
  Init();

#if defined(OS_WIN)
  google_updater_ = new GoogleUpdate();
  google_updater_->AddStatusChangeListener(this);
#endif

  if (kBackgroundBmp == NULL) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    kBackgroundBmp = rb.GetBitmapNamed(IDR_ABOUT_BACKGROUND_COLOR);
  }
}

AboutChromeView::~AboutChromeView() {
#if defined(OS_WIN)
  // The Google Updater will hold a pointer to us until it reports status, so we
  // need to let it know that we will no longer be listening.
  if (google_updater_)
    google_updater_->RemoveStatusChangeListener();
#endif
}

void AboutChromeView::Init() {
  text_direction_is_rtl_ =
      l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();

  scoped_ptr<FileVersionInfo> version_info(
      FileVersionInfo::CreateFileVersionInfoForCurrentModule());
  if (version_info.get() == NULL) {
    NOTREACHED() << L"Failed to initialize about window";
    return;
  }

  current_version_ = version_info->file_version();
#if defined(GOOGLE_CHROME_BUILD)
#if defined(OS_WIN)
  current_version_ += L" ";
  current_version_ += CurrentChromeChannel();
#endif
#else
  current_version_ += L" (";
  current_version_ += version_info->last_change();
  current_version_ += L")";
#endif

  // Views we will add to the *parent* of this dialog, since it will display
  // next to the buttons which we don't draw ourselves.
  throbber_.reset(new views::Throbber(50, true));
  throbber_->set_parent_owned(false);
  throbber_->SetVisible(false);

  SkBitmap* success_image = rb.GetBitmapNamed(IDR_UPDATE_UPTODATE);
  success_indicator_.SetImage(*success_image);
  success_indicator_.set_parent_owned(false);

  SkBitmap* update_available_image = rb.GetBitmapNamed(IDR_UPDATE_AVAILABLE);
  update_available_indicator_.SetImage(*update_available_image);
  update_available_indicator_.set_parent_owned(false);

  SkBitmap* timeout_image = rb.GetBitmapNamed(IDR_UPDATE_FAIL);
  timeout_indicator_.SetImage(*timeout_image);
  timeout_indicator_.set_parent_owned(false);

  update_label_.SetVisible(false);
{'fraction_non_alphanumeric': 0.11904418134565406, 'fraction_numerical': 0.006569448455096737, 'mean_word_length': 4.068788876692279, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '920213', 'n_tokens_mistral': 4550, 'n_tokens_neox': 4449, 'n_words': 1113}