summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorRobert Griebl <rgriebl@trolltech.com>2009-06-10 11:46:23 (GMT)
committerRobert Griebl <rgriebl@trolltech.com>2009-06-10 11:46:23 (GMT)
commit7604f8087f88171ef933d8ae08f501467e647338 (patch)
tree51d071f462ed48d0b25884d9f62b8ba11c5dff13 /src/gui/kernel
parent8c265860b41214daade7c8a28237c1e07ea71a3c (diff)
downloadQt-7604f8087f88171ef933d8ae08f501467e647338.zip
Qt-7604f8087f88171ef933d8ae08f501467e647338.tar.gz
Qt-7604f8087f88171ef933d8ae08f501467e647338.tar.bz2
Make Qt exception safer.
Squashed commit of the branch haralds-haralds-qt-s60-topics/topic/exceptions, which also contains the full history. Rev-By: Harald Fernengel Rev-By: Ralf Engels
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication.cpp8
-rw-r--r--src/gui/kernel/qapplication_p.h2
-rw-r--r--src/gui/kernel/qapplication_qws.cpp27
-rw-r--r--src/gui/kernel/qapplication_s60.cpp7
-rw-r--r--src/gui/kernel/qcursor_qws.cpp6
-rw-r--r--src/gui/kernel/qeventdispatcher_s60.cpp24
-rw-r--r--src/gui/kernel/qshortcutmap.cpp5
-rw-r--r--src/gui/kernel/qshortcutmap_p.h3
-rw-r--r--src/gui/kernel/qsound_s60.cpp7
-rw-r--r--src/gui/kernel/qt_s60_p.h1
-rw-r--r--src/gui/kernel/qwidget.cpp46
-rw-r--r--src/gui/kernel/qwidget.h1
-rw-r--r--src/gui/kernel/qwidget_mac.mm2
-rw-r--r--src/gui/kernel/qwidget_qws.cpp3
14 files changed, 106 insertions, 36 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index eaaeb4b..aa6d21e 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -1006,7 +1006,8 @@ QApplication::~QApplication()
if (QWidgetPrivate::mapper) {
QWidgetMapper * myMapper = QWidgetPrivate::mapper;
QWidgetPrivate::mapper = 0;
- for (QWidgetMapper::Iterator it = myMapper->begin(); it != myMapper->end(); ++it) {
+ for (QWidgetMapper::ConstIterator it = myMapper->constBegin();
+ it != myMapper->constEnd(); ++it) {
register QWidget *w = *it;
if (!w->parent()) // window
w->destroy(true, true);
@@ -1018,7 +1019,7 @@ QApplication::~QApplication()
if (QWidgetPrivate::uncreatedWidgets) {
QWidgetSet *mySet = QWidgetPrivate::uncreatedWidgets;
QWidgetPrivate::uncreatedWidgets = 0;
- for (QWidgetSet::Iterator it = mySet->begin(); it != mySet->end(); ++it) {
+ for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
register QWidget *w = *it;
if (!w->parent()) // window
w->destroy(true, true);
@@ -4993,8 +4994,7 @@ void QApplication::setInputContext(QInputContext *inputContext)
qWarning("QApplication::setInputContext: called with 0 input context");
return;
}
- if (d->inputContext)
- delete d->inputContext;
+ delete d->inputContext;
d->inputContext = inputContext;
}
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index a6fc602..35a532a 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -100,6 +100,7 @@ extern QSysInfo::MacVersion qt_macver;
#if defined(Q_WS_QWS)
class QWSManager;
class QDirectPainter;
+struct QWSServerCleaner { ~QWSServerCleaner(); };
#endif
#ifndef QT_NO_TABLET
@@ -382,6 +383,7 @@ public:
#ifdef Q_WS_QWS
QPointer<QWSManager> last_manager;
+ QWSServerCleaner qwsServerCleaner;
# ifndef QT_NO_DIRECTPAINTER
QMap<WId, QDirectPainter *> *directPainters;
# endif
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index 018440f..aeebde4 100644
--- a/src/gui/kernel/qapplication_qws.cpp
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -159,6 +159,8 @@ bool qws_overrideCursor = false;
#ifndef QT_NO_QWS_MANAGER
#include "qdecorationfactory_qws.h"
+extern Q_GUI_EXPORT QWSServer *qwsServer;
+
QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE
@@ -485,8 +487,13 @@ QList<QWSCommand*> *qt_get_server_queue()
void qt_server_enqueue(const QWSCommand *command)
{
QWSCommand *copy = QWSCommand::factory(command->type);
- copy->copyFrom(command);
- outgoing.append(copy);
+ QT_TRY {
+ copy->copyFrom(command);
+ outgoing.append(copy);
+ } QT_CATCH(...) {
+ delete copy;
+ QT_RETHROW;
+ }
}
QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
@@ -2295,7 +2302,7 @@ void qt_init(QApplicationPrivate *priv, int type)
qws_decoration = QApplication::qwsSetDecoration(decoration);
#endif // QT_NO_QWS_MANAGER
#ifndef QT_NO_QWS_INPUTMETHODS
- qApp->setInputContext(new QWSInputContext);
+ qApp->setInputContext(new QWSInputContext(qApp));
#endif
}
@@ -3542,10 +3549,10 @@ bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab i
#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
if (type == QEvent::KeyPress && !grab
- && static_cast<QApplicationPrivate*>(qApp->d_ptr)->use_compat()) {
+ && static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->use_compat()) {
// send accel events if the keyboard is not grabbed
QKeyEvent a(type, code, state, text, autor, int(text.length()));
- if (static_cast<QApplicationPrivate*>(qApp->d_ptr)->qt_tryAccelEvent(this, &a))
+ if (static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->qt_tryAccelEvent(this, &a))
return true;
}
#else
@@ -3745,4 +3752,14 @@ void QApplication::setArgs(int c, char **v)
d->argv = v;
}
+/* \internal
+ This is used to clean up the qws server
+ in case the QApplication constructor threw an exception
+ */
+QWSServerCleaner::~QWSServerCleaner()
+{
+ if (qwsServer && qws_single_process)
+ QWSServer::closedown();
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 2f7bdcf..976d9f6 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -441,6 +441,13 @@ void QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent)
TKeyResponse QSymbianControl::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type)
{
+ TKeyResponse r = EKeyWasNotConsumed;
+ QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(r = OfferKeyEvent(keyEvent, type));
+ return r;
+}
+
+TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type)
+{
switch (type) {
//case EEventKeyDown: // <-- Intentionally left out. See below.
case EEventKeyUp:
diff --git a/src/gui/kernel/qcursor_qws.cpp b/src/gui/kernel/qcursor_qws.cpp
index 097b982..99800a8 100644
--- a/src/gui/kernel/qcursor_qws.cpp
+++ b/src/gui/kernel/qcursor_qws.cpp
@@ -66,7 +66,11 @@ QCursorData::~QCursorData()
{
delete bm;
delete bmm;
- QPaintDevice::qwsDisplay()->destroyCursor(id);
+ QT_TRY {
+ QPaintDevice::qwsDisplay()->destroyCursor(id);
+ } QT_CATCH(const std::bad_alloc &) {
+ // do nothing.
+ }
}
diff --git a/src/gui/kernel/qeventdispatcher_s60.cpp b/src/gui/kernel/qeventdispatcher_s60.cpp
index 6ac2863..fcf572e 100644
--- a/src/gui/kernel/qeventdispatcher_s60.cpp
+++ b/src/gui/kernel/qeventdispatcher_s60.cpp
@@ -62,18 +62,22 @@ bool QEventDispatcherS60::processEvents ( QEventLoop::ProcessEventsFlags flags )
{
bool ret = false;
- bool oldNoInputEventsValue = m_noInputEvents;
- if (flags & QEventLoop::ExcludeUserInputEvents) {
- m_noInputEvents = true;
- } else {
- m_noInputEvents = false;
- ret = sendDeferredInputEvents() || ret;
+ QT_TRY {
+ bool oldNoInputEventsValue = m_noInputEvents;
+ if (flags & QEventLoop::ExcludeUserInputEvents) {
+ m_noInputEvents = true;
+ } else {
+ m_noInputEvents = false;
+ ret = sendDeferredInputEvents() || ret;
+ }
+
+ ret = QEventDispatcherSymbian::processEvents(flags) || ret;
+
+ m_noInputEvents = oldNoInputEventsValue;
+ } QT_CATCH (const std::exception& ex) {
+ CActiveScheduler::Current()->Error(qt_translateExceptionToSymbianError(ex));
}
- ret = QEventDispatcherSymbian::processEvents(flags) || ret;
-
- m_noInputEvents = oldNoInputEventsValue;
-
return ret;
}
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 86894b4..7a19252 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -148,9 +148,8 @@ public:
QShortcutMap constructor.
*/
QShortcutMap::QShortcutMap()
+ : d_ptr(new QShortcutMapPrivate(this))
{
- d_ptr = new QShortcutMapPrivate(this);
- Q_ASSERT(d_ptr != 0);
resetState();
}
@@ -159,8 +158,6 @@ QShortcutMap::QShortcutMap()
*/
QShortcutMap::~QShortcutMap()
{
- delete d_ptr;
- d_ptr = 0;
}
/*! \internal
diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/gui/kernel/qshortcutmap_p.h
index 3fe9546..28ee1f0 100644
--- a/src/gui/kernel/qshortcutmap_p.h
+++ b/src/gui/kernel/qshortcutmap_p.h
@@ -55,6 +55,7 @@
#include "QtGui/qkeysequence.h"
#include "QtCore/qvector.h"
+#include "QtCore/qscopedpointer.h"
QT_BEGIN_NAMESPACE
@@ -104,7 +105,7 @@ private:
#ifndef QT_NO_ACTION
bool correctContext(Qt::ShortcutContext context,QAction *a, QWidget *active_window) const;
#endif
- QShortcutMapPrivate *d_ptr;
+ QScopedPointer<QShortcutMapPrivate> d_ptr;
QKeySequence::SequenceMatch find(QKeyEvent *e);
QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const;
diff --git a/src/gui/kernel/qsound_s60.cpp b/src/gui/kernel/qsound_s60.cpp
index 7eb6463..00fc2fe 100644
--- a/src/gui/kernel/qsound_s60.cpp
+++ b/src/gui/kernel/qsound_s60.cpp
@@ -146,10 +146,11 @@ QAuServer* qt_new_audio_server()
QAuBucketS60::QAuBucketS60( QAuServerS60 *server, QSound *sound )
: m_sound( sound ), m_server( server ), m_prepared(false), m_playCalled(false)
{
+ QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath();
+ filepath = QDir::toNativeSeparators(filepath);
+ TPtrC filepathPtr(qt_QString2TPtrC(filepath));
TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this);
- QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath();
- filepath = QDir::toNativeSeparators(filepath);
- m_playUtility->OpenFileL(qt_QString2TPtrC(filepath)));
+ m_playUtility->OpenFileL(filepathPtr));
if(err){
m_server->playCompleted(this, err);
}
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index d2fa5da..2d47a14 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -147,6 +147,7 @@ protected:
void FocusChanged(TDrawNow aDrawNow);
private:
+ TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType);
TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent);
void sendMouseEvent(QWidget *widget, QMouseEvent *mEvent);
void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation );
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index b376f20..09299dc 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -172,7 +172,8 @@ extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
QWidgetPrivate::QWidgetPrivate(int version) :
- QObjectPrivate(version), extra(0), focus_child(0)
+ QObjectPrivate(version), extra(0),
+ focus_next(0), focus_prev(0), focus_child(0)
,layout(0), widgetItem(0)
,leftmargin(0), topmargin(0), rightmargin(0), bottommargin(0)
,leftLayoutItemMargin(0), topLayoutItemMargin(0), rightLayoutItemMargin(0)
@@ -927,6 +928,23 @@ QRegion qt_dirtyRegion(QWidget *widget)
\endlist
*/
+struct QWidgetExceptionCleaner
+{
+ /* this cleans up when the constructor throws an exception */
+ static inline void cleanup(QWidget *that, QWidgetPrivate *d)
+ {
+#ifndef QT_NO_EXCEPTIONS
+ QWidgetPrivate::uncreatedWidgets->remove(that);
+ if (d->focus_next != that) {
+ if (d->focus_next)
+ d->focus_next->d_func()->focus_prev = d->focus_prev;
+ if (d->focus_prev)
+ d->focus_prev->d_func()->focus_next = d->focus_next;
+ }
+#endif
+ }
+};
+
/*!
Constructs a widget which is a child of \a parent, with widget
flags set to \a f.
@@ -956,7 +974,12 @@ QRegion qt_dirtyRegion(QWidget *widget)
QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
: QObject(*new QWidgetPrivate, 0), QPaintDevice()
{
- d_func()->init(parent, f);
+ QT_TRY {
+ d_func()->init(parent, f);
+ } QT_CATCH(...) {
+ QWidgetExceptionCleaner::cleanup(this, d_func());
+ QT_RETHROW;
+ }
}
#ifdef QT3_SUPPORT
@@ -967,8 +990,13 @@ QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
: QObject(*new QWidgetPrivate, 0), QPaintDevice()
{
- d_func()->init(parent , f);
- setObjectName(QString::fromAscii(name));
+ QT_TRY {
+ d_func()->init(parent , f);
+ setObjectName(QString::fromAscii(name));
+ } QT_CATCH(...) {
+ QWidgetExceptionCleaner::cleanup(this, d_func());
+ QT_RETHROW;
+ }
}
#endif
@@ -977,7 +1005,13 @@ QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f)
: QObject(dd, 0), QPaintDevice()
{
- d_func()->init(parent, f);
+ Q_D(QWidget);
+ QT_TRY {
+ d->init(parent, f);
+ } QT_CATCH(...) {
+ QWidgetExceptionCleaner::cleanup(this, d_func());
+ QT_RETHROW;
+ }
}
/*!
@@ -5068,7 +5102,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
#ifndef QT_NO_SCROLLAREA
QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(q->parent());
if (scrollArea && scrollArea->viewport() == q) {
- QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr;
+ QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data();
QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate);
scrollAreaOffset = priv->contentsOffset();
p.translate(-scrollAreaOffset);
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 0dd470d..1b67ba7 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -728,6 +728,7 @@ private:
friend class QGraphicsProxyWidget;
friend class QGraphicsProxyWidgetPrivate;
friend class QStyleSheetStyle;
+ friend class QWidgetExceptionCleaner;
#ifdef Q_WS_MAC
friend class QCoreGraphicsPaintEnginePrivate;
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index b2256cd..e2197c6 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -1215,7 +1215,7 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event,
QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(widget->parent());
QPoint scrollAreaOffset;
if (scrollArea && scrollArea->viewport() == widget) {
- QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(static_cast<QWidget *>(scrollArea)->d_ptr);
+ QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(static_cast<QWidget *>(scrollArea)->d_ptr.data());
scrollAreaOffset = priv->contentsOffset();
p.translate(-scrollAreaOffset);
}
diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp
index 1445f57..0073d3f 100644
--- a/src/gui/kernel/qwidget_qws.cpp
+++ b/src/gui/kernel/qwidget_qws.cpp
@@ -652,7 +652,8 @@ void QWidgetPrivate::hide_sys()
q->releaseMouse();
// requestWindowRegion(QRegion());
- extra->topextra->backingStore->releaseBuffer();
+ if (extra->topextra->backingStore)
+ extra->topextra->backingStore->releaseBuffer();
QWidget::qwsDisplay()->requestFocus(data.winid,false);