summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qmetatype.h5
-rw-r--r--src/gui/image/qicon.cpp1
-rw-r--r--src/gui/image/qiconloader.cpp12
-rw-r--r--src/gui/kernel/qplatformservices.cpp5
-rw-r--r--src/platformsupport/services/genericunix/qgenericunixservices.cpp26
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp6
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm5
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp141
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp2
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp20
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h2
-rw-r--r--src/widgets/itemviews/qheaderview.cpp28
-rw-r--r--src/widgets/itemviews/qheaderview.h1
-rw-r--r--src/widgets/itemviews/qtableview.cpp13
-rw-r--r--src/widgets/itemviews/qtableview.h2
-rw-r--r--src/widgets/itemviews/qtreeview.cpp30
-rw-r--r--src/widgets/itemviews/qtreeview.h2
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp96
-rw-r--r--src/widgets/widgets/qabstractscrollarea.h12
-rw-r--r--src/widgets/widgets/qabstractscrollarea_p.h4
-rw-r--r--src/widgets/widgets/qscrollarea.cpp12
-rw-r--r--src/widgets/widgets/qscrollarea.h2
23 files changed, 311 insertions, 118 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 4add02f805..c5eae7a83e 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -563,11 +563,16 @@ namespace QtPrivate {
{ return -1; }
};
+#ifndef Q_COMPILER_VARIADIC_TEMPLATES
// Function pointers don't derive from QObject
template <class Result> struct IsPointerToTypeDerivedFromQObject<Result(*)()> { enum { Value = false }; };
template <class Result, class Arg0> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1)> { enum { Value = false }; };
template <class Result, class Arg0, class Arg1, class Arg2> struct IsPointerToTypeDerivedFromQObject<Result(*)(Arg0, Arg1, Arg2)> { enum { Value = false }; };
+#else
+ template <typename Result, typename... Args>
+ struct IsPointerToTypeDerivedFromQObject<Result(*)(Args...)> { enum { Value = false }; };
+#endif
template<typename T>
struct QMetaTypeTypeFlags
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index d73cd0aa57..ea35da54dc 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -1063,7 +1063,6 @@ void QIcon::setThemeName(const QString &name)
*/
QString QIcon::themeName()
{
- QIconLoader::instance()->ensureInitialized();
return QIconLoader::instance()->themeName();
}
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index c2e5161bd3..6303f5cbe1 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -127,6 +127,7 @@ void QIconLoader::ensureInitialized()
QIconLoader *QIconLoader::instance()
{
+ iconLoaderInstance()->ensureInitialized();
return iconLoaderInstance();
}
@@ -367,17 +368,14 @@ bool QIconLoaderEngine::hasIcon() const
// Lazily load the icon
void QIconLoaderEngine::ensureLoaded()
{
-
- iconLoaderInstance()->ensureInitialized();
-
- if (!(iconLoaderInstance()->themeKey() == m_key)) {
+ if (!(QIconLoader::instance()->themeKey() == m_key)) {
while (!m_entries.isEmpty())
delete m_entries.takeLast();
Q_ASSERT(m_entries.size() == 0);
- m_entries = iconLoaderInstance()->loadIcon(m_iconName);
- m_key = iconLoaderInstance()->themeKey();
+ m_entries = QIconLoader::instance()->loadIcon(m_iconName);
+ m_key = QIconLoader::instance()->themeKey();
}
}
@@ -564,7 +562,7 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
{
QIconEngine::AvailableSizesArgument &arg
= *reinterpret_cast<QIconEngine::AvailableSizesArgument*>(data);
- const QList<QIconDirInfo> directoryKey = iconLoaderInstance()->theme().keyList();
+ const QList<QIconDirInfo> directoryKey = QIconLoader::instance()->theme().keyList();
arg.sizes.clear();
// Gets all sizes from the DirectoryInfo entries
diff --git a/src/gui/kernel/qplatformservices.cpp b/src/gui/kernel/qplatformservices.cpp
index f2cade0a35..d09b74c6fe 100644
--- a/src/gui/kernel/qplatformservices.cpp
+++ b/src/gui/kernel/qplatformservices.cpp
@@ -74,7 +74,10 @@ bool QPlatformServices::openDocument(const QUrl &url)
/*!
* \brief QPlatformServices::desktopEnvironment returns the active desktop environment.
*
- * On Unix this function returns KDE, GNOME or UNKNOWN.
+ * On Unix this function returns the uppercase desktop environment name, such as
+ * KDE, GNOME, UNITY, XFCE, LXDE etc. or UNKNOWN if none was detected.
+ * The primary way to detect the desktop environment is the environment variable
+ * XDG_CURRENT_DESKTOP.
*/
QByteArray QPlatformServices::desktopEnvironment() const
{
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
index fedaa3a655..77ea0f1db8 100644
--- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
@@ -54,16 +54,24 @@ enum { debug = 0 };
static inline QByteArray detectDesktopEnvironment()
{
- if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
- return QByteArray("KDE");
- // Check Unity first, whose older versions also have "GNOME_DESKTOP_SESSION_ID" set.
const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
- if (xdgCurrentDesktop == "Unity")
- return QByteArrayLiteral("UNITY");
- // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
- if (qgetenv("DESKTOP_SESSION") == "gnome" || !qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
- return QByteArray("GNOME");
- return QByteArray("UNKNOWN");
+ if (!xdgCurrentDesktop.isEmpty())
+ return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE...
+
+ // Classic fallbacks
+ if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
+ return QByteArrayLiteral("KDE");
+ if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
+ return QByteArrayLiteral("GNOME");
+
+ // Fallback to checking $DESKTOP_SESSION (unreliable)
+ const QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
+ if (desktopSession == "gnome")
+ return QByteArrayLiteral("GNOME");
+ if (desktopSession == "xfce")
+ return QByteArrayLiteral("XFCE");
+
+ return QByteArrayLiteral("UNKNOWN");
}
static inline bool checkExecutable(const QString &candidate, QString *result)
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index cabddcc815..bf5131f393 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -492,7 +492,11 @@ QStringList QGenericUnixTheme::themeNames()
#ifndef QT_NO_SETTINGS
result.push_back(QLatin1String(QKdeTheme::name));
#endif
- } else { // Gnome, Unity, other Gtk-based desktops like XFCE.
+ } else if (desktopEnvironment == QByteArrayLiteral("GNOME") ||
+ desktopEnvironment == QByteArrayLiteral("UNITY") ||
+ desktopEnvironment == QByteArrayLiteral("MATE") ||
+ desktopEnvironment == QByteArrayLiteral("XFCE") ||
+ desktopEnvironment == QByteArrayLiteral("LXDE")) { // Gtk-based desktops
// prefer the GTK2 theme implementation with native dialogs etc.
result.push_back(QStringLiteral("gtk2"));
// fallback to the generic Gnome theme if loading the GTK2 theme fails
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 5ff1bf83ae..fc8eb0c503 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -118,7 +118,7 @@ static bool isMouseEvent(NSEvent *ev)
// Windows with a transient parent (such as combobox popup windows)
// cannot become the main window:
- if (m_cocoaPlatformWindow->window()->transientParent())
+ if (m_cocoaPlatformWindow && m_cocoaPlatformWindow->window()->transientParent())
canBecomeMain = NO;
return canBecomeMain;
@@ -155,6 +155,9 @@ static bool isMouseEvent(NSEvent *ev)
- (BOOL)canBecomeKeyWindow
{
+ if (!m_cocoaPlatformWindow)
+ return NO;
+
// Only tool or dialog windows should become key:
if (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog)
return YES;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index c0f1b3a000..7407d88f8b 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -215,7 +215,9 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
if (QWindowsContext::verboseFonts)
qDebug("%s %g", __FUNCTION__, pixelSize);
- d->directWriteFactory->AddRef();
+ Q_ASSERT(m_directWriteFontFace);
+
+ m_fontEngineData->directWriteFactory->AddRef();
m_directWriteFontFace->AddRef();
fontDef.pixelSize = pixelSize;
@@ -237,19 +239,17 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
void QWindowsFontEngineDirectWrite::collectMetrics()
{
- if (m_directWriteFontFace != 0) {
- DWRITE_FONT_METRICS metrics;
-
- m_directWriteFontFace->GetMetrics(&metrics);
- m_unitsPerEm = metrics.designUnitsPerEm;
-
- m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
- m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
- m_descent = DESIGN_TO_LOGICAL(metrics.descent);
- m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
- m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
- m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
- }
+ DWRITE_FONT_METRICS metrics;
+
+ m_directWriteFontFace->GetMetrics(&metrics);
+ m_unitsPerEm = metrics.designUnitsPerEm;
+
+ m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
+ m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
+ m_descent = DESIGN_TO_LOGICAL(metrics.descent);
+ m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
+ m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
+ m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
}
QFixed QWindowsFontEngineDirectWrite::underlinePosition() const
@@ -272,31 +272,24 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui
{
bool ret = false;
- if (m_directWriteFontFace) {
- DWORD t = qbswap<quint32>(tag);
-
- const void *tableData = 0;
- void *tableContext = 0;
- UINT32 tableSize;
- BOOL exists;
- HRESULT hr = m_directWriteFontFace->TryGetFontTable(
- t, &tableData, &tableSize, &tableContext, &exists
- );
-
- if (SUCCEEDED(hr)) {
- if (exists) {
- if (!buffer) {
- *length = tableSize;
- ret = true;
- } else if (*length >= tableSize) {
- memcpy(buffer, tableData, tableSize);
- ret = true;
- }
- }
- m_directWriteFontFace->ReleaseFontTable(tableContext);
- } else {
- qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
+ const void *tableData = 0;
+ UINT32 tableSize;
+ void *tableContext = 0;
+ BOOL exists;
+ HRESULT hr = m_directWriteFontFace->TryGetFontTable(qbswap<quint32>(tag)
+ &tableData, &tableSize,
+ &tableContext, &exists);
+ if (SUCCEEDED(hr)) {
+ if (exists) {
+ ret = true;
+ if (buffer && *length >= tableSize)
+ memcpy(buffer, tableData, tableSize);
+ else
+ *length = tableSize;
}
+ m_directWriteFontFace->ReleaseFontTable(tableContext);
+ } else {
+ qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
}
return ret;
@@ -327,43 +320,43 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QFontEngine::ShaperFlags flags) const
{
- if (m_directWriteFontFace != 0) {
- QVarLengthArray<UINT32> codePoints(len);
- for (int i=0; i<len; ++i) {
- codePoints[i] = getChar(str, i, len);
- if (flags & QFontEngine::RightToLeft)
- codePoints[i] = QChar::mirroredChar(codePoints[i]);
- }
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
- QVarLengthArray<UINT16> glyphIndices(len);
- HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
- len,
- glyphIndices.data());
+ QVarLengthArray<UINT32> codePoints(len);
+ int actualLength = 0;
+ if (flags & QFontEngine::RightToLeft) {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
+ } else {
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = getChar(str, i, len);
+ }
- if (SUCCEEDED(hr)) {
- for (int i=0; i<len; ++i)
- glyphs->glyphs[i] = glyphIndices[i];
+ QVarLengthArray<UINT16> glyphIndices(actualLength);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
+ glyphIndices.data());
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
+ return false;
+ }
- *nglyphs = len;
- glyphs->numGlyphs = len;
+ for (int i = 0; i < actualLength; ++i)
+ glyphs->glyphs[i] = glyphIndices.at(i);
- if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, 0);
+ *nglyphs = actualLength;
+ glyphs->numGlyphs = actualLength;
- return true;
- } else {
- qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
- }
- }
+ if (!(flags & GlyphIndicesOnly))
+ recalcAdvances(glyphs, 0);
- return false;
+ return true;
}
void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
// ### Caching?
@@ -391,9 +384,6 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags)
{
- if (m_directWriteFontFace == 0)
- return;
-
QVarLengthArray<UINT16> glyphIndices(nglyphs);
QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
@@ -439,9 +429,6 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &g
glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
{
- if (m_directWriteFontFace == 0)
- return glyph_metrics_t();
-
UINT16 glyphIndex = g;
DWRITE_GLYPH_METRICS glyphMetrics;
@@ -668,14 +655,14 @@ bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len)
if (FAILED(hr)) {
qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__);
return false;
- } else {
- for (int i=0; i<glyphIndices.size(); ++i) {
- if (glyphIndices.at(i) == 0)
- return false;
- }
+ }
- return true;
+ for (int i = 0; i < actualLength; ++i) {
+ if (glyphIndices.at(i) == 0)
+ return false;
}
+
+ return true;
}
QFontEngine::Type QWindowsFontEngineDirectWrite::type() const
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index 106087f757..ab14cb49eb 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -107,8 +107,6 @@ public:
static QString fontNameSubstitute(const QString &familyName);
private:
- friend class QRawFontPrivate;
-
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 4ac60f6077..02f10bba89 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -736,7 +736,7 @@ Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s)
int QXcbKeyboard::translateKeySym(uint key) const
{
- int code = -1;
+ int code = Qt::Key_unknown;
int i = 0; // any other keys
while (KeyTbl[i]) {
if (key == KeyTbl[i]) {
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 70c8f44a73..b79525b9df 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1108,6 +1108,7 @@ void QAbstractItemView::reset()
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ d->updateGeometry();
}
/*!
@@ -1124,6 +1125,7 @@ void QAbstractItemView::setRootIndex(const QModelIndex &index)
}
d->root = index;
d->doDelayedItemsLayout();
+ d->updateGeometry();
}
/*!
@@ -2668,8 +2670,10 @@ void QAbstractItemView::updateEditorGeometries()
*/
void QAbstractItemView::updateGeometries()
{
+ Q_D(QAbstractItemView);
updateEditorGeometries();
- d_func()->fetchMoreTimer.start(0, this); //fetch more later
+ d->fetchMoreTimer.start(0, this); //fetch more later
+ d->updateGeometry();
}
/*!
@@ -3231,6 +3235,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ d->updateGeometry();
}
/*!
@@ -3332,6 +3337,7 @@ void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int star
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -3412,6 +3418,7 @@ void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int s
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
@@ -3435,6 +3442,7 @@ void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int sta
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -3459,6 +3467,7 @@ void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int
QAccessible::updateAccessibility(&accessibleEvent);
}
#endif
+ updateGeometry();
}
/*!
@@ -4084,7 +4093,14 @@ void QAbstractItemViewPrivate::interruptDelayedItemsLayout() const
delayedPendingLayout = false;
}
-
+void QAbstractItemViewPrivate::updateGeometry()
+{
+ Q_Q(QAbstractItemView);
+ if (sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
+ return;
+ if (sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents || !shownOnce)
+ q->updateGeometry();
+}
QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index 86eab174ed..5da22615e2 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -127,6 +127,8 @@ public:
void doDelayedItemsLayout(int delay = 0);
void interruptDelayedItemsLayout() const;
+ void updateGeometry();
+
void startAutoScroll()
{ // ### it would be nice to make this into a style hint one day
int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50;
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index edfbc5c8f1..0dbf0a6a76 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -550,6 +550,22 @@ QSize QHeaderView::sizeHint() const
}
/*!
+ \reimp
+*/
+
+void QHeaderView::setVisible(bool v)
+{
+ bool actualChange = (v != isVisible());
+ QAbstractItemView::setVisible(v);
+ if (actualChange) {
+ QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea*>(parentWidget());
+ if (parent)
+ parent->updateGeometry();
+ }
+}
+
+
+/*!
Returns a suitable size hint for the section specified by \a logicalIndex.
\sa sizeHint(), defaultSectionSize(), minimumSectionSize(),
@@ -918,6 +934,18 @@ void QHeaderView::resizeSection(int logical, int size)
d->doDelayedResizeSections();
r = d->viewport->rect();
}
+
+ // If the parent is a QAbstractScrollArea with QAbstractScrollArea::AdjustToContents
+ // then we want to change the geometry on that widget. Not doing it at once can/will
+ // cause scrollbars flicker as they would be shown at first but then removed.
+ // In the same situation it will also allow shrinking the whole view when stretchLastSection is set
+ // (It is default on QTreeViews - and it wouldn't shrink since the last stretch was made before the
+ // viewport was resized)
+
+ QAbstractScrollArea *parent = qobject_cast<QAbstractScrollArea *>(parentWidget());
+ if (parent && parent->sizeAdjustPolicy() == QAbstractScrollArea::AdjustToContents)
+ parent->updateGeometry();
+
d->viewport->update(r.normalized());
emit sectionResized(logical, oldSize, size);
}
diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h
index 8fcd8d7a36..0b94eedf78 100644
--- a/src/widgets/itemviews/qheaderview.h
+++ b/src/widgets/itemviews/qheaderview.h
@@ -84,6 +84,7 @@ public:
int offset() const;
int length() const;
QSize sizeHint() const;
+ void setVisible(bool v);
int sectionSizeHint(int logicalIndex) const;
int visualIndexAt(int position) const;
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 573df1db6a..37c52948b0 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1056,6 +1056,19 @@ QTableView::~QTableView()
/*!
\reimp
*/
+QSize QTableView::viewportSizeHint() const
+{
+ Q_D(const QTableView);
+ QSize result( (d->verticalHeader->isHidden() ? 0 : d->verticalHeader->width()) + d->horizontalHeader->length(),
+ (d->horizontalHeader->isHidden() ? 0 : d->horizontalHeader->height()) + d->verticalHeader->length());
+ result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,
+ horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);
+ return result;
+}
+
+/*!
+ \reimp
+*/
void QTableView::setModel(QAbstractItemModel *model)
{
Q_D(QTableView);
diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h
index 824348dbe8..db956480d6 100644
--- a/src/widgets/itemviews/qtableview.h
+++ b/src/widgets/itemviews/qtableview.h
@@ -118,6 +118,8 @@ public:
void sortByColumn(int column, Qt::SortOrder order);
+ QSize viewportSizeHint() const;
+
public Q_SLOTS:
void selectRow(int row);
void selectColumn(int column);
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 70523815e8..962ed97762 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -335,6 +335,7 @@ void QTreeView::setHeader(QHeaderView *header)
this, SLOT(updateGeometries()));
setSortingEnabled(d->sortingEnabled);
+ d->updateGeometry();
}
/*!
@@ -2619,6 +2620,35 @@ void QTreeView::selectAll()
}
/*!
+ \reimp
+*/
+QSize QTreeView::viewportSizeHint() const
+{
+ Q_D(const QTreeView);
+ d->executePostedLayout(); // Make sure that viewItems are up to date.
+
+ if (d->viewItems.size() == 0)
+ return QAbstractItemView::viewportSizeHint();
+
+ // Get rect for last item
+ const QRect deepestRect = visualRect(d->viewItems.last().index);
+
+ if (!deepestRect.isValid())
+ return QAbstractItemView::viewportSizeHint();
+
+ QSize result = QSize(d->header->length(), deepestRect.bottom() + 1);
+
+ // add size for header
+ result += QSize(0, d->header->isVisible() ? d->header->height() : 0);
+
+ // add size for scrollbars
+ result += QSize(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0,
+ horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0);
+
+ return result;
+}
+
+/*!
\since 4.2
Expands all expandable items.
diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h
index 73f11f1a48..fae814c6f6 100644
--- a/src/widgets/itemviews/qtreeview.h
+++ b/src/widgets/itemviews/qtreeview.h
@@ -144,6 +144,8 @@ public:
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
void selectAll();
+ QSize viewportSizeHint() const;
+
Q_SIGNALS:
void expanded(const QModelIndex &index);
void collapsed(const QModelIndex &index);
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 900e95f4da..e7827055fb 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -167,6 +167,7 @@ QT_BEGIN_NAMESPACE
QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
:hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),
+ shownOnce(false), sizeAdjustPolicy(QAbstractScrollArea::AdjustIgnored),
viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
xoffset(0), yoffset(0), viewportFilter(0)
#ifdef Q_WS_WIN
@@ -527,6 +528,19 @@ void QAbstractScrollAreaPrivate::layoutChildren()
}
/*!
+ \enum QAbstractScrollArea::SizeAdjustPolicy
+ \since 5.2
+
+ This enum specifies how the size hint of the QAbstractScrollArea should
+ adjust when the size of the viewport changes.
+
+ \value AdjustIgnored The scroll area will behave like before - and not do any adjust.
+ \value AdjustToContents The scroll area will always adjust to the viewport
+ \value AdjustToContentsOnFirstShow The scroll area will adjust to its viewport the first time it is shown.
+*/
+
+
+/*!
\internal
Creates a new QAbstractScrollAreaPrivate, \a dd with the given \a parent.
@@ -983,6 +997,13 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::Resize:
d->layoutChildren();
break;
+ case QEvent::Show:
+ if (!d->shownOnce && d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContentsOnFirstShow) {
+ d->sizeHint = QSize();
+ updateGeometry();
+ }
+ d->shownOnce = true;
+ return QFrame::event(e);
case QEvent::Paint: {
QStyleOption option;
option.initFrom(this);
@@ -1533,17 +1554,70 @@ QSize QAbstractScrollArea::minimumSizeHint() const
}
/*!
+ Returns the sizeHint property of the scroll area. The size is determined by using
+ viewportSizeHint() plus some extra space for scroll bars, if needed.
\reimp
*/
QSize QAbstractScrollArea::sizeHint() const
{
- return QSize(256, 192);
-#if 0
Q_D(const QAbstractScrollArea);
- int h = qMax(10, fontMetrics().height());
- int f = 2 * d->frameWidth;
- return QSize((6 * h) + f, (4 * h) + f);
-#endif
+ if (d->sizeAdjustPolicy == QAbstractScrollArea::AdjustIgnored)
+ return QSize(256, 192);
+
+ if (!d->sizeHint.isValid() || d->sizeAdjustPolicy == QAbstractScrollArea::AdjustToContents) {
+ const int f = 2 * d->frameWidth;
+ const QSize frame( f, f );
+ const QSize scrollbars(d->vbarpolicy == Qt::ScrollBarAlwaysOn ? d->vbar->sizeHint().width() : 0,
+ d->hbarpolicy == Qt::ScrollBarAlwaysOn ? d->hbar->sizeHint().height() : 0);
+ d->sizeHint = frame + scrollbars + viewportSizeHint();
+ }
+ return d->sizeHint;
+}
+
+/*!
+ \since 5.2
+ Returns the recommended size for the viewport.
+ The default implementation returns viewport()->sizeHint().
+ Note that the size is just the viewport's size, without any scroll bars visible.
+ */
+QSize QAbstractScrollArea::viewportSizeHint() const
+{
+ Q_D(const QAbstractScrollArea);
+ if (d->viewport) {
+ const QSize sh = d->viewport->sizeHint();
+ if (sh.isValid()) {
+ return sh;
+ }
+ }
+ const int h = qMax(10, fontMetrics().height());
+ return QSize(6 * h, 4 * h);
+}
+
+/*!
+ \since 5.2
+ \property QAbstractScrollArea::sizeAdjustPolicy
+ This property holds the policy describing how the size of the scroll area changes when the
+ size of the viewport changes.
+
+ The default policy is QAbstractScrollArea::AdjustIgnored.
+ Changing this property might actually resize the scrollarea.
+*/
+
+QAbstractScrollArea::SizeAdjustPolicy QAbstractScrollArea::sizeAdjustPolicy() const
+{
+ Q_D(const QAbstractScrollArea);
+ return d->sizeAdjustPolicy;
+}
+
+void QAbstractScrollArea::setSizeAdjustPolicy(SizeAdjustPolicy policy)
+{
+ Q_D(QAbstractScrollArea);
+ if (d->sizeAdjustPolicy == policy)
+ return;
+
+ d->sizeAdjustPolicy = policy;
+ d->sizeHint = QSize();
+ updateGeometry();
}
/*!
@@ -1559,16 +1633,6 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
-/*!
- \internal
-
- This method is reserved for future use.
-*/
-QSize QAbstractScrollArea::viewportSizeHint() const
-{
- return QSize();
-}
-
QT_END_NAMESPACE
#include "moc_qabstractscrollarea.cpp"
diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h
index ccf16b5e5c..fb9562db1b 100644
--- a/src/widgets/widgets/qabstractscrollarea.h
+++ b/src/widgets/widgets/qabstractscrollarea.h
@@ -56,13 +56,22 @@ class QAbstractScrollAreaPrivate;
class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame
{
Q_OBJECT
+
+ Q_ENUMS(SizeAdjustPolicy)
Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy READ verticalScrollBarPolicy WRITE setVerticalScrollBarPolicy)
Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy READ horizontalScrollBarPolicy WRITE setHorizontalScrollBarPolicy)
+ Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy)
public:
explicit QAbstractScrollArea(QWidget* parent=0);
~QAbstractScrollArea();
+ enum SizeAdjustPolicy {
+ AdjustIgnored,
+ AdjustToContentsOnFirstShow,
+ AdjustToContents
+ };
+
Qt::ScrollBarPolicy verticalScrollBarPolicy() const;
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy);
QScrollBar *verticalScrollBar() const;
@@ -89,6 +98,9 @@ public:
virtual void setupViewport(QWidget *viewport);
+ SizeAdjustPolicy sizeAdjustPolicy() const;
+ void setSizeAdjustPolicy(SizeAdjustPolicy policy);
+
protected:
QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0);
void setViewportMargins(int left, int top, int right, int bottom);
diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h
index 34d767fe29..3093c2f812 100644
--- a/src/widgets/widgets/qabstractscrollarea_p.h
+++ b/src/widgets/widgets/qabstractscrollarea_p.h
@@ -75,6 +75,10 @@ public:
QScrollBar *hbar, *vbar;
Qt::ScrollBarPolicy vbarpolicy, hbarpolicy;
+ bool shownOnce;
+ mutable QSize sizeHint;
+ QAbstractScrollArea::SizeAdjustPolicy sizeAdjustPolicy;
+
QWidget *viewport;
QWidget *cornerWidget;
QRect cornerPaintingRect;
diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp
index 93c335c56b..2a6d4620d7 100644
--- a/src/widgets/widgets/qscrollarea.cpp
+++ b/src/widgets/widgets/qscrollarea.cpp
@@ -407,6 +407,18 @@ QSize QScrollArea::sizeHint() const
return sz.boundedTo(QSize(36 * h, 24 * h));
}
+/*!
+ \reimp
+ */
+QSize QScrollArea::viewportSizeHint() const
+{
+ Q_D(const QScrollArea);
+ if (d->widget) {
+ return d->resizable ? d->widget->sizeHint() : d->widget->size();
+ }
+ const int h = fontMetrics().height();
+ return QSize(6 * h, 4 * h);
+}
/*!
diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h
index 576c9bc9e0..70af5fbbd7 100644
--- a/src/widgets/widgets/qscrollarea.h
+++ b/src/widgets/widgets/qscrollarea.h
@@ -69,6 +69,8 @@ public:
void setWidgetResizable(bool resizable);
QSize sizeHint() const;
+ QSize viewportSizeHint() const;
+
bool focusNextPrevChild(bool next);
Qt::Alignment alignment() const;