diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-24 02:26:00 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-24 02:26:00 +0000 |
commit | 0afe80d755b899c188313629ea3f45f0fe5be981 (patch) | |
tree | fd2833d7e23ac5ec7ac717741eaa5e03719b43cf | |
parent | 1f8859ad6ec7ea807c0330ddf5559e13be5fb26c (diff) | |
download | chromium_src-0afe80d755b899c188313629ea3f45f0fe5be981.zip chromium_src-0afe80d755b899c188313629ea3f45f0fe5be981.tar.gz chromium_src-0afe80d755b899c188313629ea3f45f0fe5be981.tar.bz2 |
Create a dialog box for the about:network view and kill the tab type.
This adds an AppendText method to the text field view.
The job tracker stuff is just copied from the old network status file.
Review URL: http://codereview.chromium.org/18728
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8604 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser.vcproj | 8 | ||||
-rw-r--r-- | chrome/browser/browser_about_handler.cc | 12 | ||||
-rw-r--r-- | chrome/browser/tab_contents/network_status_view.cc | 320 | ||||
-rw-r--r-- | chrome/browser/tab_contents/network_status_view.h | 117 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_factory.cc | 4 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_type.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/about_network_dialog.cc | 381 | ||||
-rw-r--r-- | chrome/browser/views/about_network_dialog.h | 65 | ||||
-rw-r--r-- | chrome/browser/views/browser_views.vcproj | 8 | ||||
-rw-r--r-- | chrome/views/text_field.cc | 14 | ||||
-rw-r--r-- | chrome/views/text_field.h | 5 |
11 files changed, 481 insertions, 454 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index ac31c0f..c1cbed3 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -2134,14 +2134,6 @@ > </File> <File - RelativePath=".\tab_contents\network_status_view.cc" - > - </File> - <File - RelativePath=".\tab_contents\network_status_view.h" - > - </File> - <File RelativePath=".\tab_contents\page_navigator.h" > </File> diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index d5eadc4..0445fc4 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -30,6 +30,7 @@ #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/ipc_status_view.h" +#include "chrome/browser/views/about_network_dialog.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/l10n_util.h" #include "chrome/common/pref_names.h" @@ -173,9 +174,14 @@ bool BrowserAboutHandler::MaybeHandle(GURL* url, } if (LowerCaseEqualsASCII(url->path(), "network")) { - // about:network doesn't have an internal protocol, so don't modify |url|. - *result_type = TAB_CONTENTS_NETWORK_STATUS_VIEW; - return true; + // Run the dialog. This will re-use the existing one if it's already up. + AboutNetworkDialog::RunDialog(); + + // Navigate the renderer to about:blank. This is kind of stupid but is the + // easiest thing to do in this situation without adding a lot of complexity + // for this developer-only feature. + *url = GURL("about:blank"); + return false; } #ifdef IPC_MESSAGE_LOG_ENABLED diff --git a/chrome/browser/tab_contents/network_status_view.cc b/chrome/browser/tab_contents/network_status_view.cc deleted file mode 100644 index 2061ffe..0000000 --- a/chrome/browser/tab_contents/network_status_view.cc +++ /dev/null @@ -1,320 +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/network_status_view.h" - -#include <stdio.h> - -#include "base/string_util.h" -#include "base/thread.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/views/root_view.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_job.h" - -namespace { -const wchar_t kTitleMsg[] = L"Network Status"; -const wchar_t kStartTrackingMsg[] = L"Start I/O Tracking"; -const wchar_t kStopTrackingMsg[] = L"Stop I/O Tracking"; - -const wchar_t kShowIOStatusMsg[] = L"Show Current I/O Status"; -const wchar_t kClearOutputMsg[] = L"Clear Output"; - -// Returns a string representing the URL, handling the case where the spec -// is invalid. -std::wstring StringForURL(const GURL& url) { - if (url.is_valid()) - return UTF8ToWide(url.spec()); - return UTF8ToWide(url.possibly_invalid_spec()) + L" (invalid)"; -} - -std::wstring URLForJob(URLRequestJob* job) { - URLRequest* request = job->request(); - if (request) - return StringForURL(request->url()); - return std::wstring(L"(orphaned)"); -} - -} // namespace - -NetworkStatusView::NetworkStatusView() - : StatusView(TAB_CONTENTS_NETWORK_STATUS_VIEW) { - tracker_ = new JobTracker(this); -} - -NetworkStatusView::~NetworkStatusView() { - if (monospaced_font_) - DeleteObject(monospaced_font_); - - if (is_tracking_) { - tracker_->StopTracking(); - is_tracking_ = false; - } - - tracker_->DetachView(); -} - -const std::wstring NetworkStatusView::GetDefaultTitle() { - return kTitleMsg; -} - -void NetworkStatusView::OnCreate(const CRect& rect) { - CreateButton(IDC_CONFIG_TRACKING_BUTTON, kStartTrackingMsg); - CreateButton(IDC_CURRENT_STATUS_BUTTON, kShowIOStatusMsg); - CreateButton(IDC_CLEAR, kClearOutputMsg); - - is_tracking_ = false; - - // Initialize the text box for network tracking - // Don't worry about the size, we'll resize when we get WM_SIZE - text_area_.Create(m_hWnd, const_cast<CRect&>(rect), NULL, - WS_CHILD | WS_HSCROLL | WS_VSCROLL | - ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); - - // This raises the maximum number of chars from 32K to some large maximum, - // probably 2GB. 32K is not nearly enough for our use-case. - text_area_.SendMessageW(EM_SETLIMITTEXT, 0, 0); - - // make a monospaced font for the edit control - LOGFONT lf = {0}; - lf.lfHeight = 16; - wcscpy_s(lf.lfFaceName, LF_FACESIZE, L"Courier New"); - monospaced_font_ = CreateFontIndirect(&lf); - text_area_.SetFont(monospaced_font_); -} - -void NetworkStatusView::OnSize(const CRect& rect) { - // re-layout the edit control - text_area_.MoveWindow(rect); - - // re-layout the performance view - CRect new_rect(rect); - int list_width = rect.Width(); - int list_height = static_cast<int>(rect.Height() / 5); - int page_width = rect.Width() / 2; - int page_height = static_cast<int>(rect.Height() * 4 / 5); -} - -void NetworkStatusView::OnConfigTrackingClicked(UINT code, int button_id, - HWND hwnd) { - if (is_tracking_) { - tracker_->StopTracking(); - is_tracking_ = false; - - SetButtonText(IDC_CONFIG_TRACKING_BUTTON, kStartTrackingMsg); - } else { - tracker_->StartTracking(); - is_tracking_ = true; - - ClearTrackingResults(); - ShowTrackingResults(); - - SetButtonText(IDC_CONFIG_TRACKING_BUTTON, kStopTrackingMsg); - } -} - -void NetworkStatusView::OnCurrentStatusClicked(UINT code, int button_id, - HWND hwnd) { - ShowTrackingResults(); - if (is_tracking_) { - tracker_->ReportStatus(); - } -} - -void NetworkStatusView::OnClearClicked(UINT code, int button_id, HWND hwnd) { - ClearTrackingResults(); -} - -void NetworkStatusView::AppendText(const std::wstring& text) { - text_area_.AppendText(text.c_str()); -} - -void NetworkStatusView::HideTrackingResults() { - text_area_.ShowWindow(SW_HIDE); -} - -void NetworkStatusView::ShowTrackingResults() { - text_area_.ShowWindow(SW_SHOW); -} - -void NetworkStatusView::ClearTrackingResults() { - text_area_.SetSelAll(); - text_area_.Clear(); -} - -//----------------------------------------------------------------------------- - -// main thread: -NetworkStatusView::JobTracker::JobTracker(NetworkStatusView* view) - : view_(view), - view_message_loop_(MessageLoop::current()) { -} - -// main thread: -void NetworkStatusView::JobTracker::InvokeOnIOThread(void (JobTracker::*m)()) { - base::Thread* thread = g_browser_process->io_thread(); - if (!thread) - return; - thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, m)); -} - -// main thread: -void NetworkStatusView::JobTracker::StartTracking() { - DCHECK(MessageLoop::current() == view_message_loop_); - DCHECK(view_); - InvokeOnIOThread(&JobTracker::OnStartTracking); -} - -// main thread: -void NetworkStatusView::JobTracker::StopTracking() { - DCHECK(MessageLoop::current() == view_message_loop_); - // The tracker should not be deleted before it is removed from observer - // list. - AddRef(); - InvokeOnIOThread(&JobTracker::OnStopTracking); -} - -// main thread: -void NetworkStatusView::JobTracker::ReportStatus() { - DCHECK(MessageLoop::current() == view_message_loop_); - InvokeOnIOThread(&JobTracker::OnReportStatus); -} - -// main thread: -void NetworkStatusView::JobTracker::OnAppendText(const std::wstring& text) { - DCHECK(MessageLoop::current() == view_message_loop_); - if (view_ && view_->is_tracking_) - view_->AppendText(text); -} - -// IO thread: -void NetworkStatusView::JobTracker::AppendText(const std::wstring& text) { - DCHECK(MessageLoop::current() != view_message_loop_); - view_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &JobTracker::OnAppendText, text)); -} - -// IO thread: -void NetworkStatusView::JobTracker::OnStartTracking() { - DCHECK(MessageLoop::current() != view_message_loop_); - g_url_request_job_tracker.AddObserver(this); -} - -// IO thread: -void NetworkStatusView::JobTracker::OnStopTracking() { - DCHECK(MessageLoop::current() != view_message_loop_); - g_url_request_job_tracker.RemoveObserver(this); - // Balance the AddRef() in StopTracking() called in main thread. - Release(); -} - -// IO thread: -void NetworkStatusView::JobTracker::OnReportStatus() { - DCHECK(MessageLoop::current() != view_message_loop_); - - std::wstring text(L"\r\n===== Active Job Summary =====\r\n"); - - URLRequestJobTracker::JobIterator begin_job = - g_url_request_job_tracker.begin(); - URLRequestJobTracker::JobIterator end_job = g_url_request_job_tracker.end(); - int orphaned_count = 0; - int regular_count = 0; - for (URLRequestJobTracker::JobIterator cur = begin_job; - cur != end_job; ++cur) { - URLRequestJob* job = (*cur); - URLRequest* request = job->request(); - if (!request) { - orphaned_count++; - continue; - } - - regular_count++; - - // active state - if (job->is_done()) - text.append(L" Done: "); - else - text.append(L" Active: "); - - // URL - text.append(StringForURL(request->url())); - text.append(L"\r\n"); - } - - if (regular_count == 0) - text.append(L" (No active jobs)\r\n"); - - if (orphaned_count) { - wchar_t buf[64]; - swprintf(buf, arraysize(buf), L" %d orphaned jobs\r\n", orphaned_count); - text.append(buf); - } - - text.append(L"=====\r\n\r\n"); - AppendText(text); -} - -// IO thread: -void NetworkStatusView::JobTracker::OnJobAdded(URLRequestJob* job) { - DCHECK(MessageLoop::current() != view_message_loop_); - - std::wstring text(L"+ New job : "); - text.append(URLForJob(job)); - text.append(L"\r\n"); - AppendText(text); -} - -// IO thread: -void NetworkStatusView::JobTracker::OnJobRemoved(URLRequestJob* job) { - DCHECK(MessageLoop::current() != view_message_loop_); -} - -// IO thread: -void NetworkStatusView::JobTracker::OnJobDone(URLRequestJob* job, - const URLRequestStatus& status) { - DCHECK(MessageLoop::current() != view_message_loop_); - - std::wstring text; - if (status.is_success()) { - text.assign(L"- Complete: "); - } else if (status.status() == URLRequestStatus::CANCELED) { - text.assign(L"- Canceled: "); - } else if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) { - text.assign(L"- Handled externally: "); - } else { - wchar_t buf[32]; - swprintf(buf, arraysize(buf), L"Failed with %d: ", status.os_error()); - text.assign(buf); - } - - text.append(URLForJob(job)); - text.append(L"\r\n"); - AppendText(text); -} - -// IO thread: -void NetworkStatusView::JobTracker::OnJobRedirect(URLRequestJob* job, - const GURL& location, - int status_code) { - DCHECK(MessageLoop::current() != view_message_loop_); - - std::wstring text(L"- Redirect: "); - text.append(URLForJob(job)); - text.append(L"\r\n "); - - wchar_t buf[16]; - swprintf(buf, arraysize(buf), L"(%d) to: ", status_code); - text.append(buf); - - text.append(StringForURL(location)); - text.append(L"\r\n"); - AppendText(text); -} - -void NetworkStatusView::JobTracker::OnBytesRead(URLRequestJob* job, - int byte_count) { -} - diff --git a/chrome/browser/tab_contents/network_status_view.h b/chrome/browser/tab_contents/network_status_view.h deleted file mode 100644 index b98a25a..0000000 --- a/chrome/browser/tab_contents/network_status_view.h +++ /dev/null @@ -1,117 +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_NETWORK_STATUS_VIEW_H_ -#define CHROME_BROWSER_TAB_CONTENTS_NETWORK_STATUS_VIEW_H_ - -#include "base/basictypes.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "chrome/common/render_messages.h" -#include "chrome/browser/tab_contents/status_view.h" -#include "net/url_request/url_request_job_tracker.h" - -class MessageLoop; -class RenderProcessHost; -class NavigationPerformanceViewer; -class PageLoadView; - -class NetworkStatusView : public StatusView { - public: - // button types - enum { - IDC_CONFIG_TRACKING_BUTTON = 101, - IDC_CURRENT_STATUS_BUTTON, - IDC_CLEAR, - }; - - NetworkStatusView(); - virtual ~NetworkStatusView(); - - // TabContents overrides - virtual const std::wstring GetDefaultTitle(); - - // StatusView implementation - virtual void OnCreate(const CRect& rect); - virtual void OnSize(const CRect& rect); - - BEGIN_MSG_MAP(NetworkStatusView) - COMMAND_HANDLER_EX(IDC_CONFIG_TRACKING_BUTTON, BN_CLICKED, OnConfigTrackingClicked) - COMMAND_HANDLER_EX(IDC_CURRENT_STATUS_BUTTON, BN_CLICKED, OnCurrentStatusClicked) - COMMAND_HANDLER_EX(IDC_CLEAR, BN_CLICKED, OnClearClicked) - CHAIN_MSG_MAP(StatusView); - END_MSG_MAP() - - bool is_tracking() const { return is_tracking_; } - - private: - - // Event handlers - void OnConfigTrackingClicked(UINT code, int button_id, HWND hwnd); - void OnCurrentStatusClicked(UINT code, int button_id, HWND hwnd); - void OnClearClicked(UINT code, int button_id, HWND hwnd); - - void AppendText(const std::wstring& text); - - // Hide/Show tracking output window - void HideTrackingResults(); - void ShowTrackingResults(); - - // Clear tracking output - void ClearTrackingResults(); - - // A JobTracker is allocated to monitor network jobs running on the IO - // thread. This allows the NetworkStatusView to remain single-threaded. - class JobTracker : public URLRequestJobTracker::JobObserver, - public base::RefCountedThreadSafe<JobTracker> { - public: - JobTracker(NetworkStatusView* view); - - // Called by the NetworkStatusView on the main application thread. - void StartTracking(); - void StopTracking(); - void ReportStatus(); - - // URLRequestJobTracker::JobObserver methods (called on the IO thread): - virtual void OnJobAdded(URLRequestJob* job); - virtual void OnJobRemoved(URLRequestJob* job); - virtual void OnJobDone(URLRequestJob* job, const URLRequestStatus& status); - virtual void OnJobRedirect(URLRequestJob* job, const GURL& location, - int status_code); - virtual void OnBytesRead(URLRequestJob* job, int byte_count); - - // The JobTracker may be deleted after NetworkStatusView is deleted. - void DetachView() { view_ = NULL; } - - private: - void InvokeOnIOThread(void (JobTracker::*method)()); - - // Called on the IO thread - void OnStartTracking(); - void OnStopTracking(); - void OnReportStatus(); - void AppendText(const std::wstring& text); - - // Called on the main thread - void OnAppendText(const std::wstring& text); - - NetworkStatusView* view_; - MessageLoop* view_message_loop_; - }; - friend class JobTracker; - - scoped_refptr<JobTracker> tracker_; - - bool is_tracking_; - - // Textual output of network tracking - CEdit text_area_; - - HFONT monospaced_font_; - - DISALLOW_COPY_AND_ASSIGN(NetworkStatusView); -}; - -#endif // #ifndef CHROME_BROWSER_TAB_CONTENTS_NETWORK_STATUS_VIEW_H_ - diff --git a/chrome/browser/tab_contents/tab_contents_factory.cc b/chrome/browser/tab_contents/tab_contents_factory.cc index 8e87af9..2367592 100644 --- a/chrome/browser/tab_contents/tab_contents_factory.cc +++ b/chrome/browser/tab_contents/tab_contents_factory.cc @@ -13,7 +13,6 @@ #include "chrome/browser/debugger/debugger_contents.h" #include "chrome/browser/tab_contents/ipc_status_view.h" #include "chrome/browser/tab_contents/native_ui_contents.h" -#include "chrome/browser/tab_contents/network_status_view.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_factory.h" #include "chrome/browser/tab_contents/view_source_contents.h" @@ -45,9 +44,6 @@ TabContents* TabContents::CreateWithType(TabContentsType type, case TAB_CONTENTS_WEB: contents = new WebContents(profile, instance, NULL, MSG_ROUTING_NONE, NULL); break; - case TAB_CONTENTS_NETWORK_STATUS_VIEW: - contents = new NetworkStatusView(); - break; #ifdef IPC_MESSAGE_LOG_ENABLED case TAB_CONTENTS_IPC_STATUS_VIEW: contents = new IPCStatusView(); diff --git a/chrome/browser/tab_contents/tab_contents_type.h b/chrome/browser/tab_contents/tab_contents_type.h index 9dc3e0b..73fc81f 100644 --- a/chrome/browser/tab_contents/tab_contents_type.h +++ b/chrome/browser/tab_contents/tab_contents_type.h @@ -13,7 +13,6 @@ enum TabContentsType { TAB_CONTENTS_UNKNOWN_TYPE = 0, TAB_CONTENTS_WEB, TAB_CONTENTS_DOWNLOAD_VIEW, - TAB_CONTENTS_NETWORK_STATUS_VIEW, TAB_CONTENTS_IPC_STATUS_VIEW, TAB_CONTENTS_CHROME_VIEW_CONTENTS, TAB_CONTENTS_NEW_TAB_UI, diff --git a/chrome/browser/views/about_network_dialog.cc b/chrome/browser/views/about_network_dialog.cc new file mode 100644 index 0000000..a1af274 --- /dev/null +++ b/chrome/browser/views/about_network_dialog.cc @@ -0,0 +1,381 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/about_network_dialog.h" + +#include "base/string_util.h" +#include "base/thread.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/views/standard_layout.h" +#include "chrome/views/grid_layout.h" +#include "chrome/views/text_button.h" +#include "chrome/views/text_field.h" +#include "chrome/views/window.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_job.h" +#include "net/url_request/url_request_job_tracker.h" + +namespace { + +// We don't localize this UI since this is a developer-only feature. +const wchar_t kStartTrackingLabel[] = L"Start tracking"; +const wchar_t kStopTrackingLabel[] = L"Stop tracking"; +const wchar_t kShowCurrentLabel[] = L"Show Current"; +const wchar_t kClearLabel[] = L"Clear"; + +// The singleton dialog box. This is non-NULL when a dialog is active so we +// know not to create a new one. +AboutNetworkDialog* active_dialog = NULL; + +// Returns a string representing the URL, handling the case where the spec +// is invalid. +std::wstring StringForURL(const GURL& url) { + if (url.is_valid()) + return UTF8ToWide(url.spec()); + return UTF8ToWide(url.possibly_invalid_spec()) + L" (invalid)"; +} + +std::wstring URLForJob(URLRequestJob* job) { + URLRequest* request = job->request(); + if (request) + return StringForURL(request->url()); + return std::wstring(L"(orphaned)"); +} + +// JobTracker ------------------------------------------------------------------ + +// A JobTracker is allocated to monitor network jobs running on the IO +// thread. This allows the NetworkStatusView to remain single-threaded. +class JobTracker : public URLRequestJobTracker::JobObserver, + public base::RefCountedThreadSafe<JobTracker> { + public: + JobTracker(AboutNetworkDialog* view); + ~JobTracker(); + + // Called by the NetworkStatusView on the main application thread. + void StartTracking(); + void StopTracking(); + void ReportStatus(); + + // URLRequestJobTracker::JobObserver methods (called on the IO thread): + virtual void OnJobAdded(URLRequestJob* job); + virtual void OnJobRemoved(URLRequestJob* job); + virtual void OnJobDone(URLRequestJob* job, const URLRequestStatus& status); + virtual void OnJobRedirect(URLRequestJob* job, const GURL& location, + int status_code); + virtual void OnBytesRead(URLRequestJob* job, int byte_count); + + // The JobTracker may be deleted after NetworkStatusView is deleted. + void DetachView() { view_ = NULL; } + + private: + void InvokeOnIOThread(void (JobTracker::*method)()); + + // Called on the IO thread + void OnStartTracking(); + void OnStopTracking(); + void OnReportStatus(); + void AppendText(const std::wstring& text); + + // Called on the main thread + void OnAppendText(const std::wstring& text); + + AboutNetworkDialog* view_; + MessageLoop* view_message_loop_; +}; + +// main thread: +JobTracker::JobTracker(AboutNetworkDialog* view) + : view_(view), + view_message_loop_(MessageLoop::current()) { +} + +JobTracker::~JobTracker() { +} + +// main thread: +void JobTracker::InvokeOnIOThread(void (JobTracker::*m)()) { + base::Thread* thread = g_browser_process->io_thread(); + if (!thread) + return; + thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, m)); +} + +// main thread: +void JobTracker::StartTracking() { + DCHECK(MessageLoop::current() == view_message_loop_); + DCHECK(view_); + InvokeOnIOThread(&JobTracker::OnStartTracking); +} + +// main thread: +void JobTracker::StopTracking() { + DCHECK(MessageLoop::current() == view_message_loop_); + // The tracker should not be deleted before it is removed from observer + // list. + AddRef(); + InvokeOnIOThread(&JobTracker::OnStopTracking); +} + +// main thread: +void JobTracker::ReportStatus() { + DCHECK(MessageLoop::current() == view_message_loop_); + InvokeOnIOThread(&JobTracker::OnReportStatus); +} + +// main thread: +void JobTracker::OnAppendText(const std::wstring& text) { + DCHECK(MessageLoop::current() == view_message_loop_); + if (view_ && view_->tracking()) + view_->AppendText(text); +} + +// IO thread: +void JobTracker::AppendText(const std::wstring& text) { + DCHECK(MessageLoop::current() != view_message_loop_); + view_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &JobTracker::OnAppendText, text)); +} + +// IO thread: +void JobTracker::OnStartTracking() { + DCHECK(MessageLoop::current() != view_message_loop_); + g_url_request_job_tracker.AddObserver(this); +} + +// IO thread: +void JobTracker::OnStopTracking() { + DCHECK(MessageLoop::current() != view_message_loop_); + g_url_request_job_tracker.RemoveObserver(this); + // Balance the AddRef() in StopTracking() called in main thread. + Release(); +} + +// IO thread: +void JobTracker::OnReportStatus() { + DCHECK(MessageLoop::current() != view_message_loop_); + + std::wstring text(L"\r\n===== Active Job Summary =====\r\n"); + + URLRequestJobTracker::JobIterator begin_job = + g_url_request_job_tracker.begin(); + URLRequestJobTracker::JobIterator end_job = g_url_request_job_tracker.end(); + int orphaned_count = 0; + int regular_count = 0; + for (URLRequestJobTracker::JobIterator cur = begin_job; + cur != end_job; ++cur) { + URLRequestJob* job = (*cur); + URLRequest* request = job->request(); + if (!request) { + orphaned_count++; + continue; + } + + regular_count++; + + // active state + if (job->is_done()) + text.append(L" Done: "); + else + text.append(L" Active: "); + + // URL + text.append(StringForURL(request->url())); + text.append(L"\r\n"); + } + + if (regular_count == 0) + text.append(L" (No active jobs)\r\n"); + + if (orphaned_count) { + wchar_t buf[64]; + swprintf(buf, arraysize(buf), L" %d orphaned jobs\r\n", orphaned_count); + text.append(buf); + } + + text.append(L"=====\r\n\r\n"); + AppendText(text); +} + +// IO thread: +void JobTracker::OnJobAdded(URLRequestJob* job) { + DCHECK(MessageLoop::current() != view_message_loop_); + + std::wstring text(L"+ New job : "); + text.append(URLForJob(job)); + text.append(L"\r\n"); + AppendText(text); +} + +// IO thread: +void JobTracker::OnJobRemoved(URLRequestJob* job) { + DCHECK(MessageLoop::current() != view_message_loop_); +} + +// IO thread: +void JobTracker::OnJobDone(URLRequestJob* job, + const URLRequestStatus& status) { + DCHECK(MessageLoop::current() != view_message_loop_); + + std::wstring text; + if (status.is_success()) { + text.assign(L"- Complete: "); + } else if (status.status() == URLRequestStatus::CANCELED) { + text.assign(L"- Canceled: "); + } else if (status.status() == URLRequestStatus::HANDLED_EXTERNALLY) { + text.assign(L"- Handled externally: "); + } else { + wchar_t buf[32]; + swprintf(buf, arraysize(buf), L"Failed with %d: ", status.os_error()); + text.assign(buf); + } + + text.append(URLForJob(job)); + text.append(L"\r\n"); + AppendText(text); +} + +// IO thread: +void JobTracker::OnJobRedirect(URLRequestJob* job, + const GURL& location, + int status_code) { + DCHECK(MessageLoop::current() != view_message_loop_); + + std::wstring text(L"- Redirect: "); + text.append(URLForJob(job)); + text.append(L"\r\n "); + + wchar_t buf[16]; + swprintf(buf, arraysize(buf), L"(%d) to: ", status_code); + text.append(buf); + + text.append(StringForURL(location)); + text.append(L"\r\n"); + AppendText(text); +} + +void JobTracker::OnBytesRead(URLRequestJob* job, int byte_count) { +} + +// The singleton job tracker associated with the dialog. +JobTracker* tracker = NULL; + +} // namespace + +// AboutNetworkDialog ---------------------------------------------------------- + +AboutNetworkDialog::AboutNetworkDialog() : tracking_(false) { + SetupControls(); + tracker = new JobTracker(this); + tracker->AddRef(); +} + +AboutNetworkDialog::~AboutNetworkDialog() { + active_dialog = NULL; + tracker->Release(); + tracker = NULL; +} + +// static +void AboutNetworkDialog::RunDialog() { + if (!active_dialog) { + active_dialog = new AboutNetworkDialog; + views::Window::CreateChromeWindow(NULL, gfx::Rect(), active_dialog)->Show(); + } else { + // TOOD(brettw) it would be nice to focus the existing window. + } +} + +void AboutNetworkDialog::AppendText(const std::wstring& text) { + text_field_->AppendText(text); +} + +void AboutNetworkDialog::SetupControls() { + views::GridLayout* layout = CreatePanelGridLayout(this); + SetLayoutManager(layout); + + track_toggle_ = new views::TextButton(kStartTrackingLabel); + track_toggle_->SetListener(this, 1); + show_button_ = new views::TextButton(kShowCurrentLabel); + show_button_->SetListener(this, 2); + clear_button_ = new views::TextButton(kClearLabel); + clear_button_->SetListener(this, 3); + + text_field_ = new views::TextField(static_cast<views::TextField::StyleFlags>( + views::TextField::STYLE_MULTILINE)); + text_field_->SetReadOnly(true); + + // TODO(brettw): We may want to add this in the future. It can't be called + // from here, though, since the hwnd for the field hasn't been created yet. + // + // This raises the maximum number of chars from 32K to some large maximum, + // probably 2GB. 32K is not nearly enough for our use-case. + //SendMessageW(text_field_->GetNativeComponent(), EM_SETLIMITTEXT, 0, 0); + + static const int first_column_set = 1; + views::ColumnSet* column_set = layout->AddColumnSet(first_column_set); + column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 33.33f, views::GridLayout::FIXED, 0, 0); + column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 33.33f, views::GridLayout::FIXED, 0, 0); + column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 33.33f, views::GridLayout::FIXED, 0, 0); + + static const int text_column_set = 2; + column_set = layout->AddColumnSet(text_column_set); + column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 100.0f, + views::GridLayout::FIXED, 0, 0); + + layout->StartRow(0, first_column_set); + layout->AddView(track_toggle_); + layout->AddView(show_button_); + layout->AddView(clear_button_); + layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + layout->StartRow(1.0f, text_column_set); + layout->AddView(text_field_); +} + +gfx::Size AboutNetworkDialog::GetPreferredSize() { + return gfx::Size(800, 400); +} + +views::View* AboutNetworkDialog::GetContentsView() { + return this; +} + +int AboutNetworkDialog::GetDialogButtons() const { + // Don't want OK or Cancel. + return 0; +} + +std::wstring AboutNetworkDialog::GetWindowTitle() const { + return L"about:network"; +} + +void AboutNetworkDialog::Layout() { + GetLayoutManager()->Layout(this); +} + +bool AboutNetworkDialog::CanResize() const { + return true; +} + +void AboutNetworkDialog::ButtonPressed(views::BaseButton* button) { + if (button == track_toggle_) { + if (tracking_) { + track_toggle_->SetText(kStartTrackingLabel); + tracking_ = false; + tracker->StopTracking(); + } else { + track_toggle_->SetText(kStopTrackingLabel); + tracking_ = true; + tracker->StartTracking(); + } + track_toggle_->SchedulePaint(); + } else if (button == show_button_) { + tracker->ReportStatus(); + } else if (button == clear_button_) { + text_field_->SetText(std::wstring()); + } +} diff --git a/chrome/browser/views/about_network_dialog.h b/chrome/browser/views/about_network_dialog.h new file mode 100644 index 0000000..a9dd2cc --- /dev/null +++ b/chrome/browser/views/about_network_dialog.h @@ -0,0 +1,65 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VIEWS_ABOUT_NETWORK_DIALOG_H_ +#define CHROME_BROWSER_VIEWS_ABOUT_NETWORK_DIALOG_H_ + +#include "base/singleton.h" +#include "chrome/views/base_button.h" +#include "chrome/views/dialog_delegate.h" + +namespace views { +class TextButton; +class TextField; +} // namespace views + +class AboutNetworkDialog : public views::DialogDelegate, + public views::BaseButton::ButtonListener, + public views::View { + public: + // This dialog is a singleton. If the dialog is already opened, it won't do + // anything, so you can just blindly call this function all you want. + static void RunDialog(); + + virtual ~AboutNetworkDialog(); + + // Appends the given string to the dialog box. This is called by the job + // tracker (see the .cc file) when "stuff happens." + void AppendText(const std::wstring& text); + + // Returns true if we're currently tracking network operations. + bool tracking() const { return tracking_; } + + private: + friend struct DefaultSingletonTraits<AboutNetworkDialog>; + + AboutNetworkDialog(); + + // Sets up all UI controls for the dialog. + void SetupControls(); + + virtual gfx::Size GetPreferredSize(); + virtual views::View* GetContentsView(); + virtual int GetDialogButtons() const; + virtual std::wstring GetWindowTitle() const; + virtual void Layout(); + + // views::WindowDelegate (via view::DialogDelegate). + virtual bool CanResize() const; + + // views::BaseButton::ButtonListener. + virtual void ButtonPressed(views::BaseButton* button); + + views::TextButton* track_toggle_; + views::TextButton* show_button_; + views::TextButton* clear_button_; + views::TextField* text_field_; + + // Set to true when we're tracking network status. + bool tracking_; + + DISALLOW_COPY_AND_ASSIGN(AboutNetworkDialog); +}; + +#endif // CHROME_BROWSER_VIEWS_ABOUT_NETWORK_DIALOG_H_ diff --git a/chrome/browser/views/browser_views.vcproj b/chrome/browser/views/browser_views.vcproj index 97a98c2..825d0cc 100644 --- a/chrome/browser/views/browser_views.vcproj +++ b/chrome/browser/views/browser_views.vcproj @@ -370,6 +370,14 @@ > </File> <File + RelativePath=".\about_network_dialog.cc" + > + </File> + <File + RelativePath=".\about_network_dialog.h" + > + </File> + <File RelativePath=".\blocked_popup_container.cc" > </File> diff --git a/chrome/views/text_field.cc b/chrome/views/text_field.cc index 62ebdc8..79ee7b9 100644 --- a/chrome/views/text_field.cc +++ b/chrome/views/text_field.cc @@ -47,6 +47,7 @@ class TextField::Edit std::wstring GetText() const; void SetText(const std::wstring& text); + void AppendText(const std::wstring& text); std::wstring GetSelectedText() const; @@ -315,6 +316,13 @@ void TextField::Edit::SetText(const std::wstring& text) { SetWindowText(text_to_set.c_str()); } +void TextField::Edit::AppendText(const std::wstring& text) { + int text_length = GetWindowTextLength(); + ::SendMessage(m_hWnd, TBM_SETSEL, true, MAKELPARAM(text_length, text_length)); + ::SendMessage(m_hWnd, EM_REPLACESEL, false, + reinterpret_cast<LPARAM>(text.c_str())); +} + std::wstring TextField::Edit::GetSelectedText() const { // Figure out the length of the selection. long start; @@ -953,6 +961,12 @@ void TextField::SetText(const std::wstring& text) { edit_->SetText(text); } +void TextField::AppendText(const std::wstring& text) { + text_ += text; + if (edit_) + edit_->AppendText(text); +} + void TextField::CalculateInsets(gfx::Insets* insets) { DCHECK(insets); diff --git a/chrome/views/text_field.h b/chrome/views/text_field.h index 4fa876c..9fe0347 100644 --- a/chrome/views/text_field.h +++ b/chrome/views/text_field.h @@ -97,9 +97,12 @@ class TextField : public View { // Returns the text currently displayed in the text field. std::wstring GetText() const; - // Set the text currently displayed in the text field. + // Sets the text currently displayed in the text field. void SetText(const std::wstring& text); + // Appends the given string to the previously-existing text in the field. + void AppendText(const std::wstring& text); + virtual void Focus(); // Causes the edit field to be fully selected. |