diff options
Diffstat (limited to 'src/plugins')
68 files changed, 835 insertions, 301 deletions
diff --git a/src/plugins/accessible/qaccessiblebase.pri b/src/plugins/accessible/qaccessiblebase.pri deleted file mode 100644 index 95c1fad13a..0000000000 --- a/src/plugins/accessible/qaccessiblebase.pri +++ /dev/null @@ -1,2 +0,0 @@ -target.path += $$[QT_INSTALL_PLUGINS]/accessible -INSTALLS += target diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 0aeff6e1a3..301838997f 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -79,8 +79,7 @@ int QAccessibleTable::logicalIndex(const QModelIndex &index) const return -1; int vHeader = verticalHeader() ? 1 : 0; int hHeader = horizontalHeader() ? 1 : 0; - // row * number columns + column + 1 for one based counting - return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader) + 1; + return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader); } QAccessibleInterface *QAccessibleTable::childFromLogical(int logicalIndex) const @@ -88,7 +87,6 @@ QAccessibleInterface *QAccessibleTable::childFromLogical(int logicalIndex) const if (!view()->model()) return 0; - logicalIndex--; // one based counting ftw int vHeader = verticalHeader() ? 1 : 0; int hHeader = horizontalHeader() ? 1 : 0; @@ -376,16 +374,20 @@ int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const { if (!view()->model()) return -1; + QSharedPointer<QAccessibleInterface> parent(iface->parent()); + if (parent->object() != view()) + return -1; + Q_ASSERT(iface->role() != QAccessible::TreeItem); // should be handled by tree class if (iface->role() == QAccessible::Cell || iface->role() == QAccessible::ListItem) { const QAccessibleTableCell* cell = static_cast<const QAccessibleTableCell*>(iface); - return logicalIndex(cell->m_index) - 1; + return logicalIndex(cell->m_index); } else if (iface->role() == QAccessible::ColumnHeader){ const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface); return cell->index + (verticalHeader() ? 1 : 0); } else if (iface->role() == QAccessible::RowHeader){ const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface); - return (cell->index+1) * (view()->model()->rowCount()+1); + return (cell->index + 1) * (view()->model()->rowCount() + 1); } else if (iface->role() == QAccessible::Pane) { return 0; // corner button } else { @@ -424,8 +426,7 @@ QAccessibleInterface *QAccessibleTable::parent() const QAccessibleInterface *QAccessibleTable::child(int index) const { - // Fixme: get rid of the +1 madness - return childFromLogical(index + 1); + return childFromLogical(index); } void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t) @@ -470,9 +471,8 @@ QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0); int column = index.column(); - int i = row * view()->model()->columnCount() + column + 1; - Q_ASSERT(i > view()->model()->columnCount()); - return child(i - 1); + int i = row * view()->model()->columnCount() + column; + return child(i); } int QAccessibleTree::childCount() const @@ -521,7 +521,11 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const { if (!view()->model()) return -1; - if (iface->role() == QAccessible::TreeItem) { + QSharedPointer<QAccessibleInterface> parent(iface->parent()); + if (parent->object() != view()) + return -1; + + if (iface->role() == QAccessible::TreeItem) { const QAccessibleTableCell* cell = static_cast<const QAccessibleTableCell*>(iface); const QTreeView *treeView = qobject_cast<const QTreeView*>(view()); Q_ASSERT(treeView); @@ -534,7 +538,7 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const return index; } else if (iface->role() == QAccessible::ColumnHeader){ const QAccessibleTableHeaderCell* cell = static_cast<const QAccessibleTableHeaderCell*>(iface); - //qDebug() << "QAccessibleTree::indexOfChild header " << cell->index << "is: " << cell->index + 1; + //qDebug() << "QAccessibleTree::indexOfChild header " << cell->index; return cell->index; } else { qWarning() << "WARNING QAccessibleTable::indexOfChild invalid child" @@ -846,7 +850,7 @@ void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &) bool QAccessibleTableHeaderCell::isValid() const { - return view && view->model() && (index > 0) + return view && view->model() && (index >= 0) && ((orientation == Qt::Horizontal) ? (index < view->model()->columnCount()) : (index < view->model()->rowCount())); } diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index eac31b8068..9d0d3f0145 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -592,11 +592,6 @@ int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const return -1; } -QAccessible::Role QAccessibleDockWidget::role() const -{ - return QAccessible::Window; -} - QRect QAccessibleDockWidget::rect() const { QRect rect; diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index ec2583235f..b309d59c54 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -275,7 +275,6 @@ public: int indexOfChild(const QAccessibleInterface *child) const; int childCount() const; QRect rect () const; - QAccessible::Role role() const; QDockWidget *dockWidget() const; }; diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index bb90061a7e..9bdb1decde 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -53,6 +53,7 @@ #include <qgroupbox.h> #include <qlcdnumber.h> #include <qlineedit.h> +#include <private/qlineedit_p.h> #include <qstyle.h> #include <qstyleoption.h> #include <qtextdocument.h> @@ -672,10 +673,20 @@ int QAccessibleLineEdit::cursorPosition() const return lineEdit()->cursorPosition(); } -QRect QAccessibleLineEdit::characterRect(int /*offset*/) const +QRect QAccessibleLineEdit::characterRect(int offset) const { - // QLineEdit doesn't hand out character rects - return QRect(); + int x = lineEdit()->d_func()->control->cursorToX(offset); + int y; + lineEdit()->getTextMargins(0, &y, 0, 0); + QFontMetrics fm(lineEdit()->font()); + const QString ch = text(offset, offset + 1); + if (ch.isEmpty()) + return QRect(); + int w = fm.width(ch); + int h = fm.height(); + QRect r(x, y, w, h); + r.moveTo(lineEdit()->mapToGlobal(r.topLeft())); + return r; } int QAccessibleLineEdit::selectionCount() const diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro index 3bf7dede56..afabbac9bc 100644 --- a/src/plugins/accessible/widgets/widgets.pro +++ b/src/plugins/accessible/widgets/widgets.pro @@ -1,9 +1,9 @@ TARGET = qtaccessiblewidgets + +PLUGIN_TYPE = accessible load(qt_plugin) -include (../qaccessiblebase.pri) QT += core-private gui-private widgets-private -DESTDIR = $$QT.gui.plugins/accessible QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)" diff --git a/src/plugins/bearer/blackberry/blackberry.pro b/src/plugins/bearer/blackberry/blackberry.pro index 5d4cf29554..220a506d90 100644 --- a/src/plugins/bearer/blackberry/blackberry.pro +++ b/src/plugins/bearer/blackberry/blackberry.pro @@ -1,4 +1,6 @@ TARGET = qbbbearer + +PLUGIN_TYPE = bearer load(qt_plugin) QT = core-private network-private @@ -15,7 +17,3 @@ SOURCES += qbbengine.cpp \ main.cpp OTHER_FILES += blackberry.json - -DESTDIR = $$QT.network.plugins/bearer -target.path += $$[QT_INSTALL_PLUGINS]/bearer -INSTALLS += target diff --git a/src/plugins/bearer/blackberry/qbbengine.cpp b/src/plugins/bearer/blackberry/qbbengine.cpp index 79452aeae5..d64a8fe20f 100644 --- a/src/plugins/bearer/blackberry/qbbengine.cpp +++ b/src/plugins/bearer/blackberry/qbbengine.cpp @@ -316,15 +316,14 @@ void QBBEngine::updateConfiguration(const char *interface) const QString id = idForName(name); - const int numberOfIpAddresses = netstatus_interface_get_num_ip_addresses(details); - const bool isConnected = netstatus_interface_is_connected(details); const netstatus_interface_type_t type = netstatus_interface_get_type(details); + const netstatus_ip_status_t ipStatus = netstatus_interface_get_ip_status(details); netstatus_free_interface_details(&details); QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Defined; - if (isConnected && (numberOfIpAddresses > 0)) + if (ipStatus == NETSTATUS_IP_STATUS_OK) state |= QNetworkConfiguration::Active; QMutexLocker locker(&mutex); diff --git a/src/plugins/bearer/connman/connman.pro b/src/plugins/bearer/connman/connman.pro index 679637b37f..99d9b367f2 100644 --- a/src/plugins/bearer/connman/connman.pro +++ b/src/plugins/bearer/connman/connman.pro @@ -1,4 +1,6 @@ TARGET = qconnmanbearer + +PLUGIN_TYPE = bearer load(qt_plugin) QT = core network-private dbus @@ -17,7 +19,3 @@ SOURCES += main.cpp \ OTHER_FILES += connman.json -DESTDIR = $$QT.network.plugins/bearer -target.path += $$[QT_INSTALL_PLUGINS]/bearer -INSTALLS += target - diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro index b60dac907c..481b75c8ab 100644 --- a/src/plugins/bearer/corewlan/corewlan.pro +++ b/src/plugins/bearer/corewlan/corewlan.pro @@ -1,4 +1,6 @@ TARGET = qcorewlanbearer + +PLUGIN_TYPE = bearer load(qt_plugin) QT = core-private network-private @@ -20,7 +22,3 @@ SOURCES += main.cpp \ OBJECTIVE_SOURCES += qcorewlanengine.mm OTHER_FILES += corewlan.json - -DESTDIR = $$QT.network.plugins/bearer -target.path += $$[QT_INSTALL_PLUGINS]/bearer -INSTALLS += target diff --git a/src/plugins/bearer/generic/generic.pro b/src/plugins/bearer/generic/generic.pro index e66c5b2c7a..a1da0dddda 100644 --- a/src/plugins/bearer/generic/generic.pro +++ b/src/plugins/bearer/generic/generic.pro @@ -1,4 +1,6 @@ TARGET = qgenericbearer + +PLUGIN_TYPE = bearer load(qt_plugin) QT = core-private network-private @@ -12,7 +14,3 @@ SOURCES += qgenericengine.cpp \ main.cpp OTHER_FILES += generic.json - -DESTDIR = $$QT.network.plugins/bearer -target.path += $$[QT_INSTALL_PLUGINS]/bearer -INSTALLS += target diff --git a/src/plugins/bearer/nativewifi/nativewifi.pro b/src/plugins/bearer/nativewifi/nativewifi.pro index 3124d58ff2..4382cd08cd 100644 --- a/src/plugins/bearer/nativewifi/nativewifi.pro +++ b/src/plugins/bearer/nativewifi/nativewifi.pro @@ -1,4 +1,6 @@ TARGET = qnativewifibearer + +PLUGIN_TYPE = bearer load(qt_plugin) QT = core-private network-private @@ -13,7 +15,3 @@ SOURCES += main.cpp \ ../qnetworksession_impl.cpp OTHER_FILES += nativewifi.json - -DESTDIR = $$QT.network.plugins/bearer -target.path += $$[QT_INSTALL_PLUGINS]/bearer -INSTALLS += target diff --git a/src/plugins/bearer/networkmanager/networkmanager.pro b/src/plugins/bearer/networkmanager/networkmanager.pro index c1c6664897..4f299e22f2 100644 --- a/src/plugins/bearer/networkmanager/networkmanager.pro +++ b/src/plugins/bearer/networkmanager/networkmanager.pro @@ -1,4 +1,6 @@ TARGET = qnmbearer + +PLUGIN_TYPE = bearer load(qt_plugin) QT = core network-private dbus @@ -16,7 +18,3 @@ SOURCES += main.cpp \ ../qnetworksession_impl.cpp OTHER_FILES += networkmanager.json - -DESTDIR = $$QT.network.plugins/bearer -target.path += $$[QT_INSTALL_PLUGINS]/bearer -INSTALLS += target diff --git a/src/plugins/bearer/nla/nla.pro b/src/plugins/bearer/nla/nla.pro index 29e98953b1..56c06a57b1 100644 --- a/src/plugins/bearer/nla/nla.pro +++ b/src/plugins/bearer/nla/nla.pro @@ -1,4 +1,6 @@ TARGET = qnlabearer + +PLUGIN_TYPE = bearer load(qt_plugin) QT = core core-private network network-private @@ -19,7 +21,3 @@ SOURCES += main.cpp \ ../qnetworksession_impl.cpp OTHER_FILES += nla.json - -DESTDIR = $$QT.network.plugins/bearer -target.path += $$[QT_INSTALL_PLUGINS]/bearer -INSTALLS += target diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro index aa85fdcb06..97b827b779 100644 --- a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro +++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro @@ -1,9 +1,7 @@ TARGET = qevdevkeyboardplugin -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target +PLUGIN_TYPE = generic +load(qt_plugin) QT += core-private platformsupport-private gui-private diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro index fd7d0fee6a..c1356593df 100644 --- a/src/plugins/generic/evdevmouse/evdevmouse.pro +++ b/src/plugins/generic/evdevmouse/evdevmouse.pro @@ -1,9 +1,7 @@ TARGET = qevdevmouseplugin -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target +PLUGIN_TYPE = generic +load(qt_plugin) QT += core-private platformsupport-private gui-private diff --git a/src/plugins/generic/evdevtablet/evdevtablet.pro b/src/plugins/generic/evdevtablet/evdevtablet.pro index 841d7b96f7..066819be33 100644 --- a/src/plugins/generic/evdevtablet/evdevtablet.pro +++ b/src/plugins/generic/evdevtablet/evdevtablet.pro @@ -1,9 +1,7 @@ TARGET = qevdevtabletplugin -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target +PLUGIN_TYPE = generic +load(qt_plugin) SOURCES = main.cpp diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro index a47d00fbf0..2c1d6913ad 100644 --- a/src/plugins/generic/evdevtouch/evdevtouch.pro +++ b/src/plugins/generic/evdevtouch/evdevtouch.pro @@ -1,9 +1,7 @@ TARGET = qevdevtouchplugin -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target +PLUGIN_TYPE = generic +load(qt_plugin) SOURCES = main.cpp diff --git a/src/plugins/generic/meego/meego.pro b/src/plugins/generic/meego/meego.pro index 692ace485f..b8845418e8 100644 --- a/src/plugins/generic/meego/meego.pro +++ b/src/plugins/generic/meego/meego.pro @@ -1,10 +1,7 @@ TARGET = qmeegointegration -load(qt_plugin) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target +PLUGIN_TYPE = generic +load(qt_plugin) SOURCES = qmeegointegration.cpp \ main.cpp \ diff --git a/src/plugins/generic/tslib/tslib.pro b/src/plugins/generic/tslib/tslib.pro index 9046e18f77..ab0645d89a 100644 --- a/src/plugins/generic/tslib/tslib.pro +++ b/src/plugins/generic/tslib/tslib.pro @@ -1,9 +1,7 @@ TARGET = qtslibplugin -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/generic -target.path = $$[QT_INSTALL_PLUGINS]/generic -INSTALLS += target +PLUGIN_TYPE = generic +load(qt_plugin) HEADERS = qtslib.h diff --git a/src/plugins/imageformats/gif/gif.pro b/src/plugins/imageformats/gif/gif.pro index b85ee984ac..d5acfedff7 100644 --- a/src/plugins/imageformats/gif/gif.pro +++ b/src/plugins/imageformats/gif/gif.pro @@ -1,11 +1,9 @@ TARGET = qgif + +PLUGIN_TYPE = imageformats load(qt_plugin) include(../../../gui/image/qgifhandler.pri) SOURCES += $$PWD/main.cpp HEADERS += $$PWD/main.h OTHER_FILES += gif.json - -DESTDIR = $$QT.gui.plugins/imageformats -target.path += $$[QT_INSTALL_PLUGINS]/imageformats -INSTALLS += target diff --git a/src/plugins/imageformats/ico/ico.pro b/src/plugins/imageformats/ico/ico.pro index 242e42b869..48bfd6b344 100644 --- a/src/plugins/imageformats/ico/ico.pro +++ b/src/plugins/imageformats/ico/ico.pro @@ -1,4 +1,6 @@ TARGET = qico + +PLUGIN_TYPE = imageformats load(qt_plugin) QTDIR_build:REQUIRES = "!contains(QT_CONFIG, no-ico)" @@ -7,7 +9,3 @@ HEADERS += qicohandler.h main.h SOURCES += main.cpp \ qicohandler.cpp OTHER_FILES += ico.json - -DESTDIR = $$QT.gui.plugins/imageformats -target.path += $$[QT_INSTALL_PLUGINS]/imageformats -INSTALLS += target diff --git a/src/plugins/imageformats/jpeg/jpeg.pro b/src/plugins/imageformats/jpeg/jpeg.pro index f2a41129d5..35153eb59c 100644 --- a/src/plugins/imageformats/jpeg/jpeg.pro +++ b/src/plugins/imageformats/jpeg/jpeg.pro @@ -1,4 +1,6 @@ TARGET = qjpeg + +PLUGIN_TYPE = imageformats load(qt_plugin) QT += core-private @@ -9,7 +11,3 @@ include(../../../gui/image/qjpeghandler.pri) SOURCES += main.cpp HEADERS += main.h OTHER_FILES += jpeg.json - -DESTDIR = $$QT.gui.plugins/imageformats -target.path += $$[QT_INSTALL_PLUGINS]/imageformats -INSTALLS += target diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro index 8c8ab52c3c..033d5a4d5c 100644 --- a/src/plugins/platforminputcontexts/ibus/ibus.pro +++ b/src/plugins/platforminputcontexts/ibus/ibus.pro @@ -1,7 +1,7 @@ TARGET = ibusplatforminputcontextplugin -load(qt_plugin) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforminputcontexts +PLUGIN_TYPE = platforminputcontexts +load(qt_plugin) QT += dbus gui-private SOURCES += $$PWD/qibusplatforminputcontext.cpp \ @@ -16,6 +16,3 @@ HEADERS += $$PWD/qibusplatforminputcontext.h \ $$PWD/qibustypes.h OTHER_FILES += $$PWD/ibus.json - -target.path += $$[QT_INSTALL_PLUGINS]/platforminputcontexts -INSTALLS += target diff --git a/src/plugins/platforminputcontexts/maliit/maliit.pro b/src/plugins/platforminputcontexts/maliit/maliit.pro index 4174072c2b..dec6833196 100644 --- a/src/plugins/platforminputcontexts/maliit/maliit.pro +++ b/src/plugins/platforminputcontexts/maliit/maliit.pro @@ -1,7 +1,7 @@ TARGET = maliitplatforminputcontextplugin -load(qt_plugin) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforminputcontexts +PLUGIN_TYPE = platforminputcontexts +load(qt_plugin) QT += dbus gui-private SOURCES += $$PWD/qmaliitplatforminputcontext.cpp \ @@ -16,6 +16,3 @@ HEADERS += $$PWD/qmaliitplatforminputcontext.h \ $$PWD/contextadaptor.h OTHER_FILES += $$PWD/maliit.json - -target.path += $$[QT_INSTALL_PLUGINS]/platforminputcontexts -INSTALLS += target diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 106664a6b0..3ea5dc2d1c 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -1,6 +1,7 @@ TARGET = qcocoa + +PLUGIN_TYPE = platforms load(qt_plugin) -DESTDIR = $$QT.gui.plugins/platforms OBJECTIVE_SOURCES += main.mm \ qcocoaintegration.mm \ @@ -91,8 +92,6 @@ QT += core-private gui-private platformsupport-private } OTHER_FILES += cocoa.json -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target # Build the release libqcocoa.dylib only, skip the debug version. # The Qt plugin loader will dlopen both if found, causing duplicate diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index d465d47e12..ea43bbbc10 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -128,7 +128,9 @@ private: QAbstractEventDispatcher *mEventDispatcher; QScopedPointer<QPlatformInputContext> mInputContext; +#ifndef QT_NO_ACCESSIBILITY QScopedPointer<QPlatformAccessibility> mAccessibility; +#endif QScopedPointer<QPlatformTheme> mPlatformTheme; QList<QCocoaScreen *> mScreens; QCocoaClipboard *mCocoaClipboard; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index b069446c50..481055aae4 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -180,7 +180,9 @@ QCocoaIntegration::QCocoaIntegration() : mFontDb(new QCoreTextFontDatabase()) , mEventDispatcher(new QCocoaEventDispatcher()) , mInputContext(new QCocoaInputContext) +#ifndef QT_NO_ACCESSIBILITY , mAccessibility(new QPlatformAccessibility) +#endif , mCocoaClipboard(new QCocoaClipboard) , mCocoaDrag(new QCocoaDrag) , mNativeInterface(new QCocoaNativeInterface) @@ -302,11 +304,15 @@ void QCocoaIntegration::updateScreens() bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { - case ThreadedPixmaps: return true; - case OpenGL : return true; - case ThreadedOpenGL : return true; - case BufferQueueingOpenGL: return true; - default: return QPlatformIntegration::hasCapability(cap); + case ThreadedPixmaps: + case OpenGL: + case ThreadedOpenGL: + case BufferQueueingOpenGL: + case WindowMasks: + case MultipleWindows: + return true; + default: + return QPlatformIntegration::hasCapability(cap); } } @@ -349,7 +355,11 @@ QPlatformInputContext *QCocoaIntegration::inputContext() const QPlatformAccessibility *QCocoaIntegration::accessibility() const { +#ifndef QT_NO_ACCESSIBILITY return mAccessibility.data(); +#else + return 0; +#endif } QPlatformClipboard *QCocoaIntegration::clipboard() const diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 38952a2e5d..3afe089225 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -70,6 +70,7 @@ public: void removeMenuItem(QPlatformMenuItem *menuItem); void syncMenuItem(QPlatformMenuItem *menuItem); void setEnabled(bool enabled); + void setVisible(bool visible); void syncSeparatorsCollapsible(bool enable); void syncModalState(bool modal); diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 4d35b3202e..36d5c81f34 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -268,6 +268,12 @@ void QCocoaMenu::setParentItem(QCocoaMenuItem *item) void QCocoaMenu::setEnabled(bool enabled) { m_enabled = enabled; + syncModalState(!m_enabled); +} + +void QCocoaMenu::setVisible(bool visible) +{ + [m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)]; } QPlatformMenuItem *QCocoaMenu::menuItemAt(int position) const diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 150d3eef7d..d78ff73bb6 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -263,7 +263,7 @@ NSMenuItem *QCocoaMenuItem::sync() // [m_native setHidden:YES]; // [m_native setHidden:NO]; [m_native setHidden: !m_isVisible]; - + [m_native setEnabled: m_enabled]; QString text = m_text; QKeySequence accel = m_shortcut; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index d5dbe58de9..db3a20c2be 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -107,6 +107,7 @@ public: void lower(); void propagateSizeHints(); void setOpacity(qreal level); + void setMask(const QRegion ®ion); bool setKeyboardGrabEnabled(bool grab); bool setMouseGrabEnabled(bool grab); QMargins frameMargins() const; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index b9ad35600e..de6e7dc43e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -509,6 +509,16 @@ void QCocoaWindow::setOpacity(qreal level) [m_nsWindow setAlphaValue:level]; } +void QCocoaWindow::setMask(const QRegion ®ion) +{ + if (m_nsWindow) { + [m_nsWindow setOpaque:NO]; + [m_nsWindow setBackgroundColor:[NSColor clearColor]]; + } + + [m_contentView setMaskRegion:®ion]; +} + bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) { if (!m_nsWindow) @@ -703,11 +713,6 @@ void QCocoaWindow::setNSWindow(NSWindow *window) name:nil // Get all notifications object:m_nsWindow]; - // ### Accept touch events by default. - // Beware that enabling touch events has a negative impact on the overall performance. - // We probably need a QWindowSystemInterface API to enable/disable touch events. - [m_contentView setAcceptsTouchEvents:YES]; - [window setContentView:m_contentView]; } diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 32e140f9ff..246d311f7b 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -54,6 +54,8 @@ QT_END_NAMESPACE @interface QNSView : NSView <NSTextInputClient> { CGImageRef m_cgImage; + CGImageRef m_maskImage; + uchar *m_maskData; QWindow *m_window; QCocoaWindow *m_platformWindow; Qt::MouseButtons m_buttons; @@ -68,6 +70,7 @@ QT_END_NAMESPACE - (id)initWithQWindow:(QWindow *)window platformWindow:(QCocoaWindow *) platformWindow; - (void)setImage:(QImage *)image; +- (void)setMaskRegion:(const QRegion *)region; - (void)drawRect:(NSRect)dirtyRect; - (void)updateGeometry; - (void)windowNotification : (NSNotification *) windowNotification; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 33d0fb4bae..d62913a7af 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -75,6 +75,8 @@ static QTouchDevice *touchDevice = 0; self = [super initWithFrame : NSMakeRect(0,0, 300,300)]; if (self) { m_cgImage = 0; + m_maskImage = 0; + m_maskData = 0; m_window = 0; m_buttons = Qt::NoButton; m_sendKeyEvent = false; @@ -93,6 +95,10 @@ static QTouchDevice *touchDevice = 0; { CGImageRelease(m_cgImage); m_cgImage = 0; + CGImageRelease(m_maskImage); + m_maskImage = 0; + delete[] m_maskData; + m_maskData = 0; m_window = 0; [super dealloc]; } @@ -205,47 +211,86 @@ static QTouchDevice *touchDevice = 0; } } -- (void) setImage:(QImage *)image +static CGImageRef qt_mac_toCGImage(QImage *qImage, bool isMask, uchar **dataCopy) { - CGImageRelease(m_cgImage); - - int width = image->width(); - int height = image->height(); + int width = qImage->width(); + int height = qImage->height(); if (width <= 0 || height <= 0) { qWarning() << Q_FUNC_INFO << "setting invalid size" << width << "x" << height << "for qnsview image"; - m_cgImage = 0; - return; + return 0; } - const uchar *imageData = image->bits(); - int bitDepth = image->depth(); + const uchar *imageData = qImage->bits(); + if (dataCopy) { + delete[] *dataCopy; + *dataCopy = new uchar[qImage->byteCount()]; + memcpy(*dataCopy, imageData, qImage->byteCount()); + } + int bitDepth = qImage->depth(); int colorBufferSize = 8; - int bytesPrLine = image->bytesPerLine(); - - CGColorSpaceRef cgColourSpaceRef = CGColorSpaceCreateDeviceRGB(); + int bytesPrLine = qImage->bytesPerLine(); CGDataProviderRef cgDataProviderRef = CGDataProviderCreateWithData( NULL, - imageData, - image->byteCount(), + dataCopy ? *dataCopy : imageData, + qImage->byteCount(), NULL); - m_cgImage = CGImageCreate(width, - height, - colorBufferSize, - bitDepth, - bytesPrLine, - cgColourSpaceRef, - kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst, - cgDataProviderRef, - NULL, - false, - kCGRenderingIntentDefault); + CGImageRef cgImage = 0; + if (isMask) { + cgImage = CGImageMaskCreate(width, + height, + colorBufferSize, + bitDepth, + bytesPrLine, + cgDataProviderRef, + NULL, + false); + } else { + CGColorSpaceRef cgColourSpaceRef = CGColorSpaceCreateDeviceRGB(); + cgImage = CGImageCreate(width, + height, + colorBufferSize, + bitDepth, + bytesPrLine, + cgColourSpaceRef, + kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst, + cgDataProviderRef, + NULL, + false, + kCGRenderingIntentDefault); + CGColorSpaceRelease(cgColourSpaceRef); + } + return cgImage; +} - CGColorSpaceRelease(cgColourSpaceRef); +- (void) setImage:(QImage *)image +{ + CGImageRelease(m_cgImage); + m_cgImage = qt_mac_toCGImage(image, false, 0); +} + +- (void) setMaskRegion:(const QRegion *)region +{ + if (m_maskImage) + CGImageRelease(m_maskImage); + if (region->isEmpty()) { + m_maskImage = 0; + } + const QRect &rect = qt_mac_toQRect([self frame]); + QImage maskImage(rect.size(), QImage::Format_RGB888); + maskImage.fill(Qt::white); + QPainter p(&maskImage); + p.setRenderHint(QPainter::Antialiasing); + p.setClipRegion(*region); + p.fillRect(rect, QBrush(Qt::black)); + p.end(); + + maskImage = maskImage.convertToFormat(QImage::Format_Indexed8); + m_maskImage = qt_mac_toCGImage(&maskImage, true, &m_maskData); } - (void) drawRect:(NSRect)dirtyRect @@ -263,13 +308,19 @@ static QTouchDevice *touchDevice = 0; CGContextTranslateCTM(cgContext, 0, dy); CGContextScaleCTM(cgContext, 1, -1); + CGImageRef subMask = 0; + if (m_maskImage) { + subMask = CGImageCreateWithImageInRect(m_maskImage, dirtyCGRect); + CGContextClipToMask(cgContext, dirtyCGRect, subMask); + } + CGImageRef subImage = CGImageCreateWithImageInRect(m_cgImage, dirtyCGRect); CGContextDrawImage(cgContext,dirtyCGRect,subImage); CGContextRestoreGState(cgContext); CGImageRelease(subImage); - + CGImageRelease(subMask); } - (BOOL) isFlipped diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index f2c567f0eb..94c89ad8db 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -795,13 +795,15 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const if (d->hasCustomPageMargins) { margins << d->leftMargin << d->topMargin << d->rightMargin << d->bottomMargin; - } else { + } else if (!d->hasCustomPaperSize) { PMPaperMargins paperMargins; PMPaper paper; PMGetPageFormatPaper(d->format(), &paper); PMPaperGetMargins(paper, &paperMargins); margins << paperMargins.left << paperMargins.top << paperMargins.right << paperMargins.bottom; + } else { + margins << 0 << 0 << 0 << 0; } ret = margins; break; diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index 85821662a0..29c5ebd99b 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -1,6 +1,7 @@ TARGET = qdirectfb + +PLUGIN_TYPE = platforms load(qt_plugin) -DESTDIR = $$QT.gui.plugins/platforms QT += core-private gui-private platformsupport-private @@ -46,7 +47,5 @@ contains(QT_CONFIG, directfb_egl) { CONFIG += qpa/genericunixfontdatabase -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target OTHER_FILES += directfb.json diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro index f22ccc55d2..1223b6b133 100644 --- a/src/plugins/platforms/eglfs/eglfs.pro +++ b/src/plugins/platforms/eglfs/eglfs.pro @@ -1,10 +1,10 @@ TARGET = qeglfs + +PLUGIN_TYPE = platforms load(qt_plugin) QT += core-private gui-private platformsupport-private -DESTDIR = $$QT.gui.plugins/platforms - #DEFINES += QEGL_EXTRA_DEBUG #Avoid X11 header collision @@ -44,9 +44,6 @@ INCLUDEPATH += $$PWD CONFIG += egl qpa/genericunixfontdatabase -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target - RESOURCES += cursor.qrc OTHER_FILES += \ diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 036b26a165..32d20e6aaa 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -89,8 +89,9 @@ void QEglFSWindow::create() m_window = hooks->createNativeWindow(hooks->screenSize(), m_format); m_surface = eglCreateWindowSurface(display, config, m_window, NULL); if (m_surface == EGL_NO_SURFACE) { + EGLint error = eglGetError(); eglTerminate(display); - qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", eglGetError()); + qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error); } } diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro index 2e8af5ba9d..57191d8d97 100644 --- a/src/plugins/platforms/kms/kms.pro +++ b/src/plugins/platforms/kms/kms.pro @@ -1,8 +1,9 @@ TARGET = qkms + +PLUGIN_TYPE = platforms load(qt_plugin) QT += core-private gui-private platformsupport-private opengl-private -DESTDIR = $$QT.gui.plugins/platforms DEFINES += MESA_EGL_NO_X11_HEADERS @@ -36,8 +37,5 @@ HEADERS = qkmsintegration.h \ qkmsudevdrmhandler.h \ qkmsvthandler.h -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target - OTHER_FILES += \ kms.json diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro index 9834dea7d5..2482a64469 100644 --- a/src/plugins/platforms/linuxfb/linuxfb.pro +++ b/src/plugins/platforms/linuxfb/linuxfb.pro @@ -1,7 +1,7 @@ TARGET = qlinuxfb -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/platforms +PLUGIN_TYPE = platforms +load(qt_plugin) QT += core-private gui-private platformsupport-private @@ -10,7 +10,4 @@ HEADERS = qlinuxfbintegration.h qlinuxfbscreen.h CONFIG += qpa/genericunixfontdatabase -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target - OTHER_FILES += linuxfb.json diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 6430ccde75..9c3d37269c 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -1,8 +1,9 @@ TARGET = qminimal + +PLUGIN_TYPE = platforms load(qt_plugin) QT += core-private gui-private platformsupport-private -DESTDIR = $$QT.gui.plugins/platforms SOURCES = main.cpp \ qminimalintegration.cpp \ @@ -11,6 +12,3 @@ HEADERS = qminimalintegration.h \ qminimalbackingstore.h OTHER_FILES += minimal.json - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp index 6a2db91e34..e9fab6d87c 100644 --- a/src/plugins/platforms/minimal/qminimalintegration.cpp +++ b/src/plugins/platforms/minimal/qminimalintegration.cpp @@ -74,6 +74,7 @@ bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) co { switch (cap) { case ThreadedPixmaps: return true; + case MultipleWindows: return true; default: return QPlatformIntegration::hasCapability(cap); } } diff --git a/src/plugins/platforms/minimalegl/minimalegl.pro b/src/plugins/platforms/minimalegl/minimalegl.pro index 22e3729ed7..23a6ad9708 100644 --- a/src/plugins/platforms/minimalegl/minimalegl.pro +++ b/src/plugins/platforms/minimalegl/minimalegl.pro @@ -1,10 +1,10 @@ TARGET = qminimalegl + +PLUGIN_TYPE = platforms load(qt_plugin) QT += core-private gui-private platformsupport-private -DESTDIR = $$QT.gui.plugins/platforms - #DEFINES += QEGL_EXTRA_DEBUG #DEFINES += Q_OPENKODE @@ -25,8 +25,5 @@ HEADERS = qminimaleglintegration.h \ CONFIG += egl qpa/genericunixfontdatabase -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target - OTHER_FILES += \ minimalegl.json diff --git a/src/plugins/platforms/openwfd/openwf.pro b/src/plugins/platforms/openwfd/openwf.pro index d913a84411..1b177cba04 100644 --- a/src/plugins/platforms/openwfd/openwf.pro +++ b/src/plugins/platforms/openwfd/openwf.pro @@ -1,7 +1,7 @@ TARGET = qopenwf +PLUGIN_TYPE = platforms load(qt_plugin) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms QT += core-private gui-private platformsupport-private @@ -36,6 +36,3 @@ SOURCES += \ LIBS += -lWFD -lgbm -lGLESv2 -lEGL -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target - diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index dc16016af3..30c95b1620 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -1,7 +1,5 @@ TARGET = qnx -include(../../qpluginbase.pri) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms QT += platformsupport platformsupport-private # Uncomment this to build with support for IMF once it becomes available in the BBNDK @@ -138,5 +136,5 @@ QMAKE_CXXFLAGS += -I./private include (../../../platformsupport/eglconvenience/eglconvenience.pri) include (../../../platformsupport/fontdatabases/fontdatabases.pri) -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target +PLUGIN_TYPE = platforms +load(qt_plugin) diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp index b8ec91d488..11babe3aaa 100644 --- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp @@ -71,7 +71,10 @@ QQnxRasterBackingStore::~QQnxRasterBackingStore() QPaintDevice *QQnxRasterBackingStore::paintDevice() { - return m_platformWindow->renderBuffer().image(); + if (m_platformWindow->hasBuffers()) + return m_platformWindow->renderBuffer().image(); + + return 0; } void QQnxRasterBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 097b5788f6..c668a8867d 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -374,10 +374,22 @@ QQnxBuffer &QQnxWindow::renderBuffer() // Check if render buffer is invalid if (m_currentBufferIndex == -1) { + // check if there are any buffers available + int bufferCount = 0; + int result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount); + + if (result != 0) { + qFatal("QQnxWindow: failed to query window buffer count, errno=%d", errno); + } + + if (bufferCount != MAX_BUFFER_COUNT) { + qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d", MAX_BUFFER_COUNT, bufferCount); + } + // Get all buffers available for rendering errno = 0; screen_buffer_t buffers[MAX_BUFFER_COUNT]; - int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers); + result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers); if (result != 0) { qFatal("QQnxWindow: failed to query window buffers, errno=%d", errno); } diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 6acfd6e602..03bb94db8f 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -1493,13 +1493,26 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryService(REFGUID guidServic *iface = 0; accessibleDebug("QWindowsIA2Accessible::QS(): %s", IIDToString(riid).constData()); - if (guidService == IID_IAccessible && riid == IID_IAccessible2) { - // The conditions for entering here should be ok (from _dicoveringInterfaces in IAccessible2.idl) - *iface = static_cast<IAccessible2*>(this); - } else if (guidService == IID_IAccessible && (riid == IID_IAccessible || riid == IID_IUnknown || riid == IID_IDispatch)) { - // The above conditions works with AccProbe and NVDA. - *iface = static_cast<IAccessible*>(this); - } else if (riid == IID_IAccessibleApplication) { + + if (guidService == IID_IAccessible) { + if (riid == IID_IServiceProvider) { + // do not end up calling QueryInterface for IID_IServiceProvider + *iface = 0; + } else if (riid == IID_IAccessible || riid == IID_IUnknown || riid == IID_IDispatch) { + // The above conditions works with AccProbe and NVDA. + *iface = static_cast<IAccessible*>(this); + } else { + // According to _dicoveringInterfaces Discovery of Interfaces, we should really only + // enter here if riid == IID_IAccessible2, but some screen readers does not like that, + // and other servers seems to have realized that. (Chrome and Mozilla for instance, + // calls QueryInterface more or less in the same way) + + // For instance, accProbe discovers IID_IAccessibleTable2 by a QueryService only. + return QueryInterface(riid, iface); + } + } + + if (riid == IID_IAccessibleApplication) { *iface = new AccessibleApplication; return S_OK; } diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 87cb224d49..9e5578d35d 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -43,12 +43,9 @@ #include "qwindowscontext.h" #include "qwindowswindow.h" +#include "qwindowsintegration.h" #include "qwindowstheme.h" // Color conversion helpers -#include <QtWidgets/QColorDialog> -#include <QtWidgets/QFontDialog> -#include <QtWidgets/QFileDialog> - #include <QtGui/QGuiApplication> #include <QtGui/QColor> @@ -60,6 +57,7 @@ #include <QtCore/QSharedPointer> #include <QtCore/QObject> #include <QtCore/QThread> +#include <QtCore/QSysInfo> #include <QtCore/private/qsystemlibrary_p.h> #include "qtwindows_additional.h" @@ -384,9 +382,10 @@ void eatMouseMove() \class QWindowsNativeDialogBase \brief Base class for Windows native dialogs. - Base clases for native dialogs that mimick the - behaviour of their QDialog counterparts as close as - possible. + Base classes for native dialogs (using the CLSID-based + dialog interfaces "IFileDialog", etc. available from Windows + Vista on) that mimick the behaviour of their QDialog + counterparts as close as possible. A major difference is that there is only an exec(), which is a modal, blocking call; there is no non-blocking show(). @@ -862,12 +861,45 @@ int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items, return itemCount; } -// Copy a string to an Utf16 buffer. -static inline void toBuffer(const QString &what, WCHAR **ptr) +// Split a list of name filters into description and actual filters +struct FilterSpec +{ + QString description; + QString filter; +}; + +static QList<FilterSpec> filterSpecs(const QStringList &filters, + bool hideFilterDetails, + int *totalStringLength) { - const int length = 1 + what.size(); - memcpy(*ptr, what.utf16(), length * sizeof(WCHAR)); - *ptr += length; + QList<FilterSpec> result; + result.reserve(filters.size()); + *totalStringLength = 0; + + const QRegExp filterSeparatorRE(QStringLiteral("[;\\s]+")); + const QString separator = QStringLiteral(";"); + Q_ASSERT(filterSeparatorRE.isValid()); + // Split filter specification as 'Texts (*.txt[;] *.doc)' + // into description and filters specification as '*.txt;*.doc' + foreach (const QString &filterString, filters) { + const int openingParenPos = filterString.lastIndexOf(QLatin1Char('(')); + const int closingParenPos = openingParenPos != -1 ? + filterString.indexOf(QLatin1Char(')'), openingParenPos + 1) : -1; + FilterSpec filterSpec; + filterSpec.filter = closingParenPos == -1 ? + QString(QLatin1Char('*')) : + filterString.mid(openingParenPos + 1, closingParenPos - openingParenPos - 1).trimmed(); + filterSpec.filter.replace(filterSeparatorRE, separator); + filterSpec.description = filterString; + if (hideFilterDetails && openingParenPos != -1) { // Do not show pattern in description + filterSpec.description.truncate(openingParenPos); + while (filterSpec.description.endsWith(QLatin1Char(' '))) + filterSpec.description.truncate(filterSpec.description.size() - 1); + } + *totalStringLength += filterSpec.filter.size() + filterSpec.description.size(); + result.push_back(filterSpec); + } + return result; } void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters) @@ -875,48 +907,30 @@ void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters) /* Populates an array of COMDLG_FILTERSPEC from list of filters, * store the strings in a flat, contiguous buffer. */ m_nameFilters = filters; - const int size = filters.size(); int totalStringLength = 0; - for (int i = 0; i < size; ++i) - totalStringLength += filters.at(i).size(); + const QList<FilterSpec> specs = filterSpecs(filters, m_hideFiltersDetails, &totalStringLength); + const int size = specs.size(); - QScopedArrayPointer<WCHAR> buffer(new WCHAR[totalStringLength * 2 + 2 * size]); + QScopedArrayPointer<WCHAR> buffer(new WCHAR[totalStringLength + 2 * size]); QScopedArrayPointer<COMDLG_FILTERSPEC> comFilterSpec(new COMDLG_FILTERSPEC[size]); const QString matchesAll = QStringLiteral(" (*)"); - const QRegExp filterSeparatorRE(QStringLiteral("[;\\s]+")); - const QString separator = QStringLiteral(";"); - Q_ASSERT(filterSeparatorRE.isValid()); - WCHAR *ptr = buffer.data(); // Split filter specification as 'Texts (*.txt[;] *.doc)' // into description and filters specification as '*.txt;*.doc' + for (int i = 0; i < size; ++i) { - QString filterString = filters.at(i); - const int openingParenPos = filterString.lastIndexOf(QLatin1Char('(')); - const int closingParenPos = openingParenPos != -1 ? - filterString.indexOf(QLatin1Char(')'), openingParenPos + 1) : -1; - QString filterSpec = closingParenPos == -1 ? - QString(QLatin1Char('*')) : - filterString.mid(openingParenPos + 1, closingParenPos - openingParenPos - 1).trimmed(); - filterSpec.replace(filterSeparatorRE, separator); - if (m_hideFiltersDetails) { - // Do not show pattern in description - if (openingParenPos != -1) { - filterString.truncate(openingParenPos); - while (filterString.endsWith(QLatin1Char(' '))) - filterString.truncate(filterString.size() - 1); - } - } else { - // Display glitch: 'All files (*)' shows up as 'All files (*) (*)' - if (filterString.endsWith(matchesAll)) - filterString.truncate(filterString.size() - matchesAll.size()); - } + // Display glitch (CLSID only): 'All files (*)' shows up as 'All files (*) (*)' + QString description = specs[i].description; + if (!m_hideFiltersDetails && description.endsWith(matchesAll)) + description.truncate(description.size() - matchesAll.size()); // Add to buffer. comFilterSpec[i].pszName = ptr; - toBuffer(filterString, &ptr); + ptr += description.toWCharArray(ptr); + *ptr++ = 0; comFilterSpec[i].pszSpec = ptr; - toBuffer(filterSpec, &ptr); + ptr += specs[i].filter.toWCharArray(ptr); + *ptr++ = 0; } m_fileDialog->SetFileTypes(size, comFilterSpec.data()); @@ -947,9 +961,23 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel } } +// Return the index of the selected filter, accounting for QFileDialog +// sometimes stripping the filter specification depending on the +// hideFilterDetails setting. +static int indexOfNameFilter(const QStringList &filters, const QString &needle) +{ + const int index = filters.indexOf(needle); + if (index >= 0) + return index; + for (int i = 0; i < filters.size(); ++i) + if (filters.at(i).startsWith(needle)) + return i; + return -1; +} + void QWindowsNativeFileDialogBase::selectNameFilter(const QString &filter) { - const int index = m_nameFilters.indexOf(filter); + const int index = indexOfNameFilter(m_nameFilters, filter); if (index >= 0) { m_fileDialog->SetFileTypeIndex(index + 1); // one-based. } else { @@ -1270,6 +1298,380 @@ QString QWindowsFileDialogHelper::selectedNameFilter() const return QString(); } +#ifndef Q_OS_WINCE + +/*! + \class QWindowsXpNativeFileDialog + \brief Native Windows directory dialog for Windows XP using SHlib-functions. + + Uses the synchronous GetOpenFileNameW(), GetSaveFileNameW() from ComDlg32 + or SHBrowseForFolder() for directories. + + \internal + \sa QWindowsXpFileDialogHelper + + \ingroup qt-lighthouse-win +*/ + +class QWindowsXpNativeFileDialog : public QWindowsNativeDialogBase +{ + Q_OBJECT +public: + typedef QSharedPointer<QFileDialogOptions> OptionsPtr; + + static QWindowsXpNativeFileDialog *create(const OptionsPtr &options); + + virtual void setWindowTitle(const QString &t) { m_title = t; } + virtual void exec(HWND owner = 0); + virtual QPlatformDialogHelper::DialogCode result() const { return m_result; } + + void setDirectory(const QString &d) { m_directory = d; } + QString directory() const { return m_directory; } + void selectFile(const QString &f) { m_initialFile = f; } + QStringList selectedFiles() const { return m_selectedFiles; } + void setNameFilters(const QStringList &n) { m_nameFilters = n; } + void selectNameFilter(const QString &f); + QString selectedNameFilter() const { return m_selectedNameFilter; } + + int existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam); + +public slots: + virtual void close() {} + +private: + typedef BOOL (APIENTRY *PtrGetOpenFileNameW)(LPOPENFILENAMEW); + typedef BOOL (APIENTRY *PtrGetSaveFileNameW)(LPOPENFILENAMEW); + + explicit QWindowsXpNativeFileDialog(const OptionsPtr &options); + void populateOpenFileName(OPENFILENAME *ofn, HWND owner) const; + QStringList execExistingDir(HWND owner); + QStringList execFileNames(HWND owner, int *selectedFilterIndex) const; + + const OptionsPtr m_options; + QString m_title; + QString m_directory; + QString m_initialFile; + QStringList m_selectedFiles; + QString m_selectedNameFilter; + QStringList m_nameFilters; + QPlatformDialogHelper::DialogCode m_result; + + static PtrGetOpenFileNameW m_getOpenFileNameW; + static PtrGetSaveFileNameW m_getSaveFileNameW; +}; + +QWindowsXpNativeFileDialog::PtrGetOpenFileNameW QWindowsXpNativeFileDialog::m_getOpenFileNameW = 0; +QWindowsXpNativeFileDialog::PtrGetSaveFileNameW QWindowsXpNativeFileDialog::m_getSaveFileNameW = 0; + +QWindowsXpNativeFileDialog *QWindowsXpNativeFileDialog::create(const OptionsPtr &options) +{ + // GetOpenFileNameW() GetSaveFileName() are resolved + // dynamically as not to create a dependency on Comdlg32, which + // is used on XP only. + if (!m_getOpenFileNameW) { + QSystemLibrary library(QStringLiteral("Comdlg32")); + m_getOpenFileNameW = (PtrGetOpenFileNameW)(library.resolve("GetOpenFileNameW")); + m_getSaveFileNameW = (PtrGetSaveFileNameW)(library.resolve("GetSaveFileNameW")); + } + if (m_getOpenFileNameW && m_getSaveFileNameW) + return new QWindowsXpNativeFileDialog(options); + return 0; +} + +QWindowsXpNativeFileDialog::QWindowsXpNativeFileDialog(const OptionsPtr &options) : + m_options(options), m_result(QPlatformDialogHelper::Rejected) +{ + const QStringList nameFilters = m_options->nameFilters(); + if (!nameFilters.isEmpty()) + setNameFilters(nameFilters); + const QString initialDirectory = m_options->initialDirectory(); + if (!initialDirectory.isEmpty()) + setDirectory(initialDirectory); + const QString initialNameFilter = m_options->initiallySelectedNameFilter(); + if (!initialNameFilter.isEmpty()) + selectNameFilter(initialNameFilter); + const QStringList selectedFiles = m_options->initiallySelectedFiles(); + if (!selectedFiles.isEmpty()) + selectFile(selectedFiles.front()); + setWindowTitle(m_options->windowTitle()); +} + +void QWindowsXpNativeFileDialog::selectNameFilter(const QString &f) +{ + const int index = indexOfNameFilter(m_nameFilters, f); + if (index >= 0) + m_selectedNameFilter = m_nameFilters.at(index); +} + +void QWindowsXpNativeFileDialog::exec(HWND owner) +{ + int selectedFilterIndex = -1; + m_selectedFiles = m_options->fileMode() == QFileDialogOptions::DirectoryOnly ? + execExistingDir(owner) : execFileNames(owner, &selectedFilterIndex); + QWindowsDialogs::eatMouseMove(); + if (m_selectedFiles.isEmpty()) { + m_result = QPlatformDialogHelper::Rejected; + emit rejected(); + } else { + if (selectedFilterIndex >= 0 && selectedFilterIndex < m_nameFilters.size()) { + m_selectedNameFilter = m_nameFilters.at(selectedFilterIndex); + } else { + m_selectedNameFilter.clear(); + } + m_directory = QFileInfo(m_selectedFiles.front()).absolutePath(); + m_result = QPlatformDialogHelper::Accepted; + emit accepted(); + } +} + +// Callback for QWindowsNativeXpFileDialog directory dialog. +// MFC Directory Dialog. Contrib: Steve Williams (minor parts from Scott Powers) + +static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + QWindowsXpNativeFileDialog *dialog = reinterpret_cast<QWindowsXpNativeFileDialog *>(lpData); + return dialog->existingDirCallback(hwnd, uMsg, lParam); +} + +#ifdef Q_CC_MINGW +typedef ITEMIDLIST *qt_LpItemIdList; +#else +typedef PIDLIST_ABSOLUTE qt_LpItemIdList; +#endif + +int QWindowsXpNativeFileDialog::existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam) +{ + switch (uMsg) { + case BFFM_INITIALIZED: + if (!m_initialFile.isEmpty()) + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, LPARAM(m_initialFile.utf16())); + break; + case BFFM_SELCHANGED: { + wchar_t path[MAX_PATH]; + const bool ok = SHGetPathFromIDList(reinterpret_cast<qt_LpItemIdList>(lParam), path) + && path[0]; + SendMessage(hwnd, BFFM_ENABLEOK, ok ? 1 : 0, 1); + } + break; + } + return 0; +} + +QStringList QWindowsXpNativeFileDialog::execExistingDir(HWND owner) +{ + BROWSEINFO bi; + wchar_t initPath[MAX_PATH]; + initPath[0] = 0; + bi.hwndOwner = owner; + bi.pidlRoot = NULL; + //### This does not seem to be respected? - the dialog always displays "Browse for folder" + bi.lpszTitle = (wchar_t*)m_title.utf16(); + bi.pszDisplayName = initPath; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NEWDIALOGSTYLE; + bi.lpfn = xpFileDialogGetExistingDirCallbackProc; + bi.lParam = LPARAM(this); + QStringList selectedFiles; + if (qt_LpItemIdList pItemIDList = SHBrowseForFolder(&bi)) { + wchar_t path[MAX_PATH]; + path[0] = 0; + if (SHGetPathFromIDList(pItemIDList, path) && path[0]) + selectedFiles.push_back(QDir::cleanPath(QString::fromWCharArray(path))); + IMalloc *pMalloc; + if (SHGetMalloc(&pMalloc) == NOERROR) { + pMalloc->Free(pItemIDList); + pMalloc->Release(); + } + } + return selectedFiles; +} + +// Return an allocated wchar_t array from a QString, reserve more memory if desired. +static wchar_t *qStringToWCharArray(const QString &s, size_t reserveSize = 0) +{ + const size_t stringSize = s.size(); + wchar_t *result = new wchar_t[qMax(stringSize + 1, reserveSize)]; + s.toWCharArray(result); + result[stringSize] = 0; + return result; +} + +// Open/Save files +void QWindowsXpNativeFileDialog::populateOpenFileName(OPENFILENAME *ofn, HWND owner) const +{ + ZeroMemory(ofn, sizeof(OPENFILENAME)); + ofn->lStructSize = sizeof(OPENFILENAME); + ofn->hwndOwner = owner; + + // Create a buffer with the filter strings. + int totalStringLength = 0; + QList<FilterSpec> specs = + filterSpecs(m_options->nameFilters(), m_options->options() & QFileDialogOptions::HideNameFilterDetails, &totalStringLength); + const int size = specs.size(); + wchar_t *ptr = new wchar_t[totalStringLength + 2 * size + 1]; + ofn->lpstrFilter = ptr; + foreach (const FilterSpec &spec, specs) { + ptr += spec.description.toWCharArray(ptr); + *ptr++ = 0; + ptr += spec.filter.toWCharArray(ptr); + *ptr++ = 0; + } + *ptr = 0; + const int nameFilterIndex = indexOfNameFilter(m_nameFilters, m_selectedNameFilter); + if (nameFilterIndex >= 0) + ofn->nFilterIndex = nameFilterIndex + 1; // 1..n based. + // lpstrFile receives the initial selection and is the buffer + // for the target. If it contains any invalid character, the dialog + // will not show. + ofn->nMaxFile = 65535; + const QString initiallySelectedFile = + QDir::toNativeSeparators(m_initialFile).remove(QLatin1Char('<')). + remove(QLatin1Char('>')).remove(QLatin1Char('"')).remove(QLatin1Char('|')); + ofn->lpstrFile = qStringToWCharArray(initiallySelectedFile, ofn->nMaxFile); + ofn->lpstrInitialDir = qStringToWCharArray(QDir::toNativeSeparators(m_directory)); + ofn->lpstrTitle = (wchar_t*)m_title.utf16(); + // Determine lpstrDefExt. Note that the current MSDN docs document this + // member wrong. It should rather be documented as "the default extension + // if no extension was given and if the current filter does not have an + // extension (e.g (*)). If the current filter has an extension, use + // the extension of the current filter". + if (m_options->acceptMode() == QFileDialogOptions::AcceptSave) { + QString defaultSuffix = m_options->defaultSuffix(); + if (defaultSuffix.startsWith(QLatin1Char('.'))) + defaultSuffix.remove(0, 1); + if (!defaultSuffix.isEmpty()) + ofn->lpstrDefExt = qStringToWCharArray(defaultSuffix); + } + // Flags. + ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST); + if (m_options->fileMode() == QFileDialogOptions::ExistingFile + || m_options->fileMode() == QFileDialogOptions::ExistingFiles) + ofn->Flags |= (OFN_FILEMUSTEXIST); + if (m_options->fileMode() == QFileDialogOptions::ExistingFiles) + ofn->Flags |= (OFN_ALLOWMULTISELECT); + if (!(m_options->options() & QFileDialogOptions::DontConfirmOverwrite)) + ofn->Flags |= OFN_OVERWRITEPROMPT; +} + +QStringList QWindowsXpNativeFileDialog::execFileNames(HWND owner, int *selectedFilterIndex) const +{ + *selectedFilterIndex = -1; + OPENFILENAME ofn; + populateOpenFileName(&ofn, owner); + QStringList result; + const bool isSave = m_options->acceptMode() == QFileDialogOptions::AcceptSave; + if (isSave ? m_getSaveFileNameW(&ofn) : m_getOpenFileNameW(&ofn)) { + *selectedFilterIndex = ofn.nFilterIndex - 1; + result.push_back(QDir::cleanPath(QString::fromWCharArray(ofn.lpstrFile))); + // For multiselection, the first item is the path followed + // by "\0<file1>\0<file2>\0\0". + if (ofn.Flags & (OFN_ALLOWMULTISELECT)) { + wchar_t *ptr = ofn.lpstrFile + result.front().size() + 1; + if (*ptr) { + const QString path = result.takeAt(0) + QLatin1Char('/'); + while (*ptr) { + const QString fileName = QString::fromWCharArray(ptr); + result.push_back(path + fileName); + ptr += fileName.size() + 1; + } // extract multiple files + } // has multiple files + } // multiple flag set + } + delete [] ofn.lpstrFile; + delete [] ofn.lpstrInitialDir; + delete [] ofn.lpstrFilter; + delete [] ofn.lpstrDefExt; + return result; +} + +/*! + \class QWindowsXpFileDialogHelper + \brief Dialog helper using QWindowsXpNativeFileDialog + + \sa QWindowsXpNativeFileDialog + \internal + \ingroup qt-lighthouse-win +*/ + +class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDialogHelper> +{ +public: + QWindowsXpFileDialogHelper() {} + virtual bool supportsNonModalDialog() const { return false; } + + virtual bool defaultNameFilterDisables() const + { return true; } + virtual void setDirectory(const QString &directory); + virtual QString directory() const; + virtual void selectFile(const QString &filename); + virtual QStringList selectedFiles() const; + virtual void setFilter() {} + virtual void setNameFilters(const QStringList &); + virtual void selectNameFilter(const QString &); + virtual QString selectedNameFilter() const; + +private: + virtual QWindowsNativeDialogBase *createNativeDialog(); + inline QWindowsXpNativeFileDialog *nativeFileDialog() const + { return static_cast<QWindowsXpNativeFileDialog *>(nativeDialog()); } +}; + +QWindowsNativeDialogBase *QWindowsXpFileDialogHelper::createNativeDialog() +{ + if (QWindowsNativeDialogBase *result = QWindowsXpNativeFileDialog::create(options())) { + QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept())); + QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject())); + return result; + } + return 0; +} + +void QWindowsXpFileDialogHelper::setDirectory(const QString &directory) +{ + if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) + nfd->setDirectory(directory); +} + +QString QWindowsXpFileDialogHelper::directory() const +{ + if (const QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) + return nfd->directory(); + return QString(); +} + +void QWindowsXpFileDialogHelper::selectFile(const QString &filename) +{ + if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) + nfd->selectFile(filename); +} + +QStringList QWindowsXpFileDialogHelper::selectedFiles() const +{ + if (const QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) + return nfd->selectedFiles(); + return QStringList(); +} + +void QWindowsXpFileDialogHelper::setNameFilters(const QStringList &n) +{ + if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) + nfd->setNameFilters(n); +} + +void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f) +{ + if (QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) + nfd->selectNameFilter(f); +} + +QString QWindowsXpFileDialogHelper::selectedNameFilter() const +{ + if (const QWindowsXpNativeFileDialog *nfd = nativeFileDialog()) + return nfd->selectedNameFilter(); + return QString(); +} + +#endif // Q_OS_WINCE + /*! \class QWindowsNativeColorDialog \brief Native Windows color dialog. @@ -1399,10 +1801,11 @@ namespace QWindowsDialogs { // QWindowsDialogHelperBase creation functions bool useHelper(QPlatformTheme::DialogType type) { + if (QWindowsIntegration::instance()->options() & QWindowsIntegration::NoNativeDialogs) + return false; switch (type) { case QPlatformTheme::FileDialog: - return true; - break; + return QSysInfo::windowsVersion() >= QSysInfo::WV_XP; case QPlatformTheme::ColorDialog: #ifdef USE_NATIVE_COLOR_DIALOG return true; @@ -1417,9 +1820,20 @@ bool useHelper(QPlatformTheme::DialogType type) QPlatformDialogHelper *createHelper(QPlatformTheme::DialogType type) { + if (QWindowsIntegration::instance()->options() & QWindowsIntegration::NoNativeDialogs) + return 0; switch (type) { case QPlatformTheme::FileDialog: +#ifndef Q_OS_WINCE + if (QWindowsIntegration::instance()->options() & QWindowsIntegration::XpNativeDialogs + || QSysInfo::windowsVersion() == QSysInfo::WV_XP) { + return new QWindowsXpFileDialogHelper(); + } + if (QSysInfo::windowsVersion() > QSysInfo::WV_XP) + return new QWindowsFileDialogHelper(); +#else return new QWindowsFileDialogHelper(); +#endif // Q_OS_WINCE case QPlatformTheme::ColorDialog: #ifdef USE_NATIVE_COLOR_DIALOG return new QWindowsColorDialogHelper(); diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index f74b2140f6..805046c715 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -301,9 +301,15 @@ public: STDMETHOD(GiveFeedback)(DWORD dwEffect); private: - typedef QMap <Qt::DropAction, HCURSOR> ActionCursorMap; - - inline void clearCursors(); + class DragCursorHandle { + Q_DISABLE_COPY(DragCursorHandle) + public: + DragCursorHandle(HCURSOR c, quint64 k) : cursor(c), cacheKey(k) {} + ~DragCursorHandle() { DestroyCursor(cursor); } + HCURSOR cursor; + quint64 cacheKey; + }; + typedef QMap <Qt::DropAction, QSharedPointer<DragCursorHandle> > ActionCursorMap; QWindowsDrag *m_drag; Qt::MouseButtons m_currentButtons; @@ -322,7 +328,7 @@ QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) : QWindowsOleDropSource::~QWindowsOleDropSource() { - clearCursors(); + m_cursors.clear(); if (QWindowsContext::verboseOLE) qDebug("%s", __FUNCTION__); } @@ -347,10 +353,14 @@ void QWindowsOleDropSource::createCursors() QPixmap cpm = drag->dragCursor(action); if (cpm.isNull()) cpm = m_drag->defaultCursor(action); + QSharedPointer<DragCursorHandle> cursorHandler = m_cursors.value(action); + if (!cursorHandler.isNull() && cpm.cacheKey() == cursorHandler->cacheKey) + continue; if (cpm.isNull()) { qWarning("%s: Unable to obtain drag cursor for %d.", __FUNCTION__, action); continue; } + int w = cpm.width(); int h = cpm.height(); @@ -380,23 +390,14 @@ void QWindowsOleDropSource::createCursors() const int hotX = hasPixmap ? qMax(0,newHotSpot.x()) : 0; const int hotY = hasPixmap ? qMax(0,newHotSpot.y()) : 0; - if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY)) - m_cursors.insert(actions.at(cnum), sysCursor); + if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY)) { + m_cursors.insert(action, QSharedPointer<DragCursorHandle>(new DragCursorHandle(sysCursor, cpm.cacheKey()))); + } } if (QWindowsContext::verboseOLE) qDebug("%s %d cursors", __FUNCTION__, m_cursors.size()); } -void QWindowsOleDropSource::clearCursors() -{ - if (!m_cursors.isEmpty()) { - const ActionCursorMap::const_iterator cend = m_cursors.constEnd(); - for (ActionCursorMap::const_iterator it = m_cursors.constBegin(); it != cend; ++it) - DestroyCursor(it.value()); - m_cursors.clear(); - } -} - //--------------------------------------------------------------------- // IUnknown Methods //--------------------------------------------------------------------- @@ -488,9 +489,14 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) if (QWindowsContext::verboseOLE > 2) qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action); + QSharedPointer<DragCursorHandle> cursorHandler = m_cursors.value(action); + quint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey(); + if (cursorHandler.isNull() || currentCacheKey != cursorHandler->cacheKey) + createCursors(); + const ActionCursorMap::const_iterator it = m_cursors.constFind(action); if (it != m_cursors.constEnd()) { - SetCursor(it.value()); + SetCursor(it.value()->cursor); return ResultFromScode(S_OK); } @@ -595,6 +601,9 @@ QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->DragEnter(reinterpret_cast<HWND>(m_window->winId()), pDataObj, reinterpret_cast<POINT*>(&pt), *pdwEffect); + if (QWindowsContext::verboseOLE) qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, m_window, grfKeyState, pt.x, pt.y); @@ -608,6 +617,9 @@ QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->DragOver(reinterpret_cast<POINT*>(&pt), *pdwEffect); + QWindow *dragOverWindow = findDragOverWindow(pt); if (QWindowsContext::verboseOLE) qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, dragOverWindow, grfKeyState, pt.x, pt.y); @@ -628,6 +640,9 @@ QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QWindowsOleDropTarget::DragLeave() { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->DragLeave(); + if (QWindowsContext::verboseOLE) qDebug().nospace() <<__FUNCTION__ << ' ' << m_window; @@ -640,9 +655,12 @@ QWindowsOleDropTarget::DragLeave() #define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, +QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { + if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper()) + dh->Drop(pDataObj, reinterpret_cast<POINT*>(&pt), *pdwEffect); + QWindow *dropWindow = findDragOverWindow(pt); if (QWindowsContext::verboseOLE) @@ -700,6 +718,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, return NOERROR; } + /*! \class QWindowsDrag \brief Windows drag implementation. @@ -707,12 +726,15 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, \ingroup qt-lighthouse-win */ -QWindowsDrag::QWindowsDrag() : m_dropDataObject(0) +QWindowsDrag::QWindowsDrag() : + m_dropDataObject(0), m_cachedDropTargetHelper(0) { } QWindowsDrag::~QWindowsDrag() { + if (m_cachedDropTargetHelper) + m_cachedDropTargetHelper->Release(); } /*! @@ -726,6 +748,18 @@ QMimeData *QWindowsDrag::dropData() return &m_dropData; } +/*! + \brief May be used to handle extended cursors functionality for drags from outside the app. +*/ +IDropTargetHelper* QWindowsDrag::dropHelper() { + if (!m_cachedDropTargetHelper) { + CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, + IID_IDropTargetHelper, + reinterpret_cast<void**>(&m_cachedDropTargetHelper)); + } + return m_cachedDropTargetHelper; +} + QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const { switch (action) { diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h index ab06545884..d3bfd36955 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.h +++ b/src/plugins/platforms/windows/qwindowsdrag.h @@ -47,6 +47,8 @@ #include <qpa/qplatformdrag.h> #include <QtGui/QPixmap> +struct IDropTargetHelper; + QT_BEGIN_NAMESPACE class QWindowsDropMimeData : public QWindowsInternalMimeData { public: @@ -100,12 +102,16 @@ public: void releaseDropDataObject(); QMimeData *dropData(); + IDropTargetHelper* dropHelper(); + QPixmap defaultCursor(Qt::DropAction action) const; private: QWindowsDropMimeData m_dropData; IDataObject *m_dropDataObject; + IDropTargetHelper* m_cachedDropTargetHelper; + mutable QPixmap m_copyDragCursor; mutable QPixmap m_moveDragCursor; mutable QPixmap m_linkDragCursor; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index b7309c3f7c..a02f0cd494 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -279,6 +279,12 @@ static inline unsigned parseOptions(const QStringList ¶mList) } else if (param.endsWith(QLatin1String("native"))) { options |= QWindowsIntegration::FontDatabaseNative; } + } else if (param.startsWith(QLatin1String("dialogs="))) { + if (param.endsWith(QLatin1String("xp"))) { + options |= QWindowsIntegration::XpNativeDialogs; + } else if (param.endsWith(QLatin1String("none"))) { + options |= QWindowsIntegration::NoNativeDialogs; + } } else if (param == QLatin1String("gl=gdi")) { options |= QWindowsIntegration::DisableArb; } @@ -332,6 +338,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co #endif // !QT_NO_OPENGL case WindowMasks: return true; + case MultipleWindows: + return true; default: return QPlatformIntegration::hasCapability(cap); } diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index ca47dabb4b..abf663c052 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -56,7 +56,9 @@ public: enum Options { // Options to be passed on command line. FontDatabaseFreeType = 0x1, FontDatabaseNative = 0x2, - DisableArb = 0x4 + DisableArb = 0x4, + NoNativeDialogs = 0x8, + XpNativeDialogs = 0x10 }; explicit QWindowsIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index d9de911914..2fb905d23b 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -509,6 +509,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con case TrashIcon: resourceId = 191; break; +#ifndef Q_OS_WINCE case MessageBoxInformation: iconName = IDI_INFORMATION; break; @@ -538,6 +539,7 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con } } break; +#endif default: break; } diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 1527f0e496..ca356e1276 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -1,4 +1,6 @@ TARGET = windows + +PLUGIN_TYPE = platforms load(qt_plugin) QT *= core-private @@ -6,7 +8,6 @@ QT *= gui-private QT *= platformsupport-private INCLUDEPATH += ../../../3rdparty/harfbuzz/src -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms # Note: OpenGL32 must precede Gdi32 as it overwrites some functions. LIBS *= -lole32 @@ -172,6 +173,3 @@ contains(QT_CONFIG, freetype) { OTHER_FILES += windows.json contains(QT_CONFIG, accessibility):include(accessible/accessible.pri) - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 0510c1db5b..c1cfbd02d6 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -508,16 +508,16 @@ xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor) return c; } -void QXcbCursor::queryPointer(xcb_connection_t *conn, xcb_window_t *rootWin, QPoint *pos, int *keybMask) +void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask) { if (pos) *pos = QPoint(); - xcb_screen_iterator_t it = xcb_setup_roots_iterator(xcb_get_setup(conn)); + xcb_screen_iterator_t it = xcb_setup_roots_iterator(c->setup()); while (it.rem) { xcb_window_t root = it.data->root; - xcb_query_pointer_cookie_t cookie = xcb_query_pointer(conn, root); + xcb_query_pointer_cookie_t cookie = xcb_query_pointer(c->xcb_connection(), root); xcb_generic_error_t *err = 0; - xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(conn, cookie, &err); + xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(c->xcb_connection(), cookie, &err); if (!err && reply) { if (pos) *pos = QPoint(reply->root_x, reply->root_y); @@ -537,17 +537,16 @@ void QXcbCursor::queryPointer(xcb_connection_t *conn, xcb_window_t *rootWin, QPo QPoint QXcbCursor::pos() const { QPoint p; - queryPointer(xcb_connection(), 0, &p); + queryPointer(connection(), 0, &p); return p; } void QXcbCursor::setPos(const QPoint &pos) { - xcb_connection_t *conn = xcb_connection(); xcb_window_t root; - queryPointer(conn, &root, 0); - xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y()); - xcb_flush(conn); + queryPointer(connection(), &root, 0); + xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y()); + xcb_flush(xcb_connection()); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 9726c5955a..4c74034988 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -56,7 +56,7 @@ public: QPoint pos() const; void setPos(const QPoint &pos); - static void queryPointer(xcb_connection_t *conn, xcb_window_t *rootWin, QPoint *pos, int *keybMask = 0); + static void queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask = 0); private: xcb_cursor_t createFontCursor(int cshape); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 5170ff9e10..2ffe53c04b 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -216,6 +216,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const #endif case ThreadedOpenGL: return false; case WindowMasks: return true; + case MultipleWindows: return true; default: return QPlatformIntegration::hasCapability(cap); } } @@ -275,8 +276,8 @@ QPlatformServices *QXcbIntegration::services() const Qt::KeyboardModifiers QXcbIntegration::queryKeyboardModifiers() const { int keybMask = 0; - QXcbConnection* conn = m_connections.at(0); - QXcbCursor::queryPointer(conn->xcb_connection(), 0, 0, &keybMask); + QXcbConnection *conn = m_connections.at(0); + QXcbCursor::queryPointer(conn, 0, 0, &keybMask); return conn->keyboard()->translateModifiers(keybMask); } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 2a36fb7369..fa5f5f43d0 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -53,6 +53,8 @@ #if defined(XCB_USE_EGL) #include "QtPlatformSupport/private/qeglplatformcontext_p.h" +#elif defined (XCB_USE_GLX) +#include "qglxintegration.h" #endif QT_BEGIN_NAMESPACE @@ -68,6 +70,7 @@ public: insert("connection",QXcbNativeInterface::Connection); insert("screen",QXcbNativeInterface::Screen); insert("eglcontext",QXcbNativeInterface::EglContext); + insert("glxcontext",QXcbNativeInterface::GLXContext); } }; @@ -91,6 +94,9 @@ void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceSt case EglContext: result = eglContextForContext(context); break; + case GLXContext: + result = glxContextForContext(context); + break; default: break; } @@ -191,4 +197,17 @@ void * QXcbNativeInterface::eglContextForContext(QOpenGLContext *context) #endif } +void *QXcbNativeInterface::glxContextForContext(QOpenGLContext *context) +{ + Q_ASSERT(context); +#if defined(XCB_USE_GLX) + QGLXContext *glxPlatformContext = static_cast<QGLXContext *>(context->handle()); + return glxPlatformContext->glxContext(); +#else + Q_UNUSED(context); + return 0; +#endif + +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 1223fdc39c..c15d00255a 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -58,7 +58,8 @@ public: Connection, Screen, GraphicsDevice, - EglContext + EglContext, + GLXContext }; QXcbNativeInterface(); @@ -76,6 +77,7 @@ public: void *screenForWindow(QWindow *window); void *graphicsDeviceForWindow(QWindow *window); static void *eglContextForContext(QOpenGLContext *context); + static void *glxContextForContext(QOpenGLContext *context); private: const QByteArray m_genericEventFilterType; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 48754b0a60..eab18e2435 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -542,16 +542,18 @@ void QXcbWindow::show() propagateSizeHints(); // update WM_TRANSIENT_FOR - if (window()->transientParent() && isTransient(window())) { - QXcbWindow *transientXcbParent = static_cast<QXcbWindow *>(window()->transientParent()->handle()); - if (transientXcbParent) { - // ICCCM 4.1.2.6 - xcb_window_t parentWindow = transientXcbParent->xcb_window(); - - // todo: set transient for group (wm_client_leader) if no parent, a la qwidget_x11.cpp + if (isTransient(window())) { + xcb_window_t transientXcbParent = 0; + if (const QWindow *tp = window()->transientParent()) + transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId(); + // Default to client leader if there is no transient parent, else modal dialogs can + // be hidden by their parents. + if (!transientXcbParent) + transientXcbParent = static_cast<QXcbScreen *>(screen())->clientLeader(); + if (transientXcbParent) { // ICCCM 4.1.2.6 Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, - 1, &parentWindow)); + 1, &transientXcbParent)); } } diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro index 58521686aa..34f7c74675 100644 --- a/src/plugins/platforms/xcb/xcb.pro +++ b/src/plugins/platforms/xcb/xcb.pro @@ -1,7 +1,7 @@ TARGET = xcb +PLUGIN_TYPE = platforms load(qt_plugin) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms QT += core-private gui-private platformsupport-private @@ -110,6 +110,3 @@ LIBS += -ldbus-1 } OTHER_FILES += xcb.json - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/plugins/printsupport/cocoa/cocoa.pro b/src/plugins/printsupport/cocoa/cocoa.pro index 477715a8e2..4e99b4a8f5 100644 --- a/src/plugins/printsupport/cocoa/cocoa.pro +++ b/src/plugins/printsupport/cocoa/cocoa.pro @@ -1,6 +1,7 @@ TARGET = cocoaprintersupport + +PLUGIN_TYPE = printsupport load(qt_plugin) -DESTDIR = $$QT.gui.plugins/printsupport QT += gui-private printsupport-private LIBS += -framework Cocoa @@ -8,6 +9,3 @@ LIBS += -framework Cocoa SOURCES += main.cpp OTHER_FILES += cocoa.json - -target.path += $$[QT_INSTALL_PLUGINS]/printsupport -INSTALLS += target diff --git a/src/plugins/printsupport/cups/cups.pro b/src/plugins/printsupport/cups/cups.pro index f23ad3fb5e..bd0b6af114 100644 --- a/src/plugins/printsupport/cups/cups.pro +++ b/src/plugins/printsupport/cups/cups.pro @@ -1,6 +1,7 @@ TARGET = cupsprintersupport + +PLUGIN_TYPE = printsupport load(qt_plugin) -DESTDIR = $$QT.gui.plugins/printsupport QT += core-private gui-private printsupport printsupport-private @@ -14,6 +15,3 @@ HEADERS += qcupsprintersupport_p.h \ qcupsprintengine_p.h OTHER_FILES += cups.json - -target.path += $$[QT_INSTALL_PLUGINS]/printsupport -INSTALLS += target diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro index 3c5f22d411..5e8738554c 100644 --- a/src/plugins/printsupport/windows/windows.pro +++ b/src/plugins/printsupport/windows/windows.pro @@ -1,11 +1,12 @@ -TARGET = windows +TARGET = windowsprintersupport + +PLUGIN_TYPE = printsupport load(qt_plugin) QT *= core-private QT *= gui-private QT *= printsupport-private -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/printsupport INCLUDEPATH *= $$QT_SOURCE_TREE/src/printsupport/kernel SOURCES += \ @@ -17,6 +18,4 @@ HEADERS += \ OTHER_FILES += windows.json -target.path += $$[QT_INSTALL_PLUGINS]/printsupport -INSTALLS += target LIBS += -lwinspool -lcomdlg32 diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri deleted file mode 100644 index b22a527761..0000000000 --- a/src/plugins/qpluginbase.pri +++ /dev/null @@ -1 +0,0 @@ -load(qt_plugin) diff --git a/src/plugins/sqldrivers/qsqldriverbase.pri b/src/plugins/sqldrivers/qsqldriverbase.pri index 45638fcd4f..17424f6764 100644 --- a/src/plugins/sqldrivers/qsqldriverbase.pri +++ b/src/plugins/sqldrivers/qsqldriverbase.pri @@ -1,8 +1,6 @@ -load(qt_plugin) QT = core sql-private -DESTDIR = $$QT.sql.plugins/sqldrivers -target.path += $$[QT_INSTALL_PLUGINS]/sqldrivers -INSTALLS += target +PLUGIN_TYPE = sqldrivers +load(qt_plugin) DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII |