summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qsimpledrag.cpp32
-rw-r--r--src/gui/kernel/qsimpledrag_p.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm12
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp5
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp1
5 files changed, 43 insertions, 13 deletions
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index 99aaed0444..c98b879a15 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -58,6 +58,7 @@
#include <QtCore/QEventLoop>
#include <QtCore/QDebug>
+#include <QtCore/QLoggingCategory>
#include <private/qguiapplication_p.h>
#include <private/qdnd_p.h>
@@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DRAGANDDROP
+Q_LOGGING_CATEGORY(lcDnd, "qt.gui.dnd")
+
static QWindow* topLevelAt(const QPoint &pos)
{
QWindowList list = QGuiApplication::topLevelWindows();
@@ -94,10 +97,10 @@ static QWindow* topLevelAt(const QPoint &pos)
*/
QBasicDrag::QBasicDrag() :
- m_restoreCursor(false), m_eventLoop(0),
+ m_current_window(nullptr), m_restoreCursor(false), m_eventLoop(nullptr),
m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
- m_drag(0), m_drag_icon_window(0), m_useCompositing(true),
- m_screen(Q_NULLPTR)
+ m_drag(nullptr), m_drag_icon_window(nullptr), m_useCompositing(true),
+ m_screen(nullptr)
{
}
@@ -161,6 +164,7 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
return true; // Eat all mouse move events
}
case QEvent::MouseButtonRelease:
+ {
disableEventFilter();
if (canDrop()) {
QPoint nativePosition = getNativeMousePos(e, m_drag_icon_window);
@@ -169,8 +173,25 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
cancel();
}
exitDndEventLoop();
- QCoreApplication::postEvent(o, new QMouseEvent(*static_cast<QMouseEvent *>(e)));
+
+ // If a QShapedPixmapWindow (drag feedback) is being dragged along, the
+ // mouse event's localPos() will be relative to that, which is useless.
+ // We want a position relative to the window where the drag ends, if possible (?).
+ // If there is no such window (belonging to this Qt application),
+ // make the event relative to the window where the drag started. (QTBUG-66103)
+ const QMouseEvent *release = static_cast<QMouseEvent *>(e);
+ const QWindow *releaseWindow = topLevelAt(release->globalPos());
+ qCDebug(lcDnd) << "mouse released over" << releaseWindow << "after drag from" << m_current_window << "globalPos" << release->globalPos();
+ if (!releaseWindow)
+ releaseWindow = m_current_window;
+ QPoint releaseWindowPos = (releaseWindow ? releaseWindow->mapFromGlobal(release->globalPos()) : release->globalPos());
+ QMouseEvent *newRelease = new QMouseEvent(release->type(),
+ releaseWindowPos, releaseWindowPos, release->screenPos(),
+ release->button(), release->buttons(),
+ release->modifiers(), release->source());
+ QCoreApplication::postEvent(o, newRelease);
return true; // defer mouse release events until drag event loop has returned
+ }
case QEvent::MouseButtonDblClick:
case QEvent::Wheel:
return true;
@@ -349,7 +370,7 @@ static inline QPoint fromNativeGlobalPixels(const QPoint &point)
into account.
*/
-QSimpleDrag::QSimpleDrag() : m_current_window(0)
+QSimpleDrag::QSimpleDrag()
{
}
@@ -366,6 +387,7 @@ void QSimpleDrag::startDrag()
updateCursor(Qt::IgnoreAction);
}
setExecutedDropAction(Qt::IgnoreAction);
+ qCDebug(lcDnd) << "drag began from" << m_current_window<< "cursor pos" << QCursor::pos() << "can drop?" << canDrop();
}
void QSimpleDrag::cancel()
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 45c13e43b2..eb78cd27ad 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -105,6 +105,9 @@ protected:
QDrag *drag() const { return m_drag; }
+protected:
+ QWindow *m_current_window;
+
private:
void enableEventFilter();
void disableEventFilter();
@@ -131,9 +134,6 @@ protected:
virtual void cancel() Q_DECL_OVERRIDE;
virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
-
-private:
- QWindow *m_current_window;
};
#endif // QT_NO_DRAGANDDROP
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index fa123550ef..b02e3bc052 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -418,6 +418,13 @@ static QString strippedText(QString s)
} else {
QList<QUrl> result;
QString filename = QString::fromNSString([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
+ const QString defaultSuffix = mOptions->defaultSuffix();
+ const QFileInfo fileInfo(filename);
+ // If neither the user or the NSSavePanel have provided a suffix, use
+ // the default suffix (if it exists).
+ if (fileInfo.suffix().isEmpty() && !defaultSuffix.isEmpty()) {
+ filename.append('.').append(defaultSuffix);
+ }
result << QUrl::fromLocalFile(filename.remove(QLatin1String("___qt_very_unlikely_prefix_")));
return result;
}
@@ -445,10 +452,7 @@ static QString strippedText(QString s)
[mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead?
if (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) {
- QStringList ext = [self acceptableExtensionsForSave];
- const QString defaultSuffix = mOptions->defaultSuffix();
- if (!ext.isEmpty() && !defaultSuffix.isEmpty())
- ext.prepend(defaultSuffix);
+ const QStringList ext = [self acceptableExtensionsForSave];
[mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(ext)];
} else {
[mOpenPanel setAllowedFileTypes:nil]; // delegate panel:shouldEnableURL: does the file filtering for NSOpenPanel
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 8d37969be4..cb2c534b24 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -2830,7 +2830,10 @@ void QFileDialogPrivate::init(const QUrl &directory, const QString &nameFilter,
if (!nameFilter.isEmpty())
q->setNameFilter(nameFilter);
q->setDirectoryUrl(workingDirectory(directory));
- q->selectFile(initialSelection(directory));
+ if (directory.isLocalFile())
+ q->selectFile(initialSelection(directory));
+ else
+ q->selectUrl(directory);
#ifndef QT_NO_SETTINGS
// Try to restore from the FileDialog settings group; if it fails, fall back
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index 3926a8f719..d2ffe50ce8 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -2288,6 +2288,7 @@ void tst_QDateTime::fromStringDateFormat_data()
QTest::newRow("ISO short") << QString::fromLatin1("2017-07-01T") << Qt::ISODate << invalidDateTime();
QTest::newRow("ISO zoned date") << QString::fromLatin1("2017-07-01Z") << Qt::ISODate << invalidDateTime();
QTest::newRow("ISO zoned empty time") << QString::fromLatin1("2017-07-01TZ") << Qt::ISODate << invalidDateTime();
+ QTest::newRow("ISO mis-punctuated") << QString::fromLatin1("2018/01/30 ") << Qt::ISODate << invalidDateTime();
// Test Qt::RFC2822Date format (RFC 2822).
QTest::newRow("RFC 2822 +0100") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100")