summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/views/options/general_page_view.cc5
-rw-r--r--chrome/browser/views/options/general_page_view.h8
-rw-r--r--chrome/browser/views/shelf_item_dialog.cc313
-rw-r--r--chrome/browser/views/shelf_item_dialog.h131
-rw-r--r--chrome/browser/views/url_picker.cc317
-rw-r--r--chrome/browser/views/url_picker.h131
-rw-r--r--chrome/chrome.gyp4
7 files changed, 456 insertions, 453 deletions
diff --git a/chrome/browser/views/options/general_page_view.cc b/chrome/browser/views/options/general_page_view.cc
index e99444d..f639efe 100644
--- a/chrome/browser/views/options/general_page_view.cc
+++ b/chrome/browser/views/options/general_page_view.cc
@@ -21,7 +21,6 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/keyword_editor_view.h"
#include "chrome/browser/views/options/options_group_view.h"
-#include "chrome/browser/dom_ui/new_tab_ui.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
@@ -889,7 +888,7 @@ void GeneralPageView::SaveStartupPref() {
}
void GeneralPageView::AddURLToStartupURLs() {
- ShelfItemDialog* dialog = new ShelfItemDialog(this, profile(), false);
+ UrlPicker* dialog = new UrlPicker(this, profile(), false);
dialog->Show(GetWindow()->GetNativeWindow());
}
@@ -936,7 +935,7 @@ void GeneralPageView::EnableCustomHomepagesControls(bool enable) {
startup_custom_pages_table_->SetEnabled(enable);
}
-void GeneralPageView::AddBookmark(ShelfItemDialog* dialog,
+void GeneralPageView::AddBookmark(UrlPicker* dialog,
const std::wstring& title,
const GURL& url) {
int index = startup_custom_pages_table_->FirstSelectedRow();
diff --git a/chrome/browser/views/options/general_page_view.h b/chrome/browser/views/options/general_page_view.h
index 27827be..1cf5f30 100644
--- a/chrome/browser/views/options/general_page_view.h
+++ b/chrome/browser/views/options/general_page_view.h
@@ -7,7 +7,7 @@
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/views/options/options_page_view.h"
-#include "chrome/browser/views/shelf_item_dialog.h"
+#include "chrome/browser/views/url_picker.h"
#include "chrome/common/pref_member.h"
#include "views/controls/combobox/combobox.h"
#include "views/controls/button/button.h"
@@ -35,7 +35,7 @@ class GeneralPageView : public OptionsPageView,
public views::Combobox::Listener,
public views::ButtonListener,
public views::Textfield::Controller,
- public ShelfItemDialogDelegate,
+ public UrlPickerDelegate,
public views::TableViewObserver,
public ShellIntegration::DefaultBrowserObserver {
public:
@@ -94,8 +94,8 @@ class GeneralPageView : public OptionsPageView,
// option if that preference is not selected.
void EnableCustomHomepagesControls(bool enable);
- // ShelfItemDialogDelegate. Adds the URL to the list of startup urls.
- virtual void AddBookmark(ShelfItemDialog* dialog,
+ // UrlPickerDelegate. Adds the URL to the list of startup urls.
+ virtual void AddBookmark(UrlPicker* dialog,
const std::wstring& title,
const GURL& url);
diff --git a/chrome/browser/views/shelf_item_dialog.cc b/chrome/browser/views/shelf_item_dialog.cc
index ce3c7b0..e69de29 100644
--- a/chrome/browser/views/shelf_item_dialog.cc
+++ b/chrome/browser/views/shelf_item_dialog.cc
@@ -1,313 +0,0 @@
-// Copyright (c) 2006-2008 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/shelf_item_dialog.h"
-
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
-#include "app/table_model.h"
-#include "app/table_model_observer.h"
-#include "base/stl_util-inl.h"
-#include "base/string_util.h"
-#include "chrome/browser/net/url_fixer_upper.h"
-#include "chrome/browser/possible_url_model.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/pref_service.h"
-#include "grit/app_resources.h"
-#include "grit/generated_resources.h"
-#include "grit/locale_settings.h"
-#include "net/base/net_util.h"
-#include "views/background.h"
-#include "views/controls/label.h"
-#include "views/controls/table/table_view.h"
-#include "views/controls/textfield/textfield.h"
-#include "views/focus/focus_manager.h"
-#include "views/grid_layout.h"
-#include "views/standard_layout.h"
-#include "views/widget/widget.h"
-
-using views::ColumnSet;
-using views::GridLayout;
-
-// Preferred height of the table.
-static const int kTableWidth = 300;
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// ShelfItemDialog implementation
-//
-////////////////////////////////////////////////////////////////////////////////
-ShelfItemDialog::ShelfItemDialog(ShelfItemDialogDelegate* delegate,
- Profile* profile,
- bool show_title)
- : profile_(profile),
- expected_title_handle_(0),
- delegate_(delegate) {
- DCHECK(profile_);
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
-
- url_table_model_.reset(new PossibleURLModel());
-
- TableColumn col1(IDS_ASI_PAGE_COLUMN, TableColumn::LEFT, -1,
- 50);
- col1.sortable = true;
- TableColumn col2(IDS_ASI_URL_COLUMN, TableColumn::LEFT, -1,
- 50);
- col2.sortable = true;
- std::vector<TableColumn> cols;
- cols.push_back(col1);
- cols.push_back(col2);
-
- url_table_ = new views::TableView(url_table_model_.get(), cols,
- views::ICON_AND_TEXT, true, true,
- true);
- url_table_->SetObserver(this);
-
- // Yummy layout code.
- const int labels_column_set_id = 0;
- const int single_column_view_set_id = 1;
- GridLayout* layout = CreatePanelGridLayout(this);
- SetLayoutManager(layout);
- ColumnSet* column_set = layout->AddColumnSet(labels_column_set_id);
- column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0);
- column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
- column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0);
-
- column_set = layout->AddColumnSet(single_column_view_set_id);
- column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
- GridLayout::FIXED, kTableWidth, 0);
-
- if (show_title) {
- layout->StartRow(0, labels_column_set_id);
- views::Label* title_label = new views::Label();
- title_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- title_label->SetText(l10n_util::GetString(IDS_ASI_TITLE_LABEL));
- layout->AddView(title_label);
-
- title_field_ = new views::Textfield();
- title_field_->SetController(this);
- layout->AddView(title_field_);
-
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- } else {
- title_field_ = NULL;
- }
-
- layout->StartRow(0, labels_column_set_id);
- views::Label* url_label = new views::Label();
- url_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- url_label->SetText(l10n_util::GetString(IDS_ASI_URL));
- layout->AddView(url_label);
-
- url_field_ = new views::Textfield();
- url_field_->SetController(this);
- layout->AddView(url_field_);
-
- layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
-
- layout->StartRow(0, single_column_view_set_id);
- views::Label* description_label = new views::Label();
- description_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- description_label->SetText(l10n_util::GetString(IDS_ASI_DESCRIPTION));
- description_label->SetFont(
- description_label->GetFont().DeriveFont(0, gfx::Font::BOLD));
- layout->AddView(description_label);
-
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- layout->StartRow(1, single_column_view_set_id);
- layout->AddView(url_table_);
-
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
-
- AddAccelerator(views::Accelerator(VK_RETURN, false, false, false));
-}
-
-ShelfItemDialog::~ShelfItemDialog() {
- url_table_->SetModel(NULL);
-}
-
-void ShelfItemDialog::Show(HWND parent) {
- DCHECK(!window());
- views::Window::CreateChromeWindow(parent, gfx::Rect(), this)->Show();
- if (title_field_) {
- title_field_->SetText(l10n_util::GetString(IDS_ASI_DEFAULT_TITLE));
- title_field_->SelectAll();
- title_field_->RequestFocus();
- } else {
- url_field_->SelectAll();
- url_field_->RequestFocus();
- }
- url_table_model_->Reload(profile_);
-}
-
-void ShelfItemDialog::Close() {
- DCHECK(window());
- window()->Close();
-}
-
-std::wstring ShelfItemDialog::GetWindowTitle() const {
- return l10n_util::GetString(IDS_ASI_ADD_TITLE);
-}
-
-bool ShelfItemDialog::IsModal() const {
- return true;
-}
-
-std::wstring ShelfItemDialog::GetDialogButtonLabel(
- MessageBoxFlags::DialogButton button) const {
- if (button == MessageBoxFlags::DIALOGBUTTON_OK)
- return l10n_util::GetString(IDS_ASI_ADD);
- return std::wstring();
-}
-
-void ShelfItemDialog::OnURLInfoAvailable(
- HistoryService::Handle handle,
- bool success,
- const history::URLRow* info,
- history::VisitVector* unused) {
- if (handle != expected_title_handle_)
- return;
-
- std::wstring s;
- if (success)
- s = info->title();
- if (s.empty())
- s = l10n_util::GetString(IDS_ASI_DEFAULT_TITLE);
-
- if (title_field_) {
- // expected_title_handle_ is reset if the title Textfield is edited so we
- // can safely set the value.
- title_field_->SetText(s);
- title_field_->SelectAll();
- }
- expected_title_handle_ = 0;
-}
-
-void ShelfItemDialog::InitiateTitleAutoFill(const GURL& url) {
- HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
- if (!hs)
- return;
-
- if (expected_title_handle_)
- hs->CancelRequest(expected_title_handle_);
-
- expected_title_handle_ = hs->QueryURL(url, false, &history_consumer_,
- NewCallback(this, &ShelfItemDialog::OnURLInfoAvailable));
-}
-
-void ShelfItemDialog::ContentsChanged(views::Textfield* sender,
- const std::wstring& new_contents) {
- // If the user has edited the title field we no longer want to autofill it
- // so we reset the expected handle to an impossible value.
- if (sender == title_field_)
- expected_title_handle_ = 0;
- GetDialogClientView()->UpdateDialogButtons();
-}
-
-bool ShelfItemDialog::Accept() {
- if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) {
- if (!GetInputURL().is_valid())
- url_field_->RequestFocus();
- else if (title_field_)
- title_field_->RequestFocus();
- return false;
- }
- PerformModelChange();
- return true;
-}
-
-int ShelfItemDialog::GetDefaultDialogButton() const {
- // Don't set a default button, this view already has an accelerator for the
- // enter key.
- return MessageBoxFlags::DIALOGBUTTON_NONE;
-}
-
-bool ShelfItemDialog::IsDialogButtonEnabled(
- MessageBoxFlags::DialogButton button) const {
- if (button == MessageBoxFlags::DIALOGBUTTON_OK)
- return GetInputURL().is_valid();
- return true;
-}
-
-views::View* ShelfItemDialog::GetContentsView() {
- return this;
-}
-
-void ShelfItemDialog::PerformModelChange() {
- DCHECK(delegate_);
- GURL url(GetInputURL());
- const std::wstring title =
- title_field_ ? title_field_->text() : std::wstring();
- delegate_->AddBookmark(this, title, url);
-}
-
-gfx::Size ShelfItemDialog::GetPreferredSize() {
- return gfx::Size(views::Window::GetLocalizedContentsSize(
- IDS_SHELFITEM_DIALOG_WIDTH_CHARS,
- IDS_SHELFITEM_DIALOG_HEIGHT_LINES));
-}
-
-bool ShelfItemDialog::AcceleratorPressed(
- const views::Accelerator& accelerator) {
- if (accelerator.GetKeyCode() == VK_ESCAPE) {
- window()->Close();
- } else if (accelerator.GetKeyCode() == VK_RETURN) {
- views::FocusManager* fm = GetFocusManager();
- if (fm->GetFocusedView() == url_table_) {
- // Return on table behaves like a double click.
- OnDoubleClick();
- } else if (fm->GetFocusedView()== url_field_) {
- // Return on the url field accepts the input if url is valid. If the URL
- // is invalid, focus is left on the url field.
- if (GetInputURL().is_valid()) {
- PerformModelChange();
- if (window())
- window()->Close();
- } else {
- url_field_->SelectAll();
- }
- } else if (title_field_ && fm->GetFocusedView() == title_field_) {
- url_field_->SelectAll();
- url_field_->RequestFocus();
- }
- }
- return true;
-}
-
-void ShelfItemDialog::OnSelectionChanged() {
- int selection = url_table_->FirstSelectedRow();
- if (selection >= 0 && selection < url_table_model_->RowCount()) {
- std::wstring languages =
- profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
- // Because the url_field_ is user-editable, we set the URL with
- // username:password and escaped path and query.
- std::wstring formatted = net::FormatUrl(
- url_table_model_->GetURL(selection), languages,
- false, UnescapeRule::NONE, NULL, NULL);
- url_field_->SetText(formatted);
- if (title_field_)
- title_field_->SetText(url_table_model_->GetTitle(selection));
- GetDialogClientView()->UpdateDialogButtons();
- }
-}
-
-void ShelfItemDialog::OnDoubleClick() {
- int selection = url_table_->FirstSelectedRow();
- if (selection >= 0 && selection < url_table_model_->RowCount()) {
- OnSelectionChanged();
- PerformModelChange();
- if (window())
- window()->Close();
- }
-}
-
-GURL ShelfItemDialog::GetInputURL() const {
- return GURL(URLFixerUpper::FixupURL(url_field_->text(), L""));
-}
diff --git a/chrome/browser/views/shelf_item_dialog.h b/chrome/browser/views/shelf_item_dialog.h
index 8f5953a..e69de29 100644
--- a/chrome/browser/views/shelf_item_dialog.h
+++ b/chrome/browser/views/shelf_item_dialog.h
@@ -1,131 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_VIEWS_SHELF_ITEM_DIALOG_H_
-#define CHROME_BROWSER_VIEWS_SHELF_ITEM_DIALOG_H_
-
-#include "chrome/browser/cancelable_request.h"
-#include "chrome/browser/history/history.h"
-#include "views/controls/button/native_button.h"
-#include "views/controls/table/table_view_observer.h"
-#include "views/controls/textfield/textfield.h"
-#include "views/view.h"
-#include "views/window/dialog_delegate.h"
-#include "views/window/window.h"
-
-namespace views {
-class Button;
-class Label;
-class TableView;
-}
-
-class PossibleURLModel;
-class Profile;
-class ShelfItemDialog;
-
-// TODO(sky): rename this, perhaps to URLPicker.
-
-// ShelfItemDialog delegate. Notified when the user accepts the entry.
-class ShelfItemDialogDelegate {
- public:
- virtual void AddBookmark(ShelfItemDialog* dialog,
- const std::wstring& title,
- const GURL& url) = 0;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// This class implements the dialog that let the user add a bookmark or page
-// to the list of urls to open on startup.
-// ShelfItemDialog deletes itself when the dialog is closed.
-//
-////////////////////////////////////////////////////////////////////////////////
-class ShelfItemDialog : public views::View,
- public views::DialogDelegate,
- public views::Textfield::Controller,
- public views::TableViewObserver {
- public:
- ShelfItemDialog(ShelfItemDialogDelegate* delegate,
- Profile* profile,
- bool show_title);
- virtual ~ShelfItemDialog();
-
- // Show the dialog on the provided contents.
- virtual void Show(HWND parent);
-
- // Closes the dialog.
- void Close();
-
- // DialogDelegate.
- virtual std::wstring GetWindowTitle() const;
- virtual bool IsModal() const;
- virtual std::wstring GetDialogButtonLabel(
- MessageBoxFlags::DialogButton button) const;
- virtual bool Accept();
- virtual int GetDefaultDialogButton() const;
- virtual bool IsDialogButtonEnabled(
- MessageBoxFlags::DialogButton button) const;
- virtual views::View* GetContentsView();
-
- // TextField::Controller.
- virtual void ContentsChanged(views::Textfield* sender,
- const std::wstring& new_contents);
- virtual bool HandleKeystroke(views::Textfield* sender,
- const views::Textfield::Keystroke& key) {
- return false;
- }
-
- // Overridden from View.
- virtual gfx::Size GetPreferredSize();
- virtual bool AcceleratorPressed(const views::Accelerator& accelerator);
-
- // TableViewObserver.
- virtual void OnSelectionChanged();
- virtual void OnDoubleClick();
-
- private:
- // Modify the model from the user interface.
- void PerformModelChange();
-
- // Fetch the title for the entered URL. If we get the title in time before
- // the user starts to modify the title field, the title field is changed.
- void InitiateTitleAutoFill(const GURL& url);
-
- // Invoked by the history system when a title becomes available.
- void OnURLInfoAvailable(HistoryService::Handle handle,
- bool success,
- const history::URLRow* info,
- history::VisitVector* unused);
-
- // Returns the URL the user has typed.
- GURL GetInputURL() const;
-
- // Profile.
- Profile* profile_;
-
- // URL Field.
- views::Textfield* url_field_;
-
- // Title field. This is NULL if we're not showing the title.
- views::Textfield* title_field_;
-
- // The table model.
- scoped_ptr<PossibleURLModel> url_table_model_;
-
- // The table of visited urls.
- views::TableView* url_table_;
-
- // Handle of the title request we are expecting.
- CancelableRequestProvider::Handle expected_title_handle_;
-
- // The consumer object for the history database.
- CancelableRequestConsumer history_consumer_;
-
- // The delegate.
- ShelfItemDialogDelegate* delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(ShelfItemDialog);
-};
-
-#endif // CHROME_BROWSER_VIEWS_SHELF_ITEM_DIALOG_H_
diff --git a/chrome/browser/views/url_picker.cc b/chrome/browser/views/url_picker.cc
new file mode 100644
index 0000000..604e97f
--- /dev/null
+++ b/chrome/browser/views/url_picker.cc
@@ -0,0 +1,317 @@
+// Copyright (c) 2006-2008 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/url_picker.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "app/table_model.h"
+#include "app/table_model_observer.h"
+#include "base/stl_util-inl.h"
+#include "base/string_util.h"
+#include "chrome/browser/net/url_fixer_upper.h"
+#include "chrome/browser/possible_url_model.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+#include "grit/app_resources.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "net/base/net_util.h"
+#include "views/background.h"
+#include "views/controls/label.h"
+#include "views/controls/table/table_view.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/focus/focus_manager.h"
+#include "views/grid_layout.h"
+#include "views/standard_layout.h"
+#include "views/widget/widget.h"
+
+using views::ColumnSet;
+using views::GridLayout;
+
+// Preferred height of the table.
+static const int kTableWidth = 300;
+
+UrlPickerDelegate::~UrlPickerDelegate() {}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// UrlPicker implementation
+//
+////////////////////////////////////////////////////////////////////////////////
+UrlPicker::UrlPicker(UrlPickerDelegate* delegate,
+ Profile* profile,
+ bool show_title)
+ : profile_(profile),
+ expected_title_handle_(0),
+ delegate_(delegate) {
+ DCHECK(profile_);
+
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+
+ url_table_model_.reset(new PossibleURLModel());
+
+ TableColumn col1(IDS_ASI_PAGE_COLUMN, TableColumn::LEFT, -1,
+ 50);
+ col1.sortable = true;
+ TableColumn col2(IDS_ASI_URL_COLUMN, TableColumn::LEFT, -1,
+ 50);
+ col2.sortable = true;
+ std::vector<TableColumn> cols;
+ cols.push_back(col1);
+ cols.push_back(col2);
+
+ url_table_ = new views::TableView(url_table_model_.get(), cols,
+ views::ICON_AND_TEXT, true, true,
+ true);
+ url_table_->SetObserver(this);
+
+ // Yummy layout code.
+ GridLayout* layout = CreatePanelGridLayout(this);
+ SetLayoutManager(layout);
+
+ const int labels_column_set_id = 0;
+ const int single_column_view_set_id = 1;
+
+ ColumnSet* column_set = layout->AddColumnSet(labels_column_set_id);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
+ column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ column_set = layout->AddColumnSet(single_column_view_set_id);
+ column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
+ GridLayout::FIXED, kTableWidth, 0);
+
+ if (show_title) {
+ layout->StartRow(0, labels_column_set_id);
+ views::Label* title_label = new views::Label();
+ title_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ title_label->SetText(l10n_util::GetString(IDS_ASI_TITLE_LABEL));
+ layout->AddView(title_label);
+
+ title_field_ = new views::Textfield();
+ title_field_->SetController(this);
+ layout->AddView(title_field_);
+
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ } else {
+ title_field_ = NULL;
+ }
+
+ layout->StartRow(0, labels_column_set_id);
+ views::Label* url_label = new views::Label();
+ url_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ url_label->SetText(l10n_util::GetString(IDS_ASI_URL));
+ layout->AddView(url_label);
+
+ url_field_ = new views::Textfield();
+ url_field_->SetController(this);
+ layout->AddView(url_field_);
+
+ layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
+
+ layout->StartRow(0, single_column_view_set_id);
+ views::Label* description_label = new views::Label();
+ description_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ description_label->SetText(l10n_util::GetString(IDS_ASI_DESCRIPTION));
+ description_label->SetFont(
+ description_label->GetFont().DeriveFont(0, gfx::Font::BOLD));
+ layout->AddView(description_label);
+
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+
+ layout->StartRow(1, single_column_view_set_id);
+ layout->AddView(url_table_);
+
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+
+ AddAccelerator(views::Accelerator(VK_RETURN, false, false, false));
+}
+
+UrlPicker::~UrlPicker() {
+ url_table_->SetModel(NULL);
+}
+
+void UrlPicker::Show(HWND parent) {
+ DCHECK(!window());
+ views::Window::CreateChromeWindow(parent, gfx::Rect(), this)->Show();
+ if (title_field_) {
+ title_field_->SetText(l10n_util::GetString(IDS_ASI_DEFAULT_TITLE));
+ title_field_->SelectAll();
+ title_field_->RequestFocus();
+ } else {
+ url_field_->SelectAll();
+ url_field_->RequestFocus();
+ }
+ url_table_model_->Reload(profile_);
+}
+
+void UrlPicker::Close() {
+ DCHECK(window());
+ window()->Close();
+}
+
+std::wstring UrlPicker::GetWindowTitle() const {
+ return l10n_util::GetString(IDS_ASI_ADD_TITLE);
+}
+
+bool UrlPicker::IsModal() const {
+ return true;
+}
+
+std::wstring UrlPicker::GetDialogButtonLabel(
+ MessageBoxFlags::DialogButton button) const {
+ if (button == MessageBoxFlags::DIALOGBUTTON_OK)
+ return l10n_util::GetString(IDS_ASI_ADD);
+ return std::wstring();
+}
+
+void UrlPicker::OnURLInfoAvailable(
+ HistoryService::Handle handle,
+ bool success,
+ const history::URLRow* info,
+ history::VisitVector* unused) {
+ if (handle != expected_title_handle_)
+ return;
+
+ std::wstring s;
+ if (success)
+ s = info->title();
+ if (s.empty())
+ s = l10n_util::GetString(IDS_ASI_DEFAULT_TITLE);
+
+ if (title_field_) {
+ // expected_title_handle_ is reset if the title Textfield is edited so we
+ // can safely set the value.
+ title_field_->SetText(s);
+ title_field_->SelectAll();
+ }
+ expected_title_handle_ = 0;
+}
+
+void UrlPicker::InitiateTitleAutoFill(const GURL& url) {
+ HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
+ if (!hs)
+ return;
+
+ if (expected_title_handle_)
+ hs->CancelRequest(expected_title_handle_);
+
+ expected_title_handle_ = hs->QueryURL(url, false, &history_consumer_,
+ NewCallback(this, &UrlPicker::OnURLInfoAvailable));
+}
+
+void UrlPicker::ContentsChanged(views::Textfield* sender,
+ const std::wstring& new_contents) {
+ // If the user has edited the title field we no longer want to autofill it
+ // so we reset the expected handle to an impossible value.
+ if (sender == title_field_)
+ expected_title_handle_ = 0;
+ GetDialogClientView()->UpdateDialogButtons();
+}
+
+bool UrlPicker::Accept() {
+ if (!IsDialogButtonEnabled(MessageBoxFlags::DIALOGBUTTON_OK)) {
+ if (!GetInputURL().is_valid())
+ url_field_->RequestFocus();
+ else if (title_field_)
+ title_field_->RequestFocus();
+ return false;
+ }
+ PerformModelChange();
+ return true;
+}
+
+int UrlPicker::GetDefaultDialogButton() const {
+ // Don't set a default button, this view already has an accelerator for the
+ // enter key.
+ return MessageBoxFlags::DIALOGBUTTON_NONE;
+}
+
+bool UrlPicker::IsDialogButtonEnabled(
+ MessageBoxFlags::DialogButton button) const {
+ if (button == MessageBoxFlags::DIALOGBUTTON_OK)
+ return GetInputURL().is_valid();
+ return true;
+}
+
+views::View* UrlPicker::GetContentsView() {
+ return this;
+}
+
+void UrlPicker::PerformModelChange() {
+ DCHECK(delegate_);
+ GURL url(GetInputURL());
+ const std::wstring title =
+ title_field_ ? title_field_->text() : std::wstring();
+ delegate_->AddBookmark(this, title, url);
+}
+
+gfx::Size UrlPicker::GetPreferredSize() {
+ return gfx::Size(views::Window::GetLocalizedContentsSize(
+ IDS_SHELFITEM_DIALOG_WIDTH_CHARS,
+ IDS_SHELFITEM_DIALOG_HEIGHT_LINES));
+}
+
+bool UrlPicker::AcceleratorPressed(
+ const views::Accelerator& accelerator) {
+ if (accelerator.GetKeyCode() == VK_ESCAPE) {
+ window()->Close();
+ } else if (accelerator.GetKeyCode() == VK_RETURN) {
+ views::FocusManager* fm = GetFocusManager();
+ if (fm->GetFocusedView() == url_table_) {
+ // Return on table behaves like a double click.
+ OnDoubleClick();
+ } else if (fm->GetFocusedView()== url_field_) {
+ // Return on the url field accepts the input if url is valid. If the URL
+ // is invalid, focus is left on the url field.
+ if (GetInputURL().is_valid()) {
+ PerformModelChange();
+ if (window())
+ window()->Close();
+ } else {
+ url_field_->SelectAll();
+ }
+ } else if (title_field_ && fm->GetFocusedView() == title_field_) {
+ url_field_->SelectAll();
+ url_field_->RequestFocus();
+ }
+ }
+ return true;
+}
+
+void UrlPicker::OnSelectionChanged() {
+ int selection = url_table_->FirstSelectedRow();
+ if (selection >= 0 && selection < url_table_model_->RowCount()) {
+ std::wstring languages =
+ profile_->GetPrefs()->GetString(prefs::kAcceptLanguages);
+ // Because the url_field_ is user-editable, we set the URL with
+ // username:password and escaped path and query.
+ std::wstring formatted = net::FormatUrl(
+ url_table_model_->GetURL(selection), languages,
+ false, UnescapeRule::NONE, NULL, NULL);
+ url_field_->SetText(formatted);
+ if (title_field_)
+ title_field_->SetText(url_table_model_->GetTitle(selection));
+ GetDialogClientView()->UpdateDialogButtons();
+ }
+}
+
+void UrlPicker::OnDoubleClick() {
+ int selection = url_table_->FirstSelectedRow();
+ if (selection >= 0 && selection < url_table_model_->RowCount()) {
+ OnSelectionChanged();
+ PerformModelChange();
+ if (window())
+ window()->Close();
+ }
+}
+
+GURL UrlPicker::GetInputURL() const {
+ return GURL(URLFixerUpper::FixupURL(url_field_->text(), L""));
+}
diff --git a/chrome/browser/views/url_picker.h b/chrome/browser/views/url_picker.h
new file mode 100644
index 0000000..13376ba
--- /dev/null
+++ b/chrome/browser/views/url_picker.h
@@ -0,0 +1,131 @@
+// 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.
+
+#ifndef CHROME_BROWSER_VIEWS_URL_PICKER_H_
+#define CHROME_BROWSER_VIEWS_URL_PICKER_H_
+
+#include "chrome/browser/cancelable_request.h"
+#include "chrome/browser/history/history.h"
+#include "views/controls/button/native_button.h"
+#include "views/controls/table/table_view_observer.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/view.h"
+#include "views/window/dialog_delegate.h"
+#include "views/window/window.h"
+
+namespace views {
+class Button;
+class Label;
+class TableView;
+}
+
+class PossibleURLModel;
+class Profile;
+class UrlPicker;
+
+// UrlPicker delegate. Notified when the user accepts the entry.
+class UrlPickerDelegate {
+ public:
+ virtual ~UrlPickerDelegate();
+
+ virtual void AddBookmark(UrlPicker* dialog,
+ const std::wstring& title,
+ const GURL& url) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// This class implements the dialog that let the user add a bookmark or page
+// to the list of urls to open on startup.
+// UrlPicker deletes itself when the dialog is closed.
+//
+////////////////////////////////////////////////////////////////////////////////
+class UrlPicker : public views::View,
+ public views::DialogDelegate,
+ public views::Textfield::Controller,
+ public views::TableViewObserver {
+ public:
+ UrlPicker(UrlPickerDelegate* delegate,
+ Profile* profile,
+ bool show_title);
+ virtual ~UrlPicker();
+
+ // Show the dialog on the provided contents.
+ virtual void Show(HWND parent);
+
+ // Closes the dialog.
+ void Close();
+
+ // DialogDelegate.
+ virtual std::wstring GetWindowTitle() const;
+ virtual bool IsModal() const;
+ virtual std::wstring GetDialogButtonLabel(
+ MessageBoxFlags::DialogButton button) const;
+ virtual bool Accept();
+ virtual int GetDefaultDialogButton() const;
+ virtual bool IsDialogButtonEnabled(
+ MessageBoxFlags::DialogButton button) const;
+ virtual views::View* GetContentsView();
+
+ // TextField::Controller.
+ virtual void ContentsChanged(views::Textfield* sender,
+ const std::wstring& new_contents);
+ virtual bool HandleKeystroke(views::Textfield* sender,
+ const views::Textfield::Keystroke& key) {
+ return false;
+ }
+
+ // Overridden from View.
+ virtual gfx::Size GetPreferredSize();
+ virtual bool AcceleratorPressed(const views::Accelerator& accelerator);
+
+ // TableViewObserver.
+ virtual void OnSelectionChanged();
+ virtual void OnDoubleClick();
+
+ private:
+ // Modify the model from the user interface.
+ void PerformModelChange();
+
+ // Fetch the title for the entered URL. If we get the title in time before
+ // the user starts to modify the title field, the title field is changed.
+ void InitiateTitleAutoFill(const GURL& url);
+
+ // Invoked by the history system when a title becomes available.
+ void OnURLInfoAvailable(HistoryService::Handle handle,
+ bool success,
+ const history::URLRow* info,
+ history::VisitVector* unused);
+
+ // Returns the URL the user has typed.
+ GURL GetInputURL() const;
+
+ // Profile.
+ Profile* profile_;
+
+ // URL Field.
+ views::Textfield* url_field_;
+
+ // Title field. This is NULL if we're not showing the title.
+ views::Textfield* title_field_;
+
+ // The table model.
+ scoped_ptr<PossibleURLModel> url_table_model_;
+
+ // The table of visited urls.
+ views::TableView* url_table_;
+
+ // Handle of the title request we are expecting.
+ CancelableRequestProvider::Handle expected_title_handle_;
+
+ // The consumer object for the history database.
+ CancelableRequestConsumer history_consumer_;
+
+ // The delegate.
+ UrlPickerDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(UrlPicker);
+};
+
+#endif // CHROME_BROWSER_VIEWS_URL_PICKER_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 6b59d03..f1d5200 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1858,8 +1858,6 @@
'browser/views/sad_tab_view.h',
'browser/views/select_profile_dialog.cc',
'browser/views/select_profile_dialog.h',
- 'browser/views/shelf_item_dialog.cc',
- 'browser/views/shelf_item_dialog.h',
'browser/views/shell_dialogs_win.cc',
'browser/views/star_toggle.cc',
'browser/views/star_toggle.h',
@@ -1932,6 +1930,8 @@
'browser/views/toolbar_view.h',
'browser/views/uninstall_dialog.cc',
'browser/views/uninstall_dialog.h',
+ 'browser/views/url_picker.cc',
+ 'browser/views/url_picker.h',
'browser/views/user_data_dir_dialog.cc',
'browser/views/user_data_dir_dialog.h',
'browser/visitedlink_master.cc',