summaryrefslogtreecommitdiffstats
path: root/chrome/browser/external_tab_container.cc
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-26 23:55:29 +0000
commit09911bf300f1a419907a9412154760efd0b7abc3 (patch)
treef131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/external_tab_container.cc
parent586acc5fe142f498261f52c66862fa417c3d52d2 (diff)
downloadchromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz
chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/external_tab_container.cc')
-rw-r--r--chrome/browser/external_tab_container.cc334
1 files changed, 334 insertions, 0 deletions
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc
new file mode 100644
index 0000000..4ec21f6
--- /dev/null
+++ b/chrome/browser/external_tab_container.cc
@@ -0,0 +1,334 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/browser/external_tab_container.h"
+
+#include "base/logging.h"
+#include "chrome/browser/automation/automation_provider.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/tab_contents_container_view.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/win_util.h"
+#include "chrome/views/hwnd_view_container.h"
+#include "chrome/test/automation/automation_messages.h"
+
+static const wchar_t kWindowObjectKey[] = L"ChromeWindowObject";
+
+// TODO(sanjeevr): The external_accel_table_ and external_accel_entry_count_
+// member variables are now obsolete and we don't use them.
+// We need to remove them.
+ExternalTabContainer::ExternalTabContainer(
+ AutomationProvider* automation)
+ : automation_(automation),
+ root_view_(this, true),
+ tab_contents_(NULL),
+ external_accel_table_(NULL),
+ external_accel_entry_count_(0),
+ tab_contents_container_(NULL) {
+}
+
+ExternalTabContainer::~ExternalTabContainer() {
+}
+
+bool ExternalTabContainer::Init(Profile* profile) {
+ if (IsWindow()) {
+ NOTREACHED();
+ return false;
+ }
+ // First create the container window
+ if (!Create(NULL)) {
+ NOTREACHED();
+ return false;
+ }
+
+ // We don't ever remove the prop because the lifetime of this object
+ // is the same as the lifetime of the window
+ SetProp(*this, kWindowObjectKey, this);
+
+ ChromeViews::SetRootViewForHWND(m_hWnd, &root_view_);
+ // CreateFocusManager will subclass this window and delete the FocusManager
+ // instance when this window goes away.
+ ChromeViews::FocusManager* focus_manager =
+ ChromeViews::FocusManager::CreateFocusManager(m_hWnd, GetRootView());
+ DCHECK(focus_manager);
+ focus_manager->AddKeystrokeListener(this);
+ tab_contents_ = TabContents::CreateWithType(TAB_CONTENTS_WEB,
+ m_hWnd, profile, NULL);
+ if (!tab_contents_) {
+ NOTREACHED();
+ DestroyWindow();
+ return false;
+ }
+ tab_contents_->SetupController(profile);
+ tab_contents_->set_delegate(this);
+ // Create a TabContentsContainerView to handle focus cycling using Tab and
+ // Shift-Tab.
+ // TODO(sanjeevr): We need to create a dummy FocusTraversable object to
+ // represent the frame of the external host. This will allow Tab and
+ // Shift-Tab to cycle into the external frame.
+ tab_contents_container_ = new TabContentsContainerView();
+ root_view_.AddChildView(tab_contents_container_);
+ tab_contents_container_->SetTabContents(tab_contents_);
+
+ NavigationController* controller = tab_contents_->controller();
+ DCHECK(controller);
+ NotificationService::current()->
+ Notify(NOTIFY_EXTERNAL_TAB_CREATED,
+ Source<NavigationController>(controller),
+ NotificationService::NoDetails());
+ ::ShowWindow(tab_contents_->GetContainerHWND(), SW_SHOW);
+ return true;
+}
+
+void ExternalTabContainer::OnDestroy() {
+ ChromeViews::FocusManager * focus_manager =
+ ChromeViews::FocusManager::GetFocusManager(GetHWND());
+ if (focus_manager) {
+ focus_manager->RemoveKeystrokeListener(this);
+ }
+ root_view_.RemoveAllChildViews(true);
+ if (tab_contents_) {
+ NavigationController* controller = tab_contents_->controller();
+ DCHECK(controller);
+
+ NotificationService::current()->
+ Notify(NOTIFY_EXTERNAL_TAB_CLOSED,
+ Source<NavigationController>(controller),
+ Details<ExternalTabContainer>(this));
+ tab_contents_->set_delegate(NULL);
+ tab_contents_->CloseContents();
+ // WARNING: tab_contents_ has likely been deleted.
+ tab_contents_ = NULL;
+ }
+}
+
+void ExternalTabContainer::OnFinalMessage(HWND window) {
+ delete this;
+}
+
+LRESULT ExternalTabContainer::OnSize(UINT, WPARAM, LPARAM, BOOL& handled) {
+ if (tab_contents_) {
+ RECT client_rect = {0};
+ GetClientRect(&client_rect);
+ ::SetWindowPos(tab_contents_->GetContainerHWND(), NULL, client_rect.left,
+ client_rect.top, client_rect.right - client_rect.left,
+ client_rect.bottom - client_rect.top, SWP_NOZORDER);
+ }
+ return 0;
+}
+
+// TODO(sanjeevr): The implementation of the TabContentsDelegate interface
+// needs to be fully fleshed out based on the requirements of the
+// "Chrome tab in external browser" feature.
+
+void ExternalTabContainer::OpenURLFromTab(TabContents* source,
+ const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition) {
+ switch (disposition) {
+ case CURRENT_TAB:
+ case NEW_FOREGROUND_TAB:
+ case NEW_BACKGROUND_TAB:
+ case NEW_WINDOW:
+ if (automation_) {
+ automation_->Send(new AutomationMsg_OpenURL(0, url, disposition));
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void ExternalTabContainer::NavigationStateChanged(const TabContents* source,
+ unsigned changed_flags) {
+ if (automation_) {
+ automation_->Send(
+ new AutomationMsg_NavigationStateChanged(0,changed_flags));
+ }
+}
+
+void ExternalTabContainer::ReplaceContents(TabContents* source, TabContents* new_contents) {
+}
+
+void ExternalTabContainer::AddNewContents(TabContents* source,
+ TabContents* new_contents,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
+}
+
+void ExternalTabContainer::StartDraggingDetachedContents(
+ TabContents* source,
+ TabContents* new_contents,
+ const gfx::Rect& contents_bounds,
+ const gfx::Point& mouse_pt) {
+}
+
+void ExternalTabContainer::ActivateContents(TabContents* contents) {
+}
+
+void ExternalTabContainer::LoadingStateChanged(TabContents* source) {
+}
+
+void ExternalTabContainer::CloseContents(TabContents* source) {
+}
+
+void ExternalTabContainer::MoveContents(TabContents* source, const gfx::Rect& pos) {
+}
+
+bool ExternalTabContainer::IsPopup(TabContents* source) {
+ return false;
+}
+
+void ExternalTabContainer::URLStarredChanged(TabContents* source, bool starred) {
+}
+
+void ExternalTabContainer::UpdateTargetURL(TabContents* source,
+ const GURL& url) {
+ if (automation_) {
+ std::wstring url_string = CA2W(url.spec().c_str());
+ automation_->Send(
+ new AutomationMsg_UpdateTargetUrl(0, url_string));
+ }
+}
+
+void ExternalTabContainer::ContentsZoomChange(bool zoom_in) {
+}
+
+void ExternalTabContainer::ToolbarSizeChanged(TabContents* source,
+ bool finished) {
+}
+
+void ExternalTabContainer::DidNavigate(NavigationType nav_type,
+ int relative_navigation_offet) {
+ if (automation_) {
+ automation_->Send(
+ new AutomationMsg_DidNavigate(0, nav_type,
+ relative_navigation_offet));
+ }
+}
+
+void ExternalTabContainer::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+}
+
+void ExternalTabContainer::GetBounds(CRect *out, bool including_frame) const {
+ GetWindowRect(out);
+}
+
+void ExternalTabContainer::MoveToFront(bool should_activate) {
+}
+
+HWND ExternalTabContainer::GetHWND() const {
+ return m_hWnd;
+}
+
+void ExternalTabContainer::PaintNow(const CRect& update_rect) {
+ RedrawWindow(update_rect,
+ NULL,
+ RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_NOERASE);
+}
+
+ChromeViews::RootView* ExternalTabContainer::GetRootView() {
+ return const_cast<ChromeViews::RootView*>(&root_view_);
+}
+
+bool ExternalTabContainer::IsVisible() {
+ return !!::IsWindowVisible(*this);
+}
+
+bool ExternalTabContainer::IsActive() {
+ return win_util::IsWindowActive(*this);
+}
+
+bool ExternalTabContainer::ProcessKeyDown(HWND window, UINT message,
+ WPARAM wparam, LPARAM lparam) {
+ if (!automation_) {
+ return false;
+ }
+ if ((wparam == VK_TAB) && !win_util::IsCtrlPressed()) {
+ // Tabs are handled separately (except if this is Ctrl-Tab or
+ // Ctrl-Shift-Tab)
+ return false;
+ }
+ int flags = HIWORD(lparam);
+ if ((flags & KF_EXTENDED) || (flags & KF_ALTDOWN) ||
+ win_util::IsShiftPressed() || win_util::IsCtrlPressed()) {
+ // If this is an extended key or if one or more of Alt, Shift and Control
+ // are pressed, this might be an accelerator that the external host wants
+ // to handle. If the host does not handle this accelerator, it will reflect
+ // the accelerator back to us via the ProcessUnhandledAccelerator method.
+ MSG msg = {0};
+ msg.hwnd = window;
+ msg.message = message;
+ msg.wParam = wparam;
+ msg.lParam = lparam;
+ automation_->Send(new AutomationMsg_HandleAccelerator(0, msg));
+ return true;
+ }
+ return false;
+}
+
+void ExternalTabContainer::SetAccelerators(HACCEL accel_table,
+ int accel_table_entry_count) {
+ external_accel_table_ = accel_table;
+ external_accel_entry_count_ = accel_table_entry_count;
+}
+
+void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
+ // We just received an accelerator key that we had sent to external host
+ // back. Since the external host was not interested in handling this, we
+ // need to dispatch this message as if we had just peeked this out. (we
+ // also need to call TranslateMessage to generate a WM_CHAR if needed).
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+}
+
+// static
+bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
+ std::wstring class_name = win_util::GetClassName(window);
+ return _wcsicmp(class_name.c_str(), chrome::kExternalTabWindowClass) == 0;
+}
+
+// static
+ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
+ HWND tab_window) {
+ HWND parent_window = ::GetParent(tab_window);
+ if (!::IsWindow(parent_window)) {
+ return NULL;
+ }
+ if (!IsExternalTabContainer(parent_window)) {
+ return NULL;
+ }
+ ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
+ GetProp(parent_window, kWindowObjectKey));
+ return container;
+}