Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts: src/corelib/io/qstandardpaths_win.cpp src/plugins/platforms/ios/qioswindow.mm src/plugins/platforms/ios/quiview.mm tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp Change-Id: I5deb0a0176a454a9c566e924d074ba60ce04f0bc
This commit is contained in:
commit
7c4b0aa970
@ -82,7 +82,7 @@ Build options:
|
||||
-debug-and-release ... Build two versions of Qt, with and without
|
||||
debugging turned on [yes] (Apple and Windows only)
|
||||
-optimize-debug ...... Enable debug-friendly optimizations in debug builds
|
||||
[auto] (Not supported with MSVC)
|
||||
[auto] (Not supported with MSVC or Clang toolchains)
|
||||
-optimize-size ....... Optimize release builds for size instead of speed [no]
|
||||
-optimized-tools ..... Build optimized host tools even in debug build [no]
|
||||
-force-debug-info .... Create symbol files for release builds [no]
|
||||
|
@ -704,7 +704,7 @@
|
||||
},
|
||||
"optimize_debug": {
|
||||
"label": "Optimize debug build",
|
||||
"condition": "!config.msvc && (features.debug || features.debug_and_release) && tests.optimize_debug",
|
||||
"condition": "!config.msvc && !config.clang && (features.debug || features.debug_and_release) && tests.optimize_debug",
|
||||
"output": [ "privateConfig" ]
|
||||
},
|
||||
"optimize_size": {
|
||||
@ -1352,7 +1352,7 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
|
||||
{
|
||||
"type": "feature",
|
||||
"args": "optimize_debug",
|
||||
"condition": "!config.msvc && (features.debug || features.debug_and_release)"
|
||||
"condition": "!config.msvc && !config.clang && (features.debug || features.debug_and_release)"
|
||||
},
|
||||
{
|
||||
"type": "feature",
|
||||
|
@ -137,6 +137,9 @@ function(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target
|
||||
DEPENDS ${infile} ${moc_depends}
|
||||
${_moc_working_dir}
|
||||
VERBATIM)
|
||||
set_source_files_properties(${infile} PROPERTIES SKIP_AUTOMOC ON)
|
||||
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC ON)
|
||||
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOUIC ON)
|
||||
endfunction()
|
||||
|
||||
|
||||
@ -155,7 +158,6 @@ function(QT5_GENERATE_MOC infile outfile )
|
||||
set(moc_target ${ARGV3})
|
||||
endif()
|
||||
qt5_create_moc_command(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}" "")
|
||||
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file
|
||||
endfunction()
|
||||
|
||||
|
||||
@ -246,6 +248,7 @@ function(QT5_ADD_BINARY_RESOURCES target )
|
||||
get_filename_component(infile ${it} ABSOLUTE)
|
||||
|
||||
_QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
|
||||
set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
|
||||
set(infiles ${infiles} ${infile})
|
||||
set(out_depends ${out_depends} ${_out_depends})
|
||||
set(rc_depends ${rc_depends} ${_rc_depends})
|
||||
@ -255,7 +258,6 @@ function(QT5_ADD_BINARY_RESOURCES target )
|
||||
COMMAND ${Qt5Core_RCC_EXECUTABLE}
|
||||
ARGS ${rcc_options} --binary --name ${target} --output ${rcc_destination} ${infiles}
|
||||
DEPENDS ${rc_depends} ${out_depends} VERBATIM)
|
||||
|
||||
add_custom_target(${target} ALL DEPENDS ${rcc_destination})
|
||||
endfunction()
|
||||
|
||||
@ -283,12 +285,15 @@ function(QT5_ADD_RESOURCES outfiles )
|
||||
set(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cpp)
|
||||
|
||||
_QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
|
||||
set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
|
||||
|
||||
add_custom_command(OUTPUT ${outfile}
|
||||
COMMAND ${Qt5Core_RCC_EXECUTABLE}
|
||||
ARGS ${rcc_options} --name ${outfilename} --output ${outfile} ${infile}
|
||||
MAIN_DEPENDENCY ${infile}
|
||||
DEPENDS ${_rc_depends} "${out_depends}" VERBATIM)
|
||||
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC ON)
|
||||
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOUIC ON)
|
||||
list(APPEND ${outfiles} ${outfile})
|
||||
endforeach()
|
||||
set(${outfiles} ${${outfiles}} PARENT_SCOPE)
|
||||
|
@ -44,7 +44,16 @@
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined __F16C__
|
||||
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__AVX2__) && !defined(__F16C__)
|
||||
// All processors that support AVX2 do support F16C too. That doesn't mean
|
||||
// we're allowed to use the intrinsics directly, so we'll do it only for
|
||||
// the Intel and Microsoft's compilers.
|
||||
# if defined(Q_CC_INTEL) || defined(Q_CC_MSVC)
|
||||
# define __F16C__ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
@ -116,7 +125,7 @@ QT_WARNING_DISABLE_CLANG("-Wc99-extensions")
|
||||
QT_WARNING_DISABLE_GCC("-Wold-style-cast")
|
||||
inline qfloat16::qfloat16(float f) Q_DECL_NOTHROW
|
||||
{
|
||||
#if defined(QT_COMPILER_SUPPORTS_F16C) && (defined(__F16C__) || defined(__AVX2__))
|
||||
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
|
||||
__m128 packsingle = _mm_set_ss(f);
|
||||
__m128i packhalf = _mm_cvtps_ph(packsingle, 0);
|
||||
b16 = _mm_extract_epi16(packhalf, 0);
|
||||
@ -134,7 +143,7 @@ QT_WARNING_POP
|
||||
|
||||
inline qfloat16::operator float() const Q_DECL_NOTHROW
|
||||
{
|
||||
#if defined(QT_COMPILER_SUPPORTS_F16C) && (defined(__F16C__) || defined(__AVX2__))
|
||||
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
|
||||
__m128i packhalf = _mm_cvtsi32_si128(b16);
|
||||
__m128 packsingle = _mm_cvtph_ps(packhalf);
|
||||
return _mm_cvtss_f32(packsingle);
|
||||
|
@ -201,6 +201,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
extern QString qAppFileName();
|
||||
#endif
|
||||
|
||||
QStringList QStandardPaths::standardLocations(StandardLocation type)
|
||||
{
|
||||
QStringList dirs;
|
||||
@ -217,8 +221,13 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
|
||||
dirs.append(programData);
|
||||
}
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
dirs.append(QCoreApplication::applicationDirPath());
|
||||
const QString dataDir = QCoreApplication::applicationDirPath() + QLatin1String("/data");
|
||||
// Note: QCoreApplication::applicationDirPath(), while static, requires
|
||||
// an application instance. But we might need to resolve the standard
|
||||
// locations earlier than that, so we fall back to qAppFileName().
|
||||
QString applicationDirPath = qApp ? QCoreApplication::applicationDirPath()
|
||||
: QFileInfo(qAppFileName()).path();
|
||||
dirs.append(applicationDirPath);
|
||||
const QString dataDir = applicationDirPath + QLatin1String("/data");
|
||||
dirs.append(dataDir);
|
||||
|
||||
if (!isGenericConfigLocation(type)) {
|
||||
|
@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
|
||||
*/
|
||||
QPlatformPixmap *QPlatformPixmap::create(int w, int h, PixelType type)
|
||||
{
|
||||
if (Q_UNLIKELY(!QGuiApplicationPrivate::platformIntegration()))
|
||||
qFatal("QPlatformPixmap: QGuiApplication required");
|
||||
|
||||
QPlatformPixmap *data = QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(static_cast<QPlatformPixmap::PixelType>(type));
|
||||
data->resize(w, h);
|
||||
return data;
|
||||
|
@ -265,12 +265,12 @@ void QWindowSystemInterface::handleWindowScreenChanged(QWindow *window, QScreen
|
||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||
}
|
||||
|
||||
void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate)
|
||||
QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::ApplicationState newState, bool forcePropagate)
|
||||
{
|
||||
Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState));
|
||||
QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e =
|
||||
new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState, forcePropagate);
|
||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
|
||||
}
|
||||
|
||||
QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry)
|
||||
|
@ -180,6 +180,7 @@ public:
|
||||
static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState = -1);
|
||||
static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen);
|
||||
|
||||
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
|
||||
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
|
||||
|
||||
#ifndef QT_NO_DRAGANDDROP
|
||||
|
@ -1027,8 +1027,7 @@ QNetworkConfiguration QNetworkAccessManager::configuration() const
|
||||
if (session) {
|
||||
return session->configuration();
|
||||
} else {
|
||||
QNetworkConfigurationManager manager;
|
||||
return manager.defaultConfiguration();
|
||||
return d->networkConfigurationManager.defaultConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1052,12 +1051,11 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
|
||||
Q_D(const QNetworkAccessManager);
|
||||
|
||||
QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
|
||||
QNetworkConfigurationManager manager;
|
||||
if (networkSession) {
|
||||
return manager.configurationFromIdentifier(
|
||||
return d->networkConfigurationManager.configurationFromIdentifier(
|
||||
networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
|
||||
} else {
|
||||
return manager.defaultConfiguration();
|
||||
return d->networkConfigurationManager.defaultConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1384,17 +1382,16 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
|
||||
}
|
||||
|
||||
if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.identifier().isEmpty())) {
|
||||
QNetworkConfigurationManager manager;
|
||||
if (!d->networkConfiguration.identifier().isEmpty()) {
|
||||
if ((d->networkConfiguration.state() & QNetworkConfiguration::Defined)
|
||||
&& d->networkConfiguration != manager.defaultConfiguration())
|
||||
d->createSession(manager.defaultConfiguration());
|
||||
&& d->networkConfiguration != d->networkConfigurationManager.defaultConfiguration())
|
||||
d->createSession(d->networkConfigurationManager.defaultConfiguration());
|
||||
else
|
||||
d->createSession(d->networkConfiguration);
|
||||
|
||||
} else {
|
||||
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
|
||||
d->createSession(manager.defaultConfiguration());
|
||||
if (d->networkSessionRequired)
|
||||
d->createSession(d->networkConfigurationManager.defaultConfiguration());
|
||||
else
|
||||
d->initializeSession = false;
|
||||
}
|
||||
@ -1926,8 +1923,8 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
|
||||
online = (networkConfiguration.state() & QNetworkConfiguration::Active);
|
||||
} else {
|
||||
if (online != isOnline) {
|
||||
_q_networkSessionClosed();
|
||||
createSession(q->configuration());
|
||||
_q_networkSessionClosed();
|
||||
createSession(q->configuration());
|
||||
online = isOnline;
|
||||
}
|
||||
}
|
||||
@ -1951,13 +1948,13 @@ void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfigu
|
||||
const QString id = configuration.identifier();
|
||||
if (configuration.state().testFlag(QNetworkConfiguration::Active)) {
|
||||
if (!onlineConfigurations.contains(id)) {
|
||||
|
||||
QSharedPointer<QNetworkSession> session(getNetworkSession());
|
||||
if (session) {
|
||||
if (online && session->configuration().identifier()
|
||||
!= networkConfigurationManager.defaultConfiguration().identifier()) {
|
||||
|
||||
onlineConfigurations.insert(id);
|
||||
// CHECK: If it's having Active flag - why would it be disconnected ???
|
||||
//this one disconnected but another one is online,
|
||||
// close and create new session
|
||||
_q_networkSessionClosed();
|
||||
@ -1968,6 +1965,7 @@ void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfigu
|
||||
|
||||
} else if (onlineConfigurations.contains(id)) {
|
||||
//this one is disconnecting
|
||||
// CHECK: If it disconnected while we create a session over a down configuration ???
|
||||
onlineConfigurations.remove(id);
|
||||
if (!onlineConfigurations.isEmpty()) {
|
||||
_q_networkSessionClosed();
|
||||
|
@ -112,9 +112,11 @@ static bool isDBusTrayAvailable() {
|
||||
#ifndef QT_NO_DBUS
|
||||
static bool checkDBusGlobalMenuAvailable()
|
||||
{
|
||||
QDBusConnection connection = QDBusConnection::sessionBus();
|
||||
QString registrarService = QStringLiteral("com.canonical.AppMenu.Registrar");
|
||||
return connection.interface()->isServiceRegistered(registrarService);
|
||||
const QDBusConnection connection = QDBusConnection::sessionBus();
|
||||
static const QString registrarService = QStringLiteral("com.canonical.AppMenu.Registrar");
|
||||
if (const auto iface = connection.interface())
|
||||
return iface->isServiceRegistered(registrarService);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isDBusGlobalMenuAvailable()
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
#include "qiosapplicationstate.h"
|
||||
|
||||
#include "qiosglobal.h"
|
||||
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
|
||||
@ -72,8 +74,8 @@ static Qt::ApplicationState qtApplicationState(UIApplicationState uiApplicationS
|
||||
static void handleApplicationStateChanged(UIApplicationState uiApplicationState)
|
||||
{
|
||||
Qt::ApplicationState state = qtApplicationState(uiApplicationState);
|
||||
QWindowSystemInterface::handleApplicationStateChanged(state);
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
qCDebug(lcQpaApplication) << "moved to" << state;
|
||||
QWindowSystemInterface::handleApplicationStateChanged<QWindowSystemInterface::SynchronousDelivery>(state);
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@ -165,8 +165,6 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface)
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
framebufferObject.depthRenderbuffer);
|
||||
}
|
||||
|
||||
connect(static_cast<QIOSWindow *>(surface), SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
|
||||
} else {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle);
|
||||
}
|
||||
@ -249,8 +247,13 @@ QIOSContext::FramebufferObject &QIOSContext::backingFramebufferObjectFor(QPlatfo
|
||||
// should probably use QOpenGLMultiGroupSharedResource to track the shared default-FBOs.
|
||||
if (m_sharedContext)
|
||||
return m_sharedContext->backingFramebufferObjectFor(surface);
|
||||
else
|
||||
return m_framebufferObjects[surface];
|
||||
|
||||
if (!m_framebufferObjects.contains(surface)) {
|
||||
// We're about to create a new FBO, make sure it's cleaned up as well
|
||||
connect(static_cast<QIOSWindow *>(surface), SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
|
||||
}
|
||||
|
||||
return m_framebufferObjects[surface];
|
||||
}
|
||||
|
||||
GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
|
||||
|
@ -47,7 +47,9 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcQpaApplication);
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods);
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow);
|
||||
|
||||
#if !defined(QT_NO_DEBUG)
|
||||
#define qImDebug \
|
||||
|
@ -44,7 +44,9 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
|
||||
Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
|
||||
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
|
||||
|
||||
bool isQtApplication()
|
||||
{
|
||||
|
@ -239,15 +239,28 @@ void QIOSWindow::setWindowState(Qt::WindowStates state)
|
||||
if (window()->isTopLevel() && window()->isVisible() && window()->isActive())
|
||||
[m_view.qtViewController updateProperties];
|
||||
|
||||
if (state & Qt::WindowMinimized)
|
||||
if (state & Qt::WindowMinimized) {
|
||||
applyGeometry(QRect());
|
||||
else if (state & Qt::WindowFullScreen)
|
||||
applyGeometry(screen()->geometry());
|
||||
else if (state & Qt::WindowMaximized)
|
||||
applyGeometry(window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint ?
|
||||
screen()->geometry() : screen()->availableGeometry());
|
||||
else
|
||||
} else if (state & (Qt::WindowFullScreen | Qt::WindowMaximized)) {
|
||||
// When an application is in split-view mode, the UIScreen still has the
|
||||
// same geometry, but the UIWindow is resized to the area reserved for the
|
||||
// application. We use this to constrain the geometry used when applying the
|
||||
// fullscreen or maximized window states. Note that we do not do this
|
||||
// in applyGeometry(), as we don't want to artificially limit window
|
||||
// placement "outside" of the screen bounds if that's what the user wants.
|
||||
|
||||
QRect uiWindowBounds = QRectF::fromCGRect(m_view.window.bounds).toRect();
|
||||
QRect fullscreenGeometry = screen()->geometry().intersected(uiWindowBounds);
|
||||
QRect maximizedGeometry = window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint ?
|
||||
fullscreenGeometry : screen()->availableGeometry().intersected(uiWindowBounds);
|
||||
|
||||
if (state & Qt::WindowFullScreen)
|
||||
applyGeometry(fullscreenGeometry);
|
||||
else
|
||||
applyGeometry(maximizedGeometry);
|
||||
} else {
|
||||
applyGeometry(m_normalGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
|
||||
|
@ -161,6 +161,7 @@
|
||||
QWindow *window = m_qioswindow->window();
|
||||
QRect lastReportedGeometry = qt_window_private(window)->geometry;
|
||||
QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect();
|
||||
qCDebug(lcQpaWindow) << m_qioswindow->window() << "new geometry is" << currentGeometry;
|
||||
QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(window, currentGeometry);
|
||||
|
||||
if (currentGeometry.size() != lastReportedGeometry.size()) {
|
||||
@ -193,6 +194,7 @@
|
||||
region = QRect(QPoint(), bounds);
|
||||
}
|
||||
|
||||
qCDebug(lcQpaWindow) << m_qioswindow->window() << region << "isExposed" << m_qioswindow->isExposed();
|
||||
QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), region);
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,9 @@ function(QT5_WRAP_UI outfiles )
|
||||
COMMAND ${Qt5Widgets_UIC_EXECUTABLE}
|
||||
ARGS ${ui_options} -o ${outfile} ${infile}
|
||||
MAIN_DEPENDENCY ${infile} VERBATIM)
|
||||
set_source_files_properties(${infile} PROPERTIES SKIP_AUTOUIC ON)
|
||||
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC ON)
|
||||
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOUIC ON)
|
||||
list(APPEND ${outfiles} ${outfile})
|
||||
endforeach()
|
||||
set(${outfiles} ${${outfiles}} PARENT_SCOPE)
|
||||
|
@ -2086,40 +2086,26 @@ void QHeaderViewPrivate::_q_layoutChanged()
|
||||
{
|
||||
Q_Q(QHeaderView);
|
||||
viewport->update();
|
||||
if (persistentHiddenSections.isEmpty() || modelIsEmpty()) {
|
||||
if (modelSectionCount() != sectionCount())
|
||||
q->initializeSections();
|
||||
persistentHiddenSections.clear();
|
||||
|
||||
const auto hiddenSections = persistentHiddenSections;
|
||||
persistentHiddenSections.clear();
|
||||
|
||||
clear();
|
||||
q->initializeSections();
|
||||
invalidateCachedSizeHint();
|
||||
|
||||
if (modelIsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QBitArray oldSectionHidden = sectionsHiddenToBitVector();
|
||||
oldSectionHidden.resize(sectionItems.size());
|
||||
bool sectionCountChanged = false;
|
||||
|
||||
for (int i = 0; i < persistentHiddenSections.count(); ++i) {
|
||||
QModelIndex index = persistentHiddenSections.at(i);
|
||||
for (const auto &index : hiddenSections) {
|
||||
if (index.isValid()) {
|
||||
const int logical = (orientation == Qt::Horizontal
|
||||
? index.column()
|
||||
: index.row());
|
||||
q->setSectionHidden(logical, true);
|
||||
oldSectionHidden.setBit(logical, false);
|
||||
} else if (!sectionCountChanged && (modelSectionCount() != sectionCount())) {
|
||||
sectionCountChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
persistentHiddenSections.clear();
|
||||
|
||||
for (int i = 0; i < oldSectionHidden.count(); ++i) {
|
||||
if (oldSectionHidden.testBit(i))
|
||||
q->setSectionHidden(i, false);
|
||||
}
|
||||
|
||||
// the number of sections changed; we need to reread the state of the model
|
||||
if (sectionCountChanged)
|
||||
q->initializeSections();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -1397,6 +1397,9 @@ void QTableView::paintEvent(QPaintEvent *event)
|
||||
} else {
|
||||
dirtyArea.setRight(qMin(dirtyArea.right(), int(x)));
|
||||
}
|
||||
// dirtyArea may be invalid when the horizontal header is not stretched
|
||||
if (!dirtyArea.isValid())
|
||||
continue;
|
||||
|
||||
// get the horizontal start and end visual sections
|
||||
int left = horizontalHeader->visualIndexAt(dirtyArea.left());
|
||||
|
@ -736,7 +736,10 @@ void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto
|
||||
void QTreeView::hideColumn(int column)
|
||||
{
|
||||
Q_D(QTreeView);
|
||||
if (d->header->isSectionHidden(column))
|
||||
return;
|
||||
d->header->hideSection(column);
|
||||
doItemsLayout();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -747,7 +750,10 @@ void QTreeView::hideColumn(int column)
|
||||
void QTreeView::showColumn(int column)
|
||||
{
|
||||
Q_D(QTreeView);
|
||||
if (!d->header->isSectionHidden(column))
|
||||
return;
|
||||
d->header->showSection(column);
|
||||
doItemsLayout();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1008,11 +1014,16 @@ void QTreeView::keyboardSearch(const QString &search)
|
||||
if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))
|
||||
return;
|
||||
|
||||
// Do a relayout nows, so that we can utilize viewItems
|
||||
d->executePostedLayout();
|
||||
if (d->viewItems.isEmpty())
|
||||
return;
|
||||
|
||||
QModelIndex start;
|
||||
if (currentIndex().isValid())
|
||||
start = currentIndex();
|
||||
else
|
||||
start = d->model->index(0, 0, d->root);
|
||||
start = d->viewItems.at(0).index;
|
||||
|
||||
bool skipRow = false;
|
||||
bool keyboardTimeWasValid = d->keyboardInputTime.isValid();
|
||||
@ -1040,13 +1051,16 @@ void QTreeView::keyboardSearch(const QString &search)
|
||||
|
||||
// skip if we are searching for the same key or a new search started
|
||||
if (skipRow) {
|
||||
if (indexBelow(start).isValid())
|
||||
if (indexBelow(start).isValid()) {
|
||||
start = indexBelow(start);
|
||||
else
|
||||
start = d->model->index(0, start.column(), d->root);
|
||||
} else {
|
||||
const int origCol = start.column();
|
||||
start = d->viewItems.at(0).index;
|
||||
if (origCol != start.column())
|
||||
start = start.sibling(start.row(), origCol);
|
||||
}
|
||||
}
|
||||
|
||||
d->executePostedLayout();
|
||||
int startIndex = d->viewIndex(start);
|
||||
if (startIndex <= -1)
|
||||
return;
|
||||
|
@ -476,8 +476,10 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
|
||||
break;
|
||||
if (option->state & State_Open)
|
||||
drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
|
||||
else
|
||||
drawPrimitive(PE_IndicatorArrowRight, option, painter, widget);
|
||||
else {
|
||||
const bool reverse = (option->direction == Qt::RightToLeft);
|
||||
drawPrimitive(reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight, option, painter, widget);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if QT_CONFIG(tabbar)
|
||||
|
@ -1119,6 +1119,8 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
|
||||
static void enableMacToolBar(QToolBar *toolbar, bool enable)
|
||||
{
|
||||
QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
|
||||
if (!nativeInterface)
|
||||
return;
|
||||
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
|
||||
nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
|
||||
if (!function)
|
||||
|
@ -157,7 +157,13 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.11 AND NOT NO_WIDGETS)
|
||||
expect_pass(test_interface)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||
expect_pass(test_interface_link_libraries)
|
||||
expect_pass(test_moc_macro_target)
|
||||
expect_pass(test_interface_link_libraries)
|
||||
expect_pass(test_moc_macro_target)
|
||||
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 3.8)
|
||||
# With earlier CMake versions, this test would simply run moc multiple times and lead to:
|
||||
# /usr/bin/ld: error: CMakeFiles/mywidget.dir/mywidget_automoc.cpp.o: multiple definition of 'MyWidget::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)'
|
||||
# /usr/bin/ld: CMakeFiles/mywidget.dir/moc_mywidget.cpp.o: previous definition here
|
||||
# Reason: SKIP_* properties were added in CMake 3.8 only
|
||||
expect_pass(test_QTBUG-63422)
|
||||
endif()
|
||||
|
30
tests/auto/cmake/test_QTBUG-63422/CMakeLists.txt
Normal file
30
tests/auto/cmake/test_QTBUG-63422/CMakeLists.txt
Normal file
@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(test_dependent_modules)
|
||||
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# make sure CMP0071 warnings cause a test failure
|
||||
set(CMAKE_SUPPRESS_DEVELOPER_ERRORS FALSE CACHE INTERNAL "" FORCE)
|
||||
|
||||
qt5_wrap_cpp(moc_files mywidget.h)
|
||||
qt5_wrap_ui(ui_files mywidget.ui)
|
||||
qt5_add_resources(qrc_files res.qrc)
|
||||
|
||||
add_executable(mywidget
|
||||
# source files
|
||||
mywidget.cpp
|
||||
mywidget.h
|
||||
mywidget.ui
|
||||
res.qrc
|
||||
|
||||
# generated files
|
||||
${moc_files}
|
||||
${ui_files}
|
||||
${qrc_files}
|
||||
)
|
||||
target_link_libraries(mywidget ${Qt5Widgets_LIBRARIES})
|
43
tests/auto/cmake/test_QTBUG-63422/mywidget.cpp
Normal file
43
tests/auto/cmake/test_QTBUG-63422/mywidget.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Kevin Funk <kevin.funk@kdab.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "mywidget.h"
|
||||
#include "ui_mywidget.h"
|
||||
|
||||
MyWidget::MyWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
emit someSignal();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
MyWidget myWidget;
|
||||
return 0;
|
||||
}
|
52
tests/auto/cmake/test_QTBUG-63422/mywidget.h
Normal file
52
tests/auto/cmake/test_QTBUG-63422/mywidget.h
Normal file
@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Kevin Funk <kevin.funk@kdab.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MYWIDGET_H
|
||||
#define MYWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MyWidget;
|
||||
}
|
||||
|
||||
class MyWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyWidget(QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void someSignal();
|
||||
|
||||
private:
|
||||
Ui::MyWidget *ui = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
34
tests/auto/cmake/test_QTBUG-63422/mywidget.ui
Normal file
34
tests/auto/cmake/test_QTBUG-63422/mywidget.ui
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>PushButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
4
tests/auto/cmake/test_QTBUG-63422/res.qrc
Normal file
4
tests/auto/cmake/test_QTBUG-63422/res.qrc
Normal file
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
</qresource>
|
||||
</RCC>
|
@ -95,6 +95,7 @@ private slots:
|
||||
void stackSize();
|
||||
void stressTest();
|
||||
void takeAllAndIncreaseMaxThreadCount();
|
||||
void waitForDoneAfterTake();
|
||||
|
||||
private:
|
||||
QMutex m_functionTestMutex;
|
||||
@ -1267,5 +1268,72 @@ void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() {
|
||||
delete task3;
|
||||
}
|
||||
|
||||
void tst_QThreadPool::waitForDoneAfterTake()
|
||||
{
|
||||
class Task : public QRunnable
|
||||
{
|
||||
public:
|
||||
Task(QSemaphore *mainBarrier, QSemaphore *threadBarrier)
|
||||
: m_mainBarrier(mainBarrier)
|
||||
, m_threadBarrier(threadBarrier)
|
||||
{}
|
||||
|
||||
void run()
|
||||
{
|
||||
m_mainBarrier->release();
|
||||
m_threadBarrier->acquire();
|
||||
}
|
||||
|
||||
private:
|
||||
QSemaphore *m_mainBarrier = nullptr;
|
||||
QSemaphore *m_threadBarrier = nullptr;
|
||||
};
|
||||
|
||||
int threadCount = 4;
|
||||
|
||||
// Blocks the main thread from releasing the threadBarrier before all run() functions have started
|
||||
QSemaphore mainBarrier;
|
||||
// Blocks the tasks from completing their run function
|
||||
QSemaphore threadBarrier;
|
||||
|
||||
QThreadPool manager;
|
||||
manager.setMaxThreadCount(threadCount);
|
||||
|
||||
// Fill all the threads with runnables that wait for the threadBarrier
|
||||
for (int i = 0; i < threadCount; i++) {
|
||||
auto *task = new Task(&mainBarrier, &threadBarrier);
|
||||
manager.start(task);
|
||||
}
|
||||
|
||||
QVERIFY(manager.activeThreadCount() == manager.maxThreadCount());
|
||||
|
||||
// Add runnables that are immediately removed from the pool queue.
|
||||
// This sets the queue elements to nullptr in QThreadPool and we want to test that
|
||||
// the threads keep going through the queue after encountering a nullptr.
|
||||
for (int i = 0; i < threadCount; i++) {
|
||||
QRunnable *runnable = createTask(emptyFunct);
|
||||
manager.start(runnable);
|
||||
QVERIFY(manager.tryTake(runnable));
|
||||
}
|
||||
|
||||
// Add another runnable that will not be removed
|
||||
manager.start(createTask(emptyFunct));
|
||||
|
||||
// Wait for the first runnables to start
|
||||
mainBarrier.acquire(threadCount);
|
||||
|
||||
QVERIFY(mainBarrier.available() == 0);
|
||||
QVERIFY(threadBarrier.available() == 0);
|
||||
|
||||
// Release runnables that are waiting and expect all runnables to complete
|
||||
threadBarrier.release(threadCount);
|
||||
|
||||
// Using qFatal instead of QVERIFY to force exit if threads are still running after timeout.
|
||||
// Otherwise, QCoreApplication will still wait for the stale threads and never exit the test.
|
||||
if (!manager.waitForDone(5 * 60 * 1000))
|
||||
qFatal("waitForDone returned false. Aborting to stop background threads.");
|
||||
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QThreadPool);
|
||||
#include "tst_qthreadpool.moc"
|
||||
|
@ -622,7 +622,7 @@ protected:
|
||||
Q_ASSERT(!client.isNull());
|
||||
// we need to emulate the bytesWrittenSlot call if the data is empty.
|
||||
if (dataToTransmit.size() == 0) {
|
||||
QMetaObject::invokeMethod(this, "bytesWrittenSlot", Qt::QueuedConnection);
|
||||
emit client->bytesWritten(0);
|
||||
} else {
|
||||
client->write(dataToTransmit);
|
||||
// FIXME: For SSL connections, if we don't flush the socket, the
|
||||
@ -659,22 +659,26 @@ private slots:
|
||||
#ifndef QT_NO_SSL
|
||||
void slotSslErrors(const QList<QSslError>& errors)
|
||||
{
|
||||
Q_ASSERT(!client.isNull());
|
||||
qDebug() << "slotSslErrors" << client->errorString() << errors;
|
||||
QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender());
|
||||
Q_ASSERT(currentClient);
|
||||
qDebug() << "slotSslErrors" << currentClient->errorString() << errors;
|
||||
}
|
||||
#endif
|
||||
void slotError(QAbstractSocket::SocketError err)
|
||||
{
|
||||
if (client.isNull())
|
||||
qDebug() << "slotError" << err;
|
||||
else
|
||||
qDebug() << "slotError" << err << client->errorString();
|
||||
QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender());
|
||||
Q_ASSERT(currentClient);
|
||||
qDebug() << "slotError" << err << currentClient->errorString();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void readyReadSlot()
|
||||
{
|
||||
Q_ASSERT(!client.isNull());
|
||||
QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender());
|
||||
Q_ASSERT(currentClient);
|
||||
if (currentClient != client)
|
||||
client = currentClient;
|
||||
|
||||
receivedData += client->readAll();
|
||||
const int doubleEndlPos = receivedData.indexOf("\r\n\r\n");
|
||||
|
||||
@ -8290,11 +8294,23 @@ void tst_QNetworkReply::ioHttpRedirectErrors()
|
||||
QNetworkReplyPtr reply(manager.get(request));
|
||||
if (localhost.scheme() == "https")
|
||||
reply.data()->ignoreSslErrors();
|
||||
QSignalSpy spy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError)));
|
||||
|
||||
QCOMPARE(waitForFinish(reply), int(Failure));
|
||||
QEventLoop eventLoop;
|
||||
QTimer watchDog;
|
||||
watchDog.setSingleShot(true);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->connect(reply.data(), QOverload<QNetworkReply::NetworkError>().of(&QNetworkReply::error),
|
||||
[&eventLoop](QNetworkReply::NetworkError){
|
||||
eventLoop.exit(Failure);
|
||||
});
|
||||
|
||||
watchDog.connect(&watchDog, &QTimer::timeout, [&eventLoop](){
|
||||
eventLoop.exit(Timeout);
|
||||
});
|
||||
|
||||
watchDog.start(5000);
|
||||
|
||||
QCOMPARE(eventLoop.exec(), int(Failure));
|
||||
QCOMPARE(reply->error(), error);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
windows
|
||||
[waitForConnectedEncryptedReadyRead:WithSocks5ProxyAuth]
|
||||
*
|
||||
[protocolServerSide:ssl3-any]
|
||||
rhel-7.2
|
||||
[protocolServerSide:tls1.0-any]
|
||||
|
@ -1601,7 +1601,12 @@ void tst_QSslSocket::waitForConnectedEncryptedReadyRead()
|
||||
QFETCH_GLOBAL(bool, setProxy);
|
||||
if (setProxy && !socket->waitForEncrypted(10000))
|
||||
QSKIP("Skipping flaky test - See QTBUG-29941");
|
||||
QVERIFY(socket->waitForReadyRead(10000));
|
||||
|
||||
// We only do this if we have no bytes available to read already because readyRead will
|
||||
// not be emitted again.
|
||||
if (socket->bytesAvailable() == 0)
|
||||
QVERIFY(socket->waitForReadyRead(10000));
|
||||
|
||||
QVERIFY(!socket->peerCertificate().isNull());
|
||||
QVERIFY(!socket->peerCertificateChain().isEmpty());
|
||||
}
|
||||
|
@ -210,6 +210,7 @@ private slots:
|
||||
void QTBUG12268_hiddenMovedSectionSorting();
|
||||
void QTBUG14242_hideSectionAutoSize();
|
||||
void QTBUG50171_visualRegionForSwappedItems();
|
||||
void QTBUG53221_assertShiftHiddenRow();
|
||||
void ensureNoIndexAtLength();
|
||||
void offsetConsistent();
|
||||
|
||||
@ -2384,6 +2385,54 @@ void tst_QHeaderView::QTBUG50171_visualRegionForSwappedItems()
|
||||
headerView.testVisualRegionForSelection();
|
||||
}
|
||||
|
||||
class QTBUG53221_Model : public QAbstractItemModel
|
||||
{
|
||||
public:
|
||||
void insertRowAtBeginning()
|
||||
{
|
||||
Q_EMIT layoutAboutToBeChanged();
|
||||
m_displayNames.insert(0, QStringLiteral("Item %1").arg(m_displayNames.count()));
|
||||
// Rows are always inserted at the beginning, so move all others.
|
||||
foreach (const QModelIndex &persIndex, persistentIndexList())
|
||||
{
|
||||
// The vertical header view will have a persistent index stored here on the second call to insertRowAtBeginning.
|
||||
changePersistentIndex(persIndex, index(persIndex.row() + 1, persIndex.column(), persIndex.parent()));
|
||||
}
|
||||
Q_EMIT layoutChanged();
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override
|
||||
{
|
||||
return (role == Qt::DisplayRole) ? m_displayNames.at(index.row()) : QVariant();
|
||||
}
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &) const override { return createIndex(row, column); }
|
||||
QModelIndex parent(const QModelIndex &) const override { return QModelIndex(); }
|
||||
int rowCount(const QModelIndex &) const override { return m_displayNames.count(); }
|
||||
int columnCount(const QModelIndex &) const override { return 1; }
|
||||
|
||||
private:
|
||||
QStringList m_displayNames;
|
||||
};
|
||||
|
||||
void tst_QHeaderView::QTBUG53221_assertShiftHiddenRow()
|
||||
{
|
||||
QTableView tableView;
|
||||
QTBUG53221_Model modelTableView;
|
||||
tableView.setModel(&modelTableView);
|
||||
|
||||
modelTableView.insertRowAtBeginning();
|
||||
tableView.setRowHidden(0, true);
|
||||
QCOMPARE(tableView.verticalHeader()->isSectionHidden(0), true);
|
||||
modelTableView.insertRowAtBeginning();
|
||||
QCOMPARE(tableView.verticalHeader()->isSectionHidden(0), false);
|
||||
QCOMPARE(tableView.verticalHeader()->isSectionHidden(1), true);
|
||||
modelTableView.insertRowAtBeginning();
|
||||
QCOMPARE(tableView.verticalHeader()->isSectionHidden(0), false);
|
||||
QCOMPARE(tableView.verticalHeader()->isSectionHidden(1), false);
|
||||
QCOMPARE(tableView.verticalHeader()->isSectionHidden(2), true);
|
||||
}
|
||||
|
||||
void protected_QHeaderView::testVisualRegionForSelection()
|
||||
{
|
||||
QRegion r = visualRegionForSelection(QItemSelection(model()->index(1, 0), model()->index(1, 2)));
|
||||
|
@ -196,6 +196,7 @@ private slots:
|
||||
void taskQTBUG_37813_crash();
|
||||
void taskQTBUG_45697_crash();
|
||||
void taskQTBUG_7232_AllowUserToControlSingleStep();
|
||||
void taskQTBUG_8376();
|
||||
void testInitialFocus();
|
||||
};
|
||||
|
||||
@ -1086,6 +1087,103 @@ void tst_QTreeView::keyboardSearch()
|
||||
// The item that starts with B is selected.
|
||||
view.keyboardSearch(QLatin1String("B"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(1, 0)));
|
||||
|
||||
// Test that it wraps round
|
||||
model.appendRow(new QStandardItem("Andy"));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(3, 0)));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(0, 0)));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(3, 0)));
|
||||
|
||||
// Test that it handles the case where the first item is hidden correctly
|
||||
model.insertRow(0, new QStandardItem("Hidden item"));
|
||||
view.setRowHidden(0, QModelIndex(), true);
|
||||
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(1, 0)));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(4, 0)));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(1, 0)));
|
||||
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
model.clear();
|
||||
view.setCurrentIndex(QModelIndex());
|
||||
QList<QStandardItem *> items = { new QStandardItem("Andreas"), new QStandardItem("Alicia") };
|
||||
model.appendRow(items);
|
||||
items = { new QStandardItem("Baldrian"), new QStandardItem("Belinda") };
|
||||
model.appendRow(items);
|
||||
items = { new QStandardItem("Cecilie"), new QStandardItem("Claire") };
|
||||
model.appendRow(items);
|
||||
QVERIFY(!view.selectionModel()->hasSelection());
|
||||
QVERIFY(!view.selectionModel()->isSelected(model.index(0, 0)));
|
||||
|
||||
// We want to search on the 2nd column so we have to force it to have
|
||||
// an index in that column as a starting point
|
||||
view.setCurrentIndex(QModelIndex(model.index(0, 1)));
|
||||
// Second item in first row is selected
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QTRY_VERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
|
||||
QVERIFY(view.currentIndex() == model.index(0, 1));
|
||||
|
||||
// Second item in first row is still selected
|
||||
view.keyboardSearch(QLatin1String("l"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(0, 1));
|
||||
|
||||
// No "AnB" item - keep the same selection.
|
||||
view.keyboardSearch(QLatin1String("B"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(0, 1));
|
||||
|
||||
// Wait a bit.
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
|
||||
// The item that starts with B is selected.
|
||||
view.keyboardSearch(QLatin1String("B"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(1, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(1, 1));
|
||||
|
||||
// Test that it wraps round
|
||||
items = { new QStandardItem("Andy"), new QStandardItem("Adele") };
|
||||
model.appendRow(items);
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(3, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(3, 1));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(0, 1));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(3, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(3, 1));
|
||||
|
||||
// Test that it handles the case where the first item is hidden correctly
|
||||
model.insertRow(0, new QStandardItem("Hidden item"));
|
||||
view.setRowHidden(0, QModelIndex(), true);
|
||||
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(1, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(1, 1));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(4, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(4, 1));
|
||||
QTest::qWait(QApplication::keyboardInputInterval() * 2);
|
||||
view.keyboardSearch(QLatin1String("A"));
|
||||
QVERIFY(view.selectionModel()->isSelected(model.index(1, 1)));
|
||||
QCOMPARE(view.currentIndex(), model.index(1, 1));
|
||||
}
|
||||
|
||||
void tst_QTreeView::keyboardSearchMultiColumn()
|
||||
@ -4466,5 +4564,51 @@ void tst_QTreeView::statusTip()
|
||||
QTest::mouseMove(mw.windowHandle(), centerPoint);
|
||||
QTRY_COMPARE(mw.statusBar()->currentMessage(), QLatin1String("Header 0 -- Status"));
|
||||
}
|
||||
|
||||
static void fillModeltaskQTBUG_8376(QAbstractItemModel &model)
|
||||
{
|
||||
model.insertRow(0);
|
||||
model.insertColumn(0);
|
||||
model.insertColumn(1);
|
||||
QModelIndex index = model.index(0, 0);
|
||||
model.setData(index, "Level0");
|
||||
{
|
||||
model.insertRow(0, index);
|
||||
model.insertRow(1, index);
|
||||
model.insertColumn(0, index);
|
||||
model.insertColumn(1, index);
|
||||
|
||||
QModelIndex idx;
|
||||
idx = model.index(0, 0, index);
|
||||
model.setData(idx, "Level1");
|
||||
|
||||
idx = model.index(0, 1, index);
|
||||
model.setData(idx, "very\nvery\nhigh\ncell");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QTreeView::taskQTBUG_8376()
|
||||
{
|
||||
QTreeView tv;
|
||||
QStandardItemModel model;
|
||||
fillModeltaskQTBUG_8376(model);
|
||||
tv.setModel(&model);
|
||||
tv.expandAll(); // init layout
|
||||
|
||||
QModelIndex idxLvl0 = model.index(0, 0);
|
||||
QModelIndex idxLvl1 = model.index(0, 1, idxLvl0);
|
||||
const int rowHeightLvl0 = tv.rowHeight(idxLvl0);
|
||||
const int rowHeightLvl1Visible = tv.rowHeight(idxLvl1);
|
||||
QVERIFY(rowHeightLvl0 < rowHeightLvl1Visible);
|
||||
|
||||
tv.hideColumn(1);
|
||||
const int rowHeightLvl1Hidden = tv.rowHeight(idxLvl1);
|
||||
QCOMPARE(rowHeightLvl0, rowHeightLvl1Hidden);
|
||||
|
||||
tv.showColumn(1);
|
||||
const int rowHeightLvl1Visible2 = tv.rowHeight(idxLvl1);
|
||||
QCOMPARE(rowHeightLvl1Visible, rowHeightLvl1Visible2);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTreeView)
|
||||
#include "tst_qtreeview.moc"
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "menuramaapplication.h"
|
||||
|
||||
MenuramaApplication::MenuramaApplication(int argc, char **argv)
|
||||
MenuramaApplication::MenuramaApplication(int &argc, char **argv)
|
||||
: QApplication (argc, argv)
|
||||
{
|
||||
#if 0
|
||||
|
@ -36,7 +36,7 @@
|
||||
class MenuramaApplication : public QApplication
|
||||
{
|
||||
public:
|
||||
MenuramaApplication(int argc, char **argv);
|
||||
MenuramaApplication(int &argc, char **argv);
|
||||
void addDynMenu(QLatin1String title, QMenu *parentMenu);
|
||||
QAction *findAction(QLatin1String title, QMenu *parentMenu);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user