summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@collabora.co.uk>2011-05-05 08:49:59 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2011-05-05 08:49:59 (GMT)
commit124ec3200f8453142717fcfe7a4aa0a55164aaa6 (patch)
tree4748b83c5941cd5c839f8e3423b384015e8ffe2f
parent4237c59dba78d80be165ae8dd1691abfc61503b1 (diff)
downloadQt-124ec3200f8453142717fcfe7a4aa0a55164aaa6.zip
Qt-124ec3200f8453142717fcfe7a4aa0a55164aaa6.tar.gz
Qt-124ec3200f8453142717fcfe7a4aa0a55164aaa6.tar.bz2
Ensure that QDateTimeEdit::calendarWidget() will always return a valid widget.
This case may be triggered in the (admittedly slightly abnormal) case where a user wishes to embed the calendar widget in a layout or, for whatever reason, do something else that will change its ownership. We work around this by detecting when it is deleted and recreating the widget. This will also have a positive side effect if setCalendarWidget() is called with a widget which is then subsequently deleted, returning the default widget instead of a pointer to (now deleted) memory. Reviewed-by: Denis Dzyubenko Merge-request: 2568 Reviewed-by: Denis Dzyubenko <denis.dzyubenko@nokia.com>
-rw-r--r--src/gui/widgets/qdatetimeedit.cpp41
-rw-r--r--src/gui/widgets/qdatetimeedit_p.h10
-rw-r--r--tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp23
3 files changed, 56 insertions, 18 deletions
diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp
index 6337113..a4739a7 100644
--- a/src/gui/widgets/qdatetimeedit.cpp
+++ b/src/gui/widgets/qdatetimeedit.cpp
@@ -2538,20 +2538,32 @@ void QDateTimeEditPrivate::syncCalendarWidget()
}
QCalendarPopup::QCalendarPopup(QWidget * parent, QCalendarWidget *cw)
- : QWidget(parent, Qt::Popup), calendar(0)
+ : QWidget(parent, Qt::Popup)
{
setAttribute(Qt::WA_WindowPropagation);
dateChanged = false;
if (!cw) {
- cw = new QCalendarWidget(this);
+ verifyCalendarInstance();
+ } else {
+ setCalendarWidget(cw);
+ }
+}
+
+QCalendarWidget *QCalendarPopup::verifyCalendarInstance()
+{
+ if (calendar.isNull()) {
+ QCalendarWidget *cw = new QCalendarWidget(this);
cw->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled())
cw->setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);
#endif
+ setCalendarWidget(cw);
+ return cw;
+ } else {
+ return calendar.data();
}
- setCalendarWidget(cw);
}
void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw)
@@ -2563,28 +2575,29 @@ void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw)
widgetLayout->setMargin(0);
widgetLayout->setSpacing(0);
}
- delete calendar;
- calendar = cw;
- widgetLayout->addWidget(calendar);
+ delete calendar.data();
+ calendar = QWeakPointer<QCalendarWidget>(cw);
+ widgetLayout->addWidget(cw);
- connect(calendar, SIGNAL(activated(QDate)), this, SLOT(dateSelected(QDate)));
- connect(calendar, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate)));
- connect(calendar, SIGNAL(selectionChanged()), this, SLOT(dateSelectionChanged()));
+ connect(cw, SIGNAL(activated(QDate)), this, SLOT(dateSelected(QDate)));
+ connect(cw, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate)));
+ connect(cw, SIGNAL(selectionChanged()), this, SLOT(dateSelectionChanged()));
- calendar->setFocus();
+ cw->setFocus();
}
void QCalendarPopup::setDate(const QDate &date)
{
oldDate = date;
- calendar->setSelectedDate(date);
+ verifyCalendarInstance()->setSelectedDate(date);
}
void QCalendarPopup::setDateRange(const QDate &min, const QDate &max)
{
- calendar->setMinimumDate(min);
- calendar->setMaximumDate(max);
+ QCalendarWidget *cw = verifyCalendarInstance();
+ cw->setMinimumDate(min);
+ cw->setMaximumDate(max);
}
void QCalendarPopup::mousePressEvent(QMouseEvent *event)
@@ -2620,7 +2633,7 @@ bool QCalendarPopup::event(QEvent *event)
void QCalendarPopup::dateSelectionChanged()
{
dateChanged = true;
- emit newDateSelected(calendar->selectedDate());
+ emit newDateSelected(verifyCalendarInstance()->selectedDate());
}
void QCalendarPopup::dateSelected(const QDate &date)
{
diff --git a/src/gui/widgets/qdatetimeedit_p.h b/src/gui/widgets/qdatetimeedit_p.h
index acdc878..c85c0fb 100644
--- a/src/gui/widgets/qdatetimeedit_p.h
+++ b/src/gui/widgets/qdatetimeedit_p.h
@@ -148,11 +148,11 @@ class QCalendarPopup : public QWidget
Q_OBJECT
public:
QCalendarPopup(QWidget *parent = 0, QCalendarWidget *cw = 0);
- QDate selectedDate() { return calendar->selectedDate(); }
+ QDate selectedDate() { return verifyCalendarInstance()->selectedDate(); }
void setDate(const QDate &date);
void setDateRange(const QDate &min, const QDate &max);
- void setFirstDayOfWeek(Qt::DayOfWeek dow) { calendar->setFirstDayOfWeek(dow); }
- QCalendarWidget *calendarWidget() const { return calendar; }
+ void setFirstDayOfWeek(Qt::DayOfWeek dow) { verifyCalendarInstance()->setFirstDayOfWeek(dow); }
+ QCalendarWidget *calendarWidget() const { return const_cast<QCalendarPopup*>(this)->verifyCalendarInstance(); }
void setCalendarWidget(QCalendarWidget *cw);
Q_SIGNALS:
void activated(const QDate &date);
@@ -171,7 +171,9 @@ protected:
bool event(QEvent *e);
private:
- QCalendarWidget *calendar;
+ QCalendarWidget *verifyCalendarInstance();
+
+ QWeakPointer<QCalendarWidget> calendar;
QDate oldDate;
bool dateChanged;
};
diff --git a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
index c8c3b90..9d0c5f7 100644
--- a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
+++ b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp
@@ -275,6 +275,8 @@ private slots:
void focusNextPrevChild();
void taskQTBUG_12384_timeSpecShowTimeOnly();
+
+ void deleteCalendarWidget();
private:
EditorDateEdit* testWidget;
@@ -3438,5 +3440,26 @@ void tst_QDateTimeEdit::taskQTBUG_12384_timeSpecShowTimeOnly()
QCOMPARE(edit.time(), time.time());
}
+void tst_QDateTimeEdit::deleteCalendarWidget()
+{
+ {
+ // setup
+ QCalendarWidget *cw = 0;
+ QDateEdit edit;
+ QVERIFY(!edit.calendarWidget());
+ edit.setCalendarPopup(true);
+ QVERIFY(edit.calendarWidget());
+ edit.calendarWidget()->setObjectName("cw1");;
+
+ // delete
+ cw = edit.calendarWidget();
+ delete cw;
+
+ // it should create a new widget
+ QVERIFY(edit.calendarWidget());
+ QVERIFY(edit.calendarWidget()->objectName() != "cw1");
+ }
+}
+
QTEST_MAIN(tst_QDateTimeEdit)
#include "tst_qdatetimeedit.moc"