summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/browser_about_handler.cc12
-rw-r--r--chrome/browser/tab_contents/network_status_view.cc320
-rw-r--r--chrome/browser/tab_contents/network_status_view.h117
-rw-r--r--chrome/browser/tab_contents/tab_contents_factory.cc4
-rw-r--r--chrome/browser/tab_contents/tab_contents_type.h1
-rw-r--r--chrome/browser/views/about_network_dialog.cc381
-rw-r--r--chrome/browser/views/about_network_dialog.h65
-rw-r--r--chrome/browser/views/browser_views.vcproj8
-rw-r--r--chrome/views/text_field.cc14
-rw-r--r--chrome/views/text_field.h5
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.