/*******************************************************************************
* Copyright (c) 2009, 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nokia Corporation - initial implementation
*******************************************************************************/
#include <QPaintEvent>
#ifdef __SYMBIAN32__
#if QT_VERSION >= 0x040600
#include <QSymbianEvent>
#endif
#endif
#include <org_eclipse_swt_internal_qt_OS.h>
#include "swtapplication.h"
#include "jniutils.h"
#include "swtfontcache.h"
#include "swtlog.h"
#ifdef __SYMBIAN32__
#include "swts60.h"
#endif
using namespace Java::eSWT;
SwtApplication::SwtApplication(int &argc, char **argv, JniUtils* aJniUtils, int version)
:
#ifdef __SYMBIAN32__
QApplication(SymbianUtils::NewApplication, argc, argv, version), iMobileDevice(NULL)
#else
QApplication(argc, argv, version)
#endif
, mJniUtils(aJniUtils)
{
SWT_LOG_FUNC_CALL();
mFontCache = new SwtFontCache();
mStartTime = QTime::currentTime();
}
SwtApplication::~SwtApplication()
{
SWT_LOG_FUNC_CALL();
delete mFontCache;
mFontCache = NULL;
}
bool SwtApplication::notify(QObject* aObj, QEvent* aEvent)
{
SWT_LOG_FUNC_CALL();
// QApplication::notify will offer the event to the application event filters.
// If they don't consume the event then it will be offered to the object event
// filters. If they don't consume the event then it will be offered to the
// QObject::event.
bool consumed = QApplication::notify(aObj, aEvent);
// Note that consumed == true might mean any of these:
// 1. Event was cancelled in the application event filters
// 2. Event was cancelled in the object event filters
// 3. Event was passed to the QObject which consumed it normally
// We don't check what happened here but call Java paint listeners always.
// This means that if the event is cancelled by the application filter then
// object filters and passing to the QWidget are skipped but Java paint
// event is still sent.
switch ( aEvent->type() )
{
// Some widgets (at least QTextEdit) are not painting fully when
// receiving a paint event. Some have a weird system of object
// event filters on other widgets that trigger the painting. For that
// reason it's not enough to offer the paint event to QWidget::event()
// but all paint events must be offered also to the object event
// filters. Thus, here is the correct place where all painting has
// been done by QWidget and Java content can be painted on top.
case QEvent::Paint:
{
QPaintEvent* paintEvent = static_cast<QPaintEvent*>(aEvent);
const QRect rect = paintEvent->rect();
const QRegion* region = &(paintEvent->region());
// Made up event after QWidget has painted, Java paints here
mJniUtils->eventProcess(aObj, org_eclipse_swt_internal_qt_OS_QSWTEVENT_WIDGETPAINTED, rect.x(),
rect.y(), rect.width(), rect.height(),
reinterpret_cast<int> (region));
break;
}
case QEvent::Resize:
{
QResizeEvent* event = static_cast<QResizeEvent*>(aEvent);
const QSize& size = event->size();
const QSize& oldSize = event->oldSize();
mJniUtils->eventProcess(aObj, org_eclipse_swt_internal_qt_OS_QSWTEVENT_WIDGETRESIZED, oldSize.width(), oldSize.height(), size.width(), size.height());
break;
}
case QEvent::Move:
{
mJniUtils->eventProcess(aObj, org_eclipse_swt_internal_qt_OS_QSWTEVENT_WIDGETMOVED);
break;
}
case QEvent::ApplicationActivate:
{
#ifdef __SYMBIAN32__
if(iMobileDevice)
{
iMobileDevice->AppForeground();
}
#endif
break;
}
default:
break;
}
return consumed;
}
int SwtApplication::initializeMobileDevice()
{
SWT_LOG_FUNC_CALL();
int handle = 0;
#ifdef __SYMBIAN32__
handle = reinterpret_cast<int>(CSwtMobileDevice::NewL());
#endif
return handle;
}
void SwtApplication::destroyMobileDevice()
{
SWT_LOG_FUNC_CALL();
#ifdef __SYMBIAN32__
if(iMobileDevice)
{
delete iMobileDevice;
iMobileDevice = NULL;
}
#endif
}
int SwtApplication::eventTime()
{
SWT_LOG_FUNC_CALL();
return mStartTime.elapsed();
}
void SwtApplication::addDeferredEvent(QObject* aReceiver, QEvent* aEvent)
{
SWT_LOG_FUNC_CALL();
mDeferredEvents.append(new SwtDeferredQEvent(aReceiver, aEvent));
}
void SwtApplication::postDeferredEvents()
{
SWT_LOG_FUNC_CALL();
const int size = mDeferredEvents.size();
for(int i = 0; i < size; ++i)
{
SwtDeferredQEvent* const& eventContainer = mDeferredEvents.at(i);
postEvent(eventContainer->mReceiver, eventContainer->mEvent);
delete eventContainer;
}
if(size)
{
mDeferredEvents.erase(mDeferredEvents.begin(), mDeferredEvents.end());
}
}
#ifdef __SYMBIAN32__
#if QT_VERSION >= 0x040600
bool SwtApplication::symbianEventFilter(const QSymbianEvent* aEvent)
{
if(aEvent->type()== QSymbianEvent::ResourceChangeEvent)
{
return SymbianUtils::eventFilter(this, aEvent->resourceChangeType(), -1);
}
const TWsEvent* wsEvent = aEvent->windowServerEvent();
if(wsEvent)
{
return SymbianUtils::eventFilter(this, wsEvent);
}
return false;
}
#else
bool SwtApplication::s60EventFilter(TWsEvent* aEvent)
{
return SymbianUtils::eventFilter(this, aEvent);
}
#endif
#endif