Merge "Merge remote-tracking branch 'origin/5.11' into dev" into refs/staging/dev
This commit is contained in:
commit
100ebf1c97
@ -292,6 +292,7 @@ Gui, printing, widget options:
|
||||
(-qt-xcb still uses system version of libxcb itself)
|
||||
|
||||
Input backends:
|
||||
-libudev............ Enable udev support [auto]
|
||||
-evdev ............. Enable evdev support [auto]
|
||||
-imf ............... Enable IMF support [auto] (QNX only)
|
||||
-libinput .......... Enable libinput support [auto]
|
||||
|
@ -8,21 +8,21 @@ contains(QMAKE_MAC_SDK, .*/.*): \
|
||||
defineReplace(xcodeSDKInfo) {
|
||||
info = $$1
|
||||
equals(info, "Path"): \
|
||||
info = --show-sdk-path
|
||||
infoarg = --show-sdk-path
|
||||
equals(info, "PlatformPath"): \
|
||||
info = --show-sdk-platform-path
|
||||
infoarg = --show-sdk-platform-path
|
||||
equals(info, "SDKVersion"): \
|
||||
info = --show-sdk-version
|
||||
infoarg = --show-sdk-version
|
||||
sdk = $$2
|
||||
isEmpty(sdk): \
|
||||
sdk = $$QMAKE_MAC_SDK
|
||||
|
||||
isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) {
|
||||
QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$info 2>/dev/null")
|
||||
QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$infoarg 2>/dev/null")
|
||||
# --show-sdk-platform-path won't work for Command Line Tools; this is fine
|
||||
# only used by the XCTest backend to testlib
|
||||
isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(info, "--show-sdk-platform-path")): \
|
||||
error("Could not resolve SDK $$info for \'$$sdk\'")
|
||||
isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(infoarg, "--show-sdk-platform-path")): \
|
||||
error("Could not resolve SDK $$info for \'$$sdk\' using $$infoarg")
|
||||
cache(QMAKE_MAC_SDK.$${sdk}.$${info}, set stash, QMAKE_MAC_SDK.$${sdk}.$${info})
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
!isEmpty(SOURCES) {
|
||||
QT += qml qmltest
|
||||
load(testcase)
|
||||
CONFIG -= app_bundle
|
||||
DEFINES += QUICK_TEST_SOURCE_DIR=\"\\\"$$_PRO_FILE_PWD_\\\"\"
|
||||
} else {
|
||||
# Allow a project to run tests without a CPP stub
|
||||
|
@ -172,9 +172,10 @@ QFuture<QImage> thumbNails =
|
||||
|
||||
//! [13]
|
||||
QList<QImage> images = ...;
|
||||
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, [](const QImage &img) {
|
||||
std::function<QImage(const QImage &)> scale = [](const QImage &img) {
|
||||
return img.scaledToWidth(100, Qt::SmoothTransformation);
|
||||
});
|
||||
};
|
||||
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, scale);
|
||||
//! [13]
|
||||
|
||||
//! [14]
|
||||
|
@ -347,15 +347,15 @@ Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode)
|
||||
|
||||
void qt_apple_check_os_version()
|
||||
{
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
const char *os = "iOS";
|
||||
const int version = __IPHONE_OS_VERSION_MIN_REQUIRED;
|
||||
#if defined(__WATCH_OS_VERSION_MIN_REQUIRED)
|
||||
const char *os = "watchOS";
|
||||
const int version = __WATCH_OS_VERSION_MIN_REQUIRED;
|
||||
#elif defined(__TV_OS_VERSION_MIN_REQUIRED)
|
||||
const char *os = "tvOS";
|
||||
const int version = __TV_OS_VERSION_MIN_REQUIRED;
|
||||
#elif defined(__WATCH_OS_VERSION_MIN_REQUIRED)
|
||||
const char *os = "watchOS";
|
||||
const int version = __WATCH_OS_VERSION_MIN_REQUIRED;
|
||||
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
const char *os = "iOS";
|
||||
const int version = __IPHONE_OS_VERSION_MIN_REQUIRED;
|
||||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
const char *os = "macOS";
|
||||
const int version = __MAC_OS_X_VERSION_MIN_REQUIRED;
|
||||
|
@ -309,7 +309,7 @@
|
||||
|
||||
\endomit
|
||||
|
||||
\sa QSharedDataPointer, QWeakPointer, QScopedPointer
|
||||
\sa QSharedDataPointer, QWeakPointer, QScopedPointer, QEnableSharedFromThis
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "qnetworkinterface_p.h"
|
||||
#include "qnetworkinterface_unix_p.h"
|
||||
|
||||
#ifndef QT_NO_NETWORKINTERFACE
|
||||
|
||||
#include <qendian.h>
|
||||
#include <qobjectdefs.h>
|
||||
#include <qvarlengtharray.h>
|
||||
@ -448,3 +450,5 @@ QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan()
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_NETWORKINTERFACE
|
||||
|
@ -226,7 +226,6 @@ bool shouldBeIgnored(QAccessibleInterface *interface)
|
||||
const QAccessible::Role role = interface->role();
|
||||
if (role == QAccessible::Border || // QFrame
|
||||
role == QAccessible::Application || // We use the system-provided application element.
|
||||
role == QAccessible::MenuItem || // The system also provides the menu items.
|
||||
role == QAccessible::ToolBar || // Access the tool buttons directly.
|
||||
role == QAccessible::Pane || // Scroll areas.
|
||||
role == QAccessible::Client) // The default for QWidget.
|
||||
|
@ -90,7 +90,9 @@ QPalette * qt_mac_createSystemPalette()
|
||||
palette->setColor(QPalette::Disabled, QPalette::Text, qc);
|
||||
palette->setColor(QPalette::Disabled, QPalette::WindowText, qc);
|
||||
palette->setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
|
||||
palette->setBrush(QPalette::ToolTipBase, QColor(255, 255, 199));
|
||||
|
||||
palette->setBrush(QPalette::ToolTipBase, qt_mac_toQBrush([NSColor controlColor]));
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
|
@ -50,11 +50,10 @@
|
||||
|
||||
@implementation QIOSApplicationDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
|
||||
{
|
||||
Q_UNUSED(application);
|
||||
Q_UNUSED(sourceApplication);
|
||||
Q_UNUSED(annotation);
|
||||
Q_UNUSED(options);
|
||||
|
||||
if (!QGuiApplication::instance())
|
||||
return NO;
|
||||
|
@ -56,8 +56,8 @@ public:
|
||||
static Qt::ApplicationState toQtApplicationState(UIApplicationState state);
|
||||
|
||||
Q_SIGNALS:
|
||||
void applicationStateWillChange(Qt::ApplicationState);
|
||||
void applicationStateDidChange(Qt::ApplicationState);
|
||||
void applicationStateWillChange(Qt::ApplicationState oldState, Qt::ApplicationState newState);
|
||||
void applicationStateDidChange(Qt::ApplicationState oldState, Qt::ApplicationState newState);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -87,18 +87,18 @@ QIOSApplicationState::QIOSApplicationState()
|
||||
|
||||
void QIOSApplicationState::handleApplicationStateChanged(UIApplicationState uiState, const QString &reason)
|
||||
{
|
||||
Qt::ApplicationState state = toQtApplicationState(uiState);
|
||||
qCDebug(lcQpaApplication) << qPrintable(reason)
|
||||
<< "- moving from" << QGuiApplication::applicationState() << "to" << state;
|
||||
Qt::ApplicationState oldState = QGuiApplication::applicationState();
|
||||
Qt::ApplicationState newState = toQtApplicationState(uiState);
|
||||
qCDebug(lcQpaApplication) << qPrintable(reason) << "- moving from" << oldState << "to" << newState;
|
||||
|
||||
if (QIOSIntegration *integration = QIOSIntegration::instance()) {
|
||||
emit integration->applicationState.applicationStateWillChange(state);
|
||||
QWindowSystemInterface::handleApplicationStateChanged(state);
|
||||
emit integration->applicationState.applicationStateDidChange(state);
|
||||
qCDebug(lcQpaApplication) << "done moving to" << state;
|
||||
emit integration->applicationState.applicationStateWillChange(oldState, newState);
|
||||
QWindowSystemInterface::handleApplicationStateChanged(newState);
|
||||
emit integration->applicationState.applicationStateDidChange(oldState, newState);
|
||||
qCDebug(lcQpaApplication) << "done moving to" << newState;
|
||||
} else {
|
||||
qCDebug(lcQpaApplication) << "no platform integration yet, setting state directly";
|
||||
QGuiApplicationPrivate::applicationState = state;
|
||||
QGuiApplicationPrivate::applicationState = newState;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,29 +301,34 @@ bool QIOSContext::verifyGraphicsHardwareAvailability()
|
||||
static dispatch_once_t onceToken = 0;
|
||||
dispatch_once(&onceToken, ^{
|
||||
QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState;
|
||||
connect(applicationState, &QIOSApplicationState::applicationStateWillChange, [](Qt::ApplicationState state) {
|
||||
if (applicationBackgrounded && state != Qt::ApplicationSuspended) {
|
||||
qCDebug(lcQpaGLContext) << "app no longer backgrounded, rendering enabled";
|
||||
applicationBackgrounded = false;
|
||||
connect(applicationState, &QIOSApplicationState::applicationStateWillChange,
|
||||
[](Qt::ApplicationState oldState, Qt::ApplicationState newState) {
|
||||
Q_UNUSED(oldState);
|
||||
if (applicationBackgrounded && newState != Qt::ApplicationSuspended) {
|
||||
qCDebug(lcQpaGLContext) << "app no longer backgrounded, rendering enabled";
|
||||
applicationBackgrounded = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(applicationState, &QIOSApplicationState::applicationStateDidChange, [](Qt::ApplicationState state) {
|
||||
if (state != Qt::ApplicationSuspended)
|
||||
return;
|
||||
);
|
||||
connect(applicationState, &QIOSApplicationState::applicationStateDidChange,
|
||||
[](Qt::ApplicationState oldState, Qt::ApplicationState newState) {
|
||||
Q_UNUSED(oldState);
|
||||
if (newState != Qt::ApplicationSuspended)
|
||||
return;
|
||||
|
||||
qCDebug(lcQpaGLContext) << "app backgrounded, rendering disabled";
|
||||
applicationBackgrounded = true;
|
||||
qCDebug(lcQpaGLContext) << "app backgrounded, rendering disabled";
|
||||
|
||||
// By the time we receive this signal the application has moved into
|
||||
// Qt::ApplactionStateSuspended, and all windows have been obscured,
|
||||
// which should stop all rendering. If there's still an active GL context,
|
||||
// we follow Apple's advice and call glFinish before making it inactive.
|
||||
if (QOpenGLContext *currentContext = QOpenGLContext::currentContext()) {
|
||||
qCWarning(lcQpaGLContext) << "explicitly glFinishing and deactivating" << currentContext;
|
||||
glFinish();
|
||||
currentContext->doneCurrent();
|
||||
// By the time we receive this signal the application has moved into
|
||||
// Qt::ApplactionStateSuspended, and all windows have been obscured,
|
||||
// which should stop all rendering. If there's still an active GL context,
|
||||
// we follow Apple's advice and call glFinish before making it inactive.
|
||||
if (QOpenGLContext *currentContext = QOpenGLContext::currentContext()) {
|
||||
qCWarning(lcQpaGLContext) << "explicitly glFinishing and deactivating" << currentContext;
|
||||
glFinish();
|
||||
currentContext->doneCurrent();
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
});
|
||||
|
||||
if (applicationBackgrounded) {
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
QIOSIntegration();
|
||||
~QIOSIntegration();
|
||||
|
||||
void initialize() override;
|
||||
|
||||
bool hasCapability(Capability cap) const override;
|
||||
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
|
||||
|
@ -95,7 +95,10 @@ QIOSIntegration::QIOSIntegration()
|
||||
|
||||
// Set current directory to app bundle folder
|
||||
QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
|
||||
}
|
||||
|
||||
void QIOSIntegration::initialize()
|
||||
{
|
||||
UIScreen *mainScreen = [UIScreen mainScreen];
|
||||
NSMutableArray<UIScreen *> *screens = [[[UIScreen screens] mutableCopy] autorelease];
|
||||
if (![screens containsObject:mainScreen]) {
|
||||
|
@ -271,6 +271,20 @@
|
||||
m_focusWindowChangeConnection = QObject::connect(qApp, &QGuiApplication::focusWindowChanged, [self]() {
|
||||
[self updateProperties];
|
||||
});
|
||||
|
||||
QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState;
|
||||
QObject::connect(applicationState, &QIOSApplicationState::applicationStateDidChange,
|
||||
[self](Qt::ApplicationState oldState, Qt::ApplicationState newState) {
|
||||
if (oldState == Qt::ApplicationSuspended && newState != Qt::ApplicationSuspended) {
|
||||
// We may have ignored an earlier layout because the application was suspended,
|
||||
// and we didn't want to render anything at that moment in fear of being killed
|
||||
// due to rendering in the background, so we trigger an explicit layout when
|
||||
// coming out of the suspended state.
|
||||
qCDebug(lcQpaWindow) << "triggering root VC layout when coming out of suspended state";
|
||||
[self.view setNeedsLayout];
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -43,7 +43,6 @@
|
||||
*/
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include "qmacstyle_mac_p.h"
|
||||
#include "qmacstyle_mac_p_p.h"
|
||||
@ -263,13 +262,7 @@ QT_BEGIN_NAMESPACE
|
||||
// The following constants are used for adjusting the size
|
||||
// of push buttons so that they are drawn inside their bounds.
|
||||
const int QMacStylePrivate::PushButtonLeftOffset = 6;
|
||||
const int QMacStylePrivate::PushButtonTopOffset = 4;
|
||||
const int QMacStylePrivate::PushButtonRightOffset = 12;
|
||||
const int QMacStylePrivate::PushButtonBottomOffset = 12;
|
||||
const int QMacStylePrivate::MiniButtonH = 26;
|
||||
const int QMacStylePrivate::SmallButtonH = 30;
|
||||
const int QMacStylePrivate::BevelButtonW = 50;
|
||||
const int QMacStylePrivate::BevelButtonH = 22;
|
||||
const int QMacStylePrivate::PushButtonContentPadding = 6;
|
||||
|
||||
QVector<QPointer<QObject> > QMacStylePrivate::scrollBars;
|
||||
@ -379,15 +372,6 @@ static const int toolButtonArrowMargin = 2;
|
||||
|
||||
static const qreal focusRingWidth = 3.5;
|
||||
|
||||
#if QT_CONFIG(tabbar)
|
||||
static bool isVerticalTabs(const QTabBar::Shape shape) {
|
||||
return (shape == QTabBar::RoundedEast
|
||||
|| shape == QTabBar::TriangularEast
|
||||
|| shape == QTabBar::RoundedWest
|
||||
|| shape == QTabBar::TriangularWest);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool setupScroller(NSScroller *scroller, const QStyleOptionSlider *sb)
|
||||
{
|
||||
const qreal length = sb->maximum - sb->minimum + sb->pageStep;
|
||||
@ -492,10 +476,10 @@ static void drawTabCloseButton(QPainter *p, bool hover, bool selected, bool pres
|
||||
#if QT_CONFIG(tabbar)
|
||||
QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
|
||||
{
|
||||
if (isVerticalTabs(shape)) {
|
||||
const auto tabDirection = QMacStylePrivate::tabDirection(shape);
|
||||
if (QMacStylePrivate::verticalTabs(tabDirection)) {
|
||||
int newX, newY, newRot;
|
||||
if (shape == QTabBar::RoundedEast
|
||||
|| shape == QTabBar::TriangularEast) {
|
||||
if (tabDirection == QMacStylePrivate::East) {
|
||||
newX = tabRect.width();
|
||||
newY = tabRect.y();
|
||||
newRot = 90;
|
||||
@ -516,23 +500,10 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
|
||||
void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, int tabOverlap)
|
||||
{
|
||||
QRect rect = tabOpt->rect;
|
||||
|
||||
switch (tabOpt->shape) {
|
||||
case QTabBar::RoundedNorth:
|
||||
case QTabBar::TriangularNorth:
|
||||
case QTabBar::RoundedSouth:
|
||||
case QTabBar::TriangularSouth:
|
||||
rect.adjust(-tabOverlap, 0, 0, 0);
|
||||
break;
|
||||
case QTabBar::RoundedEast:
|
||||
case QTabBar::TriangularEast:
|
||||
case QTabBar::RoundedWest:
|
||||
case QTabBar::TriangularWest:
|
||||
rect.adjust(0, -tabOverlap, 0, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (QMacStylePrivate::verticalTabs(QMacStylePrivate::tabDirection(tabOpt->shape)))
|
||||
rect = rect.adjusted(-tabOverlap, 0, 0, 0);
|
||||
else
|
||||
rect = rect.adjusted(0, -tabOverlap, 0, 0);
|
||||
|
||||
p->translate(rect.x(), rect.y());
|
||||
rect.moveLeft(0);
|
||||
@ -583,11 +554,11 @@ void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, in
|
||||
void drawTabBase(QPainter *p, const QStyleOptionTabBarBase *tbb, const QWidget *w)
|
||||
{
|
||||
QRect r = tbb->rect;
|
||||
if (isVerticalTabs(tbb->shape)) {
|
||||
if (QMacStylePrivate::verticalTabs(QMacStylePrivate::tabDirection(tbb->shape)))
|
||||
r.setWidth(w->width());
|
||||
} else {
|
||||
else
|
||||
r.setHeight(w->height());
|
||||
}
|
||||
|
||||
const QRect tabRect = rotateTabPainter(p, tbb->shape, r);
|
||||
const int width = tabRect.width();
|
||||
const int height = tabRect.height();
|
||||
@ -623,8 +594,7 @@ static QStyleHelper::WidgetSizePolicy getControlSize(const QStyleOption *option,
|
||||
static inline bool isTreeView(const QWidget *widget)
|
||||
{
|
||||
return (widget && widget->parentWidget() &&
|
||||
(qobject_cast<const QTreeView *>(widget->parentWidget())
|
||||
));
|
||||
qobject_cast<const QTreeView *>(widget->parentWidget()));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -662,15 +632,6 @@ static QString qt_mac_removeMnemonics(const QString &original)
|
||||
return returnText;
|
||||
}
|
||||
|
||||
bool qt_macWindowIsTextured(const QWidget *window)
|
||||
{
|
||||
if (QWindow *w = window->windowHandle())
|
||||
if (w->handle())
|
||||
if (NSWindow *nswindow = static_cast<NSWindow*>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("NSWindow"), w)))
|
||||
return ([nswindow styleMask] & NSTexturedBackgroundWindowMask) ? true : false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool qt_macWindowMainWindow(const QWidget *window)
|
||||
{
|
||||
if (QWindow *w = window->windowHandle()) {
|
||||
@ -1108,51 +1069,11 @@ static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size(const QWidget *widg, QS
|
||||
return QStyleHelper::SizeLarge;
|
||||
}
|
||||
|
||||
#if QT_CONFIG(mainwindow)
|
||||
if (qEnvironmentVariableIsSet("QWIDGET_ALL_SMALL")) {
|
||||
//if (small.width() != -1 || small.height() != -1)
|
||||
if (qEnvironmentVariableIsSet("QWIDGET_ALL_SMALL"))
|
||||
return QStyleHelper::SizeSmall;
|
||||
} else if (qEnvironmentVariableIsSet("QWIDGET_ALL_MINI")) {
|
||||
else if (qEnvironmentVariableIsSet("QWIDGET_ALL_MINI"))
|
||||
return QStyleHelper::SizeMini;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Figure out which size we're closer to, I just hacked this in, I haven't
|
||||
tested it as it would probably look pretty strange to have some widgets
|
||||
big and some widgets small in the same window?? -Sam */
|
||||
int large_delta=0;
|
||||
if (large.width() != -1) {
|
||||
int delta = large.width() - widg->width();
|
||||
large_delta += delta * delta;
|
||||
}
|
||||
if (large.height() != -1) {
|
||||
int delta = large.height() - widg->height();
|
||||
large_delta += delta * delta;
|
||||
}
|
||||
int small_delta=0;
|
||||
if (small.width() != -1) {
|
||||
int delta = small.width() - widg->width();
|
||||
small_delta += delta * delta;
|
||||
}
|
||||
if (small.height() != -1) {
|
||||
int delta = small.height() - widg->height();
|
||||
small_delta += delta * delta;
|
||||
}
|
||||
int mini_delta=0;
|
||||
if (mini.width() != -1) {
|
||||
int delta = mini.width() - widg->width();
|
||||
mini_delta += delta * delta;
|
||||
}
|
||||
if (mini.height() != -1) {
|
||||
int delta = mini.height() - widg->height();
|
||||
mini_delta += delta * delta;
|
||||
}
|
||||
if (mini_delta < small_delta && mini_delta < large_delta)
|
||||
return QStyleHelper::SizeMini;
|
||||
else if (small_delta < large_delta)
|
||||
return QStyleHelper::SizeSmall;
|
||||
#endif
|
||||
return QStyleHelper::SizeLarge;
|
||||
}
|
||||
#endif
|
||||
@ -1172,10 +1093,10 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int
|
||||
auto innerRect = targetRect;
|
||||
if (cw.type == TextField)
|
||||
innerRect = innerRect.adjusted(hMargin, vMargin, -hMargin, -vMargin).adjusted(0.5, 0.5, -0.5, -0.5);
|
||||
const auto outterRect = innerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
|
||||
const auto outterRadius = focusRingWidth;
|
||||
const auto outerRect = innerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
|
||||
const auto outerRadius = focusRingWidth;
|
||||
focusRingPath.addRect(innerRect);
|
||||
focusRingPath.addRoundedRect(outterRect, outterRadius, outterRadius);
|
||||
focusRingPath.addRoundedRect(outerRect, outerRadius, outerRadius);
|
||||
break;
|
||||
}
|
||||
case Button_CheckBox: {
|
||||
@ -1186,9 +1107,9 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int
|
||||
cw.size == QStyleHelper::SizeSmall ? 2.0 : 1.0); // As measured
|
||||
vOffset = 0.5 * qreal(targetRect.height() - cbSize);
|
||||
const auto cbInnerRect = QRectF(0, 0, cbSize, cbSize);
|
||||
const auto cbOutterRadius = cbInnerRadius + focusRingWidth;
|
||||
const auto cbOutterRect = cbInnerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
|
||||
focusRingPath.addRoundedRect(cbOutterRect, cbOutterRadius, cbOutterRadius);
|
||||
const auto cbOuterRadius = cbInnerRadius + focusRingWidth;
|
||||
const auto cbOuterRect = cbInnerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
|
||||
focusRingPath.addRoundedRect(cbOuterRect, cbOuterRadius, cbOuterRadius);
|
||||
focusRingPath.addRoundedRect(cbInnerRect, cbInnerRadius, cbInnerRadius);
|
||||
break;
|
||||
}
|
||||
@ -1199,9 +1120,9 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int
|
||||
cw.size == QStyleHelper::SizeSmall ? 1.0 : 1.0); // As measured
|
||||
vOffset = 0.5 * qreal(targetRect.height() - rbSize);
|
||||
const auto rbInnerRect = QRectF(0, 0, rbSize, rbSize);
|
||||
const auto rbOutterRect = rbInnerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
|
||||
const auto rbOuterRect = rbInnerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
|
||||
focusRingPath.addEllipse(rbInnerRect);
|
||||
focusRingPath.addEllipse(rbOutterRect);
|
||||
focusRingPath.addEllipse(rbOuterRect);
|
||||
break;
|
||||
}
|
||||
case Button_PopupButton:
|
||||
@ -1209,13 +1130,13 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int
|
||||
case Button_PushButton:
|
||||
case SegmentedControl_Single: {
|
||||
const qreal innerRadius = cw.type == Button_PushButton ? 3 : 4;
|
||||
const qreal outterRadius = innerRadius + focusRingWidth;
|
||||
const qreal outerRadius = innerRadius + focusRingWidth;
|
||||
hOffset = targetRect.left();
|
||||
vOffset = targetRect.top();
|
||||
const auto innerRect = targetRect.translated(-targetRect.topLeft());
|
||||
const auto outterRect = innerRect.adjusted(-hMargin, -vMargin, hMargin, vMargin);
|
||||
const auto outerRect = innerRect.adjusted(-hMargin, -vMargin, hMargin, vMargin);
|
||||
focusRingPath.addRoundedRect(innerRect, innerRadius, innerRadius);
|
||||
focusRingPath.addRoundedRect(outterRect, outterRadius, outterRadius);
|
||||
focusRingPath.addRoundedRect(outerRect, outerRadius, outerRadius);
|
||||
break;
|
||||
}
|
||||
case ComboBox:
|
||||
@ -1224,9 +1145,9 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int
|
||||
hOffset = targetRect.left();
|
||||
vOffset = targetRect.top();
|
||||
const qreal innerRadius = 8;
|
||||
const qreal outterRadius = innerRadius + focusRingWidth;
|
||||
const qreal outerRadius = innerRadius + focusRingWidth;
|
||||
const auto innerRect = targetRect.translated(-targetRect.topLeft());
|
||||
const auto outterRect = innerRect.adjusted(-hMargin, -vMargin, hMargin, vMargin);
|
||||
const auto outerRect = innerRect.adjusted(-hMargin, -vMargin, hMargin, vMargin);
|
||||
|
||||
const auto cbFocusFramePath = [](const QRectF &rect, qreal tRadius, qreal bRadius) {
|
||||
QPainterPath path;
|
||||
@ -1252,8 +1173,8 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int
|
||||
|
||||
const auto innerPath = cbFocusFramePath(innerRect, 0, innerRadius);
|
||||
focusRingPath.addPath(innerPath);
|
||||
const auto outterPath = cbFocusFramePath(outterRect, 2 * focusRingWidth, outterRadius);
|
||||
focusRingPath.addPath(outterPath);
|
||||
const auto outerPath = cbFocusFramePath(outerRect, 2 * focusRingWidth, outerRadius);
|
||||
focusRingPath.addPath(outerPath);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1412,6 +1333,12 @@ QMacStylePrivate::Direction QMacStylePrivate::tabDirection(QTabBar::Shape shape)
|
||||
}
|
||||
}
|
||||
|
||||
bool QMacStylePrivate::verticalTabs(QMacStylePrivate::Direction direction)
|
||||
{
|
||||
return (direction == QMacStylePrivate::East
|
||||
|| direction == QMacStylePrivate::West);
|
||||
}
|
||||
|
||||
#endif // QT_CONFIG(tabbar)
|
||||
|
||||
QStyleHelper::WidgetSizePolicy QMacStylePrivate::effectiveAquaSizeConstrain(const QStyleOption *option,
|
||||
@ -1599,7 +1526,6 @@ QMarginsF QMacStylePrivate::CocoaControl::titleMargins() const
|
||||
return QMarginsF();
|
||||
}
|
||||
|
||||
|
||||
bool QMacStylePrivate::CocoaControl::getCocoaButtonTypeAndBezelStyle(NSButtonType *buttonType, NSBezelStyle *bezelStyle) const
|
||||
{
|
||||
switch (type) {
|
||||
@ -1660,9 +1586,9 @@ QMacStylePrivate::CocoaControlType cocoaControlType(const QStyleOption *opt, con
|
||||
Carbon draws comboboxes (and other views) outside the rect given as argument. Use this function to obtain
|
||||
the corresponding inner rect for drawing the same combobox so that it stays inside the given outerBounds.
|
||||
*/
|
||||
CGRect QMacStylePrivate::comboboxInnerBounds(const CGRect &outterBounds, const CocoaControl &cocoaWidget)
|
||||
CGRect QMacStylePrivate::comboboxInnerBounds(const CGRect &outerBounds, const CocoaControl &cocoaWidget)
|
||||
{
|
||||
CGRect innerBounds = outterBounds;
|
||||
CGRect innerBounds = outerBounds;
|
||||
// Carbon draw parts of the view outside the rect.
|
||||
// So make the rect a bit smaller to compensate
|
||||
// (I wish HIThemeGetButtonBackgroundBounds worked)
|
||||
@ -1717,9 +1643,9 @@ CGRect QMacStylePrivate::comboboxInnerBounds(const CGRect &outterBounds, const C
|
||||
Inside a combobox Qt places a line edit widget. The size of this widget should depend on the kind
|
||||
of combobox we choose to draw. This function calculates and returns this size.
|
||||
*/
|
||||
QRectF QMacStylePrivate::comboboxEditBounds(const QRectF &outterBounds, const CocoaControl &cw)
|
||||
QRectF QMacStylePrivate::comboboxEditBounds(const QRectF &outerBounds, const CocoaControl &cw)
|
||||
{
|
||||
QRectF ret = outterBounds;
|
||||
QRectF ret = outerBounds;
|
||||
if (cw.type == ComboBox) {
|
||||
switch (cw.size) {
|
||||
case QStyleHelper::SizeLarge:
|
||||
@ -1746,8 +1672,7 @@ QRectF QMacStylePrivate::comboboxEditBounds(const QRectF &outterBounds, const Co
|
||||
ret.adjust(13, 4, -20, -3);
|
||||
break;
|
||||
case QStyleHelper::SizeMini:
|
||||
// FIXME Wrong
|
||||
ret.adjust(16, 5, -19, 0);
|
||||
ret.adjust(12, 0, -19, 0);
|
||||
ret.setHeight(13);
|
||||
break;
|
||||
default:
|
||||
@ -1775,27 +1700,12 @@ QMacStylePrivate::~QMacStylePrivate()
|
||||
[cell release];
|
||||
}
|
||||
|
||||
#if 0
|
||||
ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
|
||||
{
|
||||
ThemeDrawState tds = kThemeStateActive;
|
||||
if (flags & QStyle::State_Sunken) {
|
||||
tds = kThemeStatePressed;
|
||||
} else if (flags & QStyle::State_Active) {
|
||||
if (!(flags & QStyle::State_Enabled))
|
||||
tds = kThemeStateUnavailable;
|
||||
} else {
|
||||
if (flags & QStyle::State_Enabled)
|
||||
tds = kThemeStateInactive;
|
||||
else
|
||||
tds = kThemeStateUnavailableInactive;
|
||||
}
|
||||
return tds;
|
||||
}
|
||||
#endif
|
||||
|
||||
NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const
|
||||
{
|
||||
if (widget.type == QMacStylePrivate::NoControl
|
||||
|| widget.size == QStyleHelper::SizeDefault)
|
||||
return nil;
|
||||
|
||||
NSView *bv = cocoaControls.value(widget, nil);
|
||||
if (!bv) {
|
||||
switch (widget.type) {
|
||||
@ -1977,15 +1887,13 @@ NSCell *QMacStylePrivate::cocoaCell(CocoaControl widget) const
|
||||
return cell;
|
||||
}
|
||||
|
||||
void QMacStylePrivate::drawNSViewInRect(CocoaControl widget, NSView *view, const QRectF &qtRect, QPainter *p, bool isQWidget, __attribute__((noescape)) DrawRectBlock drawRectBlock) const
|
||||
void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRectF &qtRect, QPainter *p,
|
||||
__attribute__((noescape)) DrawRectBlock drawRectBlock) const
|
||||
{
|
||||
Q_UNUSED(isQWidget);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
QMacCGContext ctx(p);
|
||||
setupNSGraphicsContext(ctx, YES);
|
||||
|
||||
const CGRect rect = CGRectMake(qtRect.x(), qtRect.y(), qtRect.width(), qtRect.height());
|
||||
const CGRect rect = qtRect.toCGRect();
|
||||
|
||||
[backingStoreNSView addSubview:view];
|
||||
view.frame = rect;
|
||||
@ -2993,9 +2901,9 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
||||
case PE_FrameTabWidget:
|
||||
#endif
|
||||
{
|
||||
const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Box, QStyleHelper::SizeDefault);
|
||||
const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Box, QStyleHelper::SizeLarge);
|
||||
auto *box = static_cast<NSBox *>(d->cocoaControl(cw));
|
||||
d->drawNSViewInRect(cw, box, opt->rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
d->drawNSViewInRect(box, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height);
|
||||
CGContextScaleCTM(ctx, 1, -1);
|
||||
[box drawRect:rect];
|
||||
@ -3155,7 +3063,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
||||
|
||||
return cs == QStyleHelper::SizeSmall ? 0.5 : 0.0;
|
||||
} ();
|
||||
d->drawNSViewInRect(cw, tb, opt->rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
d->drawNSViewInRect(tb, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
CGContextTranslateCTM(ctx, 0, vOffset);
|
||||
[tb.cell drawInteriorWithFrame:rect inView:tb];
|
||||
});
|
||||
@ -3166,7 +3074,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
||||
case PE_IndicatorBranch: {
|
||||
if (!(opt->state & State_Children))
|
||||
break;
|
||||
const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Button_Disclosure, QStyleHelper::SizeLarge);
|
||||
const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Button_Disclosure, QStyleHelper::SizeLarge);
|
||||
NSButtonCell *triangleCell = static_cast<NSButtonCell *>(d->cocoaCell(cw));
|
||||
[triangleCell setState:(opt->state & State_Open) ? NSOnState : NSOffState];
|
||||
bool viewHasFocus = (w && w->hasFocus()) || (opt->state & State_HasFocus);
|
||||
@ -3208,7 +3116,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
||||
tf.bezeled = YES;
|
||||
static_cast<NSTextFieldCell *>(tf.cell).bezelStyle = isRounded ? NSTextFieldRoundedBezel : NSTextFieldSquareBezel;
|
||||
tf.frame = opt->rect.toCGRect();
|
||||
d->drawNSViewInRect(cw, tf, opt->rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
d->drawNSViewInRect(tf, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
Q_UNUSED(ctx);
|
||||
[tf.cell drawWithFrame:rect inView:tf];
|
||||
});
|
||||
@ -3298,7 +3206,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
||||
}
|
||||
}
|
||||
|
||||
static inline QPixmap darkenPixmap(const QPixmap &pixmap)
|
||||
static QPixmap darkenPixmap(const QPixmap &pixmap)
|
||||
{
|
||||
QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
|
||||
int imgh = img.height();
|
||||
@ -3321,8 +3229,6 @@ static inline QPixmap darkenPixmap(const QPixmap &pixmap)
|
||||
return QPixmap::fromImage(img);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QMacStylePrivate::setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const
|
||||
{
|
||||
if (vertical) {
|
||||
@ -3542,7 +3448,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
pb.enabled = isEnabled;
|
||||
[pb highlight:isPressed];
|
||||
pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState;
|
||||
d->drawNSViewInRect(cw, pb, frameRect, p, true, ^(CGContextRef __unused ctx, const CGRect &r) {
|
||||
d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) {
|
||||
[pb.cell drawBezelWithFrame:r inView:pb.superview];
|
||||
});
|
||||
[pb highlight:NO];
|
||||
@ -3685,6 +3591,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isActive = tabOpt->state & State_Active;
|
||||
const bool isEnabled = tabOpt->state & State_Enabled;
|
||||
const bool isPressed = tabOpt->state & State_Sunken;
|
||||
const bool isSelected = tabOpt->state & State_Selected;
|
||||
@ -3713,17 +3620,20 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
// a push NSButton instead and clip the CGContext.
|
||||
|
||||
const auto cs = d->effectiveAquaSizeConstrain(opt, w);
|
||||
// Extra hack to get the proper pressed appreance when not selected
|
||||
const auto ct = isSelected || tp == QStyleOptionTab::OnlyOneTab ?
|
||||
// Extra hacks to get the proper pressed appreance when not selected or selected and inactive
|
||||
const bool needsInactiveHack = (!isActive && isSelected);
|
||||
const auto ct = !needsInactiveHack && (isSelected || tp == QStyleOptionTab::OnlyOneTab) ?
|
||||
QMacStylePrivate::Button_PushButton :
|
||||
QMacStylePrivate::Button_PopupButton;
|
||||
const bool isPopupButton = ct == QMacStylePrivate::Button_PopupButton;
|
||||
const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
|
||||
auto *pb = static_cast<NSButton *>(d->cocoaControl(cw));
|
||||
auto vOffset = isSelected ? 2 : 1;
|
||||
|
||||
auto vOffset = isPopupButton ? 1 : 2;
|
||||
if (tabDirection == QMacStylePrivate::East)
|
||||
vOffset -= 1;
|
||||
const auto outterAdjust = isSelected ? 4 : 1;
|
||||
const auto innerAdjust = isSelected ? 10 : 20;
|
||||
const auto outerAdjust = isPopupButton ? 1 : 4;
|
||||
const auto innerAdjust = isPopupButton ? 20 : 10;
|
||||
QRectF frameRect = tabOpt->rect;
|
||||
if (verticalTabs)
|
||||
frameRect = QRectF(frameRect.y(), frameRect.x(), frameRect.height(), frameRect.width());
|
||||
@ -3733,9 +3643,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
case QStyleOptionTab::Beginning:
|
||||
// Pressed state hack: tweak adjustments in preparation for flip below
|
||||
if (!isSelected && tabDirection == QMacStylePrivate::West)
|
||||
frameRect = frameRect.adjusted(-innerAdjust, 0, outterAdjust, 0);
|
||||
frameRect = frameRect.adjusted(-innerAdjust, 0, outerAdjust, 0);
|
||||
else
|
||||
frameRect = frameRect.adjusted(-outterAdjust, 0, innerAdjust, 0);
|
||||
frameRect = frameRect.adjusted(-outerAdjust, 0, innerAdjust, 0);
|
||||
break;
|
||||
case QStyleOptionTab::Middle:
|
||||
frameRect = frameRect.adjusted(-innerAdjust, 0, innerAdjust, 0);
|
||||
@ -3743,22 +3653,24 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
case QStyleOptionTab::End:
|
||||
// Pressed state hack: tweak adjustments in preparation for flip below
|
||||
if (isSelected || tabDirection == QMacStylePrivate::West)
|
||||
frameRect = frameRect.adjusted(-innerAdjust, 0, outterAdjust, 0);
|
||||
frameRect = frameRect.adjusted(-innerAdjust, 0, outerAdjust, 0);
|
||||
else
|
||||
frameRect = frameRect.adjusted(-outterAdjust, 0, innerAdjust, 0);
|
||||
frameRect = frameRect.adjusted(-outerAdjust, 0, innerAdjust, 0);
|
||||
break;
|
||||
case QStyleOptionTab::OnlyOneTab:
|
||||
frameRect = frameRect.adjusted(-outterAdjust, 0, outterAdjust, 0);
|
||||
frameRect = frameRect.adjusted(-outerAdjust, 0, outerAdjust, 0);
|
||||
break;
|
||||
}
|
||||
pb.frame = frameRect.toCGRect();
|
||||
|
||||
pb.enabled = isEnabled;
|
||||
[pb highlight:isPressed];
|
||||
pb.state = isSelected && !isPressed ? NSOnState : NSOffState;
|
||||
d->drawNSViewInRect(cw, pb, frameRect, p, true, ^(CGContextRef ctx, const CGRect &r) {
|
||||
// Set off state when inactive. See needsInactiveHack for when it's selected
|
||||
pb.state = (isActive && isSelected && !isPressed) ? NSOnState : NSOffState;
|
||||
|
||||
const auto drawBezelBlock = ^(CGContextRef ctx, const CGRect &r) {
|
||||
CGContextClipToRect(ctx, opt->rect.toCGRect());
|
||||
if (!isSelected) {
|
||||
if (!isSelected || needsInactiveHack) {
|
||||
// Final stage of the pressed state hack: flip NSPopupButton rendering
|
||||
if (!verticalTabs && tp == QStyleOptionTab::End) {
|
||||
CGContextTranslateCTM(ctx, opt->rect.right(), 0);
|
||||
@ -3786,7 +3698,42 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
}
|
||||
|
||||
[pb.cell drawBezelWithFrame:r inView:pb.superview];
|
||||
});
|
||||
};
|
||||
|
||||
if (needsInactiveHack) {
|
||||
// First, render tab as non-selected tab on a pixamp
|
||||
const qreal pixelRatio = p->device()->devicePixelRatioF();
|
||||
QImage tabPixmap(opt->rect.size() * pixelRatio, QImage::Format_ARGB32_Premultiplied);
|
||||
tabPixmap.setDevicePixelRatio(pixelRatio);
|
||||
tabPixmap.fill(Qt::transparent);
|
||||
QPainter tabPainter(&tabPixmap);
|
||||
d->drawNSViewInRect(pb, frameRect, &tabPainter, ^(CGContextRef ctx, const CGRect &r) {
|
||||
CGContextTranslateCTM(ctx, -opt->rect.left(), -opt->rect.top());
|
||||
drawBezelBlock(ctx, r);
|
||||
});
|
||||
tabPainter.end();
|
||||
|
||||
// Then, darken it with the proper shade of gray
|
||||
const qreal inactiveGray = 0.898; // As measured
|
||||
const int inactiveGray8 = qRound(inactiveGray * 255.0);
|
||||
const QRgb inactiveGrayRGB = qRgb(inactiveGray8, inactiveGray8, inactiveGray8);
|
||||
for (int l = 0; l < tabPixmap.height(); ++l) {
|
||||
auto *line = reinterpret_cast<QRgb*>(tabPixmap.scanLine(l));
|
||||
for (int i = 0; i < tabPixmap.width(); ++i) {
|
||||
if (qAlpha(line[i]) == 255) {
|
||||
line[i] = inactiveGrayRGB;
|
||||
} else if (qAlpha(line[i]) > 128) {
|
||||
const int g = qRound(inactiveGray * qRed(line[i]));
|
||||
line[i] = qRgba(g, g, g, qAlpha(line[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, draw the tab pixmap on the current painter
|
||||
p->drawImage(opt->rect, tabPixmap);
|
||||
} else {
|
||||
d->drawNSViewInRect(pb, frameRect, p, drawBezelBlock);
|
||||
}
|
||||
|
||||
if (!isSelected && sp != QStyleOptionTab::NextIsSelected
|
||||
&& tp != QStyleOptionTab::End
|
||||
@ -4193,7 +4140,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
|
||||
const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::ProgressIndicator_Determinate, aquaSize);
|
||||
auto *pi = static_cast<NSProgressIndicator *>(d->cocoaControl(cw));
|
||||
d->drawNSViewInRect(cw, pi, rect, p, w != nullptr, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
d->drawNSViewInRect(pi, rect, p, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
d->setupVerticalInvertedXform(ctx, reverse, vertical, rect);
|
||||
pi.minValue = pb->minimum;
|
||||
pi.maxValue = pb->maximum;
|
||||
@ -4243,7 +4190,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge);
|
||||
auto *sv = static_cast<NSSplitView *>(d->cocoaControl(cw));
|
||||
sv.frame = opt->rect.toCGRect();
|
||||
d->drawNSViewInRect(cw, sv, opt->rect, p, w != nullptr, ^(CGContextRef __unused ctx, const CGRect &rect) {
|
||||
d->drawNSViewInRect(sv, opt->rect, p, ^(CGContextRef __unused ctx, const CGRect &rect) {
|
||||
[sv drawDividerInRect:rect];
|
||||
});
|
||||
} else {
|
||||
@ -5088,7 +5035,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||
[slider.cell startTrackingAt:pressPoint inView:slider];
|
||||
}
|
||||
|
||||
d->drawNSViewInRect(cw, slider, opt->rect, p, widget != 0, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
d->drawNSViewInRect(slider, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) {
|
||||
if (isHorizontal && sl->upsideDown) {
|
||||
CGContextTranslateCTM(ctx, rect.size.width, 0);
|
||||
CGContextScaleCTM(ctx, -1, 1);
|
||||
@ -5250,7 +5197,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||
}
|
||||
pb.frame = frameRect.toCGRect();
|
||||
[pb highlight:isPressed];
|
||||
d->drawNSViewInRect(cw, pb, frameRect, p, widget != 0, ^(CGContextRef __unused ctx, const CGRect &r) {
|
||||
d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) {
|
||||
[pb.cell drawBezelWithFrame:r inView:pb.superview];
|
||||
});
|
||||
} else if (cw.type == QMacStylePrivate::ComboBox) {
|
||||
@ -5263,7 +5210,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||
#else
|
||||
// TODO Render to pixmap and darken the button manually
|
||||
#endif
|
||||
d->drawNSViewInRect(cw, cb, frameRect, p, widget != 0, ^(CGContextRef __unused ctx, const CGRect &r) {
|
||||
d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef __unused ctx, const CGRect &r) {
|
||||
// FIXME This is usually drawn in the control's superview, but we wouldn't get inactive look in this case
|
||||
[cb.cell drawWithFrame:r inView:cb];
|
||||
});
|
||||
@ -5300,12 +5247,12 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||
|
||||
// FIXME A single drawPath() with 0-sized pen
|
||||
// doesn't look as good as this double fillPath().
|
||||
const auto outterFrameRect = QRectF(opt->rect.adjusted(0, 0, 0, opt->rect.height()));
|
||||
QPainterPath outterFramePath = d->windowPanelPath(outterFrameRect);
|
||||
p->fillPath(outterFramePath, opt->palette.dark());
|
||||
const auto outerFrameRect = QRectF(opt->rect.adjusted(0, 0, 0, opt->rect.height()));
|
||||
QPainterPath outerFramePath = d->windowPanelPath(outerFrameRect);
|
||||
p->fillPath(outerFramePath, opt->palette.dark());
|
||||
|
||||
const auto frameAdjust = 1.0 / p->device()->devicePixelRatioF();
|
||||
const auto innerFrameRect = outterFrameRect.adjusted(frameAdjust, frameAdjust, -frameAdjust, 0);
|
||||
const auto innerFrameRect = outerFrameRect.adjusted(frameAdjust, frameAdjust, -frameAdjust, 0);
|
||||
QPainterPath innerFramePath = d->windowPanelPath(innerFrameRect);
|
||||
if (isActive) {
|
||||
QLinearGradient g;
|
||||
@ -5341,7 +5288,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||
auto *wbCell = static_cast<NSButtonCell *>(wb.cell);
|
||||
[wbCell drawWithFrame:rect inView:wb];
|
||||
};
|
||||
d->drawNSViewInRect(cw, wb, buttonRect, p, widget != nullptr, drawBlock);
|
||||
d->drawNSViewInRect(wb, buttonRect, p, drawBlock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5451,7 +5398,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||
[pb highlight:isPressed];
|
||||
pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState;
|
||||
const auto buttonRect = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
|
||||
d->drawNSViewInRect(cw, pb, buttonRect, p, ^(CGContextRef __unused ctx, const CGRect &rect) {
|
||||
d->drawNSViewInRect(pb, buttonRect, p, ^(CGContextRef __unused ctx, const CGRect &rect) {
|
||||
[pb.cell drawBezelWithFrame:rect inView:pb];
|
||||
});
|
||||
}
|
||||
|
@ -236,13 +236,7 @@ public:
|
||||
|
||||
// Ideally these wouldn't exist, but since they already exist we need some accessors.
|
||||
static const int PushButtonLeftOffset;
|
||||
static const int PushButtonTopOffset;
|
||||
static const int PushButtonRightOffset;
|
||||
static const int PushButtonBottomOffset;
|
||||
static const int MiniButtonH;
|
||||
static const int SmallButtonH;
|
||||
static const int BevelButtonW;
|
||||
static const int BevelButtonH;
|
||||
static const int PushButtonContentPadding;
|
||||
|
||||
enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen, AquaScrollBar };
|
||||
@ -269,7 +263,7 @@ public:
|
||||
|
||||
void setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const;
|
||||
|
||||
void drawNSViewInRect(CocoaControl widget, NSView *view, const QRectF &rect, QPainter *p, bool isQWidget = true, __attribute__((noescape)) DrawRectBlock drawRectBlock = nil) const;
|
||||
void drawNSViewInRect(NSView *view, const QRectF &rect, QPainter *p, __attribute__((noescape)) DrawRectBlock drawRectBlock = nil) const;
|
||||
void resolveCurrentNSView(QWindow *window) const;
|
||||
|
||||
void drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const;
|
||||
@ -283,6 +277,7 @@ public:
|
||||
#if QT_CONFIG(tabbar)
|
||||
void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const;
|
||||
static Direction tabDirection(QTabBar::Shape shape);
|
||||
static bool verticalTabs(QMacStylePrivate::Direction tabDirection);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
@ -130,6 +130,7 @@ QT_BEGIN_NAMESPACE
|
||||
}
|
||||
|
||||
Q_CORE_EXPORT void qt_call_post_routines();
|
||||
Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1);
|
||||
|
||||
QApplicationPrivate *QApplicationPrivate::self = 0;
|
||||
|
||||
@ -3075,8 +3076,19 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
|
||||
|
||||
switch (e->type()) {
|
||||
case QEvent::KeyPress: {
|
||||
int key = static_cast<QKeyEvent*>(e)->key();
|
||||
qt_in_tab_key_event = (key == Qt::Key_Backtab
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(e);
|
||||
const int key = keyEvent->key();
|
||||
// When a key press is received which is not spontaneous then it needs to
|
||||
// be manually sent as a shortcut override event to ensure that any
|
||||
// matching shortcut is triggered first. This enables emulation/playback
|
||||
// of recorded events to still have the same effect.
|
||||
if (!e->spontaneous() && receiver->isWidgetType()) {
|
||||
if (qt_sendShortcutOverrideEvent(qobject_cast<QWidget *>(receiver), keyEvent->timestamp(),
|
||||
key, keyEvent->modifiers(), keyEvent->text(),
|
||||
keyEvent->isAutoRepeat(), keyEvent->count()))
|
||||
return true;
|
||||
}
|
||||
qt_in_tab_key_event = (key == Qt::Key_Backtab
|
||||
|| key == Qt::Key_Tab
|
||||
|| key == Qt::Key_Left
|
||||
|| key == Qt::Key_Up
|
||||
|
@ -187,8 +187,15 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge
|
||||
active_window = active_window->parentWidget()->window();
|
||||
}
|
||||
|
||||
if (active_window != tlw)
|
||||
if (active_window != tlw) {
|
||||
#if QT_CONFIG(menubar)
|
||||
// If the tlw is a QMenuBar then we allow it to proceed as this indicates that
|
||||
// the QMenuBar is a parentless one and is therefore used for multiple top level
|
||||
// windows in the application. This is common on macOS platforms for example.
|
||||
if (!qobject_cast<QMenuBar *>(tlw))
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if we live in a MDI subwindow, ignore the event if we are
|
||||
not the active document window */
|
||||
|
@ -327,15 +327,13 @@ void QTipLabel::timerEvent(QTimerEvent *e)
|
||||
bool QTipLabel::eventFilter(QObject *o, QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
#if 0 // Used to be included in Qt4 for Q_WS_MAC
|
||||
#ifdef Q_OS_MACOS
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease: {
|
||||
int key = static_cast<QKeyEvent *>(e)->key();
|
||||
Qt::KeyboardModifiers mody = static_cast<QKeyEvent *>(e)->modifiers();
|
||||
if (!(mody & Qt::KeyboardModifierMask)
|
||||
&& key != Qt::Key_Shift && key != Qt::Key_Control
|
||||
&& key != Qt::Key_Alt && key != Qt::Key_Meta)
|
||||
hideTip();
|
||||
const int key = static_cast<QKeyEvent *>(e)->key();
|
||||
// Anything except key modifiers or caps-lock, etc.
|
||||
if (key < Qt::Key_Shift || key > Qt::Key_ScrollLock)
|
||||
hideTipImmediately();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -1231,9 +1231,9 @@ QSplitterHandle *QSplitter::createHandle()
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the handle to the left (or above) for the item in the
|
||||
splitter's layout at the given \a index. The handle at index 0 is
|
||||
always hidden.
|
||||
Returns the handle to the left of (or above) the item in the
|
||||
splitter's layout at the given \a index, or \c nullptr if there is no such item.
|
||||
The handle at index 0 is always hidden.
|
||||
|
||||
For right-to-left languages such as Arabic and Hebrew, the layout
|
||||
of horizontal splitters is reversed. The handle will be to the
|
||||
@ -1250,7 +1250,8 @@ QSplitterHandle *QSplitter::handle(int index) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the widget at the given \a index in the splitter's layout.
|
||||
Returns the widget at the given \a index in the splitter's layout,
|
||||
or \c nullptr if there is no such widget.
|
||||
|
||||
\sa count(), handle(), indexOf(), insertWidget()
|
||||
*/
|
||||
|
@ -376,7 +376,8 @@ QTabWidget::~QTabWidget()
|
||||
\fn int QTabWidget::addTab(QWidget *page, const QString &label)
|
||||
|
||||
Adds a tab with the given \a page and \a label to the tab widget,
|
||||
and returns the index of the tab in the tab bar.
|
||||
and returns the index of the tab in the tab bar. Ownership of \a page
|
||||
is passed on to the QTabWidget.
|
||||
|
||||
If the tab's \a label contains an ampersand, the letter following
|
||||
the ampersand is used as a shortcut for the tab, e.g. if the
|
||||
@ -403,7 +404,8 @@ int QTabWidget::addTab(QWidget *child, const QString &label)
|
||||
\overload
|
||||
|
||||
Adds a tab with the given \a page, \a icon, and \a label to the tab
|
||||
widget, and returns the index of the tab in the tab bar.
|
||||
widget, and returns the index of the tab in the tab bar. Ownership
|
||||
of \a page is passed on to the QTabWidget.
|
||||
|
||||
This function is the same as addTab(), but with an additional \a
|
||||
icon.
|
||||
@ -419,7 +421,8 @@ int QTabWidget::addTab(QWidget *child, const QIcon& icon, const QString &label)
|
||||
|
||||
Inserts a tab with the given \a label and \a page into the tab
|
||||
widget at the specified \a index, and returns the index of the
|
||||
inserted tab in the tab bar.
|
||||
inserted tab in the tab bar. Ownership of \a page is passed on to the
|
||||
QTabWidget.
|
||||
|
||||
The label is displayed in the tab and may vary in appearance depending
|
||||
on the configuration of the tab widget.
|
||||
@ -458,7 +461,8 @@ int QTabWidget::insertTab(int index, QWidget *w, const QString &label)
|
||||
|
||||
Inserts a tab with the given \a label, \a page, and \a icon into
|
||||
the tab widget at the specified \a index, and returns the index of the
|
||||
inserted tab in the tab bar.
|
||||
inserted tab in the tab bar. Ownership of \a page is passed on to the
|
||||
QTabWidget.
|
||||
|
||||
This function is the same as insertTab(), but with an additional
|
||||
\a icon.
|
||||
|
@ -23,3 +23,6 @@ osx-10.12 ci
|
||||
|
||||
[testInputEvents]
|
||||
rhel-7.4
|
||||
[isActive]
|
||||
# QTBUG-67768
|
||||
ubuntu
|
||||
|
@ -67,6 +67,7 @@ private slots:
|
||||
void keysequence(); // QTBUG-53381
|
||||
void disableShortcutsWithBlockedWidgets_data();
|
||||
void disableShortcutsWithBlockedWidgets();
|
||||
void shortcutFromKeyEvent(); // QTBUG-48325
|
||||
|
||||
private:
|
||||
int m_lastEventType;
|
||||
@ -509,5 +510,41 @@ void tst_QAction::disableShortcutsWithBlockedWidgets()
|
||||
QCOMPARE(spy.count(), 0);
|
||||
}
|
||||
|
||||
class ShortcutOverrideWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
ShortcutOverrideWidget(QWidget *parent = 0) : QWidget(parent), shortcutOverrideCount(0) {}
|
||||
int shortcutOverrideCount;
|
||||
protected:
|
||||
bool event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::ShortcutOverride)
|
||||
++shortcutOverrideCount;
|
||||
return QWidget::event(e);
|
||||
}
|
||||
};
|
||||
|
||||
// Test that a key press event sent with sendEvent() still gets handled as a possible
|
||||
// ShortcutOverride event first before passing it on as a normal KeyEvent.
|
||||
void tst_QAction::shortcutFromKeyEvent()
|
||||
{
|
||||
ShortcutOverrideWidget testWidget;
|
||||
QAction action;
|
||||
action.setShortcut(Qt::Key_1);
|
||||
testWidget.addAction(&action);
|
||||
testWidget.show();
|
||||
QSignalSpy spy(&action, &QAction::triggered);
|
||||
QVERIFY(spy.isValid());
|
||||
QVERIFY(QTest::qWaitForWindowActive(&testWidget));
|
||||
QCOMPARE(testWidget.shortcutOverrideCount, 0);
|
||||
|
||||
// Don't use the QTest::keyPress approach as this will take the
|
||||
// shortcut route for us
|
||||
QKeyEvent e(QEvent::KeyPress, Qt::Key_1, Qt::NoModifier);
|
||||
QApplication::sendEvent(&testWidget, &e);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(testWidget.shortcutOverrideCount, 1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QAction)
|
||||
#include "tst_qaction.moc"
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
@ -36,200 +37,123 @@
|
||||
class ShortcutTester : public QWidget
|
||||
{
|
||||
public:
|
||||
ShortcutTester() {
|
||||
ShortcutTester()
|
||||
{
|
||||
const QString title = QLatin1String(QT_VERSION_STR) + QLatin1Char(' ')
|
||||
+ qApp->platformName();
|
||||
setWindowTitle(title);
|
||||
setupLayout();
|
||||
}
|
||||
protected:
|
||||
void setupLayout()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
QLabel *testPurpose = new QLabel();
|
||||
testPurpose->setWordWrap(true);
|
||||
testPurpose->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding);
|
||||
testPurpose->setText("This test come in handy to verify shortcuts under different "
|
||||
"keyboard layouts - qwerty, dvorak, non-latin (russian, arabic), etc.");
|
||||
layout->addWidget(testPurpose);
|
||||
private:
|
||||
void setupLayout();
|
||||
void addToGrid(QWidget *w, int &row, int col);
|
||||
void addShortcutToGrid(const QKeySequence &k, int &row, int col);
|
||||
void addShortcutToGrid(int key, int &row, int col)
|
||||
{ addShortcutToGrid(QKeySequence(key), row, col); }
|
||||
|
||||
QKeySequence altShiftG(Qt::AltModifier + Qt::ShiftModifier + Qt::Key_G);
|
||||
QPushButton *_altShiftG = new QPushButton(altShiftG.toString());
|
||||
_altShiftG->setShortcut(altShiftG);
|
||||
layout->addWidget(_altShiftG);
|
||||
|
||||
QKeySequence altG(Qt::AltModifier + Qt::Key_G);
|
||||
QPushButton *_altG = new QPushButton(altG.toString());
|
||||
_altG->setShortcut(altG);
|
||||
layout->addWidget(_altG);
|
||||
|
||||
QKeySequence ctrlShiftR(Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_R);
|
||||
QPushButton *_ctrlShiftR = new QPushButton(ctrlShiftR.toString());
|
||||
_ctrlShiftR->setShortcut(ctrlShiftR);
|
||||
layout->addWidget(_ctrlShiftR);
|
||||
|
||||
QKeySequence ctrlR(Qt::ControlModifier + Qt::Key_R);
|
||||
QPushButton *_ctrlR = new QPushButton(ctrlR.toString());
|
||||
_ctrlR->setShortcut(ctrlR);
|
||||
layout->addWidget(_ctrlR);
|
||||
|
||||
QKeySequence ctrlReturn(Qt::ControlModifier + Qt::Key_Return);
|
||||
QPushButton *_ctrlReturn = new QPushButton(ctrlReturn.toString());
|
||||
_ctrlReturn->setShortcut(ctrlReturn);
|
||||
layout->addWidget(_ctrlReturn);
|
||||
|
||||
QKeySequence ctrlEnter(Qt::ControlModifier + Qt::Key_Enter);
|
||||
QPushButton *_ctrlEnter = new QPushButton(ctrlEnter.toString());
|
||||
_ctrlEnter->setShortcut(ctrlEnter);
|
||||
layout->addWidget(_ctrlEnter);
|
||||
|
||||
QKeySequence ctrlShiftAltR(Qt::ControlModifier + Qt::ShiftModifier + Qt::AltModifier + Qt::Key_R);
|
||||
QPushButton *_ctrlShiftAltR = new QPushButton(ctrlShiftAltR.toString());
|
||||
_ctrlShiftAltR->setShortcut(ctrlShiftAltR);
|
||||
layout->addWidget(_ctrlShiftAltR);
|
||||
|
||||
QKeySequence shift5(Qt::ShiftModifier + Qt::Key_5);
|
||||
QPushButton *_shift5 = new QPushButton(shift5.toString());
|
||||
_shift5->setShortcut(shift5);
|
||||
layout->addWidget(_shift5);
|
||||
|
||||
QKeySequence shiftPercent(Qt::ShiftModifier + Qt::Key_Percent);
|
||||
QPushButton *_shiftPercent = new QPushButton(shiftPercent.toString());
|
||||
_shiftPercent->setShortcut(shiftPercent);
|
||||
layout->addWidget(_shiftPercent);
|
||||
|
||||
QKeySequence percent(Qt::Key_Percent);
|
||||
QPushButton *_percent = new QPushButton(percent.toString());
|
||||
_percent->setShortcut(percent);
|
||||
layout->addWidget(_percent);
|
||||
|
||||
QKeySequence key5(Qt::Key_5);
|
||||
QPushButton *_key5 = new QPushButton(key5.toString());
|
||||
_key5->setShortcut(key5);
|
||||
layout->addWidget(_key5);
|
||||
|
||||
QKeySequence keyQ(Qt::Key_Q);
|
||||
QPushButton *_keyQ = new QPushButton(keyQ.toString());
|
||||
_keyQ->setShortcut(keyQ);
|
||||
layout->addWidget(_keyQ);
|
||||
|
||||
QKeySequence ctrlPercent(Qt::ControlModifier + Qt::Key_Percent);
|
||||
QPushButton *_ctrlPercent = new QPushButton(ctrlPercent.toString());
|
||||
_ctrlPercent->setShortcut(ctrlPercent);
|
||||
layout->addWidget(_ctrlPercent);
|
||||
|
||||
QKeySequence ctrlShift5(Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_5);
|
||||
QPushButton *_ctrlShift5 = new QPushButton(ctrlShift5.toString());
|
||||
_ctrlShift5->setShortcut(ctrlShift5);
|
||||
layout->addWidget(_ctrlShift5);
|
||||
|
||||
QKeySequence ctrl5(Qt::ControlModifier + Qt::Key_5);
|
||||
QPushButton *_ctrl5 = new QPushButton(ctrl5.toString());
|
||||
_ctrl5->setShortcut(ctrl5);
|
||||
layout->addWidget(_ctrl5);
|
||||
|
||||
QKeySequence alt5(Qt::AltModifier + Qt::Key_5);
|
||||
QPushButton *_alt5 = new QPushButton(alt5.toString());
|
||||
_alt5->setShortcut(alt5);
|
||||
layout->addWidget(_alt5);
|
||||
|
||||
QKeySequence ctrlPlus(Qt::ControlModifier + Qt::Key_Plus);
|
||||
QPushButton *_ctrlPlus = new QPushButton(ctrlPlus.toString());
|
||||
_ctrlPlus->setShortcut(ctrlPlus);
|
||||
layout->addWidget(_ctrlPlus);
|
||||
|
||||
QKeySequence ctrlShiftPlus(Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_Plus);
|
||||
QPushButton *_ctrlShiftPlus = new QPushButton(ctrlShiftPlus.toString());
|
||||
_ctrlShiftPlus->setShortcut(ctrlShiftPlus);
|
||||
layout->addWidget(_ctrlShiftPlus);
|
||||
|
||||
QKeySequence ctrlY(Qt::ControlModifier + Qt::Key_Y);
|
||||
QPushButton *_ctrlY = new QPushButton(ctrlY.toString());
|
||||
_ctrlY->setShortcut(ctrlY);
|
||||
layout->addWidget(_ctrlY);
|
||||
|
||||
QKeySequence shiftComma(Qt::ShiftModifier + Qt::Key_Comma);
|
||||
QPushButton *_shiftComma = new QPushButton(shiftComma.toString());
|
||||
_shiftComma->setShortcut(shiftComma);
|
||||
layout->addWidget(_shiftComma);
|
||||
|
||||
QKeySequence ctrlComma(Qt::ControlModifier + Qt::Key_Comma);
|
||||
QPushButton *_ctrlComma = new QPushButton(ctrlComma.toString());
|
||||
_ctrlComma->setShortcut(ctrlComma);
|
||||
layout->addWidget(_ctrlComma);
|
||||
|
||||
QKeySequence ctrlSlash(Qt::ControlModifier + Qt::Key_Slash);
|
||||
QPushButton *_ctrlSlash = new QPushButton(ctrlSlash.toString());
|
||||
_ctrlSlash->setShortcut(ctrlSlash);
|
||||
layout->addWidget(_ctrlSlash);
|
||||
|
||||
QKeySequence ctrlBackslash(Qt::ControlModifier + Qt::Key_Backslash);
|
||||
QPushButton *_ctrlBackslash = new QPushButton(ctrlBackslash.toString());
|
||||
_ctrlBackslash->setShortcut(ctrlBackslash);
|
||||
layout->addWidget(_ctrlBackslash);
|
||||
|
||||
QKeySequence metaShiftA(Qt::MetaModifier + Qt::ShiftModifier + Qt::Key_A);
|
||||
QPushButton *_metaShiftA = new QPushButton(metaShiftA.toString());
|
||||
_metaShiftA->setShortcut(metaShiftA);
|
||||
layout->addWidget(_metaShiftA);
|
||||
|
||||
QKeySequence metaShift5(Qt::MetaModifier + Qt::ShiftModifier + Qt::Key_5);
|
||||
QPushButton *_metaShift5 = new QPushButton(metaShift5.toString());
|
||||
_metaShift5->setShortcut(metaShift5);
|
||||
layout->addWidget(_metaShift5);
|
||||
|
||||
QKeySequence ctrlBracketRigth(Qt::ControlModifier + Qt::Key_BracketRight);
|
||||
QPushButton *_ctrlBracketRigth = new QPushButton(ctrlBracketRigth.toString());
|
||||
_ctrlBracketRigth->setShortcut(ctrlBracketRigth);
|
||||
layout->addWidget(_ctrlBracketRigth);
|
||||
|
||||
QKeySequence shiftF3(Qt::ShiftModifier + Qt::Key_F3);
|
||||
QPushButton *_shiftF3 = new QPushButton(shiftF3.toString());
|
||||
_shiftF3->setShortcut(shiftF3);
|
||||
layout->addWidget(_shiftF3);
|
||||
|
||||
QKeySequence ctrlF3(Qt::ControlModifier + Qt::Key_F3);
|
||||
QPushButton *_ctrlF3 = new QPushButton(ctrlF3.toString());
|
||||
_ctrlF3->setShortcut(ctrlF3);
|
||||
layout->addWidget(_ctrlF3);
|
||||
|
||||
QKeySequence euro(0x20AC); // EURO SIGN e.g. US (with euro on 5) on 3rd keyboard level
|
||||
QPushButton *_euro = new QPushButton(euro.toString());
|
||||
_euro->setShortcut(euro);
|
||||
layout->addWidget(_euro);
|
||||
|
||||
QKeySequence ctrlEuro(Qt::ControlModifier + 0x20AC);
|
||||
QPushButton *_ctrlEuro = new QPushButton(ctrlEuro.toString());
|
||||
_ctrlEuro->setShortcut(ctrlEuro);
|
||||
layout->addWidget(_ctrlEuro);
|
||||
|
||||
// with german (neo 2) layout on linux under ISO_Level3_Shift + ISO_Level5_Shift + I
|
||||
QKeySequence greekPsi(QString(QStringLiteral("\u03A8")));
|
||||
QPushButton *_greekPsi = new QPushButton(greekPsi.toString());
|
||||
_greekPsi->setShortcut(greekPsi);
|
||||
layout->addWidget(_greekPsi);
|
||||
|
||||
layout->addWidget(new QLabel("Norwegian layout"));
|
||||
// LATIN SMALL LETTER O WITH STROKE
|
||||
QKeySequence norwegianO(QString(QStringLiteral("\u00F8")));
|
||||
QPushButton *_norwegianO = new QPushButton(norwegianO.toString());
|
||||
_norwegianO->setShortcut(norwegianO);
|
||||
layout->addWidget(_norwegianO);
|
||||
|
||||
layout->addWidget(new QLabel("Russian layout"));
|
||||
// CYRILLIC SMALL LETTER ZHE
|
||||
QKeySequence zhe(QString(QStringLiteral("\u0436")));
|
||||
QPushButton *_zhe = new QPushButton(zhe.toString());
|
||||
_zhe->setShortcut(zhe);
|
||||
layout->addWidget(_zhe);
|
||||
|
||||
// for sequence definitons see qplatformtheme.cpp
|
||||
layout->addWidget(new QLabel("QKeySequence::StandardKey(s)"));
|
||||
QPushButton *_open = new QPushButton("Open");
|
||||
_open->setShortcut(QKeySequence::Open); // Qt::CTRL | Qt::Key_O
|
||||
layout->addWidget(_open);
|
||||
}
|
||||
QGridLayout *m_gridLayout = new QGridLayout;
|
||||
};
|
||||
|
||||
inline void ShortcutTester::addToGrid(QWidget *w, int &row, int col)
|
||||
{
|
||||
m_gridLayout->addWidget(w, row++, col);
|
||||
}
|
||||
|
||||
void ShortcutTester::addShortcutToGrid(const QKeySequence &k, int &row, int col)
|
||||
{
|
||||
QPushButton *button = new QPushButton(k.toString());
|
||||
button->setShortcut(k);
|
||||
addToGrid(button, row, col);
|
||||
}
|
||||
|
||||
void addShortcutToGrid(int key, int &row, int col);
|
||||
|
||||
void ShortcutTester::setupLayout()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
QLabel *testPurpose = new QLabel();
|
||||
testPurpose->setWordWrap(true);
|
||||
testPurpose->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding);
|
||||
testPurpose->setText("This test come in handy to verify shortcuts under different "
|
||||
"keyboard layouts - qwerty, dvorak, non-latin (russian, arabic), etc.");
|
||||
layout->addWidget(testPurpose);
|
||||
|
||||
layout->addLayout(m_gridLayout);
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
const int keys1[] = {
|
||||
Qt::AltModifier + Qt::ShiftModifier + Qt::Key_G,
|
||||
Qt::AltModifier + Qt::Key_G,
|
||||
Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_R,
|
||||
Qt::ControlModifier + Qt::Key_R,
|
||||
Qt::ControlModifier + Qt::Key_Return, Qt::ControlModifier + Qt::Key_Enter,
|
||||
Qt::ControlModifier + Qt::ShiftModifier + Qt::AltModifier + Qt::Key_R,
|
||||
Qt::ShiftModifier + Qt::Key_5, Qt::ShiftModifier + Qt::Key_Percent,
|
||||
Qt::Key_Percent, Qt::Key_5, Qt::Key_Q
|
||||
};
|
||||
|
||||
for (int k : keys1)
|
||||
addShortcutToGrid(k, row, col);
|
||||
|
||||
row = 0;
|
||||
col++;
|
||||
|
||||
const int keys2[] = {
|
||||
Qt::ControlModifier + Qt::Key_Percent,
|
||||
Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_5,
|
||||
Qt::ControlModifier + Qt::Key_5, Qt::AltModifier + Qt::Key_5,
|
||||
Qt::ControlModifier + Qt::Key_Plus,
|
||||
Qt::ControlModifier + Qt::ShiftModifier + Qt::Key_Plus,
|
||||
Qt::ControlModifier + Qt::Key_Y, Qt::ShiftModifier + Qt::Key_Comma,
|
||||
Qt::ControlModifier + Qt::Key_Comma, Qt::ControlModifier + Qt::Key_Slash,
|
||||
Qt::ControlModifier + Qt::Key_Backslash
|
||||
};
|
||||
|
||||
for (int k : keys2)
|
||||
addShortcutToGrid(k, row, col);
|
||||
|
||||
row = 0;
|
||||
col++;
|
||||
|
||||
const int keys3[] = {
|
||||
Qt::MetaModifier + Qt::ShiftModifier + Qt::Key_A,
|
||||
Qt::MetaModifier + Qt::ShiftModifier + Qt::Key_5,
|
||||
Qt::ControlModifier + Qt::Key_BracketRight,
|
||||
Qt::ShiftModifier + Qt::Key_F3,
|
||||
Qt::ControlModifier + Qt::Key_F3,
|
||||
0x20AC, // EURO SIGN e.g. US (with euro on 5) on 3rd keyboard level
|
||||
Qt::ControlModifier + 0x20AC
|
||||
};
|
||||
|
||||
for (int k : keys3)
|
||||
addShortcutToGrid(k, row, col);
|
||||
|
||||
// with german (neo 2) layout on linux under ISO_Level3_Shift + ISO_Level5_Shift + I
|
||||
const QKeySequence greekPsi(QString(QStringLiteral("\u03A8")));
|
||||
addShortcutToGrid(greekPsi, row, col);
|
||||
|
||||
row = 0;
|
||||
col++;
|
||||
|
||||
addToGrid(new QLabel("Norwegian layout"), row, col);
|
||||
// LATIN SMALL LETTER O WITH STROKE
|
||||
QKeySequence norwegianO(QString(QStringLiteral("\u00F8")));
|
||||
addShortcutToGrid(norwegianO, row, col);
|
||||
|
||||
addToGrid(new QLabel("Russian layout"), row, col);
|
||||
// CYRILLIC SMALL LETTER ZHE
|
||||
QKeySequence zhe(QString(QStringLiteral("\u0436")));
|
||||
addShortcutToGrid(zhe, row, col);
|
||||
|
||||
// for sequence definitons see qplatformtheme.cpp
|
||||
addToGrid(new QLabel("QKeySequence::StandardKey(s)"), row, col);
|
||||
addShortcutToGrid(QKeySequence(QKeySequence::Open), row, col); // Qt::CTRL | Qt::Key_O
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
Loading…
Reference in New Issue
Block a user