diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-03 21:49:29 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-03 21:49:29 +0000 |
commit | 1c9e90e17741f9c34f4cbe7f3e68a8300ed24e08 (patch) | |
tree | a71ad0a43ff69da776078899976dce66f4bf302c | |
parent | 9cea0d120a21c80f812be19cc7eb6e3fffdd6913 (diff) | |
download | chromium_src-1c9e90e17741f9c34f4cbe7f3e68a8300ed24e08.zip chromium_src-1c9e90e17741f9c34f4cbe7f3e68a8300ed24e08.tar.gz chromium_src-1c9e90e17741f9c34f4cbe7f3e68a8300ed24e08.tar.bz2 |
Remove NativeUI, HistoryTabUI, DownloadsTabUI since they've been superceded.
Review URL: http://codereview.chromium.org/39005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10832 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autocomplete/autocomplete.cc | 4 | ||||
-rw-r--r-- | chrome/browser/back_forward_menu_model.cc | 1 | ||||
-rw-r--r-- | chrome/browser/base_history_model.cc | 158 | ||||
-rw-r--r-- | chrome/browser/base_history_model.h | 186 | ||||
-rw-r--r-- | chrome/browser/browser.vcproj | 64 | ||||
-rw-r--r-- | chrome/browser/history_model.cc | 297 | ||||
-rw-r--r-- | chrome/browser/history_model.h | 91 | ||||
-rw-r--r-- | chrome/browser/history_tab_ui.cc | 149 | ||||
-rw-r--r-- | chrome/browser/history_tab_ui.h | 90 | ||||
-rw-r--r-- | chrome/browser/history_view.cc | 1316 | ||||
-rw-r--r-- | chrome/browser/history_view.h | 217 | ||||
-rw-r--r-- | chrome/browser/tab_contents/native_ui_contents.cc | 670 | ||||
-rw-r--r-- | chrome/browser/tab_contents/native_ui_contents.h | 295 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_factory.cc | 7 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_type.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/download_shelf_view.cc | 1 | ||||
-rw-r--r-- | chrome/browser/views/download_tab_view.cc | 1341 | ||||
-rw-r--r-- | chrome/browser/views/download_tab_view.h | 281 |
18 files changed, 4 insertions, 5165 deletions
diff --git a/chrome/browser/autocomplete/autocomplete.cc b/chrome/browser/autocomplete/autocomplete.cc index 9f455c8..18abde0 100644 --- a/chrome/browser/autocomplete/autocomplete.cc +++ b/chrome/browser/autocomplete/autocomplete.cc @@ -13,6 +13,7 @@ #include "chrome/browser/autocomplete/keyword_provider.h" #include "chrome/browser/autocomplete/search_provider.h" #include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/dom_ui/history_ui.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/profile.h" #include "chrome/common/gfx/text_elider.h" @@ -31,7 +32,6 @@ // TODO(port): Port this file. #if defined(OS_WIN) #include "chrome/browser/external_protocol_handler.h" -#include "chrome/browser/history_tab_ui.h" #else #include "chrome/common/temp_scaffolding_stubs.h" #endif @@ -832,7 +832,7 @@ void AutocompleteController::AddHistoryContentsShortcut() { ACMatchClassification::NONE)); } match.destination_url = - HistoryTabUI::GetHistoryURLWithSearchText(input_.text()); + HistoryUI::GetHistoryURLWithSearchText(input_.text()); match.transition = PageTransition::AUTO_BOOKMARK; match.provider = history_contents_provider_; latest_result_.AddMatch(match); diff --git a/chrome/browser/back_forward_menu_model.cc b/chrome/browser/back_forward_menu_model.cc index a57541d..d0e4ab3 100644 --- a/chrome/browser/back_forward_menu_model.cc +++ b/chrome/browser/back_forward_menu_model.cc @@ -17,7 +17,6 @@ #if defined(OS_WIN) // TODO(port): port these headers and remove the platform defines. -#include "chrome/browser/history_tab_ui.h" #include "chrome/browser/tab_contents/tab_contents.h" #elif defined(OS_POSIX) #include "chrome/common/temp_scaffolding_stubs.h" diff --git a/chrome/browser/base_history_model.cc b/chrome/browser/base_history_model.cc deleted file mode 100644 index f8e5d17..0000000 --- a/chrome/browser/base_history_model.cc +++ /dev/null @@ -1,158 +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/base_history_model.h" - -#include "base/gfx/jpeg_codec.h" -#include "base/gfx/png_decoder.h" -#include "chrome/browser/profile.h" -#include "chrome/common/resource_bundle.h" -#include "grit/theme_resources.h" -#include "SkBitmap.h" - -// Size of the favicon and thumbnail caches. -static const int kThumbnailCacheSize = 100; - -// Icon to display when one isn't found for the page. -static SkBitmap* kDefaultFavicon = NULL; - -// static -const int BaseHistoryModel::kHistoryScopeMonths = 18; - -BaseHistoryModel::BaseHistoryModel(Profile* profile) - : profile_(profile), - observer_(NULL), - is_search_results_(false), - thumbnails_(kThumbnailCacheSize), - favicons_(kThumbnailCacheSize) { - if (!kDefaultFavicon) { - kDefaultFavicon = ResourceBundle::GetSharedInstance(). - GetBitmapNamed(IDR_DEFAULT_FAVICON); - } -} - -BaseHistoryModel::~BaseHistoryModel() { -} - -void BaseHistoryModel::SetObserver(BaseHistoryModelObserver* observer) { - observer_ = observer; -} - -BaseHistoryModelObserver* BaseHistoryModel::GetObserver() const { - return observer_; -} - -SkBitmap* BaseHistoryModel::GetThumbnail(int index) { - return GetImage(THUMBNAIL, index); -} - -SkBitmap* BaseHistoryModel::GetFavicon(int index) { - SkBitmap* favicon = GetImage(FAVICON, index); - return favicon ? favicon : kDefaultFavicon; -} - -void BaseHistoryModel::AboutToScheduleRequest() { - if (observer_ && cancelable_consumer_.PendingRequestCount() == 0) - observer_->ModelBeginWork(); -} - -void BaseHistoryModel::RequestCompleted() { - if (observer_ && cancelable_consumer_.PendingRequestCount() == 1) - observer_->ModelEndWork(); -} - -SkBitmap* BaseHistoryModel::GetImage(ImageType image_type, int index) { -#ifndef NDEBUG - DCHECK(IsValidIndex(index)); -#endif - history::URLID id = GetURLID(index); - DCHECK(id); - - CacheType* cache = (image_type == THUMBNAIL) ? &thumbnails_ : &favicons_; - CacheType::iterator iter = cache->Get(id); - if (iter != cache->end()) { - // Empty bitmaps indicate one that is pending a load. We still return NULL - // in this case. - return iter->second.getSize() ? &iter->second : NULL; - } - - HistoryService* history_service = - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); - if (!history_service) - return NULL; - - // The entry isn't cached, ask the history service for it. - - // Add an entry to the cache. This ensures we don't request the same page - // more than once. - cache->Put(id, SkBitmap()); - - // If this is the first request, we need to notify our delegate we're - // beginning work. - AboutToScheduleRequest(); - - // Start the request & associate the page ID with this thumbnail request. - HistoryService::Handle request; - if (image_type == THUMBNAIL) { - request = history_service->GetPageThumbnail(GetURL(index), - &cancelable_consumer_, - NewCallback(this, &BaseHistoryModel::OnThumbnailDataAvailable)); - } else { - request = history_service->GetFavIconForURL(GetURL(index), - &cancelable_consumer_, - NewCallback(this, &BaseHistoryModel::OnFaviconDataAvailable)); - } - cancelable_consumer_.SetClientData(history_service, request, id); - return NULL; -} - -void BaseHistoryModel::OnThumbnailDataAvailable( - HistoryService::Handle request_handle, - scoped_refptr<RefCountedBytes> data) { - RequestCompleted(); - - if (!data || data->data.empty()) { // This gets called on failure too. - return; - } - - // The client data for this request is the page ID for the thumbnail. - HistoryService* history_service = - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); - history::URLID page = cancelable_consumer_.GetClientData(history_service, - request_handle); - DCHECK(page > 0) << "Page ID is not found, maybe we forgot to set it"; - - scoped_ptr<SkBitmap> bitmap(JPEGCodec::Decode( - &data->data.front(), data->data.size())); - if (!bitmap.get()) - return; - - thumbnails_.Put(page, *bitmap); - - if (observer_) - observer_->ModelChanged(false); -} - -void BaseHistoryModel::OnFaviconDataAvailable( - HistoryService::Handle handle, - bool know_favicon, - scoped_refptr<RefCountedBytes> data, - bool expired, - GURL icon_url) { - RequestCompleted(); - - SkBitmap fav_icon; - if (!know_favicon || !data.get() || - !PNGDecoder::Decode(&data->data, &fav_icon)) { - return; - } - history::URLID page = - cancelable_consumer_.GetClientData( - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS), handle); - favicons_.Put(page, fav_icon); - - if (observer_) - observer_->ModelChanged(false); -} - diff --git a/chrome/browser/base_history_model.h b/chrome/browser/base_history_model.h deleted file mode 100644 index 21f3dd3..0000000 --- a/chrome/browser/base_history_model.h +++ /dev/null @@ -1,186 +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. - -// Base class used by history view. BaseHistoryModel provides support for -// fetching thumbnails and favicons, but not the actual contents that are -// displayed. - -#ifndef CHROME_BROWSER_BASE_HISTORY_MODEL_H__ -#define CHROME_BROWSER_BASE_HISTORY_MODEL_H__ - -#include "base/basictypes.h" -#include "base/time.h" -#include "chrome/browser/history/history.h" -#include "chrome/common/mru_cache.h" -#include "SkBitmap.h" - -class Profile; - -// Defines functions that allow a view associated with this model to -// learn that it should relayout/paint itself. -class BaseHistoryModelObserver { - public: - // Called when the data in the model has changed. - // |result_set_changed| is true when the model item counts have changed, - // false when the change is just item metadata (like thumbnails or - // starredness). - virtual void ModelChanged(bool result_set_changed) = 0; - - // Called when a long operation has begun, to allow the observer to show - // that work is pending. - virtual void ModelBeginWork() = 0; - - // Called when a long operation has completed. - virtual void ModelEndWork() = 0; -}; - -class BaseHistoryModel { - public: - explicit BaseHistoryModel(Profile* profile); - virtual ~BaseHistoryModel(); - - // The observer, notified of changes to the model or when processing - // begins/ends. - void SetObserver(BaseHistoryModelObserver* observer); - BaseHistoryModelObserver* GetObserver() const; - - // Returns the number of history items currently in the model. - virtual int GetItemCount() = 0; - - // Returns the time of the visit with the given index. - virtual base::Time GetVisitTime(int index) = 0; - - // Returns the title at the specified index. - virtual const std::wstring& GetTitle(int index) = 0; - - // Returns the URL at the specified index. - virtual const GURL& GetURL(int index) = 0; - - // Returns the id of the URL at the specified index. - virtual history::URLID GetURLID(int index) = 0; - - // Returns true if the page at the specified index is starred. - virtual bool IsStarred(int index) = 0; - - // Returns true if the entries are search results (this affects the UI shown). - virtual bool IsSearchResults() { return is_search_results_; } - - // Returns the snippet at the specified index. - virtual const Snippet& GetSnippet(int index) = 0; - - // Returns the favicon or thumbnail for the specified page. If the image is - // not available, NULL is returned. If the image has NOT been loaded, it is - // loaded and the observer is called back when done loading. - SkBitmap* GetThumbnail(int index); - SkBitmap* GetFavicon(int index); - - // Sets the new value of the search text, and requeries if the new value - // is different from the previous value. - virtual void SetSearchText(const std::wstring& search_text) { } - - // Returns the search text. - virtual const std::wstring& GetSearchText() const = 0; - - // Change the starred state of a given index. - virtual void SetPageStarred(int index, bool state) = 0; - - // The following methods are only invoked by HistoryView if the HistoryView - // is configured to show bookmark controls. - - // Returns true if the item is shown on the bookmark bar. - virtual bool IsOnBookmarkBar(int index) { return false; } - - // Returns the path of the item on the bookmark bar. This may return the - // empty string. - virtual std::wstring GetBookmarkBarPath(int index) { return std::wstring(); } - - // Edits the specified entry. This is intended for bookmarks where the user - // can edit various properties of the bookmark. - virtual void Edit(int index) {} - - // Removes the specified entry. - virtual void Remove(int index) {} - - // Removes the specified range from the model. This should NOT update the - // backend, rather it should just update the model and notify listeners - // appropriately. This need only be implemented if you turn on delete controls - // in the hosting HistoryView. - virtual void RemoveFromModel(int start, int length) { NOTREACHED(); } - - // Reloads the model. - virtual void Refresh() = 0; - - Profile* profile() const { return profile_; } - - // Number of months history requests should go back for. - static const int kHistoryScopeMonths; - - protected: - // Invoke when you're about to schedule a request on the history service. If - // no requests have been made, the observer is notified of ModelBeginWork. - void AboutToScheduleRequest(); - - // Invoke from a callback from the history service. If no requests are pending - // on the history service the observer is notified of ModelEndWork. - void RequestCompleted(); - -#ifndef NDEBUG - // For debugging, meant to be wrapped in a DCHECK. - bool IsValidIndex(int index) { - return (index >= 0 && index < GetItemCount()); - } -#endif - - // The user profile associated with the page that this model feeds. - Profile* profile_; - - // For history requests. This is used when requesting favicons and - // thumbnails, subclasses may also use this. - CancelableRequestConsumerT<history::URLID, 0> cancelable_consumer_; - - // Notified of changes to the content, typically HistoryView. - BaseHistoryModelObserver* observer_; - - // Whether the last returned result was a set of search results. - bool is_search_results_; - - private: - // Enum of the types of image we cache. Used by GetImage. - enum ImageType { - THUMBNAIL, - FAVICON - }; - - typedef MRUCache<history::URLID, SkBitmap> CacheType; - - // Returns the image at the specified index. If the image has not been loaded - // it is loaded. - SkBitmap* GetImage(ImageType type, int index); - - // Called when a request for the thumbnail data is complete. Updates the - // thumnails_ cache and notifies the observer (assuming the image is valid). - void OnThumbnailDataAvailable( - HistoryService::Handle request_handle, - scoped_refptr<RefCountedBytes> data); - - // Callback when a favicon is available. Updates the favicons_ cache and - // notifies the observer (assuming we can extract a valid image). - void OnFaviconDataAvailable( - HistoryService::Handle handle, - bool know_favicon, - scoped_refptr<RefCountedBytes> data, - bool expired, - GURL icon_url); - - // Keeps track of thumbnails for pages - CacheType thumbnails_; - - // Keeps track of favicons for pages - CacheType favicons_; - - DISALLOW_EVIL_CONSTRUCTORS(BaseHistoryModel); -}; - -#endif // CHROME_BROWSER_BASE_HISTORY_MODEL_H__ - diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index cc48667..2b032b6 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -174,7 +174,7 @@ > </File> <File - RelativePath=".\autocomplete\autocomplete_popup_view_win.h" + RelativePath=".\autocomplete\autocomplete_popup_model.h" > </File> <File @@ -182,15 +182,11 @@ > </File> <File - RelativePath=".\autocomplete\autocomplete_popup_model.h" - > - </File> - <File RelativePath=".\autocomplete\autocomplete_popup_view_win.cc" > </File> <File - RelativePath=".\autocomplete\autocomplete_popup_view.h" + RelativePath=".\autocomplete\autocomplete_popup_view_win.h" > </File> <File @@ -787,42 +783,6 @@ </File> </Filter> <Filter - Name="Destination" - > - <File - RelativePath=".\base_history_model.cc" - > - </File> - <File - RelativePath=".\base_history_model.h" - > - </File> - <File - RelativePath=".\views\download_tab_view.cc" - > - </File> - <File - RelativePath=".\views\download_tab_view.h" - > - </File> - <File - RelativePath=".\history_model.cc" - > - </File> - <File - RelativePath=".\history_model.h" - > - </File> - <File - RelativePath=".\history_view.cc" - > - </File> - <File - RelativePath=".\history_view.h" - > - </File> - </Filter> - <Filter Name="Automation" > <File @@ -1583,18 +1543,6 @@ </File> </Filter> <Filter - Name="NativeUI" - > - <File - RelativePath=".\history_tab_ui.cc" - > - </File> - <File - RelativePath=".\history_tab_ui.h" - > - </File> - </Filter> - <Filter Name="Net" > <File @@ -2174,14 +2122,6 @@ > </File> <File - RelativePath=".\tab_contents\native_ui_contents.cc" - > - </File> - <File - RelativePath=".\tab_contents\native_ui_contents.h" - > - </File> - <File RelativePath=".\tab_contents\navigation_controller.cc" > </File> diff --git a/chrome/browser/history_model.cc b/chrome/browser/history_model.cc deleted file mode 100644 index c9df37c..0000000 --- a/chrome/browser/history_model.cc +++ /dev/null @@ -1,297 +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/history_model.h" - -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/profile.h" -#include "chrome/common/notification_service.h" - -using base::Time; - -// The max number of results to retrieve when browsing user's history. -static const int kMaxBrowseResults = 800; - -// The max number of search results to retrieve. -static const int kMaxSearchResults = 100; - -HistoryModel::HistoryModel(Profile* profile, const std::wstring& search_text) - : BaseHistoryModel(profile), - search_text_(search_text), - search_depth_(0) { - // Register for notifications about URL starredness changing on this profile. - NotificationService::current()->AddObserver( - this, - NotificationType::URLS_STARRED, - Source<Profile>(profile->GetOriginalProfile())); - NotificationService::current()->AddObserver( - this, - NotificationType::HISTORY_URLS_DELETED, - Source<Profile>(profile->GetOriginalProfile())); -} - -HistoryModel::~HistoryModel() { - // Unregister for notifications about URL starredness. - NotificationService::current()->RemoveObserver( - this, - NotificationType::URLS_STARRED, - Source<Profile>(profile_->GetOriginalProfile())); - NotificationService::current()->RemoveObserver( - this, - NotificationType::HISTORY_URLS_DELETED, - Source<Profile>(profile_->GetOriginalProfile())); -} - -int HistoryModel::GetItemCount() { - return static_cast<int>(results_.size()); -} - -Time HistoryModel::GetVisitTime(int index) { -#ifndef NDEBUG - DCHECK(IsValidIndex(index)); -#endif - return results_[index].visit_time(); -} - -const std::wstring& HistoryModel::GetTitle(int index) { - return results_[index].title(); -} - -const GURL& HistoryModel::GetURL(int index) { - return results_[index].url(); -} - -history::URLID HistoryModel::GetURLID(int index) { - return results_[index].id(); -} - -bool HistoryModel::IsStarred(int index) { - if (star_state_[index] == UNKNOWN) { - bool is_starred = profile_->GetBookmarkModel()->IsBookmarked(GetURL(index)); - star_state_[index] = is_starred ? STARRED : NOT_STARRED; - } - return (star_state_[index] == STARRED); -} - -const Snippet& HistoryModel::GetSnippet(int index) { - return results_[index].snippet(); -} - -void HistoryModel::RemoveFromModel(int start, int length) { - DCHECK(start >= 0 && start + length <= GetItemCount()); - results_.DeleteRange(start, start + length); - if (observer_) - observer_->ModelChanged(true); -} - -void HistoryModel::SetSearchText(const std::wstring& search_text) { - if (search_text == search_text_) - return; - - search_text_ = search_text; - search_depth_ = 0; - Refresh(); -} - -void HistoryModel::InitVisitRequest(int depth) { - HistoryService* history_service = - profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); - if (!history_service) - return; - - AboutToScheduleRequest(); - - history::QueryOptions options; - - // Limit our search so that it doesn't return more than the maximum required - // number of results. - int max_total_results = search_text_.empty() ? - kMaxBrowseResults : kMaxSearchResults; - - if (depth == 0) { - // Set the end time of this first search to null (which will - // show results from the future, should the user's clock have - // been set incorrectly). - options.end_time = Time(); - - search_start_ = Time::Now(); - - // Configure the begin point of the search to the start of the - // current month. - Time::Exploded start_exploded; - search_start_.LocalMidnight().LocalExplode(&start_exploded); - start_exploded.day_of_month = 1; - options.begin_time = Time::FromLocalExploded(start_exploded); - - options.max_count = max_total_results; - } else { - Time::Exploded exploded; - search_start_.LocalMidnight().LocalExplode(&exploded); - exploded.day_of_month = 1; - - // Set the end-time of this search to the end of the month that is - // |depth| months before the search end point. The end time is not - // inclusive, so we should feel free to set it to midnight on the - // first day of the following month. - exploded.month -= depth - 1; - while (exploded.month < 1) { - exploded.month += 12; - exploded.year--; - } - options.end_time = Time::FromLocalExploded(exploded); - - // Set the begin-time of the search to the start of the month - // that is |depth| months prior to search_start_. - if (exploded.month > 1) { - exploded.month--; - } else { - exploded.month = 12; - exploded.year--; - } - options.begin_time = Time::FromLocalExploded(exploded); - - // Subtract off the number of pages we already got. - options.max_count = max_total_results - static_cast<int>(results_.size()); - } - - // This will make us get only one entry for each page. This is definitely - // correct for "starred only" queries, but more debatable for regular - // history queries. We might want to get all of them but then remove adjacent - // duplicates like Mozilla. - // - // We'll still get duplicates across month boundaries, which is probably fine. - options.most_recent_visit_only = true; - - HistoryService::QueryHistoryCallback* callback = - NewCallback(this, &HistoryModel::VisitedPagesQueryComplete); - history_service->QueryHistory(search_text_, options, - &cancelable_consumer_, callback); -} - -void HistoryModel::SetPageStarred(int index, bool state) { - const history::URLResult& result = results_[index]; - if (!UpdateStarredStateOfURL(result.url(), state)) - return; // Nothing was changed. - - if (observer_) - observer_->ModelChanged(false); - - BookmarkModel* bb_model = profile_->GetBookmarkModel(); - if (bb_model) - bb_model->SetURLStarred(result.url(), result.title(), state); -} - -void HistoryModel::Refresh() { - cancelable_consumer_.CancelAllRequests(); - if (observer_) - observer_->ModelEndWork(); - search_depth_ = 0; - InitVisitRequest(search_depth_); - - if (results_.size() > 0) { - // There are results and we've been asked to reload. If we don't swap out - // the results now, the view is left holding indices that are going to - // change as soon as the load completes, which poses problems for deletion. - // In particular, if the user deletes a range, then clicks on delete again - // a modal dialog is shown. If during the time the modal dialog is shown - // and the user clicks ok the load completes, the index passed to delete is - // no longer valid. To avoid this we empty out the results immediately. - history::QueryResults empty_results; - results_.Swap(&empty_results); - if (observer_) - observer_->ModelChanged(true); - } -} - -void HistoryModel::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - switch (type.value) { - case NotificationType::URLS_STARRED: { // Somewhere a URL has been starred. - Details<history::URLsStarredDetails> starred_state(details); - - // In the degenerate case when there are a lot of pages starred, this may - // be unacceptably slow. - std::set<GURL>::const_iterator i; - bool changed = false; - for (i = starred_state->changed_urls.begin(); - i != starred_state->changed_urls.end(); ++i) { - changed |= UpdateStarredStateOfURL(*i, starred_state->starred); - } - if (changed && observer_) - observer_->ModelChanged(false); - break; - } - - case NotificationType::HISTORY_URLS_DELETED: - // TODO(brettw) bug 1140015: This should actually update the current query - // rather than re-querying. This should be much more efficient and - // user-friendly. - // - // Note that we can special case when the "all_history" flag is set to just - // clear the view. - Refresh(); - break; - - // TODO(brettw) bug 1140015, 1140017, 1140020: Add a more observers to catch - // title changes, new additions, etc.. Also, URLS_ADDED when that - // notification exists. - - default: - NOTREACHED(); - break; - } -} - -void HistoryModel::VisitedPagesQueryComplete( - HistoryService::Handle request_handle, - history::QueryResults* results) { - bool changed = (results->size() > 0); - if (search_depth_ == 0) { - if (results_.size() > 0) - changed = true; - results_.Swap(results); - } else { - results_.AppendResultsBySwapping(results, true); - } - - is_search_results_ = !search_text_.empty(); - - if (changed) { - star_state_.reset(new StarState[results_.size()]); - memset(star_state_.get(), 0, sizeof(StarState) * results_.size()); - if (observer_) - observer_->ModelChanged(true); - } - - search_depth_++; - - int max_results = search_text_.empty() ? - kMaxBrowseResults : kMaxSearchResults; - - // TODO(glen/brettw): bug 1203052 - Need to detect if we've reached the - // end of the user's history. - if (search_depth_ < kHistoryScopeMonths && - static_cast<int>(results_.size()) < max_results) { - InitVisitRequest(search_depth_); - } else { - RequestCompleted(); - } -} - -bool HistoryModel::UpdateStarredStateOfURL(const GURL& url, bool is_starred) { - bool changed = false; - - // See if we've got any of the changed URLs in our results. There may be - // more than once instance of the URL, and we have to update them all. - size_t num_matches; - const size_t* match_indices = results_.MatchesForURL(url, &num_matches); - for (size_t i = 0; i < num_matches; i++) { - if (IsStarred(static_cast<int>(match_indices[i])) != is_starred) { - star_state_[match_indices[i]] = is_starred ? STARRED : NOT_STARRED; - changed = true; - } - } - return changed; -} diff --git a/chrome/browser/history_model.h b/chrome/browser/history_model.h deleted file mode 100644 index c9567ab..0000000 --- a/chrome/browser/history_model.h +++ /dev/null @@ -1,91 +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. - -// Describes a class that can represent the information displayed in a history -// view; that is, a list of visited pages. This object knows how to -// talk to the HistoryService to update its state. - -#ifndef CHROME_BROWSER_HISTORY_MODEL_H_ -#define CHROME_BROWSER_HISTORY_MODEL_H_ - -#include "chrome/browser/base_history_model.h" -#include "chrome/common/notification_observer.h" - -typedef BaseHistoryModelObserver HistoryModelObserver; - -class HistoryModel : public BaseHistoryModel, - public NotificationObserver { - public: - HistoryModel(Profile* profile, const std::wstring& search_text); - virtual ~HistoryModel(); - - // BaseHistoryModel methods (see BaseHistoryModel for description). - virtual int GetItemCount(); - virtual base::Time GetVisitTime(int index); - virtual const std::wstring& GetTitle(int index); - virtual const GURL& GetURL(int index); - virtual history::URLID GetURLID(int index); - virtual bool IsStarred(int index); - virtual const Snippet& GetSnippet(int index); - virtual void RemoveFromModel(int start, int length); - - // Sets the new value of the search text, and requeries if the new value - // is different from the previous value. - virtual void SetSearchText(const std::wstring& search_text); - - // Returns the search text. - virtual const std::wstring& GetSearchText() const { return search_text_; } - - // Change the starred state of a given index. - virtual void SetPageStarred(int index, bool state); - - // To be called when the user wants to manually refresh this view. - virtual void Refresh(); - - // NotificationObserver implementation. If the type is NOTIFY_URLS_STARRED, - // the model is updated appropriately. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - private: - // Initiates a request for the current visit list. - void InitVisitRequest(int depth); - - // Callback for visited page requests of the history system. - void VisitedPagesQueryComplete(HistoryService::Handle request_handle, - history::QueryResults* results); - - // Sets the starred state of each instance of the given URL in the result set - // to the given value. Returns true if anything was updated. - bool UpdateStarredStateOfURL(const GURL& url, bool is_starred); - - // The current search string. - std::wstring search_text_; - - // Contents of the current query. - history::QueryResults results_; - - // We lazily ask the BookmarkModel for whether a URL is starred. This enum - // gives the state of a particular entry. - enum StarState { - UNKNOWN = 0, // Indicates we haven't determined the state yet. - STARRED, - NOT_STARRED - }; - - // star_state_ has an entry for each element of results_ indicating whether - // the URL is starred. - scoped_array<StarState> star_state_; - - // How many months back the current query has gone. - int search_depth_; - - // The time that the current query was started. - base::Time search_start_; - - DISALLOW_COPY_AND_ASSIGN(HistoryModel); -}; - -#endif // CHROME_BROWSER_HISTORY_MODEL_H_ diff --git a/chrome/browser/history_tab_ui.cc b/chrome/browser/history_tab_ui.cc deleted file mode 100644 index 40027c6..0000000 --- a/chrome/browser/history_tab_ui.cc +++ /dev/null @@ -1,149 +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/history_tab_ui.h" - -#include "base/string_util.h" -#include "chrome/browser/history_model.h" -#include "chrome/browser/history_view.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/common/l10n_util.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/views/checkbox.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "net/base/escape.h" - -// State key used to identify search text. -static const wchar_t kSearchTextKey[] = L"st"; - -// State key used for whether the search is for starred pages only. -static const wchar_t kStarredOnlyKey[] = L"starred_only"; - -// HistoryTabUIFactory ------------------------------------------------------ - -class HistoryTabUIFactory : public NativeUIFactory { - public: - HistoryTabUIFactory() {} - virtual ~HistoryTabUIFactory() {} - - virtual NativeUI* CreateNativeUIForURL(const GURL& url, - NativeUIContents* contents) { - HistoryTabUI* tab_ui = new HistoryTabUI(contents); - tab_ui->Init(); - return tab_ui; - } - - private: - DISALLOW_EVIL_CONSTRUCTORS(HistoryTabUIFactory); -}; - -// HistoryTabUI ------------------------------------------------------------- - -HistoryTabUI::HistoryTabUI(NativeUIContents* contents) -#pragma warning(suppress: 4355) // Okay to pass "this" here. - : searchable_container_(this), - contents_(contents) { -} - -void HistoryTabUI::Init() { - model_ = CreateModel(); - searchable_container_.SetContents(CreateHistoryView()); -} - -const std::wstring HistoryTabUI::GetTitle() const { - return l10n_util::GetString(IDS_HISTORY_TITLE); -} - -const int HistoryTabUI::GetFavIconID() const { - return IDR_HISTORY_FAVICON; -} - -const int HistoryTabUI::GetSectionIconID() const { - return IDR_HISTORY_SECTION; -} - -const std::wstring HistoryTabUI::GetSearchButtonText() const { - return l10n_util::GetString(IDS_HISTORY_SEARCH_BUTTON); -} - -views::View* HistoryTabUI::GetView() { - return &searchable_container_; -} - -void HistoryTabUI::WillBecomeVisible(NativeUIContents* parent) { - UserMetrics::RecordAction(L"Destination_History", parent->profile()); -} - -void HistoryTabUI::WillBecomeInvisible(NativeUIContents* parent) { -} - -void HistoryTabUI::Navigate(const PageState& state) { - std::wstring search_text; - state.GetProperty(kSearchTextKey, &search_text); - // Make sure a query starts on navigation, that way if history has changed - // since we last issued the query we'll show the right thing. - if (model_->GetSearchText() == search_text) - model_->Refresh(); - else - model_->SetSearchText(search_text); - searchable_container_.GetSearchField()->SetText(search_text); - - ChangedModel(); -} - -bool HistoryTabUI::SetInitialFocus() { - searchable_container_.GetSearchField()->RequestFocus(); - return true; -} - -// static -GURL HistoryTabUI::GetURL() { - std::string spec(NativeUIContents::GetScheme()); - spec.append("://history"); - return GURL(spec); -} - -// static -NativeUIFactory* HistoryTabUI::GetNativeUIFactory() { - return new HistoryTabUIFactory(); -} - -// static -const GURL HistoryTabUI::GetHistoryURLWithSearchText( - const std::wstring& text) { - return GURL(GetURL().spec() + "/params?" + WideToUTF8(kSearchTextKey) + "=" + - EscapeQueryParamValue(WideToUTF8(text))); -} - -BaseHistoryModel* HistoryTabUI::CreateModel() { - return new HistoryModel(contents_->profile(), std::wstring()); -} - -HistoryView* HistoryTabUI::CreateHistoryView() { - return new HistoryView(&searchable_container_, model_, contents_); -} - -void HistoryTabUI::ChangedModel() { - HistoryView* history_view = - static_cast<HistoryView*>(searchable_container_.GetContents()); - history_view->SetShowDeleteControls(model_->GetSearchText().empty()); - if (!model_->GetSearchText().empty()) - UserMetrics::RecordAction(L"History_Search", contents_->profile()); -} - -void HistoryTabUI::DoSearch(const std::wstring& text) { - if (model_->GetSearchText() == text) - return; - - model_->SetSearchText(text); - - // Update the page state. - PageState* page_state = contents_->page_state().Copy(); - page_state->SetProperty(kSearchTextKey, text); - contents_->SetPageState(page_state); - - ChangedModel(); -} - diff --git a/chrome/browser/history_tab_ui.h b/chrome/browser/history_tab_ui.h deleted file mode 100644 index 927ad5b..0000000 --- a/chrome/browser/history_tab_ui.h +++ /dev/null @@ -1,90 +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. - -#ifndef CHROME_BROWSER_HISTORY_TAB_UI_H__ -#define CHROME_BROWSER_HISTORY_TAB_UI_H__ - -#include "chrome/browser/tab_contents/native_ui_contents.h" - -class BaseHistoryModel; -class HistoryView; - -// HistoryTabUI ------------------------------------------------------------- - -// HistoryTabUI provides the glue to make HistoryView available in -// NativeUIContents. - -class HistoryTabUI : public NativeUI, - public SearchableUIContainer::Delegate { - public: - // Creates the HistoryTabUI. You must invoke Init to finish initialization. - HistoryTabUI(NativeUIContents* contents); - virtual ~HistoryTabUI() {} - - // Creates the model and view. - void Init(); - - virtual const std::wstring GetTitle() const; - virtual const int GetFavIconID() const; - virtual const int GetSectionIconID() const; - virtual const std::wstring GetSearchButtonText() const; - virtual views::View* GetView(); - virtual void WillBecomeVisible(NativeUIContents* parent); - virtual void WillBecomeInvisible(NativeUIContents* parent); - virtual void Navigate(const PageState& state); - virtual bool SetInitialFocus(); - - // Return the URL that can be used to show this view in a NativeUIContents. - static GURL GetURL(); - - // Return the NativeUIFactory object for application views. This object is - // owned by the caller. - static NativeUIFactory* GetNativeUIFactory(); - - // Returns a URL that shows history tab ui with the search text set to - // text. - static const GURL GetHistoryURLWithSearchText(const std::wstring& text); - - // Returns the model. - BaseHistoryModel* model() const { return model_; } - - // Returns the NativeUIContents we're contained in. - NativeUIContents* contents() const { return contents_; } - - protected: - // Returns the SearchableUIContainer that contains the HistoryView. - SearchableUIContainer* searchable_container() { - return &searchable_container_; - } - - // Creates the HistoryModel. - virtual BaseHistoryModel* CreateModel(); - - // Creates the HistoryView. - virtual HistoryView* CreateHistoryView(); - - // Invoked after refreshing the model, or resetting the search text. - // This implementation updates whether the delete controls should be shown - // as well as sending UMA metrics. - virtual void ChangedModel(); - - private: - // Updates the query text of the model. - virtual void DoSearch(const std::wstring& text); - - // Our host. - NativeUIContents* contents_; - - // The view we return from GetView. The contents of this is the - // bookmarks_view_ - SearchableUIContainer searchable_container_; - - // The model. This is deleted by the HistoryView we create. - BaseHistoryModel* model_; - - DISALLOW_EVIL_CONSTRUCTORS(HistoryTabUI); -}; - -#endif // CHROME_BROWSER_HISTORY_TAB_UI_H__ - diff --git a/chrome/browser/history_view.cc b/chrome/browser/history_view.cc deleted file mode 100644 index f1902e9..0000000 --- a/chrome/browser/history_view.cc +++ /dev/null @@ -1,1316 +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/history_view.h" - -#include "base/string_util.h" -#include "base/time_format.h" -#include "base/word_iterator.h" -#include "chrome/browser/browsing_data_remover.h" -#include "chrome/browser/drag_utils.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/tab_contents/native_ui_contents.h" -#include "chrome/browser/tab_contents/page_navigator.h" -#include "chrome/browser/views/bookmark_bubble_view.h" -#include "chrome/browser/views/event_utils.h" -#include "chrome/browser/views/star_toggle.h" -#include "chrome/common/drag_drop_types.h" -#include "chrome/common/gfx/chrome_canvas.h" -#include "chrome/common/gfx/favicon_size.h" -#include "chrome/common/l10n_util.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/common/time_format.h" -#include "chrome/common/win_util.h" -#include "chrome/views/link.h" -#include "chrome/views/widget.h" -#include "grit/generated_resources.h" - -using base::Time; -using base::TimeDelta; - -// The extra-wide space between groups of entries for each new day. -static const int kDayHeadingHeight = 50; - -// The space between groups of entries within a day. -static const int kSessionBreakHeight = 24; - -// Amount of time between page-views that triggers a break (in microseconds). -static const int64 kSessionBreakTime = 1800 * 1000000; // 30 minutes - -// Horizontal space between the left edge of the entries and the -// left edge of the view. -static const int kLeftMargin = 38; - -// x-position of the page title (massage this so it visually matches -// kDestinationSearchOffset in native_ui_contents.cc -static const int kPageTitleOffset = 102; - -// x-position of the Time -static const int kTimeOffset = 24; - -// Vertical offset for the delete control (distance from the top of a day -// break segment). -static const int kDeleteControlOffset = 30; - -// x-position of the session gap filler (currently a thin vertical line -// joining the times on either side of a session gap). -static const int kSessionGapOffset = 16; - -// Horizontal space between the right edge of the item -// and the right edge of the view. -static const int kRightMargin = 20; - -// The ideal height of an entry. This may change depending on font line-height. -static const int kSearchResultsHeight = 72; -static const int kBrowseResultsHeight = 24; - -// How much room to leave above the first result. -static const int kResultsMargin = 24; - -// Height of the results text area. -static const int kResultTextHeight = 24; - -// Height of the area when there are no results to display. -static const int kNoResultTextHeight = 48; -static const int kNoResultMinWidth = 512; - -// Extra vertical space between the different lines of text. -// (Note that the height() variables are baseline-to-baseline already.) -static const int kLeading = 2; - -// The amount of space from the edges of an entry to the edges of its contents. -static const int kEntryPadding = 8; - -// Padding between the icons (star, favicon) and other elements. -static const int kIconPadding = 4; - -// SnippetRenderer is a View that can displayed text with bolding and wrapping. -// It's used to display search result snippets. -class SnippetRenderer : public views::View { - public: - SnippetRenderer(); - - // Set the text snippet. - void SetSnippet(const Snippet& snippet); - - int GetLineHeight(); - - virtual void Paint(ChromeCanvas* canvas); - - private: - // The snippet that we're drawing. - Snippet snippet_; - - // Font for plain text. - ChromeFont text_font_; - // Font for match text. (TODO(evanm): use red for Chinese (bug 844518).) - ChromeFont match_font_; - - // Layout/draw a substring of the snippet from [start,end) at (x, y). - // ProcessRun is strictly for text in a single line: it doesn't do any - // word-wrapping, and is used as a helper for laying out multiple lines - // of output in Pain(). - // match_iter is an iterator in match_runs_ that covers a region - // before or at start. - // When canvas is NULL, does no drawing and only computes the size. - // Returns the pixel width of the run. - // TODO(evanm): this could be optimizing by only measuring the text once - // and returning the layout, but it's worth profiling first. - int ProcessRun(ChromeCanvas* canvas, - int x, - int y, - Snippet::MatchPositions::const_iterator match_iter, - size_t start, - size_t end); - - DISALLOW_EVIL_CONSTRUCTORS(SnippetRenderer); -}; - -SnippetRenderer::SnippetRenderer() { - ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); - - text_font_ = resource_bundle.GetFont(ResourceBundle::WebFont); - match_font_ = text_font_.DeriveFont(0, ChromeFont::BOLD); -} - -void SnippetRenderer::SetSnippet(const Snippet& snippet) { - snippet_ = snippet; -} - -int SnippetRenderer::GetLineHeight() { - return std::max(text_font_.height(), match_font_.height()) + kLeading; -} - -void SnippetRenderer::Paint(ChromeCanvas* canvas) { - const int line_height = GetLineHeight(); - - WordIterator iter(snippet_.text(), WordIterator::BREAK_LINE); - if (!iter.Init()) - return; - Snippet::MatchPositions::const_iterator match_iter = - snippet_.matches().begin(); - - int x = 0; - int y = 0; - while (iter.Advance()) { - // Advance match_iter to a run that potentially covers this region. - while (match_iter != snippet_.matches().end() && - match_iter->second <= iter.prev()) { - ++match_iter; - } - - // The region from iter.prev() to iter.pos() should be on one line. - // It can be a mixture of bold and non-bold, so first lay it out to - // compute its width. - const int width = ProcessRun(NULL, 0, 0, - match_iter, iter.prev(), iter.pos()); - // Advance to the next line if necessary. - if (x + width > View::width()) { - x = 0; - y += line_height; - if (y >= height()) - return; // Out of vertical space. - } - ProcessRun(canvas, x, y, match_iter, iter.prev(), iter.pos()); - x += width; - } -} - -int SnippetRenderer::ProcessRun( - ChromeCanvas* canvas, - int x, - int y, - Snippet::MatchPositions::const_iterator match_iter, - size_t start, - size_t end) { - int total_width = 0; - - while (start < end) { - // Advance match_iter to the next match that can cover the current - // position. - while (match_iter != snippet_.matches().end() && - match_iter->second <= start) { - ++match_iter; - } - - // Determine the next substring to process by examining whether - // we're before a match or within a match. - ChromeFont* font = &text_font_; - size_t next = end; - if (match_iter != snippet_.matches().end()) { - if (match_iter->first > start) { - // We're in a plain region. - next = std::min(match_iter->first, end); - } else if (match_iter->first <= start && - match_iter->second > start) { - // We're in a match region. - font = &match_font_; - next = std::min(match_iter->second, end); - } - } - - // Draw/layout the text. - const std::wstring run = snippet_.text().substr(start, next - start); - const int width = font->GetStringWidth(run); - if (canvas) { - canvas->DrawStringInt(run, *font, SkColorSetRGB(0, 0, 0), - x + total_width, y, - width, height(), - ChromeCanvas::TEXT_VALIGN_BOTTOM); - } - - // Advance. - total_width += width; - start = next; - } - - return total_width; -} - -// A View for an individual history result. -class HistoryItemRenderer : public views::View, - public views::LinkController, - public StarToggle::Delegate { - public: - HistoryItemRenderer(HistoryView* parent, bool show_full); - ~HistoryItemRenderer(); - - // Set the BaseHistoryModel that this renderer displays. - // model_index is the index of this entry, and is passed to all of the - // model functions. - void SetModel(BaseHistoryModel* model, int model_index); - - // Set whether we should display full size or partial-sized items. - void SetDisplayStyle(bool show_full); - - // Layout the contents of this view. - void Layout(); - - protected: - // Overridden to do a drag if over the favicon or thumbnail. - virtual int GetDragOperations(int press_x, int press_y); - virtual void WriteDragData(int press_x, int press_y, OSExchangeData* data); - - private: - // Regions drags may originate from. - enum DragRegion { - FAV_ICON, - THUMBNAIL, - NONE - }; - - // The thickness of the border drawn around thumbnails. - static const int kThumbnailBorderWidth = 1; - - // The height of the thumbnail images. - static const int kThumbnailHeight = kSearchResultsHeight - kEntryPadding * 2; - - // The width of the thumbnail images. - static const int kThumbnailWidth = static_cast<int>(1.44 * kThumbnailHeight); - - // The maximum width of a snippet - we want to constrain this to make - // snippets easier to read (like Google search results). - static const int kMaxSnippetWidth = 500; - - // Returns the bounds of the thumbnail. - void GetThumbnailBounds(CRect* rect); - - // Convert a GURL into a displayable string. - std::wstring DisplayURL(const GURL& url); - - virtual void Paint(ChromeCanvas* canvas); - - // Notification that the star was changed. - virtual void StarStateChanged(bool state); - - // Notification that the link was clicked. - virtual void LinkActivated(views::Link* source, int event_flags); - - // Returns the region the mouse is over. - DragRegion GetDragRegion(int x, int y); - - // The HistoryView containing this view. - HistoryView* parent_; - - // Whether we're showing a fullsize item, or a single-line item. - bool show_full_; - - // The model and index of this entry within the model. - BaseHistoryModel* model_; - int model_index_; - - // Widgets. - StarToggle* star_toggle_; - views::Link* title_link_; - views::Label* time_label_; - SnippetRenderer* snippet_label_; - - DISALLOW_EVIL_CONSTRUCTORS(HistoryItemRenderer); -}; - -HistoryItemRenderer::HistoryItemRenderer(HistoryView* parent, - bool show_full) - : parent_(parent), - show_full_(show_full) { - ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); - - ChromeFont text_font(resource_bundle.GetFont(ResourceBundle::WebFont)); - - star_toggle_ = new StarToggle(this); - star_toggle_->set_change_state_immediately(false); - AddChildView(star_toggle_); - - title_link_ = new views::Link(); - title_link_->SetFont(text_font); - title_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - title_link_->SetController(this); - AddChildView(title_link_); - - const SkColor kTimeColor = SkColorSetRGB(136, 136, 136); // Gray. - - time_label_ = new views::Label(); - ChromeFont time_font(text_font); - time_label_->SetFont(time_font); - time_label_->SetColor(kTimeColor); - time_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(time_label_); - - snippet_label_ = new SnippetRenderer(); - AddChildView(snippet_label_); -} - -HistoryItemRenderer::~HistoryItemRenderer() { -} - -void HistoryItemRenderer::GetThumbnailBounds(CRect* rect) { - DCHECK(rect); - rect->right = width() - kEntryPadding; - rect->left = rect->right - kThumbnailWidth; - rect->top = kEntryPadding; - rect->bottom = rect->top + kThumbnailHeight; -} - -std::wstring HistoryItemRenderer::DisplayURL(const GURL& url) { - std::string url_str = url.spec(); - // Hide the "http://" prefix like web search does. - if (url_str.find("http://") == 0) - url_str.erase(0, strlen("http://")); - return UTF8ToWide(url_str); -} - -void HistoryItemRenderer::Paint(ChromeCanvas* canvas) { - views::View::Paint(canvas); - - // Draw thumbnail or placeholder. - if (show_full_) { - SkBitmap* thumbnail = model_->GetThumbnail(model_index_); - CRect thumbnail_rect; - GetThumbnailBounds(&thumbnail_rect); // Includes border - - // If the UI layout is right-to-left, we must mirror the bounds so that we - // render the bitmap in the correct position. - gfx::Rect mirrored_rect(thumbnail_rect); - thumbnail_rect.MoveToX(MirroredLeftPointForRect(mirrored_rect)); - - if (thumbnail) { - // This will create a MipMap for the bitmap if one doesn't exist already - // (it's a NOP if a MipMap already exists). This will give much smoother - // results for the scaled-down thumbnails. - thumbnail->buildMipMap(false); - - canvas->DrawBitmapInt( - *thumbnail, - 0, 0, thumbnail->width(), thumbnail->height(), - thumbnail_rect.left, thumbnail_rect.top, - thumbnail_rect.Width(), thumbnail_rect.Height(), - true); - } else { - canvas->FillRectInt(SK_ColorWHITE, - thumbnail_rect.left, thumbnail_rect.top, - thumbnail_rect.Width(), thumbnail_rect.Height()); - } - canvas->DrawRectInt(SkColorSetRGB(153, 153, 191), - thumbnail_rect.left, thumbnail_rect.top, - thumbnail_rect.Width(), thumbnail_rect.Height()); - } - - // Draw the favicon. - SkBitmap* favicon = model_->GetFavicon(model_index_); - if (favicon) { - // WARNING: if you change these values, update the code that determines - // whether we should allow a drag (GetDragRegion). - - // We need to tweak the favicon position if the UI layout is RTL. - gfx::Rect favicon_bounds; - favicon_bounds.set_x(title_link_->x() - kIconPadding - kFavIconSize); - favicon_bounds.set_y(kEntryPadding); - favicon_bounds.set_width(favicon->width()); - favicon_bounds.set_height(favicon->height()); - favicon_bounds.set_x(MirroredLeftPointForRect(favicon_bounds)); - - // Drawing the bitmap using the possibly adjusted bounds. - canvas->DrawBitmapInt(*favicon, favicon_bounds.x(), favicon_bounds.y()); - } - - // The remainder of painting is handled by drawing our children, which - // is managed by the View class for us. -} - -void HistoryItemRenderer::Layout() { - // Figure out the maximum x-position of any text. - CRect thumbnail_rect; - int max_x; - if (show_full_) { - GetThumbnailBounds(&thumbnail_rect); - max_x = thumbnail_rect.left - kEntryPadding; - } else { - max_x = width() - kEntryPadding; - } - - // Calculate the ideal positions of some items. If possible, we - // want the title to line up with kPageTitleOffset (and we would lay - // out the star and the favicon to the left of that), but in cases - // where font or language choices cause the time label to be - // horizontally large, we need to push everything to the right. - // - // If you fiddle with the calculations below, you may need to adjust - // the favicon painting in Paint() (and in GetDragRegion by extension). - - // First we calculate the ideal position of the title. - int title_x = kPageTitleOffset; - - // We calculate the size of the star. - gfx::Size star_size = star_toggle_->GetPreferredSize(); - - // Measure and lay out the time label, and potentially move - // our title to suit. - Time visit_time = model_->GetVisitTime(model_index_); - int time_x = kTimeOffset; - if (visit_time.is_null()) { - // We will get null times if the page has never been visited, for example, - // bookmarks after you clear history. - time_label_->SetText(std::wstring()); - } else if (show_full_) { - time_x = 0; - time_label_->SetText(base::TimeFormatShortDate(visit_time)); - } else { - time_label_->SetText(base::TimeFormatTimeOfDay(visit_time)); - } - gfx::Size time_size = time_label_->GetPreferredSize(); - - time_label_->SetBounds(time_x, kEntryPadding, - time_size.width(), time_size.height()); - - // Calculate the position of the favicon. - int favicon_x = title_x - kFavIconSize - kIconPadding; - - // Now we look to see if the favicon overlaps the time label, - // and if so, we push the title to the right. If we're not - // showing the time label, then ignore this step. - int overlap = favicon_x - (time_x + time_size.width() + kIconPadding); - if (overlap < 0) { - title_x -= overlap; - } - - // Populate and measure the title label. - const std::wstring& title = model_->GetTitle(model_index_); - if (!title.empty()) - title_link_->SetText(title); - else - title_link_->SetText(l10n_util::GetString(IDS_HISTORY_UNTITLED_TITLE)); - gfx::Size title_size = title_link_->GetPreferredSize(); - - // Lay out the title label. - int max_title_x; - - max_title_x = std::max(0, max_x - title_x); - - if (title_size.width() + kEntryPadding > max_title_x) { - // We need to shrink the title to make everything fit. - title_size.set_width(max_title_x - kEntryPadding); - } - title_link_->SetBounds(title_x, kEntryPadding, - title_size.width(), title_size.height()); - - // Lay out the star. - if (model_->IsStarred(model_index_)) { - star_toggle_->SetBounds(title_x + title_size.width() + kIconPadding, - kEntryPadding, star_size.width(), - star_size.height()); - star_toggle_->SetState(true); - star_toggle_->SetVisible(true); - } else { - star_toggle_->SetVisible(false); - } - - // Lay out the snippet label. - snippet_label_->SetVisible(show_full_); - if (show_full_) { - const Snippet& snippet = model_->GetSnippet(model_index_); - if (snippet.text().empty()) { - snippet_label_->SetSnippet(Snippet()); // Bug 843469 will fix this. - } else { - snippet_label_->SetSnippet(snippet); - } - snippet_label_->SetBounds(title_x, - kEntryPadding + snippet_label_->GetLineHeight(), - std::min( - static_cast<int>(thumbnail_rect.left - - title_x), - kMaxSnippetWidth) - - kEntryPadding * 2, - snippet_label_->GetLineHeight() * 2); - } -} - -int HistoryItemRenderer::GetDragOperations(int x, int y) { - if (GetDragRegion(x, y) != NONE) - return DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK; - return DragDropTypes::DRAG_NONE; -} - -void HistoryItemRenderer::WriteDragData(int press_x, - int press_y, - OSExchangeData* data) { - DCHECK(GetDragOperations(press_x, press_y) != DragDropTypes::DRAG_NONE); - - if (GetDragRegion(press_x, press_y) == FAV_ICON) - UserMetrics::RecordAction(L"History_DragIcon", model_->profile()); - else - UserMetrics::RecordAction(L"History_DragThumbnail", model_->profile()); - - SkBitmap icon; - if (model_->GetFavicon(model_index_)) - icon = *model_->GetFavicon(model_index_); - - drag_utils::SetURLAndDragImage(model_->GetURL(model_index_), - model_->GetTitle(model_index_), - icon, data); -} - -void HistoryItemRenderer::SetModel(BaseHistoryModel* model, int model_index) { - DCHECK(model_index < model->GetItemCount()); - model_ = model; - model_index_ = model_index; -} - -void HistoryItemRenderer::SetDisplayStyle(bool show_full) { - show_full_ = show_full; -} - -void HistoryItemRenderer::StarStateChanged(bool state) { - // Show the user a tip that can be used to edit the bookmark/star. - gfx::Point star_location; - views::View::ConvertPointToScreen(star_toggle_, &star_location); - // Shift the location to make the bubble appear at a visually pleasing - // location. - gfx::Rect star_bounds(star_location.x(), star_location.y() + 4, - star_toggle_->width(), - star_toggle_->height()); - HWND parent = GetWidget()->GetHWND(); - Profile* profile = model_->profile(); - GURL url = model_->GetURL(model_index_); - - if (state) { - // Only change the star state if the page is not starred. The user can - // unstar by way of the bubble. - star_toggle_->SetState(true); - model_->SetPageStarred(model_index_, true); - } - // WARNING: if state is true, we've been deleted. - BookmarkBubbleView::Show(parent, star_bounds, NULL, profile, url, state); -} - -void HistoryItemRenderer::LinkActivated(views::Link* link, - int event_flags) { - if (link == title_link_) { - const GURL& url = model_->GetURL(model_index_); - PageNavigator* navigator = parent_->navigator(); - if (navigator && !url.is_empty()) { - UserMetrics::RecordAction(L"Destination_History_OpenURL", - model_->profile()); - navigator->OpenURL(url, GURL(), - event_utils::DispositionFromEventFlags(event_flags), - PageTransition::AUTO_BOOKMARK); - // WARNING: call to OpenURL likely deleted us. - return; - } - } -} - -HistoryItemRenderer::DragRegion HistoryItemRenderer::GetDragRegion(int x, - int y) { - // Is the location over the favicon? - SkBitmap* favicon = model_->GetFavicon(model_index_); - if (favicon) { - // If the UI layout is right-to-left, we must make sure we mirror the - // favicon position before doing any hit testing. - gfx::Rect favicon_bounds; - favicon_bounds.set_x(title_link_->x() - kIconPadding - kFavIconSize); - favicon_bounds.set_y(kEntryPadding); - favicon_bounds.set_width(favicon->width()); - favicon_bounds.set_height(favicon->height()); - favicon_bounds.set_x(MirroredLeftPointForRect(favicon_bounds)); - if (favicon_bounds.Contains(x, y)) { - return FAV_ICON; - } - } - - // Is it over the thumbnail? - if (show_full_ && model_->GetThumbnail(model_index_)) { - CRect thumbnail_loc; - GetThumbnailBounds(&thumbnail_loc); - - // If the UI layout is right-to-left, we mirror the thumbnail bounds before - // we check whether or not it contains the point in question. - gfx::Rect mirrored_loc(thumbnail_loc); - thumbnail_loc.MoveToX(MirroredLeftPointForRect(mirrored_loc)); - if (gfx::Rect(thumbnail_loc).Contains(x, y)) - return THUMBNAIL; - } - - return NONE; -} - -HistoryView::HistoryView(SearchableUIContainer* container, - BaseHistoryModel* model, - PageNavigator* navigator) - : container_(container), - renderer_(NULL), - model_(model), - navigator_(navigator), - scroll_helper_(this), - line_height_(-1), - show_results_(false), - show_delete_controls_(false), - delete_control_width_(0), - loading_(true) { - DCHECK(model_.get()); - DCHECK(navigator_); - model_->SetObserver(this); - - ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); - day_break_font_ = resource_bundle.GetFont(ResourceBundle::WebFont); - - // Ensure break_offsets_ is never empty. - BreakValue s = {0, 0}; - break_offsets_.insert(std::make_pair(0, s)); -} - -HistoryView::~HistoryView() { - if (renderer_) - delete renderer_; -} - -void HistoryView::EnsureRenderer() { - if (!renderer_) - renderer_ = new HistoryItemRenderer(this, show_results_); - if (show_delete_controls_ && !delete_renderer_.get()) { - delete_renderer_.reset( - new views::Link( - l10n_util::GetString(IDS_HISTORY_DELETE_PRIOR_VISITS_LINK))); - delete_renderer_->SetFont(day_break_font_); - } -} - -int HistoryView::GetLastEntryMaxY() { - if (break_offsets_.empty()) - return 0; - BreakOffsets::iterator last_entry_i = break_offsets_.end(); - last_entry_i--; - return last_entry_i->first; -} - -int HistoryView::GetEntryHeight() { - if (line_height_ == -1) { - ChromeFont font = ResourceBundle::GetSharedInstance() - .GetFont(ResourceBundle::WebFont); - line_height_ = font.height() + font.height() - font.baseline(); - } - if (show_results_) { - return std::max(line_height_ * 3 + kEntryPadding, kSearchResultsHeight); - } else { - return std::max(line_height_ + kEntryPadding, kBrowseResultsHeight); - } -} - -void HistoryView::ModelChanged(bool result_set_changed) { - DetachAllFloatingViews(); - - if (!result_set_changed) { - // Only item metadata changed. We don't need to do a full re-layout, - // but we may need to redraw the affected items. - SchedulePaint(); - return; - } - - // TODO(evanm): this could be optimized by computing break_offsets_ lazily. - // It'd be especially nice because of our incremental search; right now - // we recompute the entire layout with each key you press. - break_offsets_.clear(); - - const int count = model_->GetItemCount(); - - // If we're not viewing bookmarks and we are looking at search results, then - // show the items in a results (larger) style. - show_results_ = model_->IsSearchResults(); - if (renderer_) - renderer_->SetDisplayStyle(show_results_); - - // If we're viewing bookmarks or we're viewing the larger results, we don't - // need to insert break offsets between items. - if (show_results_) { - BreakValue s = {0, true}; - break_offsets_.insert(std::make_pair(kResultsMargin, s)); - if (count > 0) { - BreakValue s = {count, true}; - break_offsets_.insert( - std::make_pair(GetEntryHeight() * count + kResultsMargin, s)); - } - } else { - int y = 0; - Time last_time; - Time last_day; - - // Loop through our list of items and find places to insert breaks. - for (int i = 0; i < count; ++i) { - // NOTE: if you change how we calculate breaks you'll need to update - // the deletion code as well (DeleteDayAtModelIndex). - Time time = model_->GetVisitTime(i); - Time day = time.LocalMidnight(); - if (i == 0 || - (last_time - time).ToInternalValue() > kSessionBreakTime || - day != last_day) { - // We've detected something that needs a break. - - bool day_separation = true; - - // If it's not the first item, figure out if it's a day - // break or session break. - if (i != 0) - day_separation = (day != last_day); - - BreakValue s = {i, day_separation}; - - break_offsets_.insert(std::make_pair(y, s)); - y += GetBreakOffsetHeight(s); - } - last_time = time; - last_day = day; - y += GetEntryHeight(); - } - - // Insert ending day. - BreakValue s = {count, true}; - break_offsets_.insert(std::make_pair(y, s)); - } - - // Find our ScrollView and layout. - if (GetParent() && GetParent()->GetParent()) - GetParent()->GetParent()->Layout(); -} - -void HistoryView::ModelBeginWork() { - loading_ = true; - if (container_) - container_->StartThrobber(); -} - -void HistoryView::ModelEndWork() { - loading_ = false; - if (container_) - container_->StopThrobber(); - if (model_->GetItemCount() == 0) - SchedulePaint(); -} - -void HistoryView::SetShowDeleteControls(bool show_delete_controls) { - if (show_delete_controls == show_delete_controls_) - return; - - show_delete_controls_ = show_delete_controls; - - delete_renderer_.reset(NULL); - - // Be sure and rebuild the display, otherwise the floating view indices are - // off. - ModelChanged(true); -} - -int HistoryView::GetPageScrollIncrement( - views::ScrollView* scroll_view, bool is_horizontal, - bool is_positive) { - return scroll_helper_.GetPageScrollIncrement(scroll_view, is_horizontal, - is_positive); -} - -int HistoryView::GetLineScrollIncrement( - views::ScrollView* scroll_view, bool is_horizontal, - bool is_positive) { - return scroll_helper_.GetLineScrollIncrement(scroll_view, is_horizontal, - is_positive); -} - -views::VariableRowHeightScrollHelper::RowInfo - HistoryView::GetRowInfo(int y) { - // Get the time separator header for a given Y click. - BreakOffsets::iterator i = GetBreakOffsetIteratorForY(y); - int index = i->second.index; - int current_y = i->first; - - // Check if the click is on the separator header. - if (y < current_y + GetBreakOffsetHeight(i->second)) { - return views::VariableRowHeightScrollHelper::RowInfo( - current_y, GetBreakOffsetHeight(i->second)); - } - - // Otherwise increment current_y by the item height until it goes past y. - current_y += GetBreakOffsetHeight(i->second); - - while (index < model_->GetItemCount()) { - int next_y = current_y + GetEntryHeight(); - if (y < next_y) - break; - current_y = next_y; - } - - // Find the item that corresponds to this new current_y value. - return views::VariableRowHeightScrollHelper::RowInfo( - current_y, GetEntryHeight()); -} - -bool HistoryView::IsVisible() { - views::Widget* widget = GetWidget(); - return widget && widget->IsVisible(); -} - -void HistoryView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - SchedulePaint(); -} - -void HistoryView::Layout() { - DetachAllFloatingViews(); - - View* parent = GetParent(); - if (!parent) - return; - - gfx::Rect bounds = parent->GetLocalBounds(true); - - // If not visible, have zero size so we don't compute anything. - int width = 0; - int height = 0; - if (IsVisible()) { - width = bounds.width(); - height = std::max(GetLastEntryMaxY(), - kEntryPadding + kNoResultTextHeight); - } - - SetBounds(x(), y(), width, height); -} - -HistoryView::BreakOffsets::iterator HistoryView::GetBreakOffsetIteratorForY( - int y) { - BreakOffsets::iterator iter = break_offsets_.upper_bound(y); - DCHECK(iter != break_offsets_.end()); - // Move to the first offset smaller than y. - if (iter != break_offsets_.begin()) - --iter; - return iter; -} - -int HistoryView::GetBreakOffsetHeight(HistoryView::BreakValue value) { - if (show_results_) - return 0; - - if (value.day) { - return kDayHeadingHeight; - } else { - return kSessionBreakHeight; - } -} - -void HistoryView::Paint(ChromeCanvas* canvas) { - views::View::Paint(canvas); - - EnsureRenderer(); - - SkRect clip; - if (!canvas->getClipBounds(&clip)) - return; - - const int content_width = width() - kLeftMargin - kRightMargin; - - const int x1 = kLeftMargin; - int clip_y = SkScalarRound(clip.fTop); - int clip_max_y = SkScalarRound(clip.fBottom); - - if (model_->GetItemCount() == 0) { - // Display text indicating that no results were found. - int result_id; - - if (loading_) - result_id = IDS_HISTORY_LOADING; - else if (show_results_) - result_id = IDS_HISTORY_NO_RESULTS; - else - result_id = IDS_HISTORY_NO_ITEMS; - - canvas->DrawStringInt(l10n_util::GetString(result_id), - day_break_font_, - SkColorSetRGB(0, 0, 0), - x1, kEntryPadding, - std::max(content_width, kNoResultMinWidth), - kNoResultTextHeight, - ChromeCanvas::MULTI_LINE); - } - - if (clip_y >= GetLastEntryMaxY()) - return; - - BreakOffsets::iterator break_offsets_iter = - GetBreakOffsetIteratorForY(clip_y); - int item_index = break_offsets_iter->second.index; - int y = break_offsets_iter->first; - - // Display the "Search results for 'xxxx'" text. - if (show_results_ && model_->GetItemCount() > 0) { - canvas->DrawStringInt(l10n_util::GetStringF(IDS_HISTORY_SEARCH_STRING, - model_->GetSearchText()), - day_break_font_, - SkColorSetRGB(0, 0, 0), - x1, kEntryPadding, - content_width, kResultTextHeight, - ChromeCanvas::TEXT_VALIGN_BOTTOM); - } - - Time midnight_today = Time::Now().LocalMidnight(); - while (y < clip_max_y && item_index < model_->GetItemCount()) { - if (!show_results_ && y == break_offsets_iter->first) { - if (y + kDayHeadingHeight > clip_y) { - if (break_offsets_iter->second.day) { - // We're at a day break, draw the day break appropriately. - Time visit_time = model_->GetVisitTime(item_index); - DCHECK(visit_time.ToInternalValue() > 0); - - // If it's the first day, then it has a special presentation. - std::wstring date_str = TimeFormat::RelativeDate(visit_time, - &midnight_today); - if (date_str.empty()) { - date_str = base::TimeFormatFriendlyDate(visit_time); - } else { - date_str = l10n_util::GetStringF( - IDS_HISTORY_DATE_WITH_RELATIVE_TIME, - date_str, base::TimeFormatFriendlyDate(visit_time)); - } - - // Draw date - canvas->DrawStringInt(date_str, - day_break_font_, - SkColorSetRGB(0, 0, 0), - x1, y + kDayHeadingHeight - - kBrowseResultsHeight + kEntryPadding, - content_width, kBrowseResultsHeight, - ChromeCanvas::TEXT_VALIGN_BOTTOM); - - // Draw delete controls. - if (show_delete_controls_) { - gfx::Rect delete_bounds = CalculateDeleteControlBounds(y); - if (!HasFloatingViewForPoint(delete_bounds.x(), - delete_bounds.y())) { - PaintFloatingView(canvas, delete_renderer_.get(), - delete_bounds.x(), delete_bounds.y(), - delete_bounds.width(), delete_bounds.height()); - } - } - } else { - // Draw session separator. Note that we must mirror the position of - // the separator if we run in an RTL locale because we draw the - // separator directly on the canvas. - gfx::Rect separator_bounds(x1 + kSessionGapOffset + kTimeOffset, - y, - 1, - kBrowseResultsHeight); - separator_bounds.set_x(MirroredLeftPointForRect(separator_bounds)); - canvas->FillRectInt(SkColorSetRGB(178, 178, 178), - separator_bounds.x(), separator_bounds.y(), - separator_bounds.width(), - separator_bounds.height()); - } - } - - y += GetBreakOffsetHeight(break_offsets_iter->second); - } - - if (y + GetEntryHeight() > clip_y && !HasFloatingViewForPoint(x1, y)) { - renderer_->SetModel(model_.get(), item_index); - PaintFloatingView(canvas, renderer_, x1, y, content_width, - GetEntryHeight()); - } - - y += GetEntryHeight(); - - BreakOffsets::iterator next_break_offsets = break_offsets_iter; - ++next_break_offsets; - if (next_break_offsets != break_offsets_.end() && - y >= next_break_offsets->first) { - break_offsets_iter = next_break_offsets; - } - - ++item_index; - } -} - -int HistoryView::GetYCoordinateForViewID(int id, - int* model_index, - bool* is_delete_control) { - DCHECK(id < GetMaxViewID()); - - // Loop through our views and figure out model ids and y coordinates - // of the various items as we go until we find the item that matches. - // the supplied id. This should closely match the code in Paint(). - // - // Watch out, this will be is_null when there is no visit. - Time last_time = model_->GetVisitTime(0); - - int current_model_index = 0; - int y = show_results_ ? kResultsMargin : 0; - - bool show_breaks = !show_results_; - - for (int i = 0; i <= id; i++) { - // Consider day and session breaks also between when moving between groups - // of unvisited (visit_time().is_null()) and visited URLs. - Time time = model_->GetVisitTime(current_model_index); - bool at_day_break = last_time.is_null() != time.is_null() || - (i == 0 || last_time.LocalMidnight() != time.LocalMidnight()); - bool at_session_break = last_time.is_null() != time.is_null() || - (!at_day_break && - (last_time - time).ToInternalValue() > kSessionBreakTime); - bool at_result = (i == id); - - // If we're showing breaks, are a day break and are showing delete - // controls, this view id must be a delete control. - if (show_breaks && at_day_break && show_delete_controls_) { - if (at_result) { - // We've found what we're looking for. - *is_delete_control = true; - *model_index = current_model_index; - return y; - } else { - // This isn't what we're looking for, but it is a valid view, so carry - // on through the loop, but don't increment our current_model_index, - // as the next view will have the same model index. - y += kDayHeadingHeight; - last_time = time; - } - } else { - if (show_breaks) { - if (at_day_break) { - y += kDayHeadingHeight; - } else if (at_session_break) { - y += kSessionBreakHeight; - } - } - - // We're on a result item. - if (at_result) { - *is_delete_control = false; - *model_index = current_model_index; - return y; - } - - // It wasn't the one we're looking for, so increment our y coordinate and - // model index and move on to the next view. - current_model_index++; - last_time = time; - y += GetEntryHeight(); - } - } - - return y; -} - -bool HistoryView::GetFloatingViewIDForPoint(int x, int y, int* id) { - // Here's a picture of the various offsets used here. - // Let the (*) on entry #5 below represent the mouse position. - // +-------------- - // | entry #2 - // +-------------- - // <- base_y is the y coordinate of the break. - // +-------------- <- break_offsets->second.index points at this entry - // | entry #3 base_index is this entry index (3). - // +-------------- - // +-------------- - // | entry #4 - // +-------------- - // +-------------- - // | entry #5 (*) <- y is this y coordinate - // +-------------- - - // First, verify the x coordinate is within the correct region. - if (x < kLeftMargin || x > width() - kRightMargin || - y >= GetLastEntryMaxY()) { - return false; - } - - // Find the closest break to this y-coordinate. - BreakOffsets::const_iterator break_offsets_iter = - GetBreakOffsetIteratorForY(y); - - // Get the model index of the first item after that break. - int base_index = break_offsets_iter->second.index; - - // Get the view id of that item by adding the number of deletes prior to - // this item. (See comments for break_offsets_); - if (show_delete_controls_) { - base_index += CalculateDeleteOffset(break_offsets_iter); - - // The current break contains a delete, we need to account for that. - if (break_offsets_iter->second.day) - base_index++; - } - - // base_y is the top of the break block. - int base_y = break_offsets_iter->first; - - // Add the height of the break. - if (!show_results_) - base_y += GetBreakOffsetHeight(break_offsets_iter->second); - - // If y is less than base_y, then it must be over the break and so the - // only view the mouse could be over would be the delete link. - if (y < base_y) { - if (show_delete_controls_ && - break_offsets_iter->second.day) { - gfx::Rect delete_bounds = - CalculateDeleteControlBounds(base_y - kDayHeadingHeight); - - // The delete link bounds must be mirrored if the locale is RTL since the - // point we check against is in LTR coordinates. - delete_bounds.set_x(MirroredLeftPointForRect(delete_bounds)); - if (x >= delete_bounds.x() && x < delete_bounds.right()) { - *id = base_index - 1; - return true; - } - } - return false; // Point is over the day heading. - } - - // y_delta is the distance from the top of the first item in - // this block to the target y point. - const int y_delta = y - base_y; - - int view_id = base_index + (y_delta / GetEntryHeight()); - *id = view_id; - return true; -} - -bool HistoryView::EnumerateFloatingViews( - views::View::FloatingViewPosition position, - int starting_id, - int* id) { - DCHECK(id); - return View::EnumerateFloatingViewsForInterval(0, GetMaxViewID(), - true, - position, starting_id, id); -} - -views::View* HistoryView::ValidateFloatingViewForID(int id) { - if (id >= GetMaxViewID()) - return NULL; - - bool is_delete_control; - int model_index; - View* floating_view; - - int y = GetYCoordinateForViewID(id, &model_index, &is_delete_control); - if (is_delete_control) { - views::Link* delete_link = new views::Link( - l10n_util::GetString(IDS_HISTORY_DELETE_PRIOR_VISITS_LINK)); - delete_link->SetID(model_index); - delete_link->SetFont(day_break_font_); - delete_link->SetController(this); - - gfx::Rect delete_bounds = CalculateDeleteControlBounds(y); - delete_link->SetBounds(delete_bounds.x(), delete_bounds.y(), - delete_bounds.width(), delete_bounds.height()); - floating_view = delete_link; - } else { - HistoryItemRenderer* renderer = - new HistoryItemRenderer(this, - show_results_); - renderer->SetModel(model_.get(), model_index); - renderer->SetBounds(kLeftMargin, y, - width() - kLeftMargin - kRightMargin, - GetEntryHeight()); - floating_view = renderer; - } - floating_view->Layout(); - AttachFloatingView(floating_view, id); - -#ifdef DEBUG_FLOATING_VIEWS - floating_view->SetBackground(views::Background::CreateSolidBackground( - SkColorSetRGB(255, 0, 0))); - floating_view->SchedulePaint(); -#endif - return floating_view; -} - -int HistoryView::GetMaxViewID() { - if (!show_delete_controls_) - return model_->GetItemCount(); - - // Figure out how many delete controls we are displaying. - int deletes = 0; - for (BreakOffsets::iterator i = break_offsets_.begin(); - i != break_offsets_.end(); ++i) { - if (i->second.day) - deletes++; - } - - // Subtract one because we don't display a delete control at the end. - deletes--; - - return std::max(0, deletes + model_->GetItemCount()); -} - -void HistoryView::LinkActivated(views::Link* source, int event_flags) { - DeleteDayAtModelIndex(source->GetID()); -} - -void HistoryView::DeleteDayAtModelIndex(int index) { - std::wstring text = l10n_util::GetString( - IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING); - std::wstring caption = l10n_util::GetString( - IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING_TITLE); - UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST | MB_SETFOREGROUND; - - if (win_util::MessageBox(GetWidget()->GetHWND(), - text, caption, flags) != IDOK) { - return; - } - - if (index < 0 || index >= model_->GetItemCount()) { - // Bogus index. - NOTREACHED(); - return; - } - - UserMetrics::RecordAction(L"History_DeleteHistory", model_->profile()); - - // BrowsingDataRemover deletes itself when done. - // index refers to the last page at the very end of the day, so we delete - // everything after the start of the day and before the end of the day. - Time delete_begin = model_->GetVisitTime(index).LocalMidnight(); - Time delete_end = - (model_->GetVisitTime(index) + TimeDelta::FromDays(1)).LocalMidnight(); - - BrowsingDataRemover* remover = - new BrowsingDataRemover(model_->profile(), - delete_begin, - delete_end); - remover->Remove(BrowsingDataRemover::REMOVE_HISTORY | - BrowsingDataRemover::REMOVE_COOKIES | - BrowsingDataRemover::REMOVE_CACHE); - - model_->Refresh(); - - // Scroll to the origin, otherwise the scroll position isn't changed and the - // user is left looking at a region they originally weren't viewing. - ScrollRectToVisible(0, 0, 0, 0); -} - -int HistoryView::CalculateDeleteOffset( - const BreakOffsets::const_iterator& it) { - DCHECK(show_delete_controls_); - int offset = 0; - for (BreakOffsets::iterator i = break_offsets_.begin(); i != it; ++i) { - if (i->second.day) - offset++; - } - return offset; -} - -int HistoryView::GetDeleteControlWidth() { - if (delete_control_width_) - return delete_control_width_; - EnsureRenderer(); - gfx::Size pref = delete_renderer_->GetPreferredSize(); - delete_control_width_ = pref.width(); - return delete_control_width_; -} - -gfx::Rect HistoryView::CalculateDeleteControlBounds(int base_y) { - // NOTE: the height here is too big, it should be just big enough to show - // the link. Additionally this should be baseline aligned with the date. I'm - // not doing that now as a redesign of HistoryView is in the works. - const int delete_width = GetDeleteControlWidth(); - const int delete_x = width() - kRightMargin - delete_width; - return gfx::Rect(delete_x, - base_y + kDeleteControlOffset, - delete_width, - kBrowseResultsHeight); -} diff --git a/chrome/browser/history_view.h b/chrome/browser/history_view.h deleted file mode 100644 index 35c9db3..0000000 --- a/chrome/browser/history_view.h +++ /dev/null @@ -1,217 +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. - -// This view displays a list of historical page visits. It requires a -// BaseHistoryModel to provide the information that will be shown. - -#ifndef CHROME_BROWSER_HISTORY_VIEW_H_ -#define CHROME_BROWSER_HISTORY_VIEW_H_ - -#include <vector> - -#include "chrome/browser/history_model.h" -#include "chrome/views/link.h" -#include "chrome/views/scroll_view.h" - -class PageNavigator; -class HistoryItemRenderer; -class BaseHistoryModel; -class SearchableUIContainer; - -class HistoryView : public views::View, - public BaseHistoryModelObserver, - public views::LinkController, - views::VariableRowHeightScrollHelper::Controller { - public: - HistoryView(SearchableUIContainer* container, - BaseHistoryModel* model, - PageNavigator* navigator); - virtual ~HistoryView(); - - // Returns true if this view is currently visible to the user. - bool IsVisible(); - - // Overridden for layout purposes. - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); - virtual void Layout(); - - virtual bool GetFloatingViewIDForPoint(int x, int y, int* id); - - // Overriden for focus traversal. - virtual bool EnumerateFloatingViews( - views::View::FloatingViewPosition position, - int starting_id, int* id); - virtual views::View* ValidateFloatingViewForID(int id); - - // Render the visible area. - virtual void Paint(ChromeCanvas* canvas); - - // BaseHistoryModelObserver implementation. - void ModelChanged(bool result_set_changed); - void ModelBeginWork(); - void ModelEndWork(); - - // Returns the entry height, varies with font-height to prevent clipping. - int GetEntryHeight(); - - // Sets whether the delete controls are visible. - void SetShowDeleteControls(bool show_delete_controls); - - // We expose the PageNavigator so history entries can cause navigations - // directly. - PageNavigator* navigator() const { return navigator_; } - - // Scrolling. - virtual int GetPageScrollIncrement(views::ScrollView* scroll_view, - bool is_horizontal, bool is_positive); - virtual int GetLineScrollIncrement(views::ScrollView* scroll_view, - bool is_horizontal, bool is_positive); - virtual views::VariableRowHeightScrollHelper::RowInfo GetRowInfo(int y); - - private: - // For any given break (see comments for BreakOffsets, below), we store the - // index of the item following the break, and whether or not the break - // corresponds to a day break or session break. - struct BreakValue { - int index; - bool day; - }; - - // The map of our breaks (see comments for BreakOffsets, below). - typedef std::map<int, BreakValue> BreakOffsets; - - // Ensures the renderers are valid. - void EnsureRenderer(); - - // Returns the bottom of the last entry. - int GetLastEntryMaxY(); - - // Returns the max view id. - int GetMaxViewID(); - - // Returns the y coordinate for the view with the specified floating view id, - // the index into the model of the specified view and whether the view is - // a delete control. - int GetYCoordinateForViewID(int view_id, - int* model_index, - bool* is_delete_control); - - // Invoked when the user clicks the delete previous visits link. - virtual void LinkActivated(views::Link* source, int event_flags); - - // Prompts the user to make sure they really want to delete, and if so - // deletes the day at the specified model index. - void DeleteDayAtModelIndex(int index); - - // Returns the number of delete controls shown before the specified iterator. - int CalculateDeleteOffset(const BreakOffsets::const_iterator& it); - - // Returns the width of the delete control, calculating if necessary. - int GetDeleteControlWidth(); - - // Calculates the bounds for the delete control given the specified y - // location. - gfx::Rect CalculateDeleteControlBounds(int base_y); - - // The "searchable view" container for this view. - SearchableUIContainer* container_; - - // The font used for the "n days" ago heading. - ChromeFont day_break_font_; - - // A "stamper"-style renderer for only painting the things that are - // in the current view. - HistoryItemRenderer* renderer_; - - // Used to render 'delete' controls. - scoped_ptr<views::Link> delete_renderer_; - - // Class that performs the navigation when the user clicks on a page. - PageNavigator* navigator_; - - // Pointer to the model that provides the contents of this view. - scoped_ptr<BaseHistoryModel> model_; - - // For laying out the potentially huge list of history entries, we - // cache the offsets of session and day breaks. - // - // Each entry in BreakOffsets is a pair, where the key is the y - // coordinate of a day heading and the value is a struct containing - // both the index of the first history entry after that day - // heading and a boolean value indicating whether the offset - // represents a day or session break (these display differently). - // - // This lets us quickly compute, for a given y value, how to lay out - // entries in the vicinity of that y value. - // - // Here's an example: - // 4 days ago <- key: the y coordinate of the top of this block - // +---------------- - // | history item #7 <- index: 7, the index of this history item - // +---------------- - // +---------------- - // | history item #8 - // +---------------- - // <- key: the y coordinate of this separator - // +---------------- - // | history item #9 <- index: 9, the index of this history item - // +---------------- - // +---------------- - // | history item #10 - // +---------------- - // 5 days ago <- key: the y coordinate of this block - // +---------------- - // | history item #11 <- index: 11 - // +---------------- - - // Each history item is represented as a floating view. In addition the - // the delete controls are represented as floating views. A ramification - // of this is that when the delete controls are displayed the view ids do - // not necessarily directly correspond to a model index. The following - // example shows the view ids and corresponding model index. - // - // delete <- view_id=10 - // +---------------- - // | history item #7 <- view_id=11, model_index=10 - // +---------------- - // +---------------- - // | history item #8 <- view_id=12, model_index=11 - // +---------------- - // delete <- view_id=13 - // +---------------- - // | history item #9 <- view_id=14, model_index=12 - // +---------------- - // - BreakOffsets break_offsets_; - - // Retrieve the nearest BreakOffsets less than or equal to the given y. - // Another way of looking at this is that it fetches the BreakOffsets - // entry that heads the section containing y. - BreakOffsets::iterator GetBreakOffsetIteratorForY(int y); - - int GetBreakOffsetHeight(BreakValue value); - - views::VariableRowHeightScrollHelper scroll_helper_; - - // Whether we are showing search results. - bool show_results_; - - // The loading state of the model. - bool loading_; - - // Whether we're showing delete controls. - bool show_delete_controls_; - - // How tall a single line of text is. - int line_height_; - - // Width needed for the delete control. Calculated in GetDeleteControlWidth. - int delete_control_width_; - - DISALLOW_EVIL_CONSTRUCTORS(HistoryView); -}; - -#endif // CHROME_BROWSER_HISTORY_VIEW_H_ - diff --git a/chrome/browser/tab_contents/native_ui_contents.cc b/chrome/browser/tab_contents/native_ui_contents.cc deleted file mode 100644 index 11b7ba5..0000000 --- a/chrome/browser/tab_contents/native_ui_contents.cc +++ /dev/null @@ -1,670 +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/tab_contents/native_ui_contents.h" - -#include "chrome/browser/browser.h" -#include "chrome/browser/history_tab_ui.h" -#include "chrome/browser/tab_contents/navigation_entry.h" -#include "chrome/browser/views/download_tab_view.h" -#include "chrome/common/drag_drop_types.h" -#include "chrome/common/gfx/chrome_canvas.h" -#include "chrome/common/gfx/chrome_font.h" -#include "chrome/common/l10n_util.h" -#include "chrome/common/os_exchange_data.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/views/background.h" -#include "chrome/views/checkbox.h" -#include "chrome/views/grid_layout.h" -#include "chrome/views/image_view.h" -#include "chrome/views/root_view.h" -#include "chrome/views/scroll_view.h" -#include "chrome/views/throbber.h" -#include "chrome/views/widget_win.h" -#include "grit/generated_resources.h" - -using views::ColumnSet; -using views::GridLayout; - -//static -bool NativeUIContents::g_ui_factories_initialized = false; - -// The URL scheme currently used. -static const char kNativeUIContentsScheme[] = "chrome-nativeui"; - -// Unique page id generator. -static int g_next_page_id = 0; - -// The x-position of the title. -static const int kDestinationTitleOffset = 38; - -// The x-position of the search field. -static const int kDestinationSearchOffset = 128; - -// The width of the search field. -static const int kDestinationSearchWidth = 360; - -// Padding between columns -static const int kDestinationSmallerMargin = 8; - -// The background color. -static const SkColor kBackground = SkColorSetRGB(255, 255, 255); - -// The color of the bottom margin. -static const SkColor kBottomMarginColor = SkColorSetRGB(246, 249, 255); - -// The height of the bottom margin. -static const int kBottomMargin = 5; - -// The Chrome product logo. -static const SkBitmap* kProductLogo = NULL; - -// Padding around the product logo. -static const int kProductLogoPadding = 8; - -namespace { - -// NativeRootView -------------------------------------------------------------- - -// NativeRootView is a trivial RootView subclass that allows URL drops and -// forwards them to the NavigationController to open. - -class NativeRootView : public views::RootView { - public: - explicit NativeRootView(NativeUIContents* host) - : RootView(host), - host_(host) { } - - virtual ~NativeRootView() { } - - virtual bool CanDrop(const OSExchangeData& data) { - return data.HasURL(); - } - - virtual int OnDragUpdated(const views::DropTargetEvent& event) { - if (event.GetSourceOperations() & DragDropTypes::DRAG_COPY) - return DragDropTypes::DRAG_COPY; - if (event.GetSourceOperations() & DragDropTypes::DRAG_LINK) - return DragDropTypes::DRAG_LINK; - return DragDropTypes::DRAG_NONE; - } - - virtual int OnPerformDrop(const views::DropTargetEvent& event) { - GURL url; - std::wstring title; - if (!event.GetData().GetURLAndTitle(&url, &title) || !url.is_valid()) - return DragDropTypes::DRAG_NONE; - host_->controller()->LoadURL(url, GURL(), PageTransition::GENERATED); - return OnDragUpdated(event); - } - - private: - NativeUIContents* host_; - - DISALLOW_EVIL_CONSTRUCTORS(NativeRootView); -}; - -} // namespace - - -// Returns the end of the scheme and end of the host. This is temporary until -// bug 772411 is fixed. -static void GetSchemeAndHostEnd(const GURL& url, - size_t* scheme_end, - size_t* host_end) { - const std::string spec = url.spec(); - *scheme_end = spec.find("//"); - DCHECK(*scheme_end != std::string::npos); - - *host_end = spec.find('/', *scheme_end + 2); - if (*host_end == std::string::npos) - *host_end = spec.size(); -} - -NativeUIContents::NativeUIContents(Profile* profile) - : TabContents(TAB_CONTENTS_NATIVE_UI), - is_visible_(false), - current_ui_(NULL), - current_view_(NULL), - state_(new PageState()) { - if (!g_ui_factories_initialized) { - InitializeNativeUIFactories(); - g_ui_factories_initialized = true; - } -} - -NativeUIContents::~NativeUIContents() { - if (current_ui_) { - views::RootView* root_view = GetRootView(); - current_ui_->WillBecomeInvisible(this); - root_view->RemoveChildView(current_view_); - current_ui_ = NULL; - current_view_ = NULL; - } - - STLDeleteContainerPairSecondPointers(path_to_native_uis_.begin(), - path_to_native_uis_.end()); -} - -void NativeUIContents::CreateView() { - set_delete_on_destroy(false); - WidgetWin::Init(GetDesktopWindow(), gfx::Rect(), false); -} - -LRESULT NativeUIContents::OnCreate(LPCREATESTRUCT create_struct) { - // Set the view container initial size. - CRect tmp; - ::GetWindowRect(GetHWND(), &tmp); - tmp.right = tmp.Width(); - tmp.bottom = tmp.Height(); - tmp.left = tmp.top = 0; - - // Install the focus manager so we get notified of Tab key events. - views::FocusManager::InstallFocusSubclass(GetHWND(), NULL); - GetRootView()->set_background(new NativeUIBackground); - return 0; -} - -void NativeUIContents::OnDestroy() { - views::FocusManager::UninstallFocusSubclass(GetHWND()); -} - -void NativeUIContents::OnSize(UINT size_command, const CSize& new_size) { - Layout(); - ::RedrawWindow(GetHWND(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); -} - -void NativeUIContents::OnWindowPosChanged(WINDOWPOS* position) { - // NOTE: this may be invoked even when the visbility didn't change, in which - // case hiding and showing are both false. - const bool hiding = (position->flags & SWP_HIDEWINDOW) == SWP_HIDEWINDOW; - const bool showing = (position->flags & SWP_SHOWWINDOW) == SWP_SHOWWINDOW; - if (hiding || showing) { - if (is_visible_ != showing) { - is_visible_ = showing; - if (current_ui_) { - if (is_visible_) - current_ui_->WillBecomeVisible(this); - else - current_ui_->WillBecomeInvisible(this); - } - } - } - ChangeSize(0, CSize(position->cx, position->cy)); - - SetMsgHandled(FALSE); -} - -void NativeUIContents::GetContainerBounds(gfx::Rect* out) const { - GetBounds(out, false); -} - -void NativeUIContents::SetPageState(PageState* page_state) { - if (!page_state) - page_state = new PageState(); - state_.reset(page_state); - NavigationController* ctrl = controller(); - if (ctrl) { - int ne_index = ctrl->GetLastCommittedEntryIndex(); - NavigationEntry* ne = ctrl->GetEntryAtIndex(ne_index); - if (ne) { - // NavigationEntry is null if we're being restored. - DCHECK(ne); - std::string rep; - state_->GetByteRepresentation(&rep); - ne->set_content_state(rep); - ctrl->NotifyEntryChanged(ne, ne_index); - } - } -} - -bool NativeUIContents::NavigateToPendingEntry(bool reload) { - views::RootView* root_view = GetRootView(); - DCHECK(root_view); - - if (current_ui_) { - current_ui_->WillBecomeInvisible(this); - root_view->RemoveChildView(current_view_); - current_ui_ = NULL; - current_view_ = NULL; - } - - NavigationEntry* pending_entry = controller()->GetPendingEntry(); - NativeUI* new_ui = GetNativeUIForURL(pending_entry->url()); - if (new_ui) { - current_ui_ = new_ui; - is_visible_ = true; - current_ui_->WillBecomeVisible(this); - current_view_ = new_ui->GetView(); - root_view->AddChildView(current_view_); - - std::string s = pending_entry->content_state(); - if (s.empty()) - state_->InitWithURL(pending_entry->url()); - else - state_->InitWithBytes(s); - - current_ui_->Navigate(*state_); - Layout(); - } - - // Commit the new load in the navigation controller. If the ID of the - // NavigationEntry we were given was -1, that means this is a new load, so - // we have to generate a new ID. - controller()->CommitPendingEntry(); - - // Populate the committed entry. - NavigationEntry* committed_entry = controller()->GetLastCommittedEntry(); - committed_entry->set_title(GetDefaultTitle()); - committed_entry->favicon().set_bitmap(GetFavIcon()); - committed_entry->favicon().set_is_valid(true); - if (new_ui) { - // Strip out the query params, they should have moved to state. - // TODO(sky): use GURL methods for replacements once bug is fixed. - size_t scheme_end, host_end; - GetSchemeAndHostEnd(committed_entry->url(), &scheme_end, &host_end); - committed_entry->set_url( - GURL(committed_entry->url().spec().substr(0, host_end))); - } - std::string content_state; - state_->GetByteRepresentation(&content_state); - committed_entry->set_content_state(content_state); - - // Broadcast the fact that we just updated all that crap. - controller()->NotifyEntryChanged( - committed_entry, - controller()->GetIndexOfEntry(committed_entry)); - return true; -} - -void NativeUIContents::Layout() { - if (current_view_) { - views::RootView* root_view = GetRootView(); - current_view_->SetBounds(0, 0, root_view->width(), - root_view->height()); - current_view_->Layout(); - } -} - -const std::wstring NativeUIContents::GetDefaultTitle() const { - if (current_ui_) - return current_ui_->GetTitle(); - else - return std::wstring(); -} - -SkBitmap NativeUIContents::GetFavIcon() const { - int icon_id; - - if (current_ui_) - icon_id = current_ui_->GetFavIconID(); - else - icon_id = IDR_DEFAULT_FAVICON; - - return *ResourceBundle::GetSharedInstance().GetBitmapNamed(icon_id); -} - -void NativeUIContents::DidBecomeSelected() { - TabContents::DidBecomeSelected(); - Layout(); -} - -void NativeUIContents::SetInitialFocus() { - if (!current_ui_ || !current_ui_->SetInitialFocus()) { - int tab_index; - Browser* browser = Browser::GetBrowserForController( - this->controller(), &tab_index); - if (browser) - browser->SetFocusToLocationBar(); - else - TabContents::SetInitialFocus(); // Will set focus to our HWND. - } -} - -void NativeUIContents::SetIsLoading(bool is_loading, - LoadNotificationDetails* details) { - TabContents::SetIsLoading(is_loading, details); -} - -// FocusTraversable Implementation -views::View* NativeUIContents::FindNextFocusableView( - views::View* starting_view, bool reverse, - views::FocusTraversable::Direction direction, bool dont_loop, - views::FocusTraversable** focus_traversable, - views::View** focus_traversable_view) { - return GetRootView()->FindNextFocusableView( - starting_view, reverse, direction, dont_loop, - focus_traversable, focus_traversable_view); -} - -//static -std::string NativeUIContents::GetScheme() { - return kNativeUIContentsScheme; -} - -//static -void NativeUIContents::InitializeNativeUIFactories() { - RegisterNativeUIFactory(DownloadTabUI::GetURL(), - DownloadTabUI::GetNativeUIFactory()); - RegisterNativeUIFactory(HistoryTabUI::GetURL(), - HistoryTabUI::GetNativeUIFactory()); -} - -// static -std::string NativeUIContents::GetFactoryKey(const GURL& url) { - size_t scheme_end; - size_t host_end; - GetSchemeAndHostEnd(url, &scheme_end, &host_end); - return url.spec().substr(scheme_end + 2, host_end - scheme_end - 2); -} - -typedef std::map<std::string, NativeUIFactory*> PathToFactoryMap; - -static PathToFactoryMap* g_path_to_factory = NULL; - -//static -void NativeUIContents::RegisterNativeUIFactory(const GURL& url, - NativeUIFactory* factory) { - const std::string key = GetFactoryKey(url); - - if (!g_path_to_factory) - g_path_to_factory = new PathToFactoryMap; - - PathToFactoryMap::iterator i = g_path_to_factory->find(key); - if (i != g_path_to_factory->end()) { - delete i->second; - g_path_to_factory->erase(i); - } - (*g_path_to_factory)[key] = factory; -} - -views::RootView* NativeUIContents::CreateRootView() { - return new NativeRootView(this); -} - -//static -NativeUI* NativeUIContents::InstantiateNativeUIForURL( - const GURL& url, NativeUIContents* contents) { - if (!g_path_to_factory) - return NULL; - - const std::string key = GetFactoryKey(url); - - NativeUIFactory* factory = (*g_path_to_factory)[key]; - if (factory) - return factory->CreateNativeUIForURL(url, contents); - else - return NULL; -} - -NativeUI* NativeUIContents::GetNativeUIForURL(const GURL& url) { - const std::string key = GetFactoryKey(url); - - PathToUI::iterator i = path_to_native_uis_.find(key); - if (i != path_to_native_uis_.end()) - return i->second; - - NativeUI* ui = InstantiateNativeUIForURL(url, this); - if (ui) - path_to_native_uis_[key] = ui; - return ui; -} - - -//////////////////////////////////////////////////////////////////////////////// -// -// Standard NativeUI background implementation. -// -//////////////////////////////////////////////////////////////////////////////// -NativeUIBackground::NativeUIBackground() { -} - -NativeUIBackground::~NativeUIBackground() { -} - -void NativeUIBackground::Paint(ChromeCanvas* canvas, - views::View* view) const { - static const SkColor kBackground = SkColorSetRGB(255, 255, 255); - canvas->FillRectInt(kBackground, 0, 0, view->width(), view->height()); -} - -///////////////////////////////////////////////////////////////////////////// -// -// SearchableUIBackground -// A Background subclass to be used with SearchableUIContainer objects. -// Paint() is overridden to do nothing here; the background of the bar is -// painted in SearchableUIContainer::Paint. This class is necessary -// only for native controls to be able to get query the background -// brush. - -class SearchableUIBackground : public views::Background { - public: - explicit SearchableUIBackground(SkColor native_control_color) { - SetNativeControlColor(native_control_color); - } - virtual ~SearchableUIBackground() {}; - - // Empty implementation. - // The actual painting of the bar happens in SearchableUIContainer::Paint. - virtual void Paint(ChromeCanvas* canvas, views::View* view) const { } - - private: - DISALLOW_EVIL_CONSTRUCTORS(SearchableUIBackground); -}; - -///////////////////////////////////////////////////////////////////////////// -// -// SearchableUIContainer implementation. -// -///////////////////////////////////////////////////////////////////////////// - -SearchableUIContainer::SearchableUIContainer( - SearchableUIContainer::Delegate* delegate) - : delegate_(delegate), - search_field_(NULL), - title_link_(NULL), - title_image_(NULL), - scroll_view_(NULL) { - title_link_ = new views::Link; - ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance(); - ChromeFont title_font(resource_bundle - .GetFont(ResourceBundle::WebFont).DeriveFont(2)); - title_link_->SetFont(title_font); - title_link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - title_link_->SetController(this); - - title_image_ = new views::ImageView(); - title_image_->SetVisible(false); - - // Get the product logo - if (!kProductLogo) { - kProductLogo = resource_bundle.GetBitmapNamed(IDR_PRODUCT_LOGO); - } - - product_logo_ = new views::ImageView(); - product_logo_->SetVisible(true); - product_logo_->SetImage(*kProductLogo); - AddChildView(product_logo_); - - search_field_ = new views::TextField; - search_field_->SetFont(ResourceBundle::GetSharedInstance().GetFont( - ResourceBundle::WebFont)); - search_field_->SetController(this); - - scroll_view_ = new views::ScrollView; - scroll_view_->set_background( - views::Background::CreateSolidBackground(kBackground)); - - // Set background class so that native controls can get a color. - set_background(new SearchableUIBackground(kBackground)); - - throbber_ = new views::SmoothedThrobber(50); - - GridLayout* layout = new GridLayout(this); - // View owns the LayoutManager and will delete it along with all the columns - // we create here. - SetLayoutManager(layout); - - search_button_ = - new views::NativeButton(std::wstring()); - search_button_->SetFont(resource_bundle.GetFont(ResourceBundle::WebFont)); - search_button_->SetListener(this); - - // Set a background color for the search button. If SearchableUIContainer - // provided a background, then the search button could inherit that instead. - search_button_->set_background(new SearchableUIBackground(kBackground)); - - // For the first row (icon, title/text field, search button and throbber). - ColumnSet* column_set = layout->AddColumnSet(0); - column_set->AddPaddingColumn(0, kDestinationTitleOffset); - - // Add the icon column. - column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, - GridLayout::USE_PREF, - kDestinationSearchOffset - kDestinationTitleOffset - - kDestinationSmallerMargin, - kDestinationSearchOffset - kDestinationTitleOffset - - kDestinationSmallerMargin); - column_set->AddPaddingColumn(0, kDestinationSmallerMargin); - - // Add the title/search field column. - column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, - GridLayout::USE_PREF, kDestinationSearchWidth, - kDestinationSearchWidth); - column_set->AddPaddingColumn(0, kDestinationSmallerMargin); - - // Add the search button column. - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, kDestinationSmallerMargin); - - // Add the throbber column. - column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, - GridLayout::USE_PREF, 0, 0); - - // For the scroll view. - column_set = layout->AddColumnSet(1); - column_set->AddPaddingColumn(0, 1); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, - GridLayout::USE_PREF, 0, 0); - - layout->AddPaddingRow(0, kDestinationSmallerMargin); - layout->StartRow(0, 0); - layout->AddView(title_image_, 1, 2); - layout->AddView(title_link_); - - layout->StartRow(0, 0); - layout->SkipColumns(1); - layout->AddView(search_field_); - layout->AddView(search_button_); - layout->AddView(throbber_); - - layout->AddPaddingRow(0, kDestinationSmallerMargin); - layout->StartRow(1, 1); - layout->AddView(scroll_view_); -} - -SearchableUIContainer::~SearchableUIContainer() { -} - -void SearchableUIContainer::SetContents(views::View* contents) { - // The column view will resize to accomodate long titles. - title_link_->SetText(delegate_->GetTitle()); - - int section_icon_id = delegate_->GetSectionIconID(); - if (section_icon_id != 0) { - title_image_->SetImage(*ResourceBundle::GetSharedInstance(). - GetBitmapNamed(section_icon_id)); - title_image_->SetVisible(true); - } - - search_button_->SetLabel(delegate_->GetSearchButtonText()); - scroll_view_->SetContents(contents); -} - -views::View* SearchableUIContainer::GetContents() { - return scroll_view_->GetContents(); -} - -void SearchableUIContainer::Layout() { - View::Layout(); - - gfx::Size search_button_size = search_button_->GetPreferredSize(); - gfx::Size product_logo_size = product_logo_->GetPreferredSize(); - - int field_width = kDestinationSearchOffset + - kDestinationSearchWidth + - kDestinationSmallerMargin + - static_cast<int>(search_button_size.width()) + - kDestinationSmallerMargin; - - product_logo_->SetBounds(std::max(width() - kProductLogo->width() - - kProductLogoPadding, - field_width), - kProductLogoPadding, - product_logo_size.width(), - product_logo_size.height()); -} - -void SearchableUIContainer::Paint(ChromeCanvas* canvas) { - SkColor top_color(kBackground); - canvas->FillRectInt(top_color, 0, 0, - width(), scroll_view_->y()); - - canvas->FillRectInt(kBottomMarginColor, 0, scroll_view_->y() - - kBottomMargin, width(), kBottomMargin); - - canvas->FillRectInt(SkColorSetRGB(196, 196, 196), - 0, scroll_view_->y() - 1, width(), 1); -} - -views::TextField* SearchableUIContainer::GetSearchField() const { - return search_field_; -} - -views::ScrollView* SearchableUIContainer::GetScrollView() const { - return scroll_view_; -} - -void SearchableUIContainer::SetSearchEnabled(bool enabled) { - search_field_->SetReadOnly(!enabled); - search_button_->SetEnabled(enabled); -} - -void SearchableUIContainer::StartThrobber() { - throbber_->Start(); -} - -void SearchableUIContainer::StopThrobber() { - throbber_->Stop(); -} - -void SearchableUIContainer::ButtonPressed(views::NativeButton* sender) { - DoSearch(); -} - -void SearchableUIContainer::LinkActivated(views::Link *link, - int event_flags) { - if (link == title_link_) { - search_field_->SetText(std::wstring()); - DoSearch(); - } -} - -void SearchableUIContainer::HandleKeystroke(views::TextField* sender, - UINT message, - TCHAR key, - UINT repeat_count, - UINT flags) { - if (key == VK_RETURN) - DoSearch(); -} - -void SearchableUIContainer::DoSearch() { - if (delegate_) - delegate_->DoSearch(search_field_->GetText()); - - scroll_view_->ScrollToPosition(scroll_view_->vertical_scroll_bar(), 0); -} - diff --git a/chrome/browser/tab_contents/native_ui_contents.h b/chrome/browser/tab_contents/native_ui_contents.h deleted file mode 100644 index 3982f91..0000000 --- a/chrome/browser/tab_contents/native_ui_contents.h +++ /dev/null @@ -1,295 +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. - -#ifndef CHROME_BROWSER_TAB_CONTENTS_NATIVE_UI_CONTENTS_H_ -#define CHROME_BROWSER_TAB_CONTENTS_NATIVE_UI_CONTENTS_H_ - -#include "chrome/browser/page_state.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/views/background.h" -#include "chrome/views/link.h" -#include "chrome/views/native_button.h" -#include "chrome/views/text_field.h" -#include "chrome/views/widget_win.h" - -namespace views { -class CheckBox; -class FocusTraversable; -class ImageView; -class ScrollView; -class Throbber; -} - -class NativeUIFactory; -class NativeUI; - -//////////////////////////////////////////////////////////////////////////////// -// -// NativeUIContents -// -// NativeUIContents is a TabContents that is used to show some pages made with -// some native user interface elements. NativeUIContents maintains a list of URL -// path mapping to specific NativeUI implementations. -// -//////////////////////////////////////////////////////////////////////////////// -class NativeUIContents : public TabContents, - public views::WidgetWin { - public: - explicit NativeUIContents(Profile* profile); - - virtual void CreateView(); - virtual gfx::NativeView GetNativeView() const { return GetHWND(); } - virtual void GetContainerBounds(gfx::Rect* out) const; - - // Sets the page state. NativeUIContents takes ownership of the supplied - // PageState. Use a value of NULL to set the state to empty. - void SetPageState(PageState* page_state); - - // Returns the page state. This is intended for UIs that want to store page - // state. - const PageState& page_state() const { return *state_; } - - // - // TabContents implementation - // - virtual bool NavigateToPendingEntry(bool reload); - virtual const std::wstring GetDefaultTitle() const; - virtual SkBitmap GetFavIcon() const; - virtual bool ShouldDisplayURL() { return false; } - virtual bool ShouldDisplayFavIcon() { return true; } - virtual void DidBecomeSelected(); - virtual void SetInitialFocus(); - - // Sets the current loading state. This is public for NativeUIs to update. - void SetIsLoading(bool is_loading, LoadNotificationDetails* details); - - // FocusTraversable Implementation - virtual views::View* FindNextFocusableView( - views::View* starting_view, - bool reverse, - views::FocusTraversable::Direction direction, - bool dont_loop, - views::FocusTraversable** focus_traversable, - views::View** focus_traversable_view); - virtual views::RootView* GetContentsRootView() { return GetRootView(); } - - // Return the scheme used. We currently use chrome-nativeui: - static std::string GetScheme(); - - // Register a NativeUIFactory for a given path. - static void RegisterNativeUIFactory(const GURL& url, - NativeUIFactory* factory); - - protected: - // Should be deleted via CloseContents. - virtual ~NativeUIContents(); - - // Overridden to create a view that that handles drag and drop. - virtual views::RootView* CreateRootView(); - - private: - // Initialize the factories. This is called the first time a NativeUIContents - // object is created. If you add a new factory, you need to add a line in this - // method. - static void InitializeNativeUIFactories(); - - // Instantiates a native UI for the provided URL. This is done by using the - // native factories which have been registered. - static NativeUI* InstantiateNativeUIForURL(const GURL& url, - NativeUIContents* contents); - - // Returns the key to use based on the TabUI's url. - static std::string GetFactoryKey(const GURL& url); - - // Size the current UI if any. - void Layout(); - - // Return the Native UI for the provided URL. The NativeUIs are returned from - // a cache. Returns NULL if no such UI exists. - NativeUI* GetNativeUIForURL(const GURL& url); - - // Windows message handlers. - virtual LRESULT OnCreate(LPCREATESTRUCT create_struct); - virtual void OnDestroy(); - virtual void OnSize(UINT size_command, const CSize& new_size); - virtual void OnWindowPosChanged(WINDOWPOS* position); - - // Whether this contents is visible. - bool is_visible_; - - // Path to NativeUI map. We keep reusing the same UIs. - typedef std::map<std::string, NativeUI*> PathToUI; - PathToUI path_to_native_uis_; - - // The current UI. - NativeUI* current_ui_; - - // The current view for the current UI. We don't ask again just in case the - // UI implementation keeps allocating new uis. - views::View* current_view_; - - // The current page state for the native contents. - scoped_ptr<PageState> state_; - - // Whether factories have been initialized. - static bool g_ui_factories_initialized; - - DISALLOW_EVIL_CONSTRUCTORS(NativeUIContents); -}; - -///////////////////////////////////////////////////////////////////////////// -// -// A native UI needs to implement the following interface to work with the -// NativeUIContents. -// -///////////////////////////////////////////////////////////////////////////// -class NativeUI { - public: - virtual ~NativeUI() {} - - // Return the title for this user interface. The title is used as a tab title. - virtual const std::wstring GetTitle() const = 0; - - // Return the favicon id for this user interface. - virtual const int GetFavIconID () const = 0; - - // Return the view that should be used to render this user interface. - virtual views::View* GetView() = 0; - - // Inform the view that it is about to become visible. - virtual void WillBecomeVisible(NativeUIContents* parent) = 0; - - // Inform the view that it is about to become invisible. - virtual void WillBecomeInvisible(NativeUIContents* parent) = 0; - - // Inform the view that it should recreate the provided state. The state - // should be updated as needed by using the current navigation entry of - // the provided tab contents. - virtual void Navigate(const PageState& state) = 0; - - // Requests the contents set the initial focus. A return value of true - // indicates the contents wants focus and requested focus. A return value of - // false indicates the contents does not want focus, and that focus should - // go to the location bar. - virtual bool SetInitialFocus() = 0; -}; - -///////////////////////////////////////////////////////////////////////////// -// -// NativeUIFactory defines the method necessary to instantiate a NativeUI -// object. Typically, each NativeUI implementation registers an object that -// can instantiate NativeUI objects given the necessary path. -// -///////////////////////////////////////////////////////////////////////////// -class NativeUIFactory { - public: - virtual ~NativeUIFactory() {} - - // Request the factory to instantiate a NativeUI object given the provided - // url. The url is a nativeui: URL which contains the path for which this - // factory was registered. - // - // See NativeUIContents::RegisterNativeUI(). - virtual NativeUI* CreateNativeUIForURL(const GURL& url, - NativeUIContents* contents) = 0; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// -// A standard background for native UIs. -// -//////////////////////////////////////////////////////////////////////////////// -class NativeUIBackground : public views::Background { - public: - NativeUIBackground(); - virtual ~NativeUIBackground(); - - virtual void Paint(ChromeCanvas* canvas, views::View* view) const; - - private: - - DISALLOW_EVIL_CONSTRUCTORS(NativeUIBackground); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// A view subclass used to implement native uis that feature a search field. -// This view contains a search field and a ScrollView for the contents. It -// implements a consistent look for these UIs. -// -//////////////////////////////////////////////////////////////////////////////// -class SearchableUIContainer : public views::View, - public views::NativeButton::Listener, - public views::LinkController, - public views::TextField::Controller { - public: - // The Delegate is notified when the user clicks the search button. - class Delegate { - public: - virtual void DoSearch(const std::wstring& text) = 0; - virtual const std::wstring GetTitle() const = 0; - virtual const int GetSectionIconID() const = 0; - virtual const std::wstring GetSearchButtonText() const = 0; - }; - - // Create a new SearchableUIContainer given a delegate. - explicit SearchableUIContainer(Delegate* delegate); - - virtual ~SearchableUIContainer(); - - // Add the view as the contents of the container. - void SetContents(views::View* contents); - views::View* GetContents(); - - virtual void Layout(); - - // Overriden to paint the container. - virtual void Paint(ChromeCanvas* canvas); - - // Provide the mode access to various UI elements. - views::TextField* GetSearchField() const; - views::ScrollView* GetScrollView() const; - - // Enable/disable the search text-field/button. - void SetSearchEnabled(bool enabled); - - // Start and stop the throbber. - void StartThrobber(); - void StopThrobber(); - - private: - // Invoked when the user presses the search button. - virtual void ButtonPressed(views::NativeButton* sender); - - // TextField method, does nothing. - virtual void ContentsChanged(views::TextField* sender, - const std::wstring& new_contents) {} - - // Textfield method, if key is the return key the search is updated. - virtual void HandleKeystroke(views::TextField* sender, - UINT message, - TCHAR key, - UINT repeat_count, - UINT flags); - - // Notifies the delegate to update the search. - void DoSearch(); - - void LinkActivated(views::Link* link, int event_flags); - - Delegate* delegate_; - views::Link* title_link_; - views::ImageView* title_image_; - views::ImageView* product_logo_; - views::TextField* search_field_; - views::NativeButton* search_button_; - views::ScrollView* scroll_view_; - views::Throbber* throbber_; - - DISALLOW_EVIL_CONSTRUCTORS(SearchableUIContainer); -}; - -#endif // CHROME_BROWSER_TAB_CONTENTS_NATIVE_UI_CONTENTS_H_ - diff --git a/chrome/browser/tab_contents/tab_contents_factory.cc b/chrome/browser/tab_contents/tab_contents_factory.cc index 9297eec..0226b4f 100644 --- a/chrome/browser/tab_contents/tab_contents_factory.cc +++ b/chrome/browser/tab_contents/tab_contents_factory.cc @@ -17,7 +17,6 @@ #if defined(OS_WIN) // TODO(port): port these headers to posix. #include "chrome/browser/dom_ui/html_dialog_contents.h" -#include "chrome/browser/tab_contents/native_ui_contents.h" #include "chrome/browser/tab_contents/tab_contents.h" #elif defined(OS_POSIX) #include "chrome/common/temp_scaffolding_stubs.h" @@ -57,9 +56,6 @@ TabContents* TabContents::CreateWithType(TabContentsType type, case TAB_CONTENTS_HTML_DIALOG: contents = new HtmlDialogContents(profile, instance, NULL); break; - case TAB_CONTENTS_NATIVE_UI: - contents = new NativeUIContents(profile); - break; #endif // defined(OS_WIN) case TAB_CONTENTS_DEBUGGER: case TAB_CONTENTS_NEW_TAB_UI: @@ -103,9 +99,6 @@ TabContentsType TabContents::TypeForURL(GURL* url) { if (BrowserURLHandler::HandleBrowserURL(url, &type)) return type; - if (url->SchemeIs(NativeUIContents::GetScheme().c_str())) - return TAB_CONTENTS_NATIVE_UI; - if (HtmlDialogContents::IsHtmlDialogUrl(*url)) return TAB_CONTENTS_HTML_DIALOG; diff --git a/chrome/browser/tab_contents/tab_contents_type.h b/chrome/browser/tab_contents/tab_contents_type.h index 53e79b0..9955258 100644 --- a/chrome/browser/tab_contents/tab_contents_type.h +++ b/chrome/browser/tab_contents/tab_contents_type.h @@ -15,7 +15,6 @@ enum TabContentsType { TAB_CONTENTS_DOWNLOAD_VIEW, TAB_CONTENTS_CHROME_VIEW_CONTENTS, TAB_CONTENTS_NEW_TAB_UI, - TAB_CONTENTS_NATIVE_UI, TAB_CONTENTS_HTML_DIALOG, TAB_CONTENTS_ABOUT_UI, TAB_CONTENTS_DEBUGGER, diff --git a/chrome/browser/views/download_shelf_view.cc b/chrome/browser/views/download_shelf_view.cc index 59f8b6f..f9081e8 100644 --- a/chrome/browser/views/download_shelf_view.cc +++ b/chrome/browser/views/download_shelf_view.cc @@ -12,7 +12,6 @@ #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/views/download_item_view.h" -#include "chrome/browser/views/download_tab_view.h" #include "chrome/common/gfx/chrome_canvas.h" #include "chrome/common/l10n_util.h" #include "chrome/common/resource_bundle.h" diff --git a/chrome/browser/views/download_tab_view.cc b/chrome/browser/views/download_tab_view.cc deleted file mode 100644 index f4ab642..0000000 --- a/chrome/browser/views/download_tab_view.cc +++ /dev/null @@ -1,1341 +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/download_tab_view.h" - -#include <time.h> - -#include <algorithm> -#include <functional> - -#include "base/file_util.h" -#include "base/string_util.h" -#include "base/task.h" -#include "base/time_format.h" -#include "base/timer.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profile.h" -#include "chrome/common/gfx/chrome_canvas.h" -#include "chrome/common/gfx/chrome_font.h" -#include "chrome/common/gfx/text_elider.h" -#include "chrome/common/l10n_util.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/resource_bundle.h" -#include "chrome/common/stl_util-inl.h" -#include "chrome/common/time_format.h" -#include "chrome/views/background.h" -#include "googleurl/src/gurl.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" - -using base::Time; -using base::TimeDelta; - -// Approximate spacing, in pixels, taken from initial UI mock up screens -static const int kVerticalPadding = 5; -static const int kHorizontalLinkPadding = 15; -static const int kHorizontalButtonPadding = 8; - -// For vertical and horizontal element spacing -static const int kSpacer = 20; - -// Horizontal space between the left edge of the entries and the -// left edge of the view. -static const int kLeftMargin = 38; - -// x-position of the icon (massage this so it visually matches -// kDestinationSearchOffset in native_ui_contents.cc -static const int kDownloadIconOffset = 132; - -// Padding between the progress icon and the title, url -static const int kInfoPadding = 16; - -// Horizontal distance from the left window edge to the left icon edge -static const int kDateSize = 132; - -// Maximum size of the text for the file name or URL -static const int kFilenameSize = 350; - -// Maximum size of the progress text during download, which is taken -// out of kFilenameSize -static const int kProgressSize = 170; - -// Status label color (grey) -static const SkColor kStatusColor = SkColorSetRGB(128, 128, 128); - -// URL label color (green) -static const SkColor kUrlColor = SkColorSetRGB(0, 128, 0); - -// Paused download indicator (red) -static const SkColor kPauseColor = SkColorSetRGB(128, 0, 0); - -// Warning label color (blue) -static const SkColor kWarningColor = SkColorSetRGB(87, 108, 149); - -// Selected item background color -static const SkColor kSelectedItemColor = SkColorSetRGB(215, 232, 255); - -// State key used to identify search text. -static const wchar_t kSearchTextKey[] = L"st"; - -// The maximum number of characters we show in a file name when displaying the -// dangerous download message. -static const int kFileNameMaxLength = 20; - -// Sorting functor for DownloadItem -------------------------------------------- - -// Sort DownloadItems into ascending order by their start time. -class DownloadItemSorter : public std::binary_function<DownloadItem*, - DownloadItem*, - bool> { - public: - bool operator()(const DownloadItem* lhs, const DownloadItem* rhs) { - return lhs->start_time() < rhs->start_time(); - } -}; - - -// DownloadItemTabView implementation ------------------------------------------ -DownloadItemTabView::DownloadItemTabView() - : model_(NULL), - parent_(NULL), - is_floating_view_renderer_(false) { - // Create our element views using empty strings for now, - // set them based on the model's state in Layout(). - since_ = new views::Label(L""); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - ChromeFont font = rb.GetFont(ResourceBundle::WebFont); - since_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - since_->SetFont(font); - AddChildView(since_); - - date_ = new views::Label(L""); - date_->SetColor(kStatusColor); - date_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - date_->SetFont(font); - AddChildView(date_); - - // file_name_ is enabled once the download has finished and we can open - // it via ShellExecute. - file_name_ = new views::Link(L""); - file_name_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - file_name_->SetController(this); - file_name_->SetFont(font); - AddChildView(file_name_); - - // dangerous_download_warning_ is enabled when a dangerous download has been - // initiated. - dangerous_download_warning_ = new views::Label(); - dangerous_download_warning_ ->SetMultiLine(true); - dangerous_download_warning_->SetColor(kWarningColor); - dangerous_download_warning_->SetHorizontalAlignment( - views::Label::ALIGN_LEFT); - dangerous_download_warning_->SetFont(font); - AddChildView(dangerous_download_warning_); - - // The save and discard buttons are shown to prompt the user when a dangerous - // download was started. - save_button_ = new views::NativeButton( - l10n_util::GetString(IDS_SAVE_DOWNLOAD)); - save_button_->set_enforce_dlu_min_size(false); - save_button_->SetListener(this); - discard_button_ = new views::NativeButton( - l10n_util::GetString(IDS_DISCARD_DOWNLOAD)); - discard_button_->SetListener(this); - discard_button_->set_enforce_dlu_min_size(false); - AddChildView(save_button_); - AddChildView(discard_button_); - - // Set our URL name - download_url_ = new views::Label(L""); - download_url_->SetColor(kUrlColor); - download_url_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - download_url_->SetFont(font); - AddChildView(download_url_); - - // Set our time remaining - time_remaining_ = new views::Label(L""); - time_remaining_->SetColor(kStatusColor); - time_remaining_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - time_remaining_->SetFont(font); - AddChildView(time_remaining_); - - // Set our download progress - download_progress_ = new views::Label(L""); - download_progress_->SetColor(kStatusColor); - download_progress_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - download_progress_->SetFont(font); - AddChildView(download_progress_); - - // Set our 'Pause', 'Cancel' and 'Show in folder' links using - // actual strings, since these are constant - pause_ = new views::Link(l10n_util::GetString(IDS_DOWNLOAD_LINK_PAUSE)); - pause_->SetController(this); - pause_->SetFont(font); - AddChildView(pause_); - - cancel_ = new views::Link(l10n_util::GetString(IDS_DOWNLOAD_LINK_CANCEL)); - cancel_->SetController(this); - cancel_->SetFont(font); - AddChildView(cancel_); - - show_ = new views::Link(l10n_util::GetString(IDS_DOWNLOAD_LINK_SHOW)); - show_->SetController(this); - show_->SetFont(font); - AddChildView(show_); -} - -DownloadItemTabView::~DownloadItemTabView() { -} - -void DownloadItemTabView::SetModel(DownloadItem* model, - DownloadTabView* parent) { - DCHECK(model && parent); - model_ = model; - parent_ = parent; - parent_->LookupIcon(model_); -} - -gfx::Size DownloadItemTabView::GetPreferredSize() { - gfx::Size pause_size = pause_->GetPreferredSize(); - gfx::Size cancel_size = cancel_->GetPreferredSize(); - gfx::Size show_size = show_->GetPreferredSize(); - return gfx::Size(parent_->big_icon_size() + - 2 * kSpacer + - kHorizontalLinkPadding + - kFilenameSize + - std::max(pause_size.width() + cancel_size.width() + - kHorizontalLinkPadding, show_size.width()), - parent_->big_icon_size()); -} - -// Each DownloadItemTabView has reasonably complex layout requirements -// that are based on the state of its model. To make the code much simpler -// to read, Layout() is split into state specific code which will result -// in some redundant code. -void DownloadItemTabView::Layout() { - DCHECK(model_); - switch (model_->state()) { - case DownloadItem::COMPLETE: - if (model_->safety_state() == DownloadItem::DANGEROUS) - LayoutPromptDangerousDownload(); - else - LayoutComplete(); - break; - case DownloadItem::CANCELLED: - LayoutCancelled(); - break; - case DownloadItem::IN_PROGRESS: - if (model_->safety_state() == DownloadItem::DANGEROUS) - LayoutPromptDangerousDownload(); - else - LayoutInProgress(); - break; - case DownloadItem::REMOVING: - break; - default: - NOTREACHED(); - } -} - -// Only display the date if the download is the last that occurred -// on a given day. -void DownloadItemTabView::LayoutDate() { - if (!parent_->ShouldDrawDateForDownload(model_)) { - since_->SetVisible(false); - date_->SetVisible(false); - return; - } - - since_->SetText(TimeFormat::RelativeDate(model_->start_time(), NULL)); - gfx::Size since_size = since_->GetPreferredSize(); - since_->SetBounds(kLeftMargin, parent_->big_icon_offset(), - kDateSize, since_size.height()); - since_->SetVisible(true); - - date_->SetText(base::TimeFormatShortDate(model_->start_time())); - gfx::Size date_size = date_->GetPreferredSize(); - date_->SetBounds(kLeftMargin, since_size.height() + kVerticalPadding + - parent_->big_icon_offset(), - kDateSize, date_size.height()); - date_->SetVisible(true); -} - -// DownloadItem::COMPLETE state layout -void DownloadItemTabView::LayoutComplete() { - // Hide unused UI elements - pause_->SetVisible(false); - pause_->SetEnabled(false); - cancel_->SetVisible(false); - cancel_->SetEnabled(false); - time_remaining_->SetVisible(false); - download_progress_->SetVisible(false); - dangerous_download_warning_->SetVisible(false); - save_button_->SetVisible(false); - save_button_->SetEnabled(false); - discard_button_->SetVisible(false); - discard_button_->SetEnabled(false); - - LayoutDate(); - int dx = kDownloadIconOffset - parent_->big_icon_offset() + - parent_->big_icon_size() + kInfoPadding; - - // File name and URL - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - ChromeFont font = rb.GetFont(ResourceBundle::WebFont); - file_name_->SetText( - gfx::ElideFilename(model_->GetFileName().ToWStringHack(), font, - kFilenameSize)); - - gfx::Size file_name_size = file_name_->GetPreferredSize(); - - file_name_->SetBounds(dx, parent_->big_icon_offset(), - std::min(kFilenameSize, - static_cast<int>(file_name_size.width())), - file_name_size.height()); - file_name_->SetVisible(true); - file_name_->SetEnabled(true); - - GURL url(model_->url()); - download_url_->SetURL(url); - gfx::Size url_size = download_url_->GetPreferredSize(); - download_url_->SetBounds(dx, - file_name_size.height() + kVerticalPadding + - parent_->big_icon_offset(), - std::min(kFilenameSize, - static_cast<int>(width() - dx)), - url_size.height()); - download_url_->SetVisible(true); - dx += kFilenameSize + kSpacer; - - // Action button (text is constant and set in constructor) - gfx::Size show_size = show_->GetPreferredSize(); - show_->SetBounds(dx, ((file_name_size.height() + url_size.height()) / 2) + - parent_->big_icon_offset(), - show_size.width(), show_size.height()); - show_->SetVisible(true); - show_->SetEnabled(true); -} - -// DownloadItem::CANCELLED state layout -void DownloadItemTabView::LayoutCancelled() { - // Hide unused UI elements - show_->SetVisible(false); - show_->SetEnabled(false); - pause_->SetVisible(false); - pause_->SetEnabled(false); - cancel_->SetVisible(false); - cancel_->SetEnabled(false); - dangerous_download_warning_->SetVisible(false); - save_button_->SetVisible(false); - save_button_->SetEnabled(false); - discard_button_->SetVisible(false); - discard_button_->SetEnabled(false); - - LayoutDate(); - int dx = kDownloadIconOffset - parent_->big_icon_offset() + - parent_->big_icon_size() + kInfoPadding; - - // File name and URL, truncated to show cancelled status - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - ChromeFont font = rb.GetFont(ResourceBundle::WebFont); - file_name_->SetText(gfx::ElideFilename(model_->GetFileName().ToWStringHack(), - font, - kFilenameSize)); - gfx::Size file_name_size = file_name_->GetPreferredSize(); - file_name_->SetBounds(dx, parent_->big_icon_offset(), - kFilenameSize - kProgressSize - kSpacer, - file_name_size.height()); - file_name_->SetVisible(true); - file_name_->SetEnabled(false); - - GURL url(model_->url()); - download_url_->SetURL(url); - gfx::Size url_size = download_url_->GetPreferredSize(); - download_url_->SetBounds(dx, - file_name_size.height() + kVerticalPadding + - parent_->big_icon_offset(), - std::min(kFilenameSize - kProgressSize - kSpacer, - static_cast<int>(width() - dx)), - url_size.height()); - download_url_->SetVisible(true); - - dx += kFilenameSize - kProgressSize; - - // Display cancelled status - time_remaining_->SetColor(kStatusColor); - time_remaining_->SetText(l10n_util::GetString(IDS_DOWNLOAD_TAB_CANCELLED)); - gfx::Size cancel_size = time_remaining_->GetPreferredSize(); - time_remaining_->SetBounds(dx, parent_->big_icon_offset(), - kProgressSize, cancel_size.height()); - time_remaining_->SetVisible(true); - - // Display received size, we may not know the total size if the server didn't - // provide a content-length. - int64 total = model_->total_bytes(); - int64 size = model_->received_bytes(); - DataUnits amount_units = GetByteDisplayUnits(size); - std::wstring received_size = FormatBytes(size, amount_units, true); - std::wstring amount = received_size; - - // We don't know which string we'll end up using for constructing the final - // progress string so we need to adjust both strings for the locale - // direction. - std::wstring amount_localized; - if (l10n_util::AdjustStringForLocaleDirection(amount, &amount_localized)) { - amount.assign(amount_localized); - received_size.assign(amount_localized); - } - - if (total > 0) { - amount_units = GetByteDisplayUnits(total); - std::wstring total_text = FormatBytes(total, amount_units, true); - std::wstring total_text_localized; - if (l10n_util::AdjustStringForLocaleDirection(total_text, - &total_text_localized)) - total_text.assign(total_text_localized); - - // Note that there is no need to adjust the new amount string for the - // locale direction as views::Label does that for us. - amount = l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_SIZE, - received_size, - total_text); - } - - download_progress_->SetText(amount); - gfx::Size byte_size = download_progress_->GetPreferredSize(); - download_progress_->SetBounds(dx, - file_name_size.height() + kVerticalPadding + - parent_->big_icon_offset(), - kProgressSize, - byte_size.height()); - download_progress_->SetVisible(true); -} - -// DownloadItem::IN_PROGRESS state layout -void DownloadItemTabView::LayoutInProgress() { - // Hide unused UI elements - show_->SetVisible(false); - show_->SetEnabled(false); - dangerous_download_warning_->SetVisible(false); - save_button_->SetVisible(false); - save_button_->SetEnabled(false); - discard_button_->SetVisible(false); - discard_button_->SetEnabled(false); - - LayoutDate(); - int dx = kDownloadIconOffset - parent_->big_icon_offset() + - parent_->big_icon_size() + kInfoPadding; - - // File name and URL, truncated to show progress status - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - ChromeFont font = rb.GetFont(ResourceBundle::WebFont); - file_name_->SetText(gfx::ElideFilename(model_->GetFileName().ToWStringHack(), - font, - kFilenameSize)); - gfx::Size file_name_size = file_name_->GetPreferredSize(); - file_name_->SetBounds(dx, parent_->big_icon_offset(), - kFilenameSize - kProgressSize - kSpacer, - file_name_size.height()); - file_name_->SetVisible(true); - file_name_->SetEnabled(false); - - GURL url(model_->url()); - download_url_->SetURL(url); - gfx::Size url_size = download_url_->GetPreferredSize(); - download_url_->SetBounds(dx, file_name_size.height() + kVerticalPadding + - parent_->big_icon_offset(), - std::min(kFilenameSize - kProgressSize - kSpacer, - static_cast<int>(width() - dx)), - url_size.height()); - download_url_->SetVisible(true); - - dx += kFilenameSize - kProgressSize; - - // Set the time remaining and progress display strings. This can - // be complicated by not having received the total download size - // In that case, we can't calculate time remaining so we just - // display speed and received size. - - // Size - int64 total = model_->total_bytes(); - int64 size = model_->received_bytes(); - DataUnits amount_units = GetByteDisplayUnits(size); - std::wstring received_size = FormatBytes(size, amount_units, true); - std::wstring amount = received_size; - - // Adjust both strings for the locale direction since we don't yet know which - // string we'll end up using for constructing the final progress string. - std::wstring amount_localized; - if (l10n_util::AdjustStringForLocaleDirection(amount, &amount_localized)) { - amount.assign(amount_localized); - received_size.assign(amount_localized); - } - - if (total > 0) { - amount_units = GetByteDisplayUnits(total); - std::wstring total_text = FormatBytes(total, amount_units, true); - std::wstring total_text_localized; - if (l10n_util::AdjustStringForLocaleDirection(total_text, - &total_text_localized)) - total_text.assign(total_text_localized); - - amount = l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_SIZE, - received_size, - total_text); - - // We adjust the 'amount' string in case we use it as part of the progress - // text. - if (l10n_util::AdjustStringForLocaleDirection(amount, &amount_localized)) - amount.assign(amount_localized); - } - - // Speed - int64 speed = model_->CurrentSpeed(); - std::wstring progress = amount; - if (!model_->is_paused() && speed > 0) { - amount_units = GetByteDisplayUnits(speed); - std::wstring speed_text = FormatSpeed(speed, amount_units, true); - std::wstring speed_text_localized; - if (l10n_util::AdjustStringForLocaleDirection(speed_text, - &speed_text_localized)) - speed_text.assign(speed_text_localized); - - progress = l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_SPEED, - speed_text, - amount); - - // For some reason, the appearance of the dash character ('-') in a string - // causes Windows to ignore the 'LRE'/'RLE'/'PDF' Unicode formatting - // characters within the string and this causes the string to be displayed - // incorrectly on RTL UIs. Therefore, we add the Unicode right-to-left - // override character (U+202E) if the locale is RTL in order to fix this - // problem. - if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) - progress.insert(0, L"\x202E"); - } - - // Time remaining - int y_pos = file_name_size.height() + kVerticalPadding + - parent_->big_icon_offset(); - gfx::Size time_size; - time_remaining_->SetColor(kStatusColor); - if (model_->is_paused()) { - time_remaining_->SetColor(kPauseColor); - time_remaining_->SetText( - l10n_util::GetString(IDS_DOWNLOAD_PROGRESS_PAUSED)); - time_size = time_remaining_->GetPreferredSize(); - time_remaining_->SetBounds(dx, parent_->big_icon_offset(), - kProgressSize, time_size.height()); - time_remaining_->SetVisible(true); - } else if (total > 0) { - TimeDelta remaining; - if (model_->TimeRemaining(&remaining)) - time_remaining_->SetText(TimeFormat::TimeRemaining(remaining)); - time_size = time_remaining_->GetPreferredSize(); - time_remaining_->SetBounds(dx, parent_->big_icon_offset(), - kProgressSize, time_size.height()); - time_remaining_->SetVisible(true); - } else { - time_remaining_->SetText(L""); - y_pos = ((file_name_size.height() + url_size.height()) / 2) + - parent_->big_icon_offset(); - } - - download_progress_->SetText(progress); - gfx::Size byte_size = download_progress_->GetPreferredSize(); - download_progress_->SetBounds(dx, y_pos, - kProgressSize, byte_size.height()); - download_progress_->SetVisible(true); - - dx += kProgressSize + kSpacer; - y_pos = ((file_name_size.height() + url_size.height()) / 2) + - parent_->big_icon_offset(); - - // Pause (or Resume) / Cancel buttons. - if (model_->is_paused()) - pause_->SetText(l10n_util::GetString(IDS_DOWNLOAD_LINK_RESUME)); - else - pause_->SetText(l10n_util::GetString(IDS_DOWNLOAD_LINK_PAUSE)); - - pause_->SetVisible(true); - pause_->SetEnabled(true); - gfx::Size pause_size = pause_->GetPreferredSize(); - pause_->SetBounds(dx, y_pos, pause_size.width(), pause_size.height()); - - dx += pause_size.width() + kHorizontalLinkPadding; - - gfx::Size cancel_size = cancel_->GetPreferredSize(); - cancel_->SetBounds(dx, y_pos, cancel_size.width(), cancel_size.height()); - cancel_->SetVisible(true); - cancel_->SetEnabled(true); -} - -void DownloadItemTabView::LayoutPromptDangerousDownload() { - // Hide unused UI elements - show_->SetVisible(false); - show_->SetEnabled(false); - file_name_->SetVisible(false); - file_name_->SetEnabled(false); - pause_->SetVisible(false); - pause_->SetEnabled(false); - cancel_->SetVisible(false); - cancel_->SetEnabled(false); - time_remaining_->SetVisible(false); - download_progress_->SetVisible(false); - - LayoutDate(); - int dx = kDownloadIconOffset - parent_->big_icon_offset() + - parent_->big_icon_size() + kInfoPadding; - - // Warning message and URL. - std::wstring file_name; - ElideString(model_->original_name().ToWStringHack(), kFileNameMaxLength, &file_name); - dangerous_download_warning_->SetText( - l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, file_name)); - gfx::Size warning_size = dangerous_download_warning_->GetPreferredSize(); - dangerous_download_warning_->SetBounds(dx, 0, - kFilenameSize, warning_size.height()); - dangerous_download_warning_->SetVisible(true); - - GURL url(model_->url()); - download_url_->SetURL(url); - gfx::Size url_size = download_url_->GetPreferredSize(); - download_url_->SetBounds(dx, height() - url_size.height(), - std::min(kFilenameSize - kSpacer, - static_cast<int>(width() - dx)), - url_size.height()); - download_url_->SetVisible(true); - - dx += kFilenameSize + kSpacer; - - // Save/Discard buttons. - gfx::Size button_size = save_button_->GetPreferredSize(); - save_button_->SetBounds(dx, (height() - button_size.height()) / 2, - button_size.width(), button_size.height()); - save_button_->SetVisible(true); - save_button_->SetEnabled(true); - - dx += button_size.width() + kHorizontalButtonPadding; - - button_size = discard_button_->GetPreferredSize(); - discard_button_->SetBounds(dx, (height() - button_size.height()) / 2, - button_size.width(), button_size.height()); - discard_button_->SetVisible(true); - discard_button_->SetEnabled(true); -} - -void DownloadItemTabView::Paint(ChromeCanvas* canvas) { - PaintBackground(canvas); - - if (model_->state() == DownloadItem::IN_PROGRESS && - model_->safety_state() != DownloadItem::DANGEROUS) { - // For most languages, 'offset' will be 0. For languages where the dangerous - // download warning is longer than usual, the download view will be slightly - // larger and 'offset' will be positive value that lines up the progress - // halo and the file's icon in order to accomodate the larger view. - int offset = (parent_->big_icon_size() - - download_util::kBigProgressIconSize) / 2; - download_util::PaintDownloadProgress( - canvas, - this, - offset + kDownloadIconOffset - - parent_->big_icon_offset(), - offset, - parent_->start_angle(), - model_->PercentComplete(), - download_util::BIG); - } - - // Most of the UI elements in the DownloadItemTabView are represented as - // child Views and therefore they get mirrored automatically in - // right-to-left UIs. The download item icon is not contained within a child - // View so we need to mirror it manually if the locale is RTL. - SkBitmap* icon = parent_->LookupIcon(model_); - if (icon) { - gfx::Rect icon_bounds(kDownloadIconOffset, - parent_->big_icon_offset(), - icon->width(), icon->height()); - icon_bounds.set_x(MirroredLeftPointForRect(icon_bounds)); - canvas->DrawBitmapInt(*icon, icon_bounds.x(), icon_bounds.y()); - } -} - -void DownloadItemTabView::PaintBackground(ChromeCanvas* canvas) { - if (parent_->ItemIsSelected(model_)) { - // Before we paint the border and the focus rect, we need to mirror the - // highlighted area if the View is using a right-to-left UI layout. We need - // to explicitly mirror the position because the highlighted area is - // directly painted on the canvas (as opposed to being represented as a - // child View like the rest of the UI elements in DownloadItemTabView). - gfx::Rect highlighted_bounds(kDownloadIconOffset - - parent_->big_icon_offset(), - 0, - parent_->big_icon_size() + - kInfoPadding + kFilenameSize, - parent_->big_icon_size()); - highlighted_bounds.set_x(MirroredLeftPointForRect(highlighted_bounds)); - - canvas->FillRectInt(kSelectedItemColor, - highlighted_bounds.x(), - highlighted_bounds.y(), - highlighted_bounds.width(), - highlighted_bounds.height()); - - canvas->DrawFocusRect(highlighted_bounds.x(), - highlighted_bounds.y(), - highlighted_bounds.width(), - highlighted_bounds.height()); - } -} - -bool DownloadItemTabView::OnMousePressed(const views::MouseEvent& event) { - gfx::Point point(event.location()); - - // If the click is in the highlight region, then highlight this download. - // Otherwise, remove the highlighting from any download. - gfx::Rect select_rect( - kDownloadIconOffset - parent_->big_icon_offset(), - 0, - kDownloadIconOffset - parent_->big_icon_offset() + - parent_->big_icon_size() + kInfoPadding + kFilenameSize, - parent_->big_icon_size()); - - // The position of the highlighted region does not take into account the - // View's UI layout so we have to manually mirror the position if the View is - // using a right-to-left UI layout. - gfx::Rect mirrored_rect(select_rect); - select_rect.set_x(MirroredLeftPointForRect(mirrored_rect)); - if (select_rect.Contains(point)) { - parent_->ItemBecameSelected(model_); - - // Don't show the right-click menu if we are prompting the user for a - // dangerous download. - if (event.IsRightMouseButton() && - model_->safety_state() != DownloadItem::DANGEROUS) { - views::View::ConvertPointToScreen(this, &point); - - download_util::DownloadDestinationContextMenu menu( - model_, GetWidget()->GetHWND(), point.ToPOINT()); - } - } else { - parent_->ItemBecameSelected(NULL); - } - - return true; -} - -// Handle drag (file copy) operations. -bool DownloadItemTabView::OnMouseDragged(const views::MouseEvent& event) { - if (model_->state() != DownloadItem::COMPLETE || - model_->safety_state() == DownloadItem::DANGEROUS) - return false; - - CPoint point(event.x(), event.y()); - - // In order to make sure drag and drop works as expected when the UI is - // mirrored, we can either flip the mouse X coordinate or flip the X position - // of the drag rectangle. Flipping the mouse X coordinate is easier. - point.x = MirroredXCoordinateInsideView(point.x); - CRect drag_rect(kDownloadIconOffset - - parent_->big_icon_offset(), - 0, - kDownloadIconOffset - - parent_->big_icon_offset() + - parent_->big_icon_size() + kInfoPadding + - kFilenameSize, - parent_->big_icon_size()); - - if (drag_rect.PtInRect(point)) { - SkBitmap* icon = parent_->LookupIcon(model_); - if (icon) - download_util::DragDownload(model_, icon); - } - - return true; -} - -void DownloadItemTabView::LinkActivated(views::Link* source, int event_flags) { - // There are several links in our view that could have been clicked: - if (source == file_name_) { - views::Widget* widget = this->GetWidget(); - HWND parent_window = widget ? widget->GetHWND() : NULL; - model_->manager()->OpenDownloadInShell(model_, parent_window); - } else if (source == pause_) { - model_->TogglePause(); - } else if (source == cancel_) { - model_->Cancel(true /* update history service */); - } else if (source == show_) { - model_->manager()->ShowDownloadInShell(model_); - } else { - NOTREACHED(); - } - - parent_->ItemBecameSelected(model_); -} - -void DownloadItemTabView::ButtonPressed(views::NativeButton* sender) { - if (sender == save_button_) { - parent_->model()->DangerousDownloadValidated(model_); - // Relayout and repaint to display the right mode (complete or in progress). - Layout(); - SchedulePaint(); - } else if (sender == discard_button_) { - model_->Remove(true); - } else { - NOTREACHED(); - } -} - -// DownloadTabView implementation ---------------------------------------------- - -DownloadTabView::DownloadTabView(DownloadManager* model) - : model_(model), - big_icon_size_(download_util::GetBigProgressIconSize()), - big_icon_offset_(download_util::GetBigProgressIconOffset()), - start_angle_(download_util::kStartAngleDegrees), - scroll_helper_(kSpacer, big_icon_size_ + kSpacer), - selected_index_(-1) { - DCHECK(model_); -} - -DownloadTabView::~DownloadTabView() { - StopDownloadProgress(); - model_->RemoveObserver(this); - - // DownloadManager owns the contents. - for (OrderedDownloads::iterator it = downloads_.begin(); - it != downloads_.end(); ++it) { - (*it)->RemoveObserver(this); - } - downloads_.clear(); - ClearDownloadInProgress(); - ClearDangerousDownloads(); - - - icon_consumer_.CancelAllRequests(); -} - -void DownloadTabView::Initialize() { - model_->AddObserver(this); -} - -// Start progress animation timers when we get our first (in-progress) download. -void DownloadTabView::StartDownloadProgress() { - if (progress_timer_.IsRunning()) - return; - progress_timer_.Start( - TimeDelta::FromMilliseconds(download_util::kProgressRateMs), this, - &DownloadTabView::UpdateDownloadProgress); -} - -// Stop progress animation when there are no more in-progress downloads. -void DownloadTabView::StopDownloadProgress() { - progress_timer_.Stop(); -} - -// Update our animations. -void DownloadTabView::UpdateDownloadProgress() { - start_angle_ = (start_angle_ + download_util::kUnknownIncrementDegrees) % - download_util::kMaxDegrees; - SchedulePaint(); -} - -void DownloadTabView::Layout() { - DetachAllFloatingViews(); - // Dangerous downloads items use NativeButtons, so they need to be attached - // as NativeControls are not supported yet in floating views. - gfx::Rect visible_bounds = GetVisibleBounds(); - int row_start = (visible_bounds.y() - kSpacer) / - (big_icon_size_ + kSpacer); - int row_stop = (visible_bounds.y() - kSpacer + visible_bounds.height()) / - (big_icon_size_ + kSpacer); - row_stop = std::min(row_stop, static_cast<int>(downloads_.size()) - 1); - for (int i = row_start; i <= row_stop; ++i) { - // The DownloadManager stores downloads earliest first, but this view - // displays latest first, so adjust the index: - int index = static_cast<int>(downloads_.size()) - 1 - i; - if (downloads_[index]->safety_state() == DownloadItem::DANGEROUS) - ValidateFloatingViewForID(index); - } - View* v = GetParent(); - if (v) { - int h = static_cast<int>(downloads_.size()) * - (big_icon_size_ + kSpacer) + kSpacer; - SetBounds(x(), y(), v->width(), h); - } -} - -// Paint our scrolled region -void DownloadTabView::Paint(ChromeCanvas* canvas) { - views::View::Paint(canvas); - - if (download_util::kBigIconSize == 0 || downloads_.size() == 0) - return; - - SkRect clip; - if (canvas->getClipBounds(&clip)) { - int row_start = (SkScalarRound(clip.fTop) - kSpacer) / - (big_icon_size_ + kSpacer); - int row_stop = - std::min(static_cast<int>(downloads_.size()) - 1, - (SkScalarRound(clip.fBottom) - kSpacer) / - (big_icon_size_ + kSpacer)); - SkRect download_rect; - for (int i = row_start; i <= row_stop; ++i) { - int y = i * (big_icon_size_ + kSpacer) + kSpacer; - if (HasFloatingViewForPoint(0, y)) - continue; - download_rect.set(SkIntToScalar(0), - SkIntToScalar(y), - SkIntToScalar(width()), - SkIntToScalar(y + big_icon_size_)); - if (SkRect::Intersects(clip, download_rect)) { - // The DownloadManager stores downloads earliest first, but this - // view displays latest first, so adjust the index: - int index = static_cast<int>(downloads_.size()) - 1 - i; - download_renderer_.SetModel(downloads_[index], this); - PaintFloatingView(canvas, &download_renderer_, - 0, y, width(), big_icon_size_); - } - } - } -} - -// Draw the DownloadItemTabView for the current position. -bool DownloadTabView::GetFloatingViewIDForPoint(int x, int y, int* id) { - if (y < kSpacer || - y > (kSpacer + big_icon_size_) * static_cast<int>(downloads_.size())) - return false; - - // Are we hovering over a download or the spacer? If we're over the - // download, create a floating view for it. - if ((y - kSpacer) % (big_icon_size_ + kSpacer) < big_icon_size_) { - int row = y / (big_icon_size_ + kSpacer); - *id = static_cast<int>(downloads_.size()) - 1 - row; - return true; - } - return false; -} - -views::View* DownloadTabView::CreateFloatingViewForIndex(int index) { - if (index >= static_cast<int>(downloads_.size())) { - // It's possible that the downloads have been cleared via the "Clear - // Browsing Data" command, so this index is gone. - return NULL; - } - - DownloadItemTabView* dl = new DownloadItemTabView(); - // We attach the view before layout as the Save/Discard buttons are native - // and need to be in the tree hierarchy to compute their preferred size - // correctly. - AttachFloatingView(dl, index); - dl->SetModel(downloads_[index], this); - int row = static_cast<int>(downloads_.size()) - 1 - index; - int y_pos = row * (big_icon_size_ + kSpacer) + kSpacer; - dl->SetBounds(0, y_pos, width(), big_icon_size_); - dl->Layout(); - return dl; -} - -bool DownloadTabView::EnumerateFloatingViews( - views::View::FloatingViewPosition position, - int starting_id, int* id) { - DCHECK(id); - return View::EnumerateFloatingViewsForInterval( - 0, static_cast<int>(downloads_.size()), false, position, starting_id, id); -} - -views::View* DownloadTabView::ValidateFloatingViewForID(int id) { - return CreateFloatingViewForIndex(id); -} - -void DownloadTabView::OnDownloadUpdated(DownloadItem* download) { - switch (download->state()) { - case DownloadItem::COMPLETE: - case DownloadItem::CANCELLED: { - base::hash_set<DownloadItem*>::iterator d = in_progress_.find(download); - if (d != in_progress_.end()) { - // If this is a dangerous download not yet validated by the user, we - // still need to be notified when the validation happens. - if (download->safety_state() != DownloadItem::DANGEROUS) { - (*d)->RemoveObserver(this); - } else { - // Add the download to dangerous_downloads_ so we call RemoveObserver - // on ClearDangerousDownloads(). - dangerous_downloads_.insert(download); - } - in_progress_.erase(d); - } - if (in_progress_.empty()) - StopDownloadProgress(); - LoadIcon(download); - break; - } - case DownloadItem::IN_PROGRESS: { - // If all IN_PROGRESS downloads are paused, don't waste CPU issuing any - // further progress updates until at least one download is active again. - if (download->is_paused()) { - bool continue_update = false; - base::hash_set<DownloadItem*>::iterator it = in_progress_.begin(); - for (; it != in_progress_.end(); ++it) { - if (!(*it)->is_paused()) { - continue_update = true; - break; - } - } - if (!continue_update) - StopDownloadProgress(); - } else { - StartDownloadProgress(); - } - break; - } - case DownloadItem::REMOVING: - // Handled below. - break; - default: - NOTREACHED(); - break; - } - - OrderedDownloads::iterator it = find(downloads_.begin(), - downloads_.end(), - download); - if (it == downloads_.end()) - return; - - const int index = static_cast<int>(it - downloads_.begin()); - DownloadItemTabView* view = - static_cast<DownloadItemTabView*>(RetrieveFloatingViewForID(index)); - if (view) { - if (download->state() != DownloadItem::REMOVING) { - view->Layout(); - SchedulePaintForViewAtIndex(index); - } else if (selected_index_ == index) { - selected_index_ = -1; - } - } -} - -// A download has started or been deleted. Query our DownloadManager for the -// current set of downloads, which will call us back in SetDownloads once it -// has retrieved them. -void DownloadTabView::ModelChanged() { - downloads_.clear(); - ClearDownloadInProgress(); - ClearDangerousDownloads(); - DetachAllFloatingViews(); - - // Issue the query. - model_->GetDownloads(this, search_text_); -} - -void DownloadTabView::SetDownloads(std::vector<DownloadItem*>& downloads) { - // Stop progress timers. - StopDownloadProgress(); - - // Clear out old state and remove self as observer for each download. - downloads_.clear(); - ClearDownloadInProgress(); - ClearDangerousDownloads(); - - // Swap new downloads in. - downloads_.swap(downloads); - sort(downloads_.begin(), downloads_.end(), DownloadItemSorter()); - - // Scan for any in progress downloads and add ourself to them as an observer. - for (OrderedDownloads::iterator it = downloads_.begin(); - it != downloads_.end(); ++it) { - DownloadItem* download = *it; - if (download->state() == DownloadItem::IN_PROGRESS) { - download->AddObserver(this); - in_progress_.insert(download); - } else if (download->safety_state() == DownloadItem::DANGEROUS) { - // We need to be notified when the user validates the dangerous download. - download->AddObserver(this); - dangerous_downloads_.insert(download); - } - } - - // Start any progress timers if required. - if (!in_progress_.empty()) - StartDownloadProgress(); - - // Update the UI. - selected_index_ = -1; - GetParent()->GetParent()->Layout(); - SchedulePaint(); -} - - -// If we have the icon in our cache, then return it. If not, look it up via the -// IconManager. Ignore in progress requests (duplicates). -SkBitmap* DownloadTabView::LookupIcon(DownloadItem* download) { - IconManager* im = g_browser_process->icon_manager(); - // Fast look up. - SkBitmap* icon = im->LookupIcon(download->full_path().ToWStringHack(), - IconLoader::NORMAL); - - // Expensive look up. - if (!icon) - LoadIcon(download); - - return icon; -} - -// Bypass the caches and perform the Icon extraction directly. This is useful in -// the case where the download has completed and we want to re-check the file -// to see if it has an embedded icon (which we couldn't do at download start). -void DownloadTabView::LoadIcon(DownloadItem* download) { - IconManager* im = g_browser_process->icon_manager(); - IconManager::Handle h = - im->LoadIcon(download->full_path().ToWStringHack(), IconLoader::NORMAL, - &icon_consumer_, - NewCallback(this, &DownloadTabView::OnExtractIconComplete)); - icon_consumer_.SetClientData(im, h, download); -} - -void DownloadTabView::ClearDownloadInProgress() { - for (base::hash_set<DownloadItem*>::iterator it = in_progress_.begin(); - it != in_progress_.end(); ++it) - (*it)->RemoveObserver(this); - in_progress_.clear(); -} - -void DownloadTabView::ClearDangerousDownloads() { - base::hash_set<DownloadItem*>::const_iterator it; - for (it = dangerous_downloads_.begin(); - it != dangerous_downloads_.end(); ++it) - (*it)->RemoveObserver(this); - dangerous_downloads_.clear(); -} - -// Check to see if the download is the latest download on a given day. -// We use this to determine when to draw the date next to a particular -// download view: if the DownloadItem is the latest download on a given -// day, the date gets drawn. -bool DownloadTabView::ShouldDrawDateForDownload(DownloadItem* download) { - DCHECK(download); - OrderedDownloads::iterator it = find(downloads_.begin(), - downloads_.end(), - download); - DCHECK(it != downloads_.end()); - const int index = static_cast<int>(it - downloads_.begin()); - - // If download is the last or only download, it draws the date. - if (downloads_.size() - 1 == index) - return true; - - const DownloadItem* next = downloads_[index + 1]; - - Time next_midnight = next->start_time().LocalMidnight(); - Time curr_midnight = download->start_time().LocalMidnight(); - if (next_midnight == curr_midnight) { - // 'next' happened today: let it draw the date so we don't have to. - return false; - } - return true; -} - -int DownloadTabView::GetPageScrollIncrement( - views::ScrollView* scroll_view, bool is_horizontal, - bool is_positive) { - return scroll_helper_.GetPageScrollIncrement(scroll_view, is_horizontal, - is_positive); -} - -int DownloadTabView::GetLineScrollIncrement( - views::ScrollView* scroll_view, bool is_horizontal, - bool is_positive) { - return scroll_helper_.GetLineScrollIncrement(scroll_view, is_horizontal, - is_positive); -} - -void DownloadTabView::ItemBecameSelected(const DownloadItem* download) { - int index = -1; - if (download != NULL) { - OrderedDownloads::const_iterator it = find(downloads_.begin(), - downloads_.end(), - download); - DCHECK(it != downloads_.end()); - index = static_cast<int>(it - downloads_.begin()); - if (index == selected_index_) - return; // Avoid unnecessary paint. - } - - if (selected_index_ >= 0) - SchedulePaintForViewAtIndex(selected_index_); - if (index >= 0) - SchedulePaintForViewAtIndex(index); - selected_index_ = index; -} - -bool DownloadTabView::ItemIsSelected(DownloadItem* download) { - OrderedDownloads::iterator it = find(downloads_.begin(), - downloads_.end(), - download); - if (it != downloads_.end()) - return selected_index_ == static_cast<int>(it - downloads_.begin()); - return false; -} - -void DownloadTabView::SchedulePaintForViewAtIndex(int index) { - int y = GetYPositionForIndex(index); - SchedulePaint(0, y, width(), big_icon_size_); -} - -int DownloadTabView::GetYPositionForIndex(int index) { - int row = static_cast<int>(downloads_.size()) - 1 - index; - return row * (big_icon_size_ + kSpacer) + kSpacer; -} - -void DownloadTabView::SetSearchText(const std::wstring& search_text) { - search_text_ = search_text; - model_->GetDownloads(this, search_text_); -} - -// The 'icon_bitmap' is ignored here, since it is cached by the IconManager. -// When the paint message runs, we'll use the fast IconManager lookup API to -// retrieve it. -void DownloadTabView::OnExtractIconComplete(IconManager::Handle handle, - SkBitmap* icon_bitmap) { - IconManager* im = g_browser_process->icon_manager(); - DownloadItem* download = icon_consumer_.GetClientData(im, handle); - OrderedDownloads::iterator it = find(downloads_.begin(), - downloads_.end(), - download); - if (it != downloads_.end()) { - const int index = static_cast<int>(it - downloads_.begin()); - SchedulePaintForViewAtIndex(index); - } -} - -// DownloadTabUIFactory ------------------------------------------------------ - -class DownloadTabUIFactory : public NativeUIFactory { - public: - DownloadTabUIFactory() {} - virtual ~DownloadTabUIFactory() {} - - virtual NativeUI* CreateNativeUIForURL(const GURL& url, - NativeUIContents* contents) { - return new DownloadTabUI(contents); - } - - private: - DISALLOW_EVIL_CONSTRUCTORS(DownloadTabUIFactory); -}; - -// DownloadTabUI ------------------------------------------------------------- - -DownloadTabUI::DownloadTabUI(NativeUIContents* contents) -#pragma warning(suppress: 4355) // Okay to pass "this" here. - : searchable_container_(this), - download_tab_view_(NULL), - contents_(contents) { - DownloadManager* dlm = contents_->profile()->GetDownloadManager(); - download_tab_view_ = new DownloadTabView(dlm); - searchable_container_.SetContents(download_tab_view_); - download_tab_view_->Initialize(); - - NotificationService* ns = NotificationService::current(); - ns->AddObserver(this, NotificationType::DOWNLOAD_START, - NotificationService::AllSources()); - ns->AddObserver(this, NotificationType::DOWNLOAD_STOP, - NotificationService::AllSources()); - - // Spin the throbber if there are active downloads, since we may have been - // created after the NOTIFY_DOWNLOAD_START was sent. If the download manager - // has not been created, don't bother since it will negatively impact start - // up time with history requests. - Profile* profile = contents_->profile(); - if (profile && - profile->HasCreatedDownloadManager() && - profile->GetDownloadManager()->in_progress_count() > 0) - contents_->SetIsLoading(true, NULL); -} - -DownloadTabUI::~DownloadTabUI() { - NotificationService* ns = NotificationService::current(); - ns->RemoveObserver(this, NotificationType::DOWNLOAD_START, - NotificationService::AllSources()); - ns->RemoveObserver(this, NotificationType::DOWNLOAD_STOP, - NotificationService::AllSources()); -} - -const std::wstring DownloadTabUI::GetTitle() const { - return l10n_util::GetString(IDS_DOWNLOAD_TITLE); -} - -const int DownloadTabUI::GetFavIconID() const { - return IDR_DOWNLOADS_FAVICON; -} - -const int DownloadTabUI::GetSectionIconID() const { - return IDR_DOWNLOADS_SECTION; -} - -const std::wstring DownloadTabUI::GetSearchButtonText() const { - return l10n_util::GetString(IDS_DOWNLOAD_SEARCH_BUTTON); -} - -views::View* DownloadTabUI::GetView() { - return &searchable_container_; -} - -void DownloadTabUI::WillBecomeVisible(NativeUIContents* parent) { - UserMetrics::RecordAction(L"Destination_Downloads", parent->profile()); -} - -void DownloadTabUI::WillBecomeInvisible(NativeUIContents* parent) { -} - -void DownloadTabUI::Navigate(const PageState& state) { - std::wstring search_text; - state.GetProperty(kSearchTextKey, &search_text); - download_tab_view_->SetSearchText(search_text); - searchable_container_.GetSearchField()->SetText(search_text); -} - -bool DownloadTabUI::SetInitialFocus() { - searchable_container_.GetSearchField()->RequestFocus(); - return true; -} - -// static -GURL DownloadTabUI::GetURL() { - std::string spec(NativeUIContents::GetScheme()); - spec.append("://downloads"); - return GURL(spec); -} - -// static -NativeUIFactory* DownloadTabUI::GetNativeUIFactory() { - return new DownloadTabUIFactory(); -} - -void DownloadTabUI::DoSearch(const std::wstring& new_text) { - download_tab_view_->SetSearchText(new_text); - PageState* page_state = contents_->page_state().Copy(); - page_state->SetProperty(kSearchTextKey, new_text); - contents_->SetPageState(page_state); -} - -void DownloadTabUI::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - switch (type.value) { - case NotificationType::DOWNLOAD_START: - case NotificationType::DOWNLOAD_STOP: - DCHECK(profile()->HasCreatedDownloadManager()); - contents_->SetIsLoading( - profile()->GetDownloadManager()->in_progress_count() > 0, - NULL); - break; - default: - break; - } -} diff --git a/chrome/browser/views/download_tab_view.h b/chrome/browser/views/download_tab_view.h deleted file mode 100644 index db6861f..0000000 --- a/chrome/browser/views/download_tab_view.h +++ /dev/null @@ -1,281 +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. - -#ifndef CHROME_BROWSER_VIEWS_DONWLOAD_TAB_VIEW_H__ -#define CHROME_BROWSER_VIEWS_DONWLOAD_TAB_VIEW_H__ - -#include "base/hash_tables.h" -#include "chrome/browser/cancelable_request.h" -#include "chrome/browser/download/download_manager.h" -#include "chrome/browser/download/download_util.h" -#include "chrome/browser/icon_manager.h" -#include "chrome/browser/tab_contents/native_ui_contents.h" -#include "chrome/views/event.h" -#include "chrome/views/label.h" -#include "chrome/views/link.h" -#include "chrome/views/scroll_view.h" - -class DownloadTabView; -class SkBitmap; -class Task; - -namespace base { -class Timer; -} - -class DownloadItemTabView : public views::View, - public views::LinkController, - public views::NativeButton::Listener { - public: - DownloadItemTabView(); - virtual ~DownloadItemTabView(); - - // View overrides - virtual void Layout(); - virtual void Paint(ChromeCanvas* canvas); - void PaintBackground(ChromeCanvas* canvas); - virtual gfx::Size GetPreferredSize(); - virtual bool OnMousePressed(const views::MouseEvent& event); - virtual bool OnMouseDragged(const views::MouseEvent& event); - - // Mode specific layouts - void LayoutDate(); - void LayoutComplete(); - void LayoutCancelled(); - void LayoutInProgress(); - void LayoutPromptDangerousDownload(); - - // LinkController overrides - virtual void LinkActivated(views::Link* source, int event_flags); - - // NativeButton Listener overrides. - virtual void ButtonPressed(views::NativeButton* sender); - - // Used to set our model temporarily during layout and paint operations - void SetModel(DownloadItem* model, DownloadTabView* parent); - -private: - // Our model. - DownloadItem* model_; - - // Containing view. - DownloadTabView* parent_; - - // Whether we are the renderer for floating views. - bool is_floating_view_renderer_; - - // Time display. - views::Label* since_; - views::Label* date_; - - // The name of the file. Clicking this link will open the download. - views::Link* file_name_; - - // The name of the downloaded URL. - views::Label* download_url_; - - // The current status of the download. - views::Label* time_remaining_; - views::Label* download_progress_; - - // The message warning of a dangerous download. - views::Label* dangerous_download_warning_; - - // Actions that can be initiated. - views::Link* pause_; - views::Link* cancel_; - views::Link* show_; - - // The buttons used to prompt the user when a dangerous download has been - // initiated. - views::NativeButton* save_button_; - views::NativeButton* discard_button_; - - DISALLOW_EVIL_CONSTRUCTORS(DownloadItemTabView); -}; - - -// A view that manages each of the individual download views -// (DownloadItemTabView) in the destination tab. -class DownloadTabView : public views::View, - public DownloadItem::Observer, - public DownloadManager::Observer { - public: - DownloadTabView(DownloadManager* model); - ~DownloadTabView(); - - void Initialize(); - - DownloadManager* model() const { return model_; } - - // View overrides - virtual void Layout(); - virtual void Paint(ChromeCanvas* canvas); - virtual bool GetFloatingViewIDForPoint(int x, int y, int* id); - virtual bool EnumerateFloatingViews( - views::View::FloatingViewPosition position, - int starting_id, int* id); - virtual views::View* ValidateFloatingViewForID(int id); - - // DownloadItem::Observer interface - virtual void OnDownloadUpdated(DownloadItem* download); - - // DownloadManager::Observer interface - virtual void ModelChanged(); - virtual void SetDownloads(std::vector<DownloadItem*>& downloads); - - // IconManager callback interface - void OnExtractIconComplete(IconManager::Handle handle, SkBitmap* icon_bitmap); - - // Progress animation task interface and timer management. - void UpdateDownloadProgress(); - void StartDownloadProgress(); - void StopDownloadProgress(); - - // Returns a non owning pointer to an icon in the icon_cache_. If - // that file extension doesn't exist in our cache, we query Windows - // and add it to our cache. Returns NULL if we can't determine the - // icon. - SkBitmap* LookupIcon(DownloadItem* download); - - // Determine if we should draw the date beside a particular download - bool ShouldDrawDateForDownload(DownloadItem* download); - - virtual int GetPageScrollIncrement(views::ScrollView* scroll_view, - bool is_horizontal, bool is_positive); - virtual int GetLineScrollIncrement(views::ScrollView* scroll_view, - bool is_horizontal, bool is_positive); - - int start_angle() const { return start_angle_; } - - // Called by a DownloadItemTabView when it becomes selected. Passing a NULL - // for 'download' causes any selected download to become unselected. - void ItemBecameSelected(const DownloadItem* download); - bool ItemIsSelected(DownloadItem* download); - - // The destination view's search box text has changed. - void SetSearchText(const std::wstring& search_text); - - inline int big_icon_size() const { return big_icon_size_; } - inline int big_icon_offset() const { return big_icon_offset_; } - - private: - // Creates and attaches to the view the floating view at |index|. - views::View* CreateFloatingViewForIndex(int index); - - // Utility functions for operating on DownloadItemTabViews by index. - void SchedulePaintForViewAtIndex(int index); - int GetYPositionForIndex(int index); - - // Initiates an asynchronous icon extraction. - void LoadIcon(DownloadItem* download); - - // Clears the list of "in progress" downloads and removes this DownloadTabView - // from their observer list. - void ClearDownloadInProgress(); - - // Clears the list of dangerous downloads and removes this DownloadTabView - // from their observer list. - void ClearDangerousDownloads(); - - // Our model - DownloadManager* model_; - - // For drawing individual download items - DownloadItemTabView download_renderer_; - - // The current set of visible DownloadItems for this view received from the - // DownloadManager. DownloadManager owns the DownloadItems. The vector is - // kept in order, sorted by ascending start time. - typedef std::vector<DownloadItem*> OrderedDownloads; - OrderedDownloads downloads_; - - // Progress animations - base::RepeatingTimer<DownloadTabView> progress_timer_; - - // Since this view manages the progress animation timers for all the floating - // views, we need to track the current in progress downloads. This container - // does not own the DownloadItems. - base::hash_set<DownloadItem*> in_progress_; - - // Keeps track of the downloads we are an observer for as a consequence of - // being a dangerous download. - base::hash_set<DownloadItem*> dangerous_downloads_; - - // Cache the language specific large icon positional information. - int big_icon_size_; - int big_icon_offset_; - - // Provide a start position for downloads with no known size. - int start_angle_; - - views::FixedRowHeightScrollHelper scroll_helper_; - - // Keep track of the currently selected view, so that we can inform it when - // the user changes the selection. - int selected_index_; - - // Text in the download search box input by the user. - std::wstring search_text_; - - // For requesting icons from the IconManager. - CancelableRequestConsumerT<DownloadItem*, 0> icon_consumer_; - - DISALLOW_EVIL_CONSTRUCTORS(DownloadTabView); -}; - -// DownloadTabUI ------------------------------------------------------------- - -// DownloadTabUI provides the glue to make DownloadTabView available in -// NativeUIContents. - -class DownloadTabUI : public NativeUI, - public SearchableUIContainer::Delegate, - public NotificationObserver { - public: - explicit DownloadTabUI(NativeUIContents* contents); - virtual ~DownloadTabUI(); - - virtual const std::wstring GetTitle() const; - virtual const int GetFavIconID() const; - virtual const int GetSectionIconID() const; - virtual const std::wstring GetSearchButtonText() const; - virtual views::View* GetView(); - virtual void WillBecomeVisible(NativeUIContents* parent); - virtual void WillBecomeInvisible(NativeUIContents* parent); - virtual void Navigate(const PageState& state); - virtual bool SetInitialFocus(); - - // Return the URL that can be used to show this view in a NativeUIContents. - static GURL GetURL(); - - // Return the NativeUIFactory object for application views. This object is - // owned by the caller. - static NativeUIFactory* GetNativeUIFactory(); - - private: - // Sent from the search box, updates the search text appropriately. - virtual void DoSearch(const std::wstring& new_text); - - // NotificationObserver method, updates loading state based on whether - // any downloads are in progress. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - Profile* profile() const { return contents_->profile(); } - - // Our host. - NativeUIContents* contents_; - - // The view we return from GetView. The contents of this is the - // bookmarks_view_ - SearchableUIContainer searchable_container_; - - DownloadTabView* download_tab_view_; - - DISALLOW_EVIL_CONSTRUCTORS(DownloadTabUI); -}; - -#endif // CHROME_BROWSER_VIEWS_DONWLOAD_TAB_VIEW_H__ |