diff options
-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. |