From 1bc673c89155119d110861efbc7b6b7b06091b39 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Mon, 16 Nov 2009 14:41:57 +0100 Subject: qmediaplayer: pausing behavior for dialog inconvenient. qmediaplayer when popping up dialogs shouldn't: * play when it's paused * pause when playing only audio Task-number: QTBUG-5851 Reviewed-by: Gareth Stockwell --- demos/qmediaplayer/mediaplayer.cpp | 28 +++++++++++++++++----------- demos/qmediaplayer/mediaplayer.h | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index 267a225..aa716c5 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -471,7 +471,7 @@ void MediaPlayer::effectChanged() void MediaPlayer::showSettingsDialog() { - playPauseForDialog(); + const bool hasPausedForDialog = playPauseForDialog(); if (!settingsDialog) initSettingsDialog(); @@ -519,7 +519,8 @@ void MediaPlayer::showSettingsDialog() ui->audioEffectsCombo->setCurrentIndex(currentEffect); } - playPauseForDialog(); + if (hasPausedForDialog) + m_MediaObject.play(); } void MediaPlayer::initVideoWindow() @@ -656,24 +657,29 @@ void MediaPlayer::setFile(const QString &fileName) m_MediaObject.play(); } -void MediaPlayer::playPauseForDialog() +bool MediaPlayer::playPauseForDialog() { - // If we're running on a small screen, we want to pause the video - // when popping up dialogs. - if (m_hasSmallScreen && - (Phonon::PlayingState == m_MediaObject.state() || - Phonon::PausedState == m_MediaObject.state())) - playPause(); + // If we're running on a small screen, we want to pause the video when + // popping up dialogs. We neither want to tamper with the state if the + // user has paused. + if (m_hasSmallScreen && m_MediaObject.hasVideo()) { + if (Phonon::PlayingState == m_MediaObject.state()) { + m_MediaObject.pause(); + return true; + } + } + return false; } void MediaPlayer::openFile() { - playPauseForDialog(); + const bool hasPausedForDialog = playPauseForDialog(); QStringList fileNames = QFileDialog::getOpenFileNames(this, QString(), QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); - playPauseForDialog(); + if (hasPausedForDialog) + m_MediaObject.play(); m_MediaObject.clearQueue(); if (fileNames.size() > 0) { diff --git a/demos/qmediaplayer/mediaplayer.h b/demos/qmediaplayer/mediaplayer.h index a1c3d92..c181e37 100644 --- a/demos/qmediaplayer/mediaplayer.h +++ b/demos/qmediaplayer/mediaplayer.h @@ -111,7 +111,7 @@ private slots: void hasVideoChanged(bool); private: - void playPauseForDialog(); + bool playPauseForDialog(); QIcon playIcon; QIcon pauseIcon; -- cgit v0.12 From e0a7245eba7207eaf43b1855a58c76dd3cf7b41b Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Mon, 16 Nov 2009 16:58:05 +0100 Subject: Keep the same capitalization for Phonon.dll. Task-number: QTBUG-4735 --- src/s60installs/s60installs.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 2d9c489..37adfa9 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -90,7 +90,7 @@ symbian: { } contains(QT_CONFIG, phonon): { - qtlibraries.sources += Phonon.dll + qtlibraries.sources += phonon.dll } contains(QT_CONFIG, script): { -- cgit v0.12 From a599898061b8b76bbd313d7b3ea0a4e0e9a6e8ed Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 18 Nov 2009 16:39:47 +0000 Subject: Mediaplayer: do not exit full-screen when paused This modifies the patch which introduced "exit full screen when end of playback is reached": f9d36789 Reviewed-by: Frans Englich --- demos/qmediaplayer/mediaplayer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index aa716c5..1cca3dc 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -363,12 +363,12 @@ void MediaPlayer::stateChanged(Phonon::State newstate, Phonon::State oldstate) } QMessageBox::warning(this, "Phonon Mediaplayer", m_MediaObject.errorString(), QMessageBox::Close); break; - case Phonon::PausedState: - case Phonon::StoppedState: - playButton->setIcon(playIcon); + case Phonon::StoppedState: m_videoWidget->setFullScreen(false); - + // Fall through + case Phonon::PausedState: + playButton->setIcon(playIcon); if (m_MediaObject.currentSource().type() != Phonon::MediaSource::Invalid){ playButton->setEnabled(true); rewindButton->setEnabled(true); -- cgit v0.12 From 20679e140afc2cea8ff16043d40a0da1145e4165 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 18 Nov 2009 16:50:53 +0000 Subject: Added 'fullscreen video' menu option to media player Task-number: QTBUG-5586 Reviewed-by: Frans Englich --- demos/qmediaplayer/mediaplayer.cpp | 175 +++++++++++++++++++------------------ demos/qmediaplayer/mediaplayer.h | 43 +++++++-- 2 files changed, 128 insertions(+), 90 deletions(-) diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index 1cca3dc..a396c70 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -47,109 +47,105 @@ #include "ui_settings.h" -class MediaVideoWidget : public Phonon::VideoWidget +MediaVideoWidget::MediaVideoWidget(MediaPlayer *player, QWidget *parent) : + Phonon::VideoWidget(parent), m_player(player), m_action(this) +{ + m_action.setCheckable(true); + m_action.setChecked(false); + m_action.setShortcut(QKeySequence( Qt::AltModifier + Qt::Key_Return)); + m_action.setShortcutContext(Qt::WindowShortcut); + connect(&m_action, SIGNAL(toggled(bool)), SLOT(setFullScreen(bool))); + addAction(&m_action); + setAcceptDrops(true); +} + +void MediaVideoWidget::setFullScreen(bool enabled) { -public: - MediaVideoWidget(MediaPlayer *player, QWidget *parent = 0) : - Phonon::VideoWidget(parent), m_player(player), m_action(this) - { - m_action.setCheckable(true); - m_action.setChecked(false); - m_action.setShortcut(QKeySequence( Qt::AltModifier + Qt::Key_Return)); - m_action.setShortcutContext(Qt::WindowShortcut); - connect(&m_action, SIGNAL(toggled(bool)), SLOT(setFullScreen(bool))); - addAction(&m_action); - setAcceptDrops(true); - } + Phonon::VideoWidget::setFullScreen(enabled); + emit fullScreenChanged(enabled); +} -protected: - void mouseDoubleClickEvent(QMouseEvent *e) - { - Phonon::VideoWidget::mouseDoubleClickEvent(e); - setFullScreen(!isFullScreen()); - } +void MediaVideoWidget::mouseDoubleClickEvent(QMouseEvent *e) +{ + Phonon::VideoWidget::mouseDoubleClickEvent(e); + setFullScreen(!isFullScreen()); +} - void keyPressEvent(QKeyEvent *e) - { - if (e->key() == Qt::Key_Space && !e->modifiers()) { - m_player->playPause(); - e->accept(); - return; - } else if (e->key() == Qt::Key_Escape && !e->modifiers()) { - setFullScreen(false); - e->accept(); - return; - } - Phonon::VideoWidget::keyPressEvent(e); +void MediaVideoWidget::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Space && !e->modifiers()) { + m_player->playPause(); + e->accept(); + return; + } else if (e->key() == Qt::Key_Escape && !e->modifiers()) { + setFullScreen(false); + e->accept(); + return; } + Phonon::VideoWidget::keyPressEvent(e); +} - bool event(QEvent *e) +bool MediaVideoWidget::event(QEvent *e) +{ + switch(e->type()) { - switch(e->type()) - { - case QEvent::Close: - //we just ignore the cose events on the video widget - //this prevents ALT+F4 from having an effect in fullscreen mode - e->ignore(); - return true; - case QEvent::MouseMove: + case QEvent::Close: + //we just ignore the cose events on the video widget + //this prevents ALT+F4 from having an effect in fullscreen mode + e->ignore(); + return true; + case QEvent::MouseMove: #ifndef QT_NO_CURSOR - unsetCursor(); + unsetCursor(); #endif - //fall through - case QEvent::WindowStateChange: - { - //we just update the state of the checkbox, in case it wasn't already - m_action.setChecked(windowState() & Qt::WindowFullScreen); - const Qt::WindowFlags flags = m_player->windowFlags(); - if (windowState() & Qt::WindowFullScreen) { - m_timer.start(1000, this); - } else { - m_timer.stop(); + //fall through + case QEvent::WindowStateChange: + { + //we just update the state of the checkbox, in case it wasn't already + m_action.setChecked(windowState() & Qt::WindowFullScreen); + const Qt::WindowFlags flags = m_player->windowFlags(); + if (windowState() & Qt::WindowFullScreen) { + m_timer.start(1000, this); + } else { + m_timer.stop(); #ifndef QT_NO_CURSOR - unsetCursor(); + unsetCursor(); #endif - } } - break; - default: - break; } - - return Phonon::VideoWidget::event(e); + break; + default: + break; } - void timerEvent(QTimerEvent *e) - { - if (e->timerId() == m_timer.timerId()) { - //let's store the cursor shape + return Phonon::VideoWidget::event(e); +} + +void MediaVideoWidget::timerEvent(QTimerEvent *e) +{ + if (e->timerId() == m_timer.timerId()) { + //let's store the cursor shape #ifndef QT_NO_CURSOR - setCursor(Qt::BlankCursor); + setCursor(Qt::BlankCursor); #endif - } - Phonon::VideoWidget::timerEvent(e); - } - - void dropEvent(QDropEvent *e) - { - m_player->handleDrop(e); } + Phonon::VideoWidget::timerEvent(e); +} - void dragEnterEvent(QDragEnterEvent *e) { - if (e->mimeData()->hasUrls()) - e->acceptProposedAction(); - } +void MediaVideoWidget::dropEvent(QDropEvent *e) +{ + m_player->handleDrop(e); +} -private: - MediaPlayer *m_player; - QBasicTimer m_timer; - QAction m_action; -}; +void MediaVideoWidget::dragEnterEvent(QDragEnterEvent *e) { + if (e->mimeData()->hasUrls()) + e->acceptProposedAction(); +} MediaPlayer::MediaPlayer(const QString &filePath, const bool hasSmallScreen) : - playButton(0), nextEffect(0), settingsDialog(0), ui(0), + playButton(0), nextEffect(0), settingsDialog(0), ui(0), m_AudioOutput(Phonon::VideoCategory), m_videoWidget(new MediaVideoWidget(this)), m_hasSmallScreen(hasSmallScreen) @@ -297,22 +293,30 @@ MediaPlayer::MediaPlayer(const QString &filePath, QAction *scaleActionCrop = scaleMenu->addAction(tr("Scale and crop")); scaleActionCrop->setCheckable(true); scaleGroup->addAction(scaleActionCrop); - - fileMenu->addSeparator(); + + m_fullScreenAction = fileMenu->addAction(tr("Full screen video")); + m_fullScreenAction->setCheckable(true); + m_fullScreenAction->setEnabled(false); // enabled by hasVideoChanged + bool b = connect(m_fullScreenAction, SIGNAL(toggled(bool)), m_videoWidget, SLOT(setFullScreen(bool))); + Q_ASSERT(b); + b = connect(m_videoWidget, SIGNAL(fullScreenChanged(bool)), m_fullScreenAction, SLOT(setChecked(bool))); + Q_ASSERT(b); + + fileMenu->addSeparator(); QAction *settingsAction = fileMenu->addAction(tr("&Settings...")); - + // Setup signal connections: connect(rewindButton, SIGNAL(clicked()), this, SLOT(rewind())); //connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); openButton->setMenu(fileMenu); - + connect(playButton, SIGNAL(clicked()), this, SLOT(playPause())); connect(forwardButton, SIGNAL(clicked()), this, SLOT(forward())); //connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); connect(settingsAction, SIGNAL(triggered(bool)), this, SLOT(showSettingsDialog())); connect(openUrlAction, SIGNAL(triggered(bool)), this, SLOT(openUrl())); connect(openFileAction, SIGNAL(triggered(bool)), this, SLOT(openFile())); - + connect(m_videoWidget, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &))); connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &))); connect(&m_MediaObject, SIGNAL(metaDataChanged()), this, SLOT(updateInfo())); @@ -874,4 +878,5 @@ void MediaPlayer::hasVideoChanged(bool bHasVideo) { info->setVisible(!bHasVideo); m_videoWindow.setVisible(bHasVideo); + m_fullScreenAction->setEnabled(bHasVideo); } diff --git a/demos/qmediaplayer/mediaplayer.h b/demos/qmediaplayer/mediaplayer.h index c181e37..00f9b54 100644 --- a/demos/qmediaplayer/mediaplayer.h +++ b/demos/qmediaplayer/mediaplayer.h @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include #include @@ -67,6 +69,36 @@ class QMenu; class Ui_settings; QT_END_NAMESPACE +class MediaPlayer; + +class MediaVideoWidget : public Phonon::VideoWidget +{ + Q_OBJECT + +public: + MediaVideoWidget(MediaPlayer *player, QWidget *parent = 0); + +public slots: + // Over-riding non-virtual Phonon::VideoWidget slot + void setFullScreen(bool); + +signals: + void fullScreenChanged(bool); + +protected: + void mouseDoubleClickEvent(QMouseEvent *e); + void keyPressEvent(QKeyEvent *e); + bool event(QEvent *e); + void timerEvent(QTimerEvent *e); + void dropEvent(QDropEvent *e); + void dragEnterEvent(QDragEnterEvent *e); + +private: + MediaPlayer *m_player; + QBasicTimer m_timer; + QAction m_action; +}; + class MediaPlayer : public QWidget { @@ -74,7 +106,7 @@ class MediaPlayer : public: MediaPlayer(const QString &, const bool hasSmallScreen); - + void dragEnterEvent(QDragEnterEvent *e); void dragMoveEvent(QDragMoveEvent *e); void dropEvent(QDropEvent *e); @@ -82,7 +114,7 @@ public: void setFile(const QString &text); void initVideoWindow(); void initSettingsDialog(); - + public slots: void openFile(); void rewind(); @@ -104,7 +136,7 @@ private slots: void stateChanged(Phonon::State newstate, Phonon::State oldstate); void effectChanged(); void showSettingsDialog(); - void showContextMenu(const QPoint &); + void showContextMenu(const QPoint& point); void bufferStatus(int percent); void openUrl(); void configureEffect(); @@ -130,11 +162,12 @@ private: Phonon::Effect *nextEffect; QDialog *settingsDialog; Ui_settings *ui; - + QAction *m_fullScreenAction; + QWidget m_videoWindow; Phonon::MediaObject m_MediaObject; Phonon::AudioOutput m_AudioOutput; - Phonon::VideoWidget *m_videoWidget; + MediaVideoWidget *m_videoWidget; Phonon::Path m_audioOutputPath; const bool m_hasSmallScreen; }; -- cgit v0.12 From 2473ab1cf217a989849190cbfa47fe312698adb9 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 18 Nov 2009 17:12:26 +0000 Subject: Added additional keyboard shortcuts to MediaPlayer These shortcuts are used for pausing video playback while in full-screen mode, and for exiting full-screen mode. They are for non-QWERTY mobile devices, which lack keys mapping to the previously existing shortcut keycodes. Reviewed-by: Frans Englich --- demos/qmediaplayer/mediaplayer.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index a396c70..4e0da3f 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -73,14 +73,23 @@ void MediaVideoWidget::mouseDoubleClickEvent(QMouseEvent *e) void MediaVideoWidget::keyPressEvent(QKeyEvent *e) { - if (e->key() == Qt::Key_Space && !e->modifiers()) { - m_player->playPause(); - e->accept(); - return; - } else if (e->key() == Qt::Key_Escape && !e->modifiers()) { - setFullScreen(false); - e->accept(); - return; + if(!e->modifiers()) { + // On non-QWERTY Symbian key-based devices, there is no space key. + // The zero key typically is marked with a space character. + if (e->key() == Qt::Key_Space || e->key() == Qt::Key_0) { + m_player->playPause(); + e->accept(); + return; + } + + // On Symbian devices, there is no key which maps to Qt::Key_Escape + // On devices which lack a backspace key (i.e. non-QWERTY devices), + // the 'C' key maps to Qt::Key_Backspace + else if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Backspace) { + setFullScreen(false); + e->accept(); + return; + } } Phonon::VideoWidget::keyPressEvent(e); } -- cgit v0.12 From 44c6308cb775e2ca53f8708ba87893b7e8bc2c2d Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 25 Nov 2009 18:03:43 +1000 Subject: Optimized the bezier flattening a bit Testcase with rounded rects went from 55 -> 62 FPS for 1000 random rects Reviewed-By: Tom Cooksey --- src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp | 55 +++++++--------------- src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h | 2 - 2 files changed, 17 insertions(+), 40 deletions(-) diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp index 1fe3999..e70b75e 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp @@ -120,8 +120,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc // qDebug("QVectorPath has element types"); for (int i=1; i(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 8)); + if (threshold < 3) threshold = 3; + qreal one_over_threshold_minus_1 = 1.f / (threshold - 1); + for (int t=0; t= beziers) { - // check if we can pop the top bezier curve from the stack - qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1); - qreal d; - if (l > inverseScale) { - d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) ) - + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) ); - d /= l; - } else { - d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) + - qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3); - } - if (d < inverseScaleHalf || b == beziers + 31) { - // good enough, we pop it off and add the endpoint - lineToArray(b->x4, b->y4); - --b; - } else { - // split, second half of the polygon goes lower into the stack - b->split(b+1, b); - ++b; - } - } -} - QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index 719904f..c53ef11 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -123,8 +123,6 @@ private: GLfloat minY; bool boundingRectDirty; - inline void curveToArray(const QGLPoint &cp1, const QGLPoint &cp2, const QGLPoint &ep, GLfloat inverseScale); - void addClosingLine(int index); void addCentroid(const QVectorPath &path, int subPathIndex); }; -- cgit v0.12 From 33628442d1c0e3b9b15ee5c54a586a80e21727c6 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 25 Nov 2009 19:05:31 +1000 Subject: Replaced QVector in GL2 vertex array with QDataBuffer to reduce mallocs Reviewed-by: Tom Cooksey --- src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp | 8 ++++---- src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h | 6 +++--- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 14 ++++++++------ src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 8 ++++---- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp index e70b75e..67a4128 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE void QGL2PEXVertexArray::clear() { vertexArray.reset(); - vertexArrayStops.clear(); + vertexArrayStops.reset(); boundingRectDirty = true; } @@ -125,7 +125,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc if (!outline) addClosingLine(lastMoveTo); // qDebug("element[%d] is a MoveToElement", i); - vertexArrayStops.append(vertexArray.size()); + vertexArrayStops.add(vertexArray.size()); if (!outline) { addCentroid(path, i); lastMoveTo = vertexArray.size(); @@ -143,7 +143,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc points[i+2]); QRectF bounds = b.bounds(); // threshold based on same algorithm as in qtriangulatingstroker.cpp - int threshold = qMin(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 8)); + int threshold = qMin(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6)); if (threshold < 3) threshold = 3; qreal one_over_threshold_minus_1 = 1.f / (threshold - 1); for (int t=0; t& stops() {return vertexArrayStops;} + int *stops() const { return vertexArrayStops.data(); } + int stopCount() const { return vertexArrayStops.size(); } QGLRect boundingRect() const; void lineToArray(const GLfloat x, const GLfloat y); private: QDataBuffer vertexArray; - QVector vertexArrayStops; + QDataBuffer vertexArrayStops; GLfloat maxX; GLfloat maxY; GLfloat minX; GLfloat minY; bool boundingRectDirty; - void addClosingLine(int index); void addCentroid(const QVectorPath &path, int subPathIndex); }; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 8c5bf0e..e281729 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -908,7 +908,8 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, int count, - const QVector *stops, + int *stops, + int stopCount, const QGLRect &bounds, StencilFillMode mode) { @@ -966,7 +967,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, // Dec. for back-facing "holes" glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP); glStencilMask(~GL_STENCIL_HIGH_BIT); - drawVertexArrays(data, stops, GL_TRIANGLE_FAN); + drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); if (q->state()->clipTestEnabled) { // Clear high bit of stencil outside of path @@ -978,7 +979,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, } else if (mode == OddEvenFillMode) { glStencilMask(GL_STENCIL_HIGH_BIT); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit - drawVertexArrays(data, stops, GL_TRIANGLE_FAN); + drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); } else { // TriStripStrokeFillMode Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops @@ -1137,7 +1138,7 @@ void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect) } // Draws the vertex array as a set of triangle fans. -void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, const QVector *stops, +void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive) { // Now setup the pointer to the vertex array: @@ -1145,7 +1146,8 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, const QVector glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, data); int previousStop = 0; - foreach(int stop, *stops) { + for (int i=0; i %d:", previousStop, stop-1); for (int i=previousStop; ifillStencilWithVertexArray(d->stroker.vertices(), d->stroker.vertexCount() / 2, - 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); + 0, 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 9720723..b554f6d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -195,18 +195,18 @@ public: void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); void drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, const QTextItemInt &ti); - void drawVertexArrays(const float *data, const QVector *stops, GLenum primitive); + void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive); void drawVertexArrays(QGL2PEXVertexArray &vertexArray, GLenum primitive) { - drawVertexArrays((const float *) vertexArray.data(), &vertexArray.stops(), primitive); + drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive); } // ^ draws whatever is in the vertex array void composite(const QGLRect& boundingRect); // ^ Composites the bounding rect onto dest buffer - void fillStencilWithVertexArray(const float *data, int count, const QVector *stops, const QGLRect &bounds, StencilFillMode mode); + void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QGLRect &bounds, StencilFillMode mode); void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill) { - fillStencilWithVertexArray((const float *) vertexArray.data(), 0, &vertexArray.stops(), + fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(), vertexArray.boundingRect(), useWindingFill ? WindingFillMode : OddEvenFillMode); } -- cgit v0.12 From 4f4f1e612488f400b2b139eaf7fea940fb6d7e7c Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 25 Nov 2009 19:14:04 +1000 Subject: Don't spend time on adding center point for convex paths, saves a few cycles. Reviewed-by: Samuel --- src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp index 67a4128..ee1a797 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp @@ -101,7 +101,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc boundingRectDirty = false; } - if (!outline) + if (!outline && !path.isConvex()) addCentroid(path, 0); int lastMoveTo = vertexArray.size(); @@ -127,7 +127,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc // qDebug("element[%d] is a MoveToElement", i); vertexArrayStops.add(vertexArray.size()); if (!outline) { - addCentroid(path, i); + if (!path.isConvex()) addCentroid(path, i); lastMoveTo = vertexArray.size(); } lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex -- cgit v0.12 From c815ebbf5689118688a9a08b19c40d5fc789b17d Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Tue, 24 Nov 2009 14:53:52 +0100 Subject: Adjust qmediaplayer's settings dialog for small screens. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch done jointly by me and Jan-arve. Task-number: QTBUG-4725 Reviewed-by: Jan-Arve Sæther Reviewed-by: Frans Englich --- demos/qmediaplayer/settings.ui | 351 ++++++++++++++++++++++------------------- 1 file changed, 191 insertions(+), 160 deletions(-) diff --git a/demos/qmediaplayer/settings.ui b/demos/qmediaplayer/settings.ui index d2cedd4..03bd70e 100644 --- a/demos/qmediaplayer/settings.ui +++ b/demos/qmediaplayer/settings.ui @@ -1,283 +1,314 @@ - + + settings - - + + 0 0 - 360 - 362 + 175 + 397 - + Settings - + - - + + Video options: - + true - - - - + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + Fit in view + + + + + Scale and crop + + + + + + + Contrast: - - - + + + + + 0 + 0 + + + -8 - + 8 - + Qt::Horizontal - + QSlider::TicksBelow - + 4 - - - + + + Brightness: - - - + + + -8 - + 8 - + Qt::Horizontal - + QSlider::TicksBelow - + 4 - - - + + + Saturation: - - - + + + -8 - + 8 - + Qt::Horizontal - + QSlider::TicksBelow - + 4 - - - + + + Hue: - - - + + + -8 - + 8 - + Qt::Horizontal - + QSlider::TicksBelow - + 4 - - - + + + Aspect ratio: - - - - - 180 - 0 - + + + + QComboBox::AdjustToContentsOnFirstShow - + Auto - + Stretch - + 4/3 - + 16/9 - - - + + + Scale Mode: - - - - - 180 - 0 - - - - - Fit in view - - - - - Scale and crop - - - - + scalemodeCombo + label_9 + contrastSlider + label_8 + brightnessSlider + label_7 + saturationSlider + label_2 + hueSlider + label_10 + aspectCombo + label_11 - - + + Audio options: - + true - + - + - - - + + + 0 0 - + - 90 + 10 0 - + Audio device: - + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - + + + 0 0 + + + 10 + 0 + + + + QComboBox::AdjustToMinimumContentsLength + - + - - - + + + 0 0 - + - 90 + 10 0 - + Audio effect: - + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - + + + 0 0 + + + 10 + 0 + + + + QComboBox::AdjustToMinimumContentsLength + - - + + false - + Setup @@ -285,123 +316,123 @@ - + - - - + + + 0 0 - + - 90 + 10 0 - + Cross fade: - + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - + - - - + + + 0 0 - + -20 - + 20 - + 1 - + 2 - + 0 - + Qt::Horizontal - + QSlider::TicksBelow - + - - + + 9 - + -10 Sec - + Qt::Horizontal - + - 40 + 0 20 - - + + 9 - + 0 - + Qt::Horizontal - + - 40 + 0 20 - - + + 9 - - 10 Sec + + 10 Sec @@ -415,11 +446,11 @@ - - + + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -434,11 +465,11 @@ settings accept() - + 248 254 - + 157 274 @@ -450,11 +481,11 @@ settings reject() - + 316 260 - + 286 274 -- cgit v0.12 From 71658bad211f12dd252a432559bd3897a8cb021a Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 19 Nov 2009 17:43:18 -0300 Subject: QGAL: deal correctly with anchors in parallel with the layout In the preferred size calculation, we should not add 'layout anchors' (either one or the two halves) into the objective function, since the layout doesn't impose or prefer any size at all. This already worked for cases when the layout anchor is one, but not when we have two halves. The mechanism was a 'skipInPreferred' flag that were not being set. The flag is pretty much redundant right now, since we can get this information from the 'isLayoutAnchor' flag. So, the flag was removed and a test was added for both a parallel case with the entire layout and other with half of the layout (which wasn't passing before). Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 6 +-- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 4 +- .../tst_qgraphicsanchorlayout.cpp | 52 ++++++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index fb67278..b324469 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1272,7 +1272,6 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() addAnchor_helper(layout, Qt::AnchorLeft, layout, Qt::AnchorRight, data); data->maxSize = QWIDGETSIZE_MAX; - data->skipInPreferred = 1; // Save a reference to layout vertices layoutFirstVertex[Horizontal] = internalVertex(layout, Qt::AnchorLeft); @@ -1284,7 +1283,6 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() addAnchor_helper(layout, Qt::AnchorTop, layout, Qt::AnchorBottom, data); data->maxSize = QWIDGETSIZE_MAX; - data->skipInPreferred = 1; // Save a reference to layout vertices layoutFirstVertex[Vertical] = internalVertex(layout, Qt::AnchorTop); @@ -2700,7 +2698,9 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QListskipInPreferred) + + // The layout original structure anchors are not relevant in preferred size calculation + if (ad->isLayoutAnchor) continue; QSimplexVariable *grower = new QSimplexVariable; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 2b365fb..8529e2e 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -124,8 +124,7 @@ struct AnchorData : public QSimplexVariable { : QSimplexVariable(), from(0), to(0), minSize(0), prefSize(0), maxSize(0), sizeAtMinimum(0), sizeAtPreferred(0), - sizeAtMaximum(0), item(0), - graphicsAnchor(0), skipInPreferred(0), + sizeAtMaximum(0), item(0), graphicsAnchor(0), type(Normal), isLayoutAnchor(false), isCenterAnchor(false), orientation(0), dependency(Independent) {} @@ -169,7 +168,6 @@ struct AnchorData : public QSimplexVariable { QGraphicsLayoutItem *item; QGraphicsAnchor *graphicsAnchor; - uint skipInPreferred : 1; uint type : 2; // either Normal, Sequential or Parallel uint isLayoutAnchor : 1; // if this anchor is an internal layout anchor uint isCenterAnchor : 1; diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 2ad024f..4f8c240 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -86,6 +86,7 @@ private slots: void parallelSimplificationOfCenter(); void simplificationVsRedundance(); void spacingPersistency(); + void snakeParallelWithLayout(); }; class RectWidget : public QGraphicsWidget @@ -1892,5 +1893,56 @@ void tst_QGraphicsAnchorLayout::spacingPersistency() QCOMPARE(anchor->spacing(), 30.0); } +/* + Test whether a correct preferred size is set when a "snake" sequence is in parallel with the + layout or half of the layout. The tricky thing here is that all items on the snake should + keep their preferred sizes. +*/ +void tst_QGraphicsAnchorLayout::snakeParallelWithLayout() +{ + QSizeF min(10, 20); + QSizeF pref(50, 20); + QSizeF max(100, 20); + + QGraphicsWidget *a = createItem(max, max, max, "A"); + QGraphicsWidget *b = createItem(min, pref, max, "B"); + QGraphicsWidget *c = createItem(max, max, max, "C"); + + QGraphicsWidget parent; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&parent); + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + + // First we'll do the case in parallel with the entire layout... + l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorRight); + l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft); + l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); + + l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); + l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); + l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); + l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom); + + parent.resize(l->effectiveSizeHint(Qt::PreferredSize)); + + // Note that A and C are fixed in the maximum size + QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(150, 60))); + QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), max)); + QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref)); + QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), max)); + + // Then, we change the "snake" to be in parallel with half of the layout + delete l->anchor(c, Qt::AnchorRight, l, Qt::AnchorRight); + l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorHorizontalCenter); + + parent.resize(l->effectiveSizeHint(Qt::PreferredSize)); + + QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(300, 60))); + QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), max)); + QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref)); + QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), max)); +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From d2ae5be7fcda5f7803e61db96d5229477ad00d70 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Wed, 18 Nov 2009 17:14:57 -0300 Subject: QGAL: sizeHint constraints needed by anchors parallel with the layout The method "constraintsFromSizeHints" does not create constraints for anchors between the layout vertices _only if_ these anchors have infinite maximum sizes. However, this test was not being done for half-anchors, ie. those created when the layout center anchorage point is used. That was OK when there was no chance that the center anchors had been simplified by a parallel anchor. Nowadays there's a chance that happens, so the test was extended. Commit also adds a test to avoid regressions. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 20 ++++++++++---- .../tst_qgraphicsanchorlayout.cpp | 32 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index b324469..a6f5992 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2269,13 +2269,21 @@ QList QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutCentralVertex[orient]); } else { layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutLastVertex[orient]); + } - // If maxSize is less then "infinite", that means there are other anchors - // grouped together with this one. We can't ignore its maximum value so we - // set back the variable to NULL to prevent the continue condition from being - // satisfied in the loop below. - if (layoutEdge->maxSize < QWIDGETSIZE_MAX) - layoutEdge = 0; + // If maxSize is less then "infinite", that means there are other anchors + // grouped together with this one. We can't ignore its maximum value so we + // set back the variable to NULL to prevent the continue condition from being + // satisfied in the loop below. + const qreal expectedMax = layoutCentralVertex[orient] ? QWIDGETSIZE_MAX / 2 : QWIDGETSIZE_MAX; + qreal actualMax; + if (layoutEdge->from == layoutFirstVertex[orient]) { + actualMax = layoutEdge->maxSize; + } else { + actualMax = -layoutEdge->minSize; + } + if (actualMax != expectedMax) { + layoutEdge = 0; } // For each variable, create constraints based on size hints diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 4f8c240..e2f87b8 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -87,6 +87,7 @@ private slots: void simplificationVsRedundance(); void spacingPersistency(); void snakeParallelWithLayout(); + void parallelToHalfLayout(); }; class RectWidget : public QGraphicsWidget @@ -1944,5 +1945,36 @@ void tst_QGraphicsAnchorLayout::snakeParallelWithLayout() QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), max)); } +/* + Avoid regression where the sizeHint constraints would not be + created for a parallel anchor that included the first layout half +*/ +void tst_QGraphicsAnchorLayout::parallelToHalfLayout() +{ + QGraphicsWidget *a = createItem(); + + QGraphicsWidget w; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w); + l->setContentsMargins(10, 10, 10, 10); + + l->addAnchors(l, a, Qt::Vertical); + + QGraphicsAnchor *anchor; + anchor = l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + anchor->setSpacing(5); + anchor = l->addAnchor(l, Qt::AnchorHorizontalCenter, a, Qt::AnchorRight); + anchor->setSpacing(-5); + + const QSizeF minimumSizeHint = w.effectiveSizeHint(Qt::MinimumSize); + const QSizeF preferredSizeHint = w.effectiveSizeHint(Qt::PreferredSize); + const QSizeF maximumSizeHint = w.effectiveSizeHint(Qt::MaximumSize); + + const QSizeF overhead = QSizeF(10 + 5 + 5, 10) * 2; + + QCOMPARE(minimumSizeHint, QSizeF(200, 100) + overhead); + QCOMPARE(preferredSizeHint, QSizeF(300, 100) + overhead); + QCOMPARE(maximumSizeHint, QSizeF(400, 100) + overhead); +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From f95cf16c3330cea6821bcaf26aa7d0948f61729f Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Wed, 25 Nov 2009 13:27:36 -0300 Subject: QGAL: default spacing can be unset using a negative value After a default spacing is set through QGAL::setSpacing() family of methods, the user must be able to unset it. To avoid adding another public method, we enabled this feature by allowing a negative value to be passed to those methods. Signed-off-by: Eduardo M. Fleury Reviewed-by: Anselmo Lacerda S. de Melo --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 23 ++---------- .../tst_qgraphicsanchorlayout.cpp | 41 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 7e5929e..686096c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -370,12 +370,6 @@ void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### We don't support negative spacing yet - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[0] = spacing; invalidate(); } @@ -389,12 +383,6 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### We don't support negative spacing yet - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[1] = spacing; invalidate(); } @@ -405,7 +393,8 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) If an item is anchored with no spacing associated with the anchor, it will use the default spacing. - Currently QGraphicsAnchorLayout does not support negative default spacings. + QGraphicsAnchorLayout does not support negative spacings. Setting a negative value will unset the + previous spacing and make the layout use the spacing provided by the current widget style. \sa setHorizontalSpacing(), setVerticalSpacing() */ @@ -413,14 +402,6 @@ void QGraphicsAnchorLayout::setSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### Currently we do not support negative anchors inside the graph. - // To avoid those being created by a negative spacing, we must - // make this test. - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[0] = d->spacings[1] = spacing; invalidate(); } diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e2f87b8..aa67ac5 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -88,6 +88,7 @@ private slots: void spacingPersistency(); void snakeParallelWithLayout(); void parallelToHalfLayout(); + void globalSpacing(); }; class RectWidget : public QGraphicsWidget @@ -1976,5 +1977,45 @@ void tst_QGraphicsAnchorLayout::parallelToHalfLayout() QCOMPARE(maximumSizeHint, QSizeF(400, 100) + overhead); } +void tst_QGraphicsAnchorLayout::globalSpacing() +{ + QGraphicsWidget *a = createItem(); + QGraphicsWidget *b = createItem(); + + QGraphicsWidget w; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w); + + l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner); + l->addCornerAnchors(a, Qt::BottomRightCorner, b, Qt::TopLeftCorner); + l->addCornerAnchors(b, Qt::BottomRightCorner, l, Qt::BottomRightCorner); + + w.resize(w.effectiveSizeHint(Qt::PreferredSize)); + qreal vSpacing = b->geometry().top() - a->geometry().bottom(); + qreal hSpacing = b->geometry().left() - a->geometry().right(); + + // Set spacings manually + l->setVerticalSpacing(vSpacing + 10); + l->setHorizontalSpacing(hSpacing + 5); + + w.resize(w.effectiveSizeHint(Qt::PreferredSize)); + qreal newVSpacing = b->geometry().top() - a->geometry().bottom(); + qreal newHSpacing = b->geometry().left() - a->geometry().right(); + + QCOMPARE(newVSpacing, vSpacing + 10); + QCOMPARE(newHSpacing, hSpacing + 5); + + // Set a negative spacing. This will unset the previous spacing and + // bring back the widget-defined spacing. + l->setSpacing(-1); + + w.resize(w.effectiveSizeHint(Qt::PreferredSize)); + newVSpacing = b->geometry().top() - a->geometry().bottom(); + newHSpacing = b->geometry().left() - a->geometry().right(); + + QCOMPARE(newVSpacing, vSpacing); + QCOMPARE(newHSpacing, hSpacing); +} + + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From f70ed1f2cc4cce16d6e844c961003fa7d545ed51 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 25 Nov 2009 14:44:49 +0000 Subject: Allow Symbian widget implementations to select native paint mode On the Symbian platform, the Qt raster paint engine targets an off-screen buffer owned by the Font & Bitmap server (FBSERV). When an area of the screen needs to be refreshed, the window server (WSERV) asks the control environment (CONE) to redraw the control(s) intersecting that screen region. Each Qt native widget has an associated Symbian control, whose Draw function blits the required region of the backing store via WSERV. Use cases involving Direct Screen Access (DSA) may require this behaviour to be modified, to either of the following: - Disable: the Draw function does nothing. In this case, the output of paint events, rendered to the backing store, is not blitted to the screen. This mode was introduced by change 8f445e13. - Zero fill: the Draw function fills all pixels within the redraw region with zeroes. This change allows the widget implementation to select either of these alternative modes by setting a flag in its QWExtra structure. Note that these alternative modes are only suitable for native widgets, because they act on a per-control rather than per-widget basis. Task-number: QTBUG-5467 Reviewed-by: Jason Barron --- src/gui/kernel/qapplication_s60.cpp | 23 ++++++++++++++++++++++- src/gui/kernel/qwidget_p.h | 33 +++++++++++++++++++++++++++------ src/gui/kernel/qwidget_s60.cpp | 2 +- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index fb2bc72..ae7b494 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -822,10 +822,31 @@ void QSymbianControl::Draw(const TRect& controlRect) const CFbsBitmap *bitmap = s60Surface->symbianBitmap(); CWindowGc &gc = SystemGc(); - if(!qwidget->d_func()->extraData()->disableBlit) { + switch(qwidget->d_func()->extraData()->nativePaintMode) { + case QWExtra::Disable: + // Do nothing + break; + + case QWExtra::Blit: if (qwidget->d_func()->isOpaque) gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect); + break; + + case QWExtra::ZeroFill: + if (Window().DisplayMode() == EColor16MA) { + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + gc.SetBrushColor(TRgb::Color16MA(0)); + gc.Clear(controlRect); + } else { + gc.SetBrushColor(TRgb(0x000000)); + gc.Clear(controlRect); + }; + break; + + default: + Q_ASSERT(false); } } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint()); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 66efcb5..025d703 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -230,12 +230,33 @@ struct QWExtra { #elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian uint activated : 1; // RWindowBase::Activated has been called - // If set, QSymbianControl::Draw does not blit this widget - // This is to allow, for use cases such as video, widgets which, from the Qt point - // of view, are just placeholders in the scene. For these widgets, any necessary - // drawing to the UI framebuffer is done by the relevant Symbian subsystem. For - // video rendering, this would be an MMF controller, or MDF post-processor. - uint disableBlit : 1; + /** + * Defines the behaviour of QSymbianControl::Draw. + */ + enum NativePaintMode { + /** + * Normal drawing mode: blits the required region of the backing store + * via WSERV. + */ + Blit, + + /** + * Disable drawing for this widget. + */ + Disable, + + /** + * Paint zeros into the WSERV framebuffer, using BitGDI APIs. For windows + * with an EColor16MU display mode, zero is written only into the R, G and B + * channels of the pixel. + */ + ZeroFill, + + Default = Blit + }; + + NativePaintMode nativePaintMode : 2; + #endif }; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 359df2a..d7d76df 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -881,7 +881,7 @@ void QWidgetPrivate::deleteTLSysExtra() void QWidgetPrivate::createSysExtra() { extra->activated = 0; - extra->disableBlit = 0; + extra->nativePaintMode = QWExtra::Default; } void QWidgetPrivate::deleteSysExtra() -- cgit v0.12 From bff3e6d8d810dbba29978d666949f4f3bb70503f Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 25 Nov 2009 14:45:33 +0000 Subject: Changed video widget native paint mode to zero-fill native window Certain S60 video stacks require the screen region in which video will be rendered to be painted with a zero brush (opaque black for EColor16MU displays; transparent black for EColor16MA / EColor16MAP). Task-number: QTBUG-5467 Reviewed-by: Jason Barron --- src/3rdparty/phonon/mmf/objectdump_symbian.cpp | 2 +- src/3rdparty/phonon/mmf/videooutput.cpp | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp index 2efebdb..edad537 100644 --- a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp +++ b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp @@ -46,7 +46,7 @@ QList QAnnotatorWidget::annotation(const QObject& object) stream << "widget (Symbian): "; stream << "activated " << extra->activated << ' '; - stream << "disableBlit " << extra->disableBlit << ' '; + stream << "nativePaintMode " << extra->nativePaintMode << ' '; stream.flush(); result.append(array); diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp index ddf30de..f16f332 100644 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ b/src/3rdparty/phonon/mmf/videooutput.cpp @@ -72,12 +72,7 @@ MMF::VideoOutput::VideoOutput setAttribute(Qt::WA_NoSystemBackground, true); setAutoFillBackground(false); - // Causes QSymbianControl::Draw not to BitBlt this widget's region of the - // backing store. Since the backing store is (by default) a 16MU bitmap, - // blitting it results in this widget's screen region in the final - // framebuffer having opaque alpha values. This in turn causes the video - // to be invisible when running on the target device. - qt_widget_private(this)->extraData()->disableBlit = true; + qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill; getVideoWindowRect(); registerForAncestorMoved(); -- cgit v0.12 From e9704a297f788bb79b2a89e9b16214443931af5d Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 25 Nov 2009 14:47:32 +0000 Subject: Symbian control invokes slots before and after native draw ops Direct Screen Access (DSA) allows a client to request notification from the window server when drawing is performed by other threads, into a specified region of the screen. This allows DSA rendering - for example video - to be suspended when notifications are drawn, preventing the video content from overwriting the notification. If the drawing originates from the same thread as that which holds the DSA session, DSA must be suspended while drawing takes place. This change allows a widget to request notification when native drawing is about to be performed by QSymbianControl::Draw. Task-number: QTBUG-5467 Reviewed-by: Jason Barron --- src/gui/kernel/qapplication_s60.cpp | 19 +++++++++++++++++++ src/gui/kernel/qwidget_p.h | 9 +++++++++ src/gui/kernel/qwidget_s60.cpp | 1 + 3 files changed, 29 insertions(+) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index ae7b494..d1471eb 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -812,6 +812,12 @@ void QSymbianControl::Draw(const TRect& controlRect) const if (!engine) return; + const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents; + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r)); + } + // Map source rectangle into coordinates of the backing store. const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY); const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase); @@ -851,6 +857,19 @@ void QSymbianControl::Draw(const TRect& controlRect) const } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint()); } + + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + // The draw ops aren't actually sent to WSERV until the graphics + // context is deactivated, which happens in the function calling + // this one. We therefore delay the delivery of endNativePaintEvent, + // to ensure that drawing has completed by the time the widget + // receives the event. Note that, if the widget needs to ensure + // that the draw ops have actually been executed into the output + // framebuffer, a call to RWsSession::Flush is required in the + // endNativePaintEvent implementation. + QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r)); + } } void QSymbianControl::SizeChanged() diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 025d703..04cf4bb 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -257,6 +257,15 @@ struct QWExtra { NativePaintMode nativePaintMode : 2; + /** + * If this bit is set, each native widget receives the signals from the + * Symbian control immediately before and immediately after draw ops are + * sent to the window server for this control: + * void beginNativePaintEvent(const QRect &paintRect); + * void endNativePaintEvent(const QRect &paintRect); + */ + uint receiveNativePaintEvents : 1; + #endif }; diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index d7d76df..37614c7 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -882,6 +882,7 @@ void QWidgetPrivate::createSysExtra() { extra->activated = 0; extra->nativePaintMode = QWExtra::Default; + extra->receiveNativePaintEvents = 0; } void QWidgetPrivate::deleteSysExtra() -- cgit v0.12 From e84f5486724bf11d2a20e405a30db618f8c48e33 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 25 Nov 2009 14:48:03 +0000 Subject: Suspend DSA while drawing is in progress In order to prevent flicker or - on some versions of the platform - video disappearing from the screen altogether, the video controller's DSA session must be suspended while the window control is redrawn. Task-number: QTBUG-5467 Reviewed-by: Jason Barron --- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 57 ++++++++++++++++++++++++++++- src/3rdparty/phonon/mmf/mmf_videoplayer.h | 7 ++++ src/3rdparty/phonon/mmf/videooutput.cpp | 16 ++++++++ src/3rdparty/phonon/mmf/videooutput.h | 6 +++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 2059fbe..0fd4d67 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -50,6 +50,8 @@ MMF::VideoPlayer::VideoPlayer() , m_window(0) , m_totalTime(0) , m_pendingChanges(false) + , m_dsaActive(false) + , m_dsaWasActive(false) { construct(); } @@ -61,6 +63,7 @@ MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player) , m_window(0) , m_totalTime(0) , m_pendingChanges(false) + , m_dsaActive(false) { construct(); } @@ -86,6 +89,9 @@ void MMF::VideoPlayer::construct() )) ); + // CVideoPlayerUtility::NewL starts DSA + m_dsaActive = true; + if (KErrNone != err) changeState(ErrorState); @@ -349,6 +355,18 @@ void MMF::VideoPlayer::initVideoOutput() Q_ASSERT(connected); connected = connect( + m_videoOutput, SIGNAL(beginVideoWindowNativePaint()), + this, SLOT(suspendDirectScreenAccess()) + ); + Q_ASSERT(connected); + + connected = connect( + m_videoOutput, SIGNAL(endVideoWindowNativePaint()), + this, SLOT(resumeDirectScreenAccess()) + ); + Q_ASSERT(connected); + + connected = connect( m_videoOutput, SIGNAL(aspectRatioChanged()), this, SLOT(aspectRatioChanged()) ); @@ -370,12 +388,48 @@ void MMF::VideoPlayer::videoWindowChanged() TRACE_ENTRY("state %d", state()); m_window = m_videoOutput->videoWindow(); - updateVideoRect(); TRACE_EXIT_0(); } +void MMF::VideoPlayer::suspendDirectScreenAccess() +{ + m_dsaWasActive = stopDirectScreenAccess(); +} + +void MMF::VideoPlayer::resumeDirectScreenAccess() +{ + if(m_dsaWasActive) { + startDirectScreenAccess(); + m_dsaWasActive = false; + } +} + +void MMF::VideoPlayer::startDirectScreenAccess() +{ + if(!m_dsaActive) { + TRAPD(err, m_player->StartDirectScreenAccessL()); + if(KErrNone == err) + m_dsaActive = true; + else + setError(NormalError); + } +} + +bool MMF::VideoPlayer::stopDirectScreenAccess() +{ + const bool dsaWasActive = m_dsaActive; + if(m_dsaActive) { + TRAPD(err, m_player->StopDirectScreenAccessL()); + if(KErrNone == err) + m_dsaActive = false; + else + setError(NormalError); + } + return dsaWasActive; +} + // Helper function for aspect ratio / scale mode handling QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight) { @@ -553,6 +607,7 @@ void MMF::VideoPlayer::applyVideoWindowChange() TRACE("SetDisplayWindowL err %d", err); setError(NormalError); } else { + m_dsaActive = true; TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (2) err %d", err); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index 599bb88..abb1da8 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -72,6 +72,8 @@ public Q_SLOTS: void videoWindowChanged(); void aspectRatioChanged(); void scaleModeChanged(); + void suspendDirectScreenAccess(); + void resumeDirectScreenAccess(); private: void construct(); @@ -89,6 +91,9 @@ private: void applyPendingChanges(); void applyVideoWindowChange(); + void startDirectScreenAccess(); + bool stopDirectScreenAccess(); + // AbstractMediaPlayer virtual int numberOfMetaDataEntries() const; virtual QPair metaDataEntry(int index) const; @@ -111,6 +116,8 @@ private: qint64 m_totalTime; bool m_pendingChanges; + bool m_dsaActive; + bool m_dsaWasActive; }; diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp index f16f332..119dcb1 100644 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ b/src/3rdparty/phonon/mmf/videooutput.cpp @@ -34,6 +34,8 @@ along with this library. If not, see . #include +#include // for CCoeEnv + QT_BEGIN_NAMESPACE using namespace Phonon; @@ -73,6 +75,7 @@ MMF::VideoOutput::VideoOutput setAutoFillBackground(false); qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill; + qt_widget_private(this)->extraData()->receiveNativePaintEvents = true; getVideoWindowRect(); registerForAncestorMoved(); @@ -283,5 +286,18 @@ void MMF::VideoOutput::dump() const #endif } +void MMF::VideoOutput::beginNativePaintEvent(const QRect& /*controlRect*/) +{ + emit beginVideoWindowNativePaint(); +} + +void MMF::VideoOutput::endNativePaintEvent(const QRect& /*controlRect*/) +{ + // Ensure that draw ops are executed into the WSERV output framebuffer + CCoeEnv::Static()->WsSession().Flush(); + + emit endVideoWindowNativePaint(); +} + QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h index 6dfe69d..2788401 100644 --- a/src/3rdparty/phonon/mmf/videooutput.h +++ b/src/3rdparty/phonon/mmf/videooutput.h @@ -63,10 +63,16 @@ public: // Debugging output void dump() const; +public Q_SLOTS: + void beginNativePaintEvent(const QRect& /*controlRect*/); + void endNativePaintEvent(const QRect& /*controlRect*/); + Q_SIGNALS: void videoWindowChanged(); void aspectRatioChanged(); void scaleModeChanged(); + void beginVideoWindowNativePaint(); + void endVideoWindowNativePaint(); protected: // Override QWidget functions -- cgit v0.12 From 3ac80bf663a2a8d69b860c44b0285fe72750da58 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 25 Nov 2009 09:09:20 +0000 Subject: Tidied up logic of retrieving video window in Phonon MMF backend Task-number: QTBUG-5467 Reviewed-by: trustme --- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 0fd4d67..be58e91 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -321,8 +321,7 @@ void MMF::VideoPlayer::getVideoWindow() m_videoOutput->dump(); initVideoOutput(); - m_window = m_videoOutput->videoWindow(); - updateVideoRect(); + videoWindowChanged(); } else // Top-level window m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); -- cgit v0.12 From 58d8c744dbcde532270b62484ea16d865589bc38 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 25 Nov 2009 09:10:19 +0000 Subject: Clip video rect to physical screen dimensions The CVideoPlayerUtility API requires both a native window handle and an absolute screen rectangle in order to define the location of the rendered video output. On certain devices, such as the Nokia E75, which runs S60 3.2, if the absolute rectangle extends outside the physical screen extent, no video is rendered. This change works around this defect in the platform by clipping the video rectangle to the physical screen extent. Task-number: QTBUG-5467 Reviewed-by: trustme --- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index be58e91..b6f53ae 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -446,7 +446,18 @@ QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight) void MMF::VideoPlayer::updateVideoRect() { QRect videoRect; - const QRect windowRect = m_videoOutput->videoWindowRect(); + QRect windowRect = m_videoOutput->videoWindowRect(); + + // Clip to physical window size + // This is due to a defect in the layout when running on S60 3.2, which + // results in the rectangle of the video widget extending outside the + // screen in certain circumstances. These include the initial startup + // of the mediaplayer demo in portrait mode. When this rectangle is + // passed to the CVideoPlayerUtility, no video is rendered. + const TSize screenSize = m_screenDevice.SizeInPixels(); + const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight); + windowRect = windowRect.intersected(screenRect); + const QSize windowSize = windowRect.size(); // Calculate size of smallest rect which contains video frame size -- cgit v0.12 From 38a44a97ee30214c450615f07588d5c2b733b5d5 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 27 Nov 2009 12:18:00 +0100 Subject: Fix QFontDialog::getFont on Mac OS X when using an invalid initial font If you passed in a QFont with a family name that did not resolve to QFontDialog::getFont(), it would not select any font in the panel, and it would always return the default font, regardless of what you actually selected in the dialog. This was because it would try to resolve the requested family name, rather than the actual family name of the initial font. That in turn caused the NSFont* returned by the system to be null, which, when set on the font manager, caused the manager to always return 0 for selectedFont. Task-number: QTBUG-6071 Reviewed-by: Trond --- src/gui/dialogs/qfontdialog_mac.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 5b0983b..0c467cd 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -625,10 +625,11 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font) } NSFontManager *mgr = [NSFontManager sharedFontManager]; - nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(font.family()) + QFontInfo fontInfo(font); + nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family()) traits:mask weight:weight - size:QFontInfo(font).pointSize()]; + size:fontInfo.pointSize()]; } [mgr setSelectedFont:nsFont isMultiple:NO]; -- cgit v0.12 From 61f2e17c497f683d7fa78232decb260bfa5b5d77 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 27 Nov 2009 12:19:14 +0100 Subject: Fixed a memory leak in the newer native filedialog on windows Reviewed-by: denis --- src/gui/dialogs/qfiledialog_win.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index d8ae73e..0116319 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -534,7 +534,7 @@ QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); // Multiple selection is allowed only in IFileOpenDialog. - IFileOpenDialog *pfd; + IFileOpenDialog *pfd = 0; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, @@ -607,6 +607,8 @@ QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, } } } + if (pfd) + pfd->Release(); return result; } -- cgit v0.12 From c91ccab6f4ae1f7dd8c2c7103d6d63e7725b9eeb Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 27 Nov 2009 11:32:41 +0100 Subject: Correctly export the horizontal part of a mixed alignment in text. Task-number: QTBUG-5542 Reviewed-by: Trust-me We should not assume that the alignment only has a horizontal part so the export should take care to fish out the relevant bits from the flags only. --- src/gui/text/qtextodfwriter.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 9b7e8de..1bd4dd6 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -447,18 +447,19 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat writer.writeStartElement(styleNS, QString::fromLatin1("paragraph-properties")); if (format.hasProperty(QTextFormat::BlockAlignment)) { + const Qt::Alignment alignment = format.alignment() & Qt::AlignHorizontal_Mask; QString value; - if (format.alignment() == Qt::AlignLeading) + if (alignment == Qt::AlignLeading) value = QString::fromLatin1("start"); - else if (format.alignment() == Qt::AlignTrailing) + else if (alignment == Qt::AlignTrailing) value = QString::fromLatin1("end"); - else if (format.alignment() == (Qt::AlignLeft | Qt::AlignAbsolute)) + else if (alignment == (Qt::AlignLeft | Qt::AlignAbsolute)) value = QString::fromLatin1("left"); - else if (format.alignment() == (Qt::AlignRight | Qt::AlignAbsolute)) + else if (alignment == (Qt::AlignRight | Qt::AlignAbsolute)) value = QString::fromLatin1("right"); - else if (format.alignment() == Qt::AlignHCenter) + else if (alignment == Qt::AlignHCenter) value = QString::fromLatin1("center"); - else if (format.alignment() == Qt::AlignJustify) + else if (alignment == Qt::AlignJustify) value = QString::fromLatin1("justify"); else qWarning() << "QTextOdfWriter: unsupported paragraph alignment; " << format.alignment(); -- cgit v0.12 From d6b91331fe9a96c0abab72fccbcc6b5fa425a459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 27 Nov 2009 12:46:44 +0100 Subject: Compile QtScript for win32-icc Reviewed-by: Kent Hansen --- src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h | 2 +- src/3rdparty/javascriptcore/WebKit.pri | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h index 56659a8..c03e8a7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h @@ -155,7 +155,7 @@ namespace WTF { typedef IntegralConstant true_type; typedef IntegralConstant false_type; -#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, // but for some unexplained reason it doesn't work on built-in types. template struct HasTrivialConstructor : public IntegralConstant{ }; diff --git a/src/3rdparty/javascriptcore/WebKit.pri b/src/3rdparty/javascriptcore/WebKit.pri index 8291f30..16f89bf 100644 --- a/src/3rdparty/javascriptcore/WebKit.pri +++ b/src/3rdparty/javascriptcore/WebKit.pri @@ -11,7 +11,7 @@ isEmpty(OUTPUT_DIR) { DEFINES += BUILDING_QT__=1 building-libs { - win32-msvc*: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 + win32-msvc*|win32-icc: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 } else { CONFIG(QTDIR_build) { QT += webkit -- cgit v0.12 From 1355eb52ce21a0bbdb1899ef283fb6e58d389213 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 27 Nov 2009 14:04:38 +0100 Subject: state wasn't being correctly reloaded on mac with unified toolbar Task-number: QTBUG-5932 --- src/gui/widgets/qtoolbararealayout.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index b7e985c..c329305 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -1296,6 +1296,8 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList toolBars = _toolBars; int lines; stream >> lines; + if (!testing) + testing = mainWindow->unifiedTitleAndToolBarOnMac(); for (int j = 0; j < lines; ++j) { int pos; @@ -1306,6 +1308,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList> cnt; QToolBarAreaLayoutInfo &dock = docks[pos]; + const bool applyingLayout = !testing && !(pos == QInternal::TopDock && mainWindow->unifiedTitleAndToolBarOnMac()); QToolBarAreaLayoutLine line(dock.o); for (int k = 0; k < cnt; ++k) { @@ -1346,7 +1349,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QListsetOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o); toolBar->setVisible(shown & 1); @@ -1357,7 +1360,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList Date: Fri, 27 Nov 2009 14:55:46 +0100 Subject: compile fix for autotest --- tests/auto/qspinbox/tst_qspinbox.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/auto/qspinbox/tst_qspinbox.cpp b/tests/auto/qspinbox/tst_qspinbox.cpp index 655de15..b5e37f2 100644 --- a/tests/auto/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/qspinbox/tst_qspinbox.cpp @@ -1018,13 +1018,17 @@ void tst_QSpinBox::taskQTBUG_5008_textFromValueAndValidate() setValue(1000000); } + QLineEdit *lineEdit() const + { + return QSpinBox::lineEdit(); + } + //we use the French delimiters here QString textFromValue (int value) const { return locale().toString(value); } - using QSpinBox::lineEdit; } spinbox; spinbox.show(); spinbox.activateWindow(); -- cgit v0.12 From 71c2cfee4bcd81b2552b66b676895dcd9a6a794b Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 27 Nov 2009 14:58:01 +0100 Subject: compile fix for autotest --- tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp index 00ebed0..157c39d 100644 --- a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp @@ -1058,13 +1058,16 @@ void tst_QDoubleSpinBox::taskQTBUG_5008_textFromValueAndValidate() setValue(1000); } + QLineEdit *lineEdit() const + { + return QDoubleSpinBox::lineEdit(); + } + //we use the French delimiters here QString textFromValue (double value) const { return locale().toString(value); } - - using QDoubleSpinBox::lineEdit; } spinbox; spinbox.show(); spinbox.activateWindow(); -- cgit v0.12 From b6029c998fcd38de95711fa6e1ff4d8b522f8bde Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Fri, 27 Nov 2009 15:15:39 +0100 Subject: Fix tst_qspinbox compilation with winscw. --- tests/auto/qspinbox/tst_qspinbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qspinbox/tst_qspinbox.cpp b/tests/auto/qspinbox/tst_qspinbox.cpp index d2fe2ac..e6dcb52 100644 --- a/tests/auto/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/qspinbox/tst_qspinbox.cpp @@ -758,7 +758,7 @@ void tst_QSpinBox::editingFinished() box->activateWindow(); box->setFocus(); - QTRY_COMPARE(qApp->focusWidget(), box); + QTRY_COMPARE(qApp->focusWidget(), (QWidget *)box); QSignalSpy editingFinishedSpy1(box, SIGNAL(editingFinished())); QSignalSpy editingFinishedSpy2(box2, SIGNAL(editingFinished())); -- cgit v0.12 From 1d5621a4958ab6f250566c26f891d3e99c6f8585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 30 Nov 2009 12:15:00 +0100 Subject: Compile webkit for win32-icc The reason for the first hunk is that the Intel compiler does not support the __has_trivial_constructor type trait. The Intel Compiler can report itself as _MSC_VER >= 1400. The reason for that is that the Intel Compiler depends on the Microsoft Platform SDK, and in order to try to be "fully" MS compatible it will "pretend" to be the same MS compiler as was shipped with the MS PSDK. (Thus, compiling with win32-icc with VC8 SDK will make the source code "think" the compiler at hand supports this type trait). The second hunk is simply for including stdint.h since MS does not ship that in their PSDK. Reviewed-by: Simon Hausmann --- src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h | 2 +- src/3rdparty/webkit/WebKit.pri | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h b/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h index 6ce6a3e..9e75e7a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h @@ -155,7 +155,7 @@ namespace WTF { typedef IntegralConstant true_type; typedef IntegralConstant false_type; -#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, // but for some unexplained reason it doesn't work on built-in types. template struct HasTrivialConstructor : public IntegralConstant{ }; diff --git a/src/3rdparty/webkit/WebKit.pri b/src/3rdparty/webkit/WebKit.pri index 10291b4..5188662 100644 --- a/src/3rdparty/webkit/WebKit.pri +++ b/src/3rdparty/webkit/WebKit.pri @@ -11,7 +11,7 @@ isEmpty(OUTPUT_DIR) { DEFINES += BUILDING_QT__=1 building-libs { - win32-msvc*: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 + win32-msvc*|win32-icc: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 } else { CONFIG(QTDIR_build) { QT += webkit -- cgit v0.12 From 0d09c6bfa5da53fedc794d6dc99f5675bdf59d49 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 30 Nov 2009 12:06:57 +0100 Subject: Do not recoginze templated types or pointers as flags. Those types can never by flags. This fixes QML as they do not use Q_DECLARE_METATYPE in a way visible to moc. Patch by Aaron Kennedy Reviewed-by: Kent Hansen --- src/tools/moc/generator.cpp | 3 ++- tests/auto/moc/namespaced-flags.h | 5 +++++ tests/auto/moc/tst_moc.cpp | 9 ++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 1ed6586..8fcc0df 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -292,7 +292,8 @@ void Generator::generateCode() QList extraList; for (int i = 0; i < cdef->propertyList.count(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); - if (!isVariantType(p.type) && !metaTypes.contains(p.type)) { + if (!isVariantType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') && + !p.type.contains('<') && !p.type.contains('>')) { int s = p.type.lastIndexOf("::"); if (s > 0) { QByteArray scope = p.type.left(s); diff --git a/tests/auto/moc/namespaced-flags.h b/tests/auto/moc/namespaced-flags.h index d3f9548..b366447 100644 --- a/tests/auto/moc/namespaced-flags.h +++ b/tests/auto/moc/namespaced-flags.h @@ -62,13 +62,18 @@ namespace Foo { Q_OBJECT //Q_PROPERTY( Bar::Flags flags READ flags WRITE setFlags ) // triggers assertion Q_PROPERTY( Foo::Bar::Flags flags READ flags WRITE setFlags ) // fails to compile, or with the same assertion if moc fix is applied + Q_PROPERTY( QList flagsList READ flagsList WRITE setFlagsList ) public: explicit Baz( QObject * parent=0 ) : QObject( parent ), mFlags() {} void setFlags( Bar::Flags f ) { mFlags = f; } Bar::Flags flags() const { return mFlags; } + + void setFlagsList( const QList &f ) { mList = f; } + QList flagsList() const { return mList; } private: Bar::Flags mFlags; + QList mList; }; } diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 69d6ca7..2316ba2 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -489,7 +489,6 @@ private slots: void constructors(); void typenameWithUnsigned(); void warnOnVirtualSignal(); - signals: void sigWithUnsignedArg(unsigned foo); void sigWithSignedArg(signed foo); @@ -817,6 +816,8 @@ void tst_Moc::structQObject() #include "namespaced-flags.h" +Q_DECLARE_METATYPE(QList); + void tst_Moc::namespacedFlags() { Foo::Baz baz; @@ -829,6 +830,12 @@ void tst_Moc::namespacedFlags() QVERIFY(v.isValid()); QVERIFY(baz.setProperty("flags", v)); QVERIFY(baz.flags() == bar.flags()); + + QList l; + l << baz.flags(); + QVariant v2 = baz.setProperty("flagsList", QVariant::fromValue(l)); + QCOMPARE(l, baz.flagsList()); + QCOMPARE(l, qvariant_cast >(baz.property("flagsList"))); } void tst_Moc::warnOnMultipleInheritance() -- cgit v0.12 From 98a23b974509bd1b6d9459e6c79677bdcbaa0108 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 30 Nov 2009 12:57:10 +0100 Subject: X11: Avoid loading all fonts in system for text with line breaks The line separator code point has no glyph in any font, something we would detect by running through a complete font merging loop and trying all fonts in the system on X11. This would cause the memory consumption to sky rocket the first time you added text with line breaks to an application, and it was an unnecessary performance hit. Now we special case the line separator and do no attempt to search for it in the fonts. Task-number: QTBUG-4537 Reviewed-by: Simon Hausmann --- src/gui/text/qfontengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 21b9cca..27fc3c1 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1370,8 +1370,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, for (int i = 0; i < len; ++i) { bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); - if (glyphs->glyphs[glyph_pos] == 0) { + if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) { QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos); for (int x = 1; x < engines.size(); ++x) { QFontEngine *engine = engines.at(x); -- cgit v0.12 From e18bad03dd51aed881a86715bfc17ef0c7fe5af9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 30 Nov 2009 14:37:15 +0100 Subject: Do not fill the disabled background of item. This is a regression against Qt 4.5 If one want special background for disabled item, one can use stylesheet, or BackgroundRole This partially revert 127e68d3dc4ff8329 Reviewed-by: jbache Task-number: QT-2388 Task-number: QTBUG-6319 --- src/gui/styles/qcommonstyle.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 4c9541b..5028e5f 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -770,8 +770,6 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight)); else if (vopt->features & QStyleOptionViewItemV2::Alternate) p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); - else if (!(vopt->state & QStyle::State_Enabled)) - p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Base)); } break; case PE_PanelItemViewItem: -- cgit v0.12 From 0f61a0f1ce02bb0248cb87055240a8a474dce452 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 27 Nov 2009 16:17:25 +0100 Subject: Fixed the GL2 engine stroker to handle Qt::SvgMiterJoin. Reviewed-by: Trond --- src/opengl/gl2paintengineex/qtriangulatingstroker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index c78f73f..6082f49 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -313,6 +313,7 @@ void QTriangulatingStroker::join(const qreal *pts) switch (m_join_style) { case Qt::BevelJoin: break; + case Qt::SvgMiterJoin: case Qt::MiterJoin: { // Find out on which side the join should be. int count = m_vertices.size(); -- cgit v0.12 From 0fa878c4d2dfc25d4641a6654a9b482230559c3a Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 30 Nov 2009 13:13:11 +0100 Subject: Fixed square root of negative number in drawTextItem(). Fixed potential bug where you could end up taking the square root of a negative number in drawTextItem() in the raster and OpenGL paint engines. Task-number: QTBUG-6327 Reviewed-by: Trond --- src/gui/painting/qpaintengine_raster.cpp | 3 ++- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 3f33319..4a72434 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3240,7 +3240,8 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; // ### Remove the TestFontEngine and Box engine crap, in these diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 07432c6..15702ba 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1452,7 +1452,8 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 -- cgit v0.12 From 85349d44d859a4a591d82f90dd128fd43426b4fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 30 Nov 2009 14:55:06 +0100 Subject: Add some notes about known issues for win32-icc --- doc/src/getting-started/known-issues.qdoc | 10 ++++++++++ doc/src/platforms/compiler-notes.qdoc | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/src/getting-started/known-issues.qdoc b/doc/src/getting-started/known-issues.qdoc index b8c2192..6632666 100644 --- a/doc/src/getting-started/known-issues.qdoc +++ b/doc/src/getting-started/known-issues.qdoc @@ -134,6 +134,16 @@ currently calls winId() on widgets, which causes whole widget hierarchies to use native window handles. This slows down resizing. + \o Compile error with Intel C++ Compiler. + There seems to be a bug in the Intel compiler wrt too agressive inlining. + The problem will manifest itself during the link phase of QtGui where it + fails with the error that it cannot find QObjectData::~QObjectData(). + See http://bugreports.qt.nokia.com/browse/QTBUG-5145 for updates on this + bug. + Also, due to some bugs in webkit, both QtScript and Webkit does not compile. + See http://bugreports.qt.nokia.com/browse/QTBUG-6297 for a workaround for + QtScript. + \endlist \section2 Mac OS X diff --git a/doc/src/platforms/compiler-notes.qdoc b/doc/src/platforms/compiler-notes.qdoc index 0ae32c3..8f1202d 100644 --- a/doc/src/platforms/compiler-notes.qdoc +++ b/doc/src/platforms/compiler-notes.qdoc @@ -196,7 +196,7 @@ \list \o Windows - Intel(R) C++ Compiler for 32-bit applications, - Version 8.1 Build 20050309Z Package ID: W_CC_PC_8.1.026 + Version 9.1.040. \o Altix - Intel(R) C++ Itanium(R) Compiler for Itanium(R)-based applications Version 8.1 Build 20050406 Package ID: l_cc_pc_8.1.030 \endlist -- cgit v0.12 From 011d3aa2bdf49127169f0726b78e13e8e9bcd73e Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 30 Nov 2009 14:58:43 +0100 Subject: Only call updateFont if the font have changed. When receiving the polish event, we call updateFont only if the font has changed (from the QApplication::font()). This avoid to clear sizeHints cache. Task-number:QTBUG-6272 Reviewed-by:janarve --- src/gui/graphicsview/qgraphicswidget.cpp | 3 +- tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 35 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index f6c06d5..fe569f4 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1301,7 +1301,8 @@ bool QGraphicsWidget::event(QEvent *event) case QEvent::Polish: polishEvent(); d->polished = true; - d->updateFont(d->font); + if (!d->font.isCopyOf(QApplication::font())) + d->updateFont(d->font); break; case QEvent::WindowActivate: case QEvent::WindowDeactivate: diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 3b98c2f..3303df5 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -106,6 +106,7 @@ private slots: void font_data(); void font(); void fontPropagation(); + void fontChangedEvent(); void fontPropagationWidgetItemWidget(); void fontPropagationSceneChange(); void geometry_data(); @@ -673,6 +674,40 @@ void tst_QGraphicsWidget::fontPropagation() QCOMPARE(child2->font().pointSize(), 43); } +void tst_QGraphicsWidget::fontChangedEvent() +{ + QGraphicsWidget *root = new QGraphicsWidget; + QGraphicsScene scene; + scene.addItem(root); + + // Check that only the application fonts apply. + QFont appFont = QApplication::font(); + QCOMPARE(scene.font(), appFont); + QCOMPARE(root->font(), appFont); + + EventSpy rootSpyFont(root, QEvent::FontChange); + EventSpy rootSpyPolish(root, QEvent::Polish); + QCOMPARE(rootSpyFont.count(), 0); + QApplication::processEvents(); //The polish event is sent + QCOMPARE(rootSpyPolish.count(), 1); + QApplication::processEvents(); //Process events to see if we get the font change event + //The font is still the same so no fontChangeEvent + QCOMPARE(rootSpyFont.count(), 0); + + QFont font; + font.setPointSize(43); + root->setFont(font); + QApplication::processEvents(); //Process events to get the font change event + //The font changed + QCOMPARE(rootSpyFont.count(), 1); + + //then roll back to the default one. + root->setFont(appFont); + QApplication::processEvents(); //Process events to get the font change event + //The font changed + QCOMPARE(rootSpyFont.count(), 2); +} + void tst_QGraphicsWidget::fontPropagationWidgetItemWidget() { QGraphicsWidget *widget = new QGraphicsWidget; -- cgit v0.12 From 565fece517519e33eb5b73aa9f2a4e55f756f9c5 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Nov 2009 15:34:49 +0100 Subject: Doc: Fixed up a known issue. Reviewed-by: Trust Me --- doc/src/getting-started/known-issues.qdoc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/src/getting-started/known-issues.qdoc b/doc/src/getting-started/known-issues.qdoc index 6632666..b26d68e 100644 --- a/doc/src/getting-started/known-issues.qdoc +++ b/doc/src/getting-started/known-issues.qdoc @@ -134,15 +134,17 @@ currently calls winId() on widgets, which causes whole widget hierarchies to use native window handles. This slows down resizing. - \o Compile error with Intel C++ Compiler. - There seems to be a bug in the Intel compiler wrt too agressive inlining. - The problem will manifest itself during the link phase of QtGui where it - fails with the error that it cannot find QObjectData::~QObjectData(). - See http://bugreports.qt.nokia.com/browse/QTBUG-5145 for updates on this + \o Compile errors with Intel C++ Compiler.\br + There seems to be a bug in the Intel compiler with respect to + over-agressive inlining of code. + The problem will manifest itself during the link phase of QtGui where + it fails with the error that it cannot find QObjectData::~QObjectData(). + See \l{http://bugreports.qt.nokia.com/browse/QTBUG-5145} for updates on this bug. - Also, due to some bugs in webkit, both QtScript and Webkit does not compile. - See http://bugreports.qt.nokia.com/browse/QTBUG-6297 for a workaround for - QtScript. + Also, due to some bugs in WebKit, the QtScript and QtWebKit modules + will not compile. + See \l{http://bugreports.qt.nokia.com/browse/QTBUG-6297} for a + workaround for QtScript. \endlist -- cgit v0.12 From 0eb65a6d6ff0665d6db2d1ba29b700a308a24fca Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 30 Nov 2009 17:10:03 +0100 Subject: Fix tst_qsharedmemory on Unix executable does not end with .exe on Unix, while it is valid to call the executable without the .exe on windows Reviewed-by: Joao --- tests/auto/qsharedmemory/tst_qsharedmemory.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp index 4ab3b0b..f72b6f7 100644 --- a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp +++ b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp @@ -708,10 +708,7 @@ void tst_QSharedMemory::simpleThreadedProducerConsumer() void tst_QSharedMemory::simpleProcessProducerConsumer_data() { QTest::addColumn("processes"); - int tries = 10; -#ifdef Q_OS_WIN - tries = 5; -#endif + int tries = 5; for (int i = 0; i < tries; ++i) { QTest::newRow("1 process") << 1; QTest::newRow("5 processes") << 5; @@ -737,7 +734,7 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() #endif QProcess producer; producer.setProcessChannelMode(QProcess::ForwardedChannels); - producer.start( QFileInfo("./lackey/lackey.exe").absoluteFilePath(), arguments); + producer.start( "./lackey/lackey", arguments); producer.waitForStarted(); QVERIFY(producer.error() != QProcess::FailedToStart); -- cgit v0.12 From bc992c8e40fcfdcfe0015dd88dda77c318c10a55 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 30 Nov 2009 06:58:20 +0100 Subject: Fix crash in qt3support QPixmap constructor Reviewed-by: Trond --- src/gui/image/qpixmap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 985a20b..617cfe5 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1165,7 +1165,7 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) Qt::HANDLE QPixmap::handle() const { #if defined(Q_WS_X11) - if (data->classId() == QPixmapData::X11Class) + if (data && data->classId() == QPixmapData::X11Class) return static_cast(data.constData())->handle(); #endif return 0; @@ -1216,7 +1216,7 @@ QPixmap::QPixmap(const QImage& image) if (!qt_pixmap_thread_test()) return; - if (data->pixelType() == QPixmapData::BitmapType) + if (data && data->pixelType() == QPixmapData::BitmapType) *this = QBitmap::fromImage(image); else *this = fromImage(image); -- cgit v0.12 From 3c1c84dd569c02bfeec66aa985616b654b69a531 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 30 Nov 2009 17:14:30 +0100 Subject: In QListViews, items were being hovered even when mouse was on the scrollbars Reviewed-by: Olivier Task-number: QTBUG-6284 --- src/gui/itemviews/qabstractitemview.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index ad15655..acfeff8 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -2552,7 +2552,9 @@ void QAbstractItemView::verticalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); - d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + if (viewport()->rect().contains(posInVp)) + d->checkMouseMove(posInVp); } /*! @@ -2563,7 +2565,9 @@ void QAbstractItemView::horizontalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); - d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + if (viewport()->rect().contains(posInVp)) + d->checkMouseMove(posInVp); } /*! -- cgit v0.12 From 4bb7bacccff707a693de6d50c7ce886126b68c25 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 1 Dec 2009 10:35:54 +0100 Subject: Fix QFontCombobox autotest on X11 On X11, Font might have a foundry within bracket. This foundry is set by the font combobox, and makes the font comparison fail. Make sure the other attributes (size, bold, ...) are preserved when the font is changed. Reviewed-by: Gabriel --- src/gui/widgets/qfontcombobox.cpp | 5 ++--- tests/auto/qfontcombobox/tst_qfontcombobox.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp index d601f81..b976b94 100644 --- a/src/gui/widgets/qfontcombobox.cpp +++ b/src/gui/widgets/qfontcombobox.cpp @@ -269,9 +269,8 @@ void QFontComboBoxPrivate::_q_updateModel() void QFontComboBoxPrivate::_q_currentChanged(const QString &text) { Q_Q(QFontComboBox); - QFont newFont(text); - if (currentFont.family() != newFont.family()) { - currentFont = newFont; + if (currentFont.family() != text) { + currentFont.setFamily(text); emit q->currentFontChanged(currentFont); } } diff --git a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp index b974ecab..657be06 100644 --- a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp +++ b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp @@ -144,9 +144,11 @@ void tst_QFontComboBox::currentFont() QFont oldCurrentFont = box.currentFont(); box.setCurrentFont(currentFont); - QCOMPARE(box.currentFont(), currentFont); - QString boxFontFamily = QFontInfo(box.currentFont()).family(); QRegExp foundry(" \\[.*\\]"); + if (!box.currentFont().family().contains(foundry)) { + QCOMPARE(box.currentFont(), currentFont); + } + QString boxFontFamily = QFontInfo(box.currentFont()).family(); if (!currentFont.family().contains(foundry)) boxFontFamily.remove(foundry); QCOMPARE(boxFontFamily, currentFont.family()); -- cgit v0.12 From f63fdc09fcaf5258694e9c2f21a5cd22c6677a17 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 1 Dec 2009 10:55:03 +0100 Subject: Extended tst_QListView::indexAt to test viewport bounds. Reviewed-by: Olivier --- tests/auto/qlistview/tst_qlistview.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 602da61..24a553f 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -586,7 +586,15 @@ void tst_QListView::indexAt() index = view.indexAt(QPoint(20,2 * sz.height())); QVERIFY(!index.isValid()); - + // Check when peeking out of the viewport bounds + index = view.indexAt(QPoint(view.viewport()->rect().width(), 0)); + QVERIFY(!index.isValid()); + index = view.indexAt(QPoint(-1, 0)); + QVERIFY(!index.isValid()); + index = view.indexAt(QPoint(20, view.viewport()->rect().height())); + QVERIFY(!index.isValid()); + index = view.indexAt(QPoint(20, -1)); + QVERIFY(!index.isValid()); model.rCount = 30; QListViewShowEventListener view2; -- cgit v0.12 From 8d83cad5d67408576c8e4e86e48aa6f952165ac3 Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Tue, 1 Dec 2009 13:33:56 +0200 Subject: Minor doc update for known-issues wiki link. Task-number: QTBUG-6211 Reviewed-by: TrustMe --- doc/src/getting-started/known-issues.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/getting-started/known-issues.qdoc b/doc/src/getting-started/known-issues.qdoc index b26d68e..a8de0a1 100644 --- a/doc/src/getting-started/known-issues.qdoc +++ b/doc/src/getting-started/known-issues.qdoc @@ -54,7 +54,7 @@ on the Qt website. An overview of known issues may also be found at: - \l{http://qt.gitorious.org/qt/pages/Qt460BetaKnownIssues} + \l{http://qt.gitorious.org/qt/pages/Qt460KnownIssues} {Known Issues Wiki}. \section1 Installation Issues -- cgit v0.12 From dbfdfdb1bc37dd18dd1b723b5d5b0b65c37f3f41 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 1 Dec 2009 09:18:47 +0100 Subject: Added caching of vectorpaths to the GL paint engine. The first time a path is drawn we call makeCachable on the path, which means that if it is drawn again, we start caching it. This is a bit of a trick to avoid caching paths that are drawn once and discared while at the same time cache paths that are reused automatically. The GL engine owns the vertex information and is responsible for cleaning it up. If the vectorpath is destroyed first, it will call the cleanup function. if the engine dies first, we still require some hooks to clean up the cache in the path. More to come. When VBO's are used, these will be a leaked if the path is destroyed after the engine. Reviewed-by: Samuel --- src/gui/painting/qpaintengineex.cpp | 16 ++- src/gui/painting/qvectorpath_p.h | 13 ++- src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h | 2 + .../gl2paintengineex/qpaintengineex_opengl2.cpp | 115 ++++++++++++++++++++- .../gl2paintengineex/qpaintengineex_opengl2_p.h | 4 + 5 files changed, 139 insertions(+), 11 deletions(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 7d1c109..9a0e319 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -56,6 +56,20 @@ QT_BEGIN_NAMESPACE * class QVectorPath * */ +QVectorPath::~QVectorPath() +{ + if (m_hints & ShouldUseCacheHint) { + CacheEntry *e = m_cache; + while (e) { + if (e->data) + e->cleanup(e->engine, e->data); + CacheEntry *n = e->next; + delete e; + e = n; + } + } +} + QRectF QVectorPath::controlPointRect() const { @@ -94,7 +108,7 @@ QRectF QVectorPath::controlPointRect() const QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data, - qvectorpath_cache_cleanup cleanup) { + qvectorpath_cache_cleanup cleanup) const{ Q_ASSERT(!lookupCacheData(engine)); if ((m_hints & IsCachedHint) == 0) { m_cache = 0; diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index ec27970..5eaddf4 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -68,7 +68,7 @@ QT_MODULE(Gui) class QPaintEngineEx; -typedef void (*qvectorpath_cache_cleanup)(void *data); +typedef void (*qvectorpath_cache_cleanup)(QPaintEngineEx *engine, void *data); struct QRealRect { qreal x1, y1, x2, y2; @@ -118,6 +118,8 @@ public: { } + ~QVectorPath(); + QRectF controlPointRect() const; inline Hint shape() const { return (Hint) (m_hints & ShapeMask); } @@ -128,6 +130,7 @@ public: inline bool hasImplicitClose() const { return m_hints & ImplicitClose; } inline bool hasWindingFill() const { return m_hints & WindingFill; } + inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = 0; } inline uint hints() const { return m_hints; } inline const QPainterPath::ElementType *elements() const { return m_elements; } @@ -146,9 +149,9 @@ public: CacheEntry *next; }; - CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup); + CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup) const; inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const { - Q_ASSERT(m_hints & IsCachedHint); + Q_ASSERT(m_hints & ShouldUseCacheHint); CacheEntry *e = m_cache; while (e) { if (e->engine == engine) @@ -162,14 +165,14 @@ public: private: Q_DISABLE_COPY(QVectorPath) - CacheEntry *m_cache; - const QPainterPath::ElementType *m_elements; const qreal *m_points; const int m_count; mutable uint m_hints; mutable QRealRect m_cp_rect; + + mutable CacheEntry *m_cache; }; Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &path); diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index 03aec17..98eaa91 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -112,6 +112,8 @@ public: int stopCount() const { return vertexArrayStops.size(); } QGLRect boundingRect() const; + int vertexCount() const { return vertexArray.size(); } + void lineToArray(const GLfloat x, const GLfloat y); private: diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 6a708b4..3fce384 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -62,6 +62,8 @@ and use the correct program when we really need it. */ +// #define QT_OPENGL_CACHE_AS_VBOS + #include "qpaintengineex_opengl2_p.h" #include //for memcpy @@ -344,6 +346,13 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() { delete shaderManager; + + while (pathCaches.size()) { + QVectorPath::CacheEntry *e = *(pathCaches.constBegin()); + e->cleanup(e->engine, e->data); + e->data = 0; + e->engine = 0; + } } void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) @@ -846,6 +855,30 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) mode = newMode; } +struct QGL2PEVectorPathCache +{ +#ifdef QT_OPENGL_CACHE_AS_VBOS + GLuint vbo; +#else + float *vertices; +#endif + int vertexCount; + GLenum primitiveType; + qreal iscale; +}; + +void qopengl2paintengine_cleanup_vectorpath(QPaintEngineEx *engine, void *data) +{ + QGL2PEVectorPathCache *c = (QGL2PEVectorPathCache *) data; +#ifdef QT_OPENGL_CACHE_AS_VBOS + QGL2PaintEngineExPrivate *d = QGL2PaintEngineExPrivate::getData((QGL2PaintEngineEx *) engine); + d->unusedVBOSToClean << c->vbo; +#else + qFree(c->vertices); +#endif + delete c; +} + // Assumes everything is configured for the brush you want to use void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) { @@ -863,10 +896,74 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) prepareForDraw(currentBrush->isOpaque()); composite(rect); } else if (path.isConvex()) { - vertexCoordinateArray.clear(); - vertexCoordinateArray.addPath(path, inverseScale, false); - prepareForDraw(currentBrush->isOpaque()); - drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); + + if (path.isCacheable()) { + QVectorPath::CacheEntry *data = path.lookupCacheData(q); + QGL2PEVectorPathCache *cache; + + if (data) { + cache = (QGL2PEVectorPathCache *) data->data; + // Check if scale factor is exceeded for curved paths and generate curves if so... + if (path.isCurved()) { + qreal scaleFactor = cache->iscale / inverseScale; + if (scaleFactor < 0.5 || scaleFactor > 2.0) { +#ifdef QT_OPENGL_CACHE_AS_VBOS + glDeleteBuffers(1, &cache->vbo); + cache->vbo = 0; +#else + qFree(cache->vertices); +#endif + cache->vertexCount = 0; + } + } + } else { + cache = new QGL2PEVectorPathCache; + cache->vertexCount = 0; + data = const_cast(path).addCacheData(q, cache, qopengl2paintengine_cleanup_vectorpath); + } + + // Flatten the path at the current scale factor and fill it into the cache struct. + if (!cache->vertexCount) { + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale, false); + int vertexCount = vertexCoordinateArray.vertexCount(); + int floatSizeInBytes = vertexCount * 2 * sizeof(float); + cache->vertexCount = vertexCount; + cache->primitiveType = GL_TRIANGLE_FAN; + cache->iscale = inverseScale; +#ifdef QT_OPENGL_CACHE_AS_VBOS + glGenBuffers(1, &cache->vbo); + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); +#else + cache->vertices = (float *) qMalloc(floatSizeInBytes); + memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes); +#endif + } + + prepareForDraw(currentBrush->isOpaque()); + glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); +#ifdef QT_OPENGL_CACHE_AS_VBOS + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, 0); +#else + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, cache->vertices); +#endif + glDrawArrays(cache->primitiveType, 0, cache->vertexCount); + + } else { + // printf(" - Marking path as cachable...\n"); + // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable + // ### Remove before release... + static bool do_vectorpath_cache = qgetenv("QT_OPENGL_NO_PATH_CACHE").isEmpty(); + if (do_vectorpath_cache) + path.makeCacheable(); + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale, false); + prepareForDraw(currentBrush->isOpaque()); + drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); + } + } else { // The path is too complicated & needs the stencil technique vertexCoordinateArray.clear(); @@ -1756,7 +1853,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->device->beginPaint(); #if !defined(QT_OPENGL_ES_2) - bool success = qt_resolve_version_2_0_functions(d->ctx); + bool success = qt_resolve_version_2_0_functions(d->ctx) + && qt_resolve_buffer_extensions(d->ctx); Q_ASSERT(success); Q_UNUSED(success); #endif @@ -1817,6 +1915,13 @@ bool QGL2PaintEngineEx::end() delete d->shaderManager; d->shaderManager = 0; +#ifdef QT_OPENGL_CACHE_AS_VBOS + if (!d->unusedVBOSToClean.isEmpty()) { + glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData()); + d->unusedVBOSToClean.clear(); + } +#endif + return false; } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index b554f6d..0084476 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -221,6 +221,7 @@ public: void restoreDepthRangeForRenderText(); static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; } + static QGL2PaintEngineExPrivate *getData(QGL2PaintEngineEx *engine) { return engine->d_func(); } QGL2PaintEngineEx* q; QGLPaintDevice* device; @@ -294,6 +295,9 @@ public: QScopedPointer fastBlurFilter; QScopedPointer dropShadowFilter; QScopedPointer fastDropShadowFilter; + + QSet pathCaches; + QVector unusedVBOSToClean; }; QT_END_NAMESPACE -- cgit v0.12 From bfd43c0d7d7e107cd20ace6603f68a6304be0821 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 1 Dec 2009 13:21:33 +0100 Subject: QVariant documentation: there is no function QVariant::isEmpty() --- doc/src/snippets/code/src_corelib_kernel_qvariant.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp b/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp index 6b9923c..41a9cb3 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp @@ -65,7 +65,6 @@ QVariant x, y(QString()), z(QString("")); x.convert(QVariant::Int); // x.isNull() == true // y.isNull() == true, z.isNull() == false -// y.isEmpty() == true, z.isEmpty() == true //! [1] -- cgit v0.12 From d3d44583fc354773f8260c3b6afa02340c51f450 Mon Sep 17 00:00:00 2001 From: axis Date: Tue, 1 Dec 2009 15:15:41 +0100 Subject: Clarify the docs a bit when setting focus. RevBy: Trust me --- src/gui/kernel/qwidget.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index b389054..d19c574 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -366,7 +366,8 @@ bool QWidget::hasEditFocus() const normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to change focus. - This feature is only available in Qt for Embedded Linux. + This feature is only available in Qt for Embedded Linux and Qt + for Symbian. \sa hasEditFocus(), QApplication::keypadNavigationEnabled() */ @@ -6045,6 +6046,11 @@ bool QWidget::hasFocus() const (Nothing happens if the focus in and focus out widgets are the same.) + \note On embedded platforms, setFocus() will not cause an input panel + to be opened by the input method. If you want this to happen, you + have to send a QEvent::RequestSoftwareInputPanel event to the + widget yourself. + setFocus() gives focus to a widget regardless of its focus policy, but does not clear any keyboard grab (see grabKeyboard()). @@ -6057,7 +6063,7 @@ bool QWidget::hasFocus() const \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(), setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(), - grabMouse(), {Keyboard Focus} + grabMouse(), {Keyboard Focus}, QEvent::RequestSoftwareInputPanel */ void QWidget::setFocus(Qt::FocusReason reason) -- cgit v0.12 From 2d470839354e022840d5e7d0f9772a23544a696e Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 1 Dec 2009 15:32:43 +0100 Subject: Fixed a potential crash in QDockWidget This happened when inserting the gap over a place holder item. Task-number: QTBUG-6107 Reviewed-by: Gabi --- src/gui/widgets/qdockarealayout.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 07914b2..0a26a77 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1167,7 +1167,8 @@ bool QDockAreaLayoutInfo::insertGap(const QList &path, QLayoutItem *dockWid QDockAreaLayoutInfo *subinfo = item.subinfo; QLayoutItem *widgetItem = item.widgetItem; - QRect r = subinfo == 0 ? dockedGeometry(widgetItem->widget()) : subinfo->rect; + QPlaceHolderItem *placeHolderItem = item.placeHolderItem; + QRect r = subinfo == 0 ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect; Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal; #ifdef QT_NO_TABBAR @@ -1176,13 +1177,15 @@ bool QDockAreaLayoutInfo::insertGap(const QList &path, QLayoutItem *dockWid QDockAreaLayoutInfo *new_info = new QDockAreaLayoutInfo(sep, dockPos, opposite, tabBarShape, mainWindow); + //item become a new top-level item.subinfo = new_info; item.widgetItem = 0; + item.placeHolderItem = 0; QDockAreaLayoutItem new_item = widgetItem == 0 ? QDockAreaLayoutItem(subinfo) - : QDockAreaLayoutItem(widgetItem); + : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem); new_item.size = pick(opposite, r.size()); new_item.pos = pick(opposite, r.topLeft()); new_info->item_list.append(new_item); -- cgit v0.12 From 537bff8c020c8fd2c150b2821d1cc035ee96f84f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 1 Dec 2009 16:55:44 +0100 Subject: QWindowStyle: make sure there is no duplicate in the list of scrollbar. Otherwise the list grow and waste memory and CPU each time the stylesheet is changed or the widget is shown Reviewed-by: Thierry Task-number: QTBUG-6409 --- src/gui/styles/qwindowsstyle.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 30f2f35..0a59d6d 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -213,10 +213,12 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) case QEvent::StyleChange: case QEvent::Show: if (QProgressBar *bar = qobject_cast(o)) { - d->bars << bar; - if (d->bars.size() == 1) { - Q_ASSERT(d->animationFps> 0); - d->animateTimer = startTimer(1000 / d->animationFps); + if (!d->bars.contains(bar)) { + d->bars << bar; + if (d->bars.size() == 1) { + Q_ASSERT(d->animationFps> 0); + d->animateTimer = startTimer(1000 / d->animationFps); + } } } break; -- cgit v0.12 From 480b395bd652a4ac6e3f262bd99a045dff95c4ac Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 1 Dec 2009 20:58:44 +0100 Subject: Fix crash in QVector::reserve when reserving smaller size on a shared vector We cannot call realloc with aalloc smaller than asize. Also include obvious optimisation: take the qMin computation out of the loop. Task-number: QTBUG-6416 Reviewed-by: Thiago --- src/corelib/tools/qvector.h | 6 ++++-- tests/auto/qvector/tst_qvector.cpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index f0de98d..201e7b3 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -324,7 +324,7 @@ void QVector::detach_helper() { realloc(d->size, d->alloc); } template void QVector::reserve(int asize) -{ if (asize > d->alloc || d->ref != 1) realloc(d->size, asize); d->capacity = 1; } +{ if (asize > d->alloc) realloc(d->size, asize); if (d->ref == 1) d->capacity = 1; } template void QVector::resize(int asize) { realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ? @@ -441,6 +441,7 @@ void QVector::free(Data *x) template void QVector::realloc(int asize, int aalloc) { + Q_ASSERT(asize <= aalloc); T *pOld; T *pNew; union { QVectorData *d; Data *p; } x; @@ -496,7 +497,8 @@ void QVector::realloc(int asize, int aalloc) pOld = p->array + x.d->size; pNew = x.p->array + x.d->size; // copy objects from the old array into the new array - while (x.d->size < qMin(asize, d->size)) { + const int toMove = qMin(asize, d->size); + while (x.d->size < toMove) { new (pNew++) T(*pOld++); x.d->size++; } diff --git a/tests/auto/qvector/tst_qvector.cpp b/tests/auto/qvector/tst_qvector.cpp index 21c9270..f538f6a 100644 --- a/tests/auto/qvector/tst_qvector.cpp +++ b/tests/auto/qvector/tst_qvector.cpp @@ -56,6 +56,7 @@ public: private slots: void outOfMemory(); + void QTBUG6416_reserve(); }; int fooCtor; @@ -220,5 +221,18 @@ void tst_QVector::outOfMemory() } } +void tst_QVector::QTBUG6416_reserve() +{ + fooCtor = 0; + fooDtor = 0; + { + QVector a; + a.resize(2); + QVector b(a); + b.reserve(1); + } + QCOMPARE(fooCtor, fooDtor); +} + QTEST_APPLESS_MAIN(tst_QVector) #include "tst_qvector.moc" -- cgit v0.12 From 1b56836c0e7715fb1321c9bd48c8d6fd5b56f217 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 2 Dec 2009 17:50:11 +1000 Subject: Reduce double-copying of textures when flipping upside down bindTexture() flipped images in-place, to reduce data copying. But there is one case where the in-place is worse: when the QImage is not detached. In that case, the flip was copying the entire image and then flipping the lines, effectively processing the contents twice. The new version uses mirrored() to reduce the overhead for non-detached images. Reviewed-by: Samuel --- src/opengl/qgl.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index d5ca218..5ada125 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2277,13 +2277,21 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - flipping bits over y (%d ms)\n", time.elapsed()); #endif - int ipl = img.bytesPerLine() / 4; - int h = img.height(); - for (int y=0; y Date: Wed, 2 Dec 2009 09:33:09 +0100 Subject: qreal-ization Defining QT_USE_MATH_H_FLOATS will enable single precision math functions that are called via Qt wrappers (qSin, qCos ...). Reviewed-by: axis --- mkspecs/common/symbian/symbian.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 79bac42..0f06b92 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -7,7 +7,7 @@ CONFIG += qt warn_on release incremental QT += core gui QMAKE_INCREMENTAL_STYLE = sublib -DEFINES += UNICODE QT_KEYPAD_NAVIGATION QT_SOFTKEYS_ENABLED +DEFINES += UNICODE QT_KEYPAD_NAVIGATION QT_SOFTKEYS_ENABLED QT_USE_MATH_H_FLOATS QMAKE_COMPILER_DEFINES += SYMBIAN QMAKE_EXT_OBJ = .o -- cgit v0.12