diff options
author | Robert Griebl <rgriebl@trolltech.com> | 2009-06-10 11:46:23 (GMT) |
---|---|---|
committer | Robert Griebl <rgriebl@trolltech.com> | 2009-06-10 11:46:23 (GMT) |
commit | 7604f8087f88171ef933d8ae08f501467e647338 (patch) | |
tree | 51d071f462ed48d0b25884d9f62b8ba11c5dff13 /src/gui/kernel | |
parent | 8c265860b41214daade7c8a28237c1e07ea71a3c (diff) | |
download | Qt-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.cpp | 8 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_qws.cpp | 27 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qcursor_qws.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qeventdispatcher_s60.cpp | 24 | ||||
-rw-r--r-- | src/gui/kernel/qshortcutmap.cpp | 5 | ||||
-rw-r--r-- | src/gui/kernel/qshortcutmap_p.h | 3 | ||||
-rw-r--r-- | src/gui/kernel/qsound_s60.cpp | 7 | ||||
-rw-r--r-- | src/gui/kernel/qt_s60_p.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 46 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_mac.mm | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_qws.cpp | 3 |
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); |