diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/external_tab_container.cc | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_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.cc | 334 |
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; +} |