Files
tubestation/widget/src/qt/nsWindow.cpp
2000-10-28 02:24:24 +00:00

551 lines
14 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsWindow.h"
#include "nsIFontMetrics.h"
#include "nsFont.h"
#include "nsGUIEvent.h"
#include "nsIRenderingContext.h"
#include "nsIDeviceContext.h"
#include "nsRect.h"
#include "nsTransform2D.h"
#include "nsGfxCIID.h"
#include "nsMenuBar.h"
#include "nsAppShell.h"
#include "nsClipboard.h"
#include "stdio.h"
#include <qapplication.h>
#include <qobjectlist.h>
#include "nslog.h"
NS_IMPL_LOG(nsWindowLog)
#define PRINTF NS_LOG_PRINTF(nsWindowLog)
#define FLUSH NS_LOG_FLUSH(nsWindowLog)
static bool gAppTopWindowSet = PR_FALSE;
// are we grabbing?
PRBool nsWindow::mIsGrabbing = PR_FALSE;
nsWindow *nsWindow::mGrabWindow = NULL;
//=============================================================================
//
// nsQWidget class
//
//=============================================================================
nsQWidget::nsQWidget(nsWidget * widget, QWidget * parent, const char * name, WFlags f)
: QWidget(parent, name, f), nsQBaseWidget(widget)
{
}
nsQWidget::~nsQWidget()
{
}
void nsQWidget::Destroy()
{
nsQBaseWidget::Destroy();
}
NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsWidget)
//-------------------------------------------------------------------------
//
// nsWindow constructor
//
//-------------------------------------------------------------------------
nsWindow::nsWindow()
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::nsWindow()\n"));
mResized = PR_FALSE;
mVisible = PR_FALSE;
mDisplayed = PR_FALSE;
mLowerLeft = PR_FALSE;
mIsDestroying = PR_FALSE;
mIsDialog = PR_FALSE;
mIsPopup = PR_FALSE;
mOnDestroyCalled = PR_FALSE;
mFont = nsnull;
mWindowType = eWindowType_child;
mBorderStyle = eBorderStyle_default;
mBlockFocusEvents = PR_FALSE;
}
//-------------------------------------------------------------------------
//
// nsWindow destructor
//
//-------------------------------------------------------------------------
nsWindow::~nsWindow()
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::~nsWindow()\n"));
// make sure that we release the grab indicator here
if (mGrabWindow == this) {
mIsGrabbing = PR_FALSE;
mGrabWindow = NULL;
}
}
//-------------------------------------------------------------------------
PRBool nsWindow::IsChild() const
{
return PR_FALSE;
}
//-------------------------------------------------------------------------
void nsWindow::ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY)
{
PR_LOG(QtWidgetsLM,
PR_LOG_DEBUG,
("nsWindow::ConvertToDeviceCoordinates()\n"));
}
//-------------------------------------------------------------------------
//
// Setup initial tooltip rectangles
//
//-------------------------------------------------------------------------
NS_METHOD nsWindow::SetTooltips(PRUint32 aNumberOfTips,nsRect* aTooltipAreas[])
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::SetTooltips()\n"));
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Update all tooltip rectangles
//
//-------------------------------------------------------------------------
NS_METHOD nsWindow::UpdateTooltips(nsRect* aNewTips[])
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::UpdateTooltips()\n"));
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Remove all tooltip rectangles
//
//-------------------------------------------------------------------------
NS_METHOD nsWindow::RemoveTooltips()
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::RemoveTooltips()\n"));
return NS_OK;
}
NS_METHOD nsWindow::SetFocus()
{
PR_LOG(QtWidgetsLM,
PR_LOG_DEBUG,
("nsWindow::SetFocus %s\n",
mWidget ? mWidget->name() : "(null)"));
if (mWidget) {
mWidget->setFocus();
}
// don't recurse
if (mBlockFocusEvents) {
return NS_OK;
}
mBlockFocusEvents = PR_TRUE;
nsGUIEvent event;
event.message = NS_GOTFOCUS;
event.widget = this;
event.eventStructType = NS_GUI_EVENT;
event.time = 0;
event.point.x = 0;
event.point.y = 0;
DispatchFocus(event);
mBlockFocusEvents = PR_FALSE;
return NS_OK;
}
NS_METHOD nsWindow::PreCreateWidget(nsWidgetInitData *aInitData)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::PreCreateWidget()\n"));
if (nsnull != aInitData) {
SetWindowType(aInitData->mWindowType);
SetBorderStyle(aInitData->mBorderStyle);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
//
// Create the native widget
//
//-------------------------------------------------------------------------
NS_METHOD nsWindow::CreateNative(QWidget *parentWidget)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::CreateNative()\n"));
QWidget::WFlags w = 0;
if (mBorderStyle == eBorderStyle_default) {
w = 0;
}
else {
if (mBorderStyle & eBorderStyle_all) {
w |= 0;
}
if (mBorderStyle & eBorderStyle_border) {
w |= Qt::WStyle_DialogBorder;
}
if (mBorderStyle & eBorderStyle_resizeh) {
w |= Qt::WStyle_NormalBorder;
}
if (mBorderStyle & eBorderStyle_title) {
w |= Qt::WStyle_Title;
}
if (mBorderStyle & eBorderStyle_menu) {
w |= Qt::WStyle_SysMenu | Qt::WStyle_Title;
}
if (mBorderStyle & eBorderStyle_minimize) {
w |= Qt::WStyle_Minimize;
}
if (mBorderStyle & eBorderStyle_maximize) {
w |= Qt::WStyle_Maximize;
}
if (mBorderStyle & eBorderStyle_close) {
PR_LOG(QtWidgetsLM,
PR_LOG_DEBUG,
("eBorderStyle_close isn't handled yet... please fix me\n"));
}
}
w |= (w) ? Qt::WStyle_Customize : 0;
switch (mWindowType) {
case eWindowType_toplevel:
w |= Qt::WType_TopLevel | Qt::WDestructiveClose;
break;
case eWindowType_dialog:
mIsDialog = PR_TRUE;
w |= Qt::WType_Modal;
break;
case eWindowType_popup:
mIsPopup = PR_TRUE;
w |= Qt::WType_Popup;
break;
case eWindowType_child:
break;
}
w |= Qt::WRepaintNoErase;
w |= Qt::WResizeNoErase;
mWidget = (QWidget*)new nsQWidget(this, parentWidget, QWidget::tr("nsWindow"), w);
if (!mWidget)
return NS_ERROR_OUT_OF_MEMORY;
if (!parentWidget) {
// This is a top-level window. I'm not sure what special actions need
// to be taken here.
mWidget->resize(mBounds.width, mBounds.height);
mIsToplevel = PR_TRUE;
mListenForResizes = PR_TRUE;
if (!gAppTopWindowSet) {
qApp->setMainWidget(mWidget);
gAppTopWindowSet = PR_TRUE;
}
}
else {
mIsToplevel = PR_FALSE;
}
// Force cursor to default setting
mCursor = eCursor_select;
SetCursor(eCursor_standard);
return nsWidget::CreateNative(parentWidget);
}
//-------------------------------------------------------------------------
//
// Initialize all the Callbacks
//
//-------------------------------------------------------------------------
void nsWindow::InitCallbacks(char * aName)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::InitCallbacks()\n"));
}
//-------------------------------------------------------------------------
//
// Set the colormap of the window
//
//-------------------------------------------------------------------------
NS_METHOD nsWindow::SetColorMap(nsColorMap *aColorMap)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::SetColorMap()\n"));
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Scroll the bits of a window
//
//-------------------------------------------------------------------------
NS_METHOD nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::Scroll: (%d,%d)\n",
aDx, aDy));
if (mWidget) {
mWidget->scroll(aDx, aDy);
}
return NS_OK;
}
NS_METHOD nsWindow::SetTitle(const nsString& aTitle)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::SetTitle()\n"));
if (!mWidget) {
return NS_ERROR_FAILURE;
}
const char * titleStr = aTitle.ToNewCString();
mWidget->setCaption(QString::fromLocal8Bit(titleStr));
delete[] titleStr;
return NS_OK;
}
/**
* Processes an Expose Event
*
**/
PRBool nsWindow::OnPaint(nsPaintEvent &event)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::OnPaint()\n"));
nsresult result ;
PRInt32 x;
PRInt32 y;
PRInt32 width;
PRInt32 height;
// call the event callback
if (mEventCallback) {
event.renderingContext = nsnull;
if (event.rect) {
PR_LOG(QtWidgetsLM,
PR_LOG_DEBUG,
("nsWindow::OnPaint: this=%p, {%d,%d,%d,%d}\n",
this,
event.rect->x,
event.rect->y,
event.rect->width,
event.rect->height));
x = event.rect->x;
y = event.rect->y;
width = event.rect->width;
height = event.rect->height;
}
else {
PR_LOG(QtWidgetsLM,
PR_LOG_DEBUG,
("nsWindow::OnPaint: this=%p, NO RECT\n",
this));
x = 0;
y = 0;
if (mWidget) {
width = mWidget->width();
height = mWidget->height();
}
else {
width = 0;
height = 0;
}
}
static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID);
static NS_DEFINE_IID(kRenderingContextIID, NS_IRENDERING_CONTEXT_IID);
if (NS_OK == nsComponentManager::CreateInstance(kRenderingContextCID,
nsnull,
kRenderingContextIID,
(void **)&event.renderingContext)) {
if (mBounds.width && mBounds.height) {
event.renderingContext->Init(mContext, this);
result = DispatchWindowEvent(&event);
NS_RELEASE(event.renderingContext);
if (mWidget && mPixmap) {
PR_LOG(QtWidgetsLM,
PR_LOG_DEBUG,
("nsWindow::OnPaint: bitBlt: {%d,%d,%d,%d}\n",
x, y, width, height));
bitBlt(mWidget, x, y, mPixmap, x, y, width, height, Qt::CopyROP);
mPixmap->fill(mWidget, 0, 0);
}
}
}
else {
result = PR_FALSE;
}
}
return result;
}
NS_METHOD nsWindow::BeginResizingChildren(void)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::BeginResizingChildren()\n"));
return NS_OK;
}
NS_METHOD nsWindow::EndResizingChildren(void)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::EndResizingChildren()\n"));
return NS_OK;
}
PRBool nsWindow::OnKey(nsKeyEvent &aEvent)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::OnKey()\n"));
if (mEventCallback) {
return DispatchWindowEvent(&aEvent);
}
return PR_FALSE;
}
PRBool nsWindow::DispatchFocus(nsGUIEvent &aEvent)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::DispatchFocus()\n"));
if (mEventCallback) {
return DispatchWindowEvent(&aEvent);
}
return PR_FALSE;
}
PRBool nsWindow::OnScroll(nsScrollbarEvent &aEvent, PRUint32 cPos)
{
PR_LOG(QtWidgetsLM, PR_LOG_DEBUG, ("nsWindow::OnScroll()\n"));
return PR_FALSE;
}
NS_METHOD nsWindow::ConstrainPosition(PRInt32 *aX, PRInt32 *aY)
{
return NS_OK;
}
NS_METHOD nsWindow::Move(PRInt32 aX, PRInt32 aY)
{
PR_LOG(QtWidgetsLM,
PR_LOG_DEBUG,
("nsWindow::Move %s by (%d,%d)\n",
mWidget ? mWidget->name() : "(null)",
aX, aY));
if (mWidget && mParent && mWindowType == eWindowType_popup) {
nsRect oldrect, newrect;
mBounds.x = aX;
mBounds.y = aY;
oldrect.x = aX;
oldrect.y = aY;
mParent->WidgetToScreen(oldrect, newrect);
mWidget->move(newrect.x,newrect.y);
return NS_OK;
}
else
return(nsWidget::Move(aX,aY));
}
NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener * aListener,
PRBool aDoCapture,
PRBool aConsumeRollupEvent)
{
if (aDoCapture)
{
/* Create a pointer region */
mIsGrabbing = PR_TRUE;
mGrabWindow = this;
gRollupConsumeRollupEvent = PR_TRUE;
gRollupListener = aListener;
gRollupWidget = getter_AddRefs(NS_GetWeakReference(NS_STATIC_CAST(nsIWidget*,this)));
}
else
{
// make sure that the grab window is marked as released
if (mGrabWindow == this) {
mGrabWindow = NULL;
}
mIsGrabbing = PR_FALSE;
gRollupListener = nsnull;
gRollupWidget = nsnull;
}
return NS_OK;
}
//////////////////////////////////////////////////////////////////////
ChildWindow::ChildWindow()
{
}
ChildWindow::~ChildWindow()
{
#ifdef NOISY_DESTROY
IndentByDepth(stdout);
PRINTF("ChildWindow::~ChildWindow:%p\n", this);
#endif
if (mEventHandler && mParent) {
((nsWidget*)(mParent.get()))->RemoveChildEventHandler(mEventHandler);
}
}
PRBool ChildWindow::IsChild() const
{
return PR_TRUE;
}
NS_METHOD ChildWindow::CreateNative(QWidget *parentWidget)
{
nsresult rv;
rv = nsWindow::CreateNative(parentWidget);
if (rv == NS_OK && mEventHandler && mParent)
((nsWidget*)(mParent.get()))->AddChildEventHandler(mEventHandler);
return rv;
}