diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 18:29:43 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 18:29:43 +0000 |
commit | 57d8663235c088b31aac1cedb0a7e46b24d8ef5c (patch) | |
tree | 379cd3cb46978d65ce0123245851e473fa570bed /chrome/browser/search_engines | |
parent | 95c1aac9bbd395e30fb4003d947f3f61089d6312 (diff) | |
download | chromium_src-57d8663235c088b31aac1cedb0a7e46b24d8ef5c.zip chromium_src-57d8663235c088b31aac1cedb0a7e46b24d8ef5c.tar.gz chromium_src-57d8663235c088b31aac1cedb0a7e46b24d8ef5c.tar.bz2 |
Refactor platform-independent stuff out of EditKeywordController.
Preparation for adding GTK implementation.
BUG=13326
TEST=Edit existing search engine, add new search engine, add engine by clicking on OpenSearch description file.
Review URL: http://codereview.chromium.org/125161
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18636 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/search_engines')
-rw-r--r-- | chrome/browser/search_engines/edit_keyword_controller_base.cc | 130 | ||||
-rw-r--r-- | chrome/browser/search_engines/edit_keyword_controller_base.h | 91 |
2 files changed, 221 insertions, 0 deletions
diff --git a/chrome/browser/search_engines/edit_keyword_controller_base.cc b/chrome/browser/search_engines/edit_keyword_controller_base.cc new file mode 100644 index 0000000..8206d1d --- /dev/null +++ b/chrome/browser/search_engines/edit_keyword_controller_base.cc @@ -0,0 +1,130 @@ +// 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/search_engines/edit_keyword_controller_base.h" + +#include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/net/url_fixer_upper.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/search_engines/template_url.h" +#include "chrome/browser/search_engines/template_url_model.h" + +EditKeywordControllerBase::EditKeywordControllerBase( + const TemplateURL* template_url, + Delegate* edit_keyword_delegate, + Profile* profile) + : template_url_(template_url), + edit_keyword_delegate_(edit_keyword_delegate), + profile_(profile) { + DCHECK(profile_); +} + +bool EditKeywordControllerBase::IsTitleValid() const { + return !GetTitleInput().empty(); +} + +bool EditKeywordControllerBase::IsURLValid() const { + std::wstring url = GetURL(); + if (url.empty()) + return false; + + // Use TemplateURLRef to extract the search placeholder. + TemplateURLRef template_ref(url, 0, 0); + if (!template_ref.IsValid()) + return false; + + if (!template_ref.SupportsReplacement()) + return GURL(WideToUTF16Hack(url)).is_valid(); + + // If the url has a search term, replace it with a random string and make + // sure the resulting URL is valid. We don't check the validity of the url + // with the search term as that is not necessarily valid. + return GURL(WideToUTF8(template_ref.ReplaceSearchTerms(TemplateURL(), L"a", + TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring()))).is_valid(); +} + +std::wstring EditKeywordControllerBase::GetURL() const { + std::wstring url; + TrimWhitespace(TemplateURLRef::DisplayURLToURLRef(GetURLInput()), + TRIM_ALL, &url); + if (url.empty()) + return url; + + // Parse the string as a URL to determine the scheme. If we need to, add the + // scheme. As the scheme may be expanded (as happens with {google:baseURL}) + // we need to replace the search terms before testing for the scheme. + TemplateURL t_url; + t_url.SetURL(url, 0, 0); + std::wstring expanded_url = + t_url.url()->ReplaceSearchTerms(t_url, L"x", 0, std::wstring()); + url_parse::Parsed parts; + std::string scheme( + URLFixerUpper::SegmentURL(WideToUTF8(expanded_url), &parts)); + if(!parts.scheme.is_valid()) { + scheme.append("://"); + url.insert(0, UTF8ToWide(scheme)); + } + + return url; +} + +bool EditKeywordControllerBase::IsKeywordValid() const { + std::wstring keyword = GetKeywordInput(); + if (keyword.empty()) + return true; // Always allow no keyword. + const TemplateURL* turl_with_keyword = + profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword); + return (turl_with_keyword == NULL || turl_with_keyword == template_url_); +} + +void EditKeywordControllerBase::AcceptAddOrEdit() { + std::wstring url_string = GetURL(); + DCHECK(!url_string.empty()); + std::wstring keyword = GetKeywordInput(); + + const TemplateURL* existing = + profile_->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword); + if (existing && + (!edit_keyword_delegate_ || existing != template_url_)) { + // An entry may have been added with the same keyword string while the + // user edited the dialog, either automatically or by the user (if we're + // confirming a JS addition, they could have the Options dialog open at the + // same time). If so, just ignore this add. + // TODO(pamg): Really, we should modify the entry so this later one + // overwrites it. But we don't expect this case to be common. + CleanUpCancelledAdd(); + return; + } + + if (!edit_keyword_delegate_) { + // Confiming an entry we got from JS. We have a template_url_, but it + // hasn't yet been added to the model. + DCHECK(template_url_); + // const_cast is ugly, but this is the same thing the TemplateURLModel + // does in a similar situation (updating an existing TemplateURL with + // data from a new one). + TemplateURL* modifiable_url = const_cast<TemplateURL*>(template_url_); + modifiable_url->set_short_name(GetTitleInput()); + modifiable_url->set_keyword(keyword); + modifiable_url->SetURL(url_string, 0, 0); + // TemplateURLModel takes ownership of template_url_. + profile_->GetTemplateURLModel()->Add(modifiable_url); + UserMetrics::RecordAction(L"KeywordEditor_AddKeywordJS", profile_); + } else { + // Adding or modifying an entry via the Delegate. + edit_keyword_delegate_->OnEditedKeyword(template_url_, + GetTitleInput(), + GetKeywordInput(), + url_string); + } +} + +void EditKeywordControllerBase::CleanUpCancelledAdd() { + if (!edit_keyword_delegate_ && template_url_) { + // When we have no Delegate, we know that the template_url_ hasn't yet been + // added to the model, so we need to clean it up. + delete template_url_; + template_url_ = NULL; + } +} diff --git a/chrome/browser/search_engines/edit_keyword_controller_base.h b/chrome/browser/search_engines/edit_keyword_controller_base.h new file mode 100644 index 0000000..11b3080 --- /dev/null +++ b/chrome/browser/search_engines/edit_keyword_controller_base.h @@ -0,0 +1,91 @@ +// 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_SEARCH_ENGINES_EDIT_KEYWORD_CONTROLLER_BASE_H_ +#define CHROME_BROWSER_SEARCH_ENGINES_EDIT_KEYWORD_CONTROLLER_BASE_H_ + +#include <string> + +class Profile; +class TemplateURL; + +// EditKeywordControllerBase provides the platform independent logic and +// interface for implementing a dialog for editing keyword searches. +class EditKeywordControllerBase { + public: + class Delegate { + public: + virtual ~Delegate() {} + + // Invoked from the EditKeywordController when the user accepts the edits. + // NOTE: |template_url| is the value supplied to EditKeywordController's + // constructor, and may be null. A null value indicates a new TemplateURL + // should be created rather than modifying an existing TemplateURL. + virtual void OnEditedKeyword(const TemplateURL* template_url, + const std::wstring& title, + const std::wstring& keyword, + const std::wstring& url) = 0; + }; + + // The |template_url| and/or |edit_keyword_delegate| may be NULL. + EditKeywordControllerBase(const TemplateURL* template_url, + Delegate* edit_keyword_delegate, + Profile* profile); + virtual ~EditKeywordControllerBase() {} + + protected: + // Interface to platform specific view + virtual std::wstring GetURLInput() const = 0; + virtual std::wstring GetKeywordInput() const = 0; + virtual std::wstring GetTitleInput() const = 0; + + // Check if content of Title entry is valid. + bool IsTitleValid() const; + + // Returns true if the currently input URL is valid. The URL is valid if it + // contains no search terms and is a valid url, or if it contains a search + // term and replacing that search term with a character results in a valid + // url. + bool IsURLValid() const; + + // Fixes up and returns the URL the user has input. The returned URL is + // suitable for use by TemplateURL. + std::wstring GetURL() const; + + // Returns whether the currently entered keyword is valid. The keyword is + // valid if it is non-empty and does not conflict with an existing entry. + // NOTE: this is just the keyword, not the title and url. + bool IsKeywordValid() const; + + // Deletes an unused TemplateURL, if its add was cancelled and it's not + // already owned by the TemplateURLModel. + void AcceptAddOrEdit(); + + // Deletes an unused TemplateURL, if its add was cancelled and it's not + // already owned by the TemplateURLModel. + void CleanUpCancelledAdd(); + + const TemplateURL* template_url() const { + return template_url_; + } + + const Profile* profile() const { + return profile_; + } + + private: + // The TemplateURL we're displaying information for. It may be NULL. If we + // have a keyword_editor_view, we assume that this TemplateURL is already in + // the TemplateURLModel; if not, we assume it isn't. + const TemplateURL* template_url_; + + // We may have been created by this, in which case we will call back to it on + // success to add/modify the entry. May be NULL. + Delegate* edit_keyword_delegate_; + + // Profile whose TemplateURLModel we're modifying. + Profile* profile_; +}; + +#endif // CHROME_BROWSER_SEARCH_ENGINES_EDIT_KEYWORD_CONTROLLER_BASE_H_ |