From 3ed427637dd76da371174e14b0f7f2a15801fcac Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 2 Dec 2009 11:39:44 +0000 Subject: Added error strings to Phonon MMF backend Note that changing Utils from a namespace into a class, and then using Q_DECLARE_TR_FUNCTIONS in the class declaration, was necessary in order to be able to call tr(...) from the implementation of Utils::symbianErrorToString. Task-number: QTBUG-4994 Reviewed-by: Oswald Buddenhagen --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 26 ++++--- src/3rdparty/phonon/mmf/abstractplayer.cpp | 12 ++- src/3rdparty/phonon/mmf/abstractplayer.h | 16 +++- src/3rdparty/phonon/mmf/audioplayer.cpp | 13 ++-- src/3rdparty/phonon/mmf/mediaobject.cpp | 12 +-- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 22 +++--- src/3rdparty/phonon/mmf/utils.cpp | 98 +++++++++++++++++++++++++ src/3rdparty/phonon/mmf/utils.h | 22 ++++-- 8 files changed, 170 insertions(+), 51 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 99e96cd..bc38513 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -70,7 +70,7 @@ void MMF::AbstractMediaPlayer::play() switch (privateState()) { case GroundState: - setError(NormalError); + setError(tr("Not ready to play")); break; case LoadingState: @@ -226,10 +226,13 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f m_source = source; TInt symbianErr = KErrNone; + QString errorMessage; switch (m_source.type()) { case MediaSource::LocalFile: { symbianErr = openFile(file); + if (KErrNone != symbianErr) + errorMessage = tr("Error opening file"); break; } @@ -238,11 +241,12 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f if (url.scheme() == QLatin1String("file")) { symbianErr = openFile(file); + if (KErrNone != symbianErr) + errorMessage = tr("Error opening URL"); } else { - TRACE_0("Source type not supported"); - // TODO: support network URLs - symbianErr = KErrNotSupported; + TRACE_0("Error opening URL: protocol not supported"); + errorMessage = tr("Error opening URL: protocol not supported"); } break; @@ -251,8 +255,8 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f case MediaSource::Invalid: case MediaSource::Disc: case MediaSource::Stream: - TRACE_0("Source type not supported"); - symbianErr = KErrNotSupported; + TRACE_0("Error opening source: type not supported"); + errorMessage = tr("Error opening source: type not supported"); break; case MediaSource::Empty: @@ -265,11 +269,13 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f TRACE_PANIC(InvalidMediaTypePanic); } - if (KErrNone == symbianErr) { + if (errorMessage.isEmpty()) { changeState(LoadingState); } else { - TRACE("error %d", symbianErr) - setError(NormalError); + if (symbianErr) + setError(errorMessage, symbianErr); + else + setError(errorMessage); } TRACE_EXIT_0(); @@ -318,7 +324,7 @@ void MMF::AbstractMediaPlayer::doVolumeChanged() const int err = setDeviceVolume(volume); if (KErrNone != err) { - setError(NormalError); + setError(tr("Setting volume failed"), err); } break; } diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index caf4092..13ff5fb 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -113,19 +113,23 @@ void MMF::AbstractPlayer::videoOutputChanged() // Default behaviour is empty - overridden by VideoPlayer } -void MMF::AbstractPlayer::setError(Phonon::ErrorType error, - const QString &errorMessage) +void MMF::AbstractPlayer::setError(const QString &errorMessage) { TRACE_CONTEXT(AbstractPlayer::setError, EAudioInternal); - TRACE_ENTRY("state %d error %d", m_state, error); + TRACE_ENTRY("state %d", m_state); - m_error = error; + m_error = Phonon::NormalError; m_errorString = errorMessage; changeState(ErrorState); TRACE_EXIT_0(); } +void MMF::AbstractPlayer::setError(const QString &errorMessage, int symbianError) +{ + setError(errorMessage + ": " + Utils::symbianErrorToString(symbianError)); +} + Phonon::ErrorType MMF::AbstractPlayer::errorType() const { const Phonon::ErrorType result = (ErrorState == m_state) diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 2e9cfa0..9af1362 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -87,10 +87,20 @@ public: void setVideoOutput(VideoOutput* videoOutput); /** - * Records error and changes state to ErrorState + * Records error message and changes state to ErrorState */ - void setError(Phonon::ErrorType error, - const QString &errorMessage = QString()); + void setError(const QString &errorMessage); + + /** + * Records error message and changes state to ErrorState + * + * Appends a human-readable version of symbianErrorCode to the error message, + * e.g. + * setError(NormalError, "Opening file failed", KErrPermissionDenied) + * results in the following error message: + * "Opening file failed: permission denied" + */ + void setError(const QString &errorMessage, int symbianErrorCode); Phonon::State state() const; diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 8fccfe6..72d6684 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -51,9 +51,8 @@ void MMF::AudioPlayer::construct() TRACE_ENTRY_0(); TRAPD(err, m_player.reset(CPlayerType::NewL(*this, 0, EMdaPriorityPreferenceNone))); - if (KErrNone != err) { - changeState(ErrorState); - } + if (KErrNone != err) + setError("Creation of audio player failed", err); TRACE_EXIT_0(); } @@ -151,7 +150,7 @@ qint64 MMF::AudioPlayer::currentTime() const // If we don't cast away constness here, we simply have to ignore // the error. - const_cast(this)->setError(NormalError); + const_cast(this)->setError(tr("Getting position failed"), err); } return result; @@ -186,8 +185,7 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError, updateMetaData(); changeState(StoppedState); } else { - // TODO: set different error states according to value of aError? - setError(NormalError); + setError(tr("Opening clip failed"), aError); } TRACE_EXIT_0(); @@ -208,8 +206,7 @@ void MMF::AudioPlayer::MapcPlayComplete(TInt aError) changeState(StoppedState); // TODO: move on to m_nextSource } else { - // TODO: do something with aError? - setError(NormalError); + setError(tr("Playback complete"), aError); } /* diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index 21dcfe1..6158ca1 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -238,7 +238,6 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) const bool oldPlayerHasVideo = oldPlayer->hasVideo(); const bool oldPlayerSeekable = oldPlayer->isSeekable(); - Phonon::ErrorType error = NoError; QString errorMessage; // Determine media type @@ -255,7 +254,6 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) } else { errorMessage = QLatin1String("Network streaming not supported yet"); - error = NormalError; } } break; @@ -263,8 +261,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) case MediaSource::Invalid: case MediaSource::Disc: case MediaSource::Stream: - TRACE_0("Unsupported media type"); - error = NormalError; + errorMessage = tr("Error opening source: type not supported"); break; case MediaSource::Empty: @@ -287,8 +284,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) newPlayer = new DummyPlayer(); } - error = NormalError; - errorMessage = tr("Media type could not be determined"); + errorMessage = tr("Error opening source: media type could not be determined"); break; case MediaTypeAudio: @@ -326,9 +322,9 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) // We need to call setError() after doing the connects, otherwise the // error won't be received. - if (error != NoError) { + if (!errorMessage.isEmpty()) { Q_ASSERT(m_player); - m_player->setError(error, errorMessage); + m_player->setError(errorMessage); } TRACE_EXIT_0(); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index b6f53ae..4619f54 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -93,7 +93,7 @@ void MMF::VideoPlayer::construct() m_dsaActive = true; if (KErrNone != err) - changeState(ErrorState); + setError("Creation of video player failed", err); TRACE_EXIT_0(); } @@ -129,7 +129,7 @@ void MMF::VideoPlayer::doPause() TRAPD(err, m_player->PauseL()); if (KErrNone != err) { TRACE("PauseL error %d", err); - setError(NormalError); + setError(tr("Pause failed"), err); } } @@ -158,7 +158,7 @@ void MMF::VideoPlayer::doSeek(qint64 ms) } else { TRACE("SetPositionL error %d", err); - setError(NormalError); + setError(tr("Seek failed"), err); } } @@ -200,7 +200,7 @@ qint64 MMF::VideoPlayer::currentTime() const // If we don't cast away constness here, we simply have to ignore // the error. - const_cast(this)->setError(NormalError); + const_cast(this)->setError(tr("Getting position failed"), err); } return result; @@ -226,7 +226,7 @@ void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError) if (KErrNone == aError) m_player->Prepare(); else - setError(NormalError); + setError(tr("Opening clip failed"), aError); TRACE_EXIT_0(); } @@ -252,7 +252,7 @@ void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError) emit totalTimeChanged(totalTime()); changeState(StoppedState); } else { - setError(NormalError); + setError(tr("Buffering clip failed"), err); } TRACE_EXIT_0(); @@ -412,7 +412,7 @@ void MMF::VideoPlayer::startDirectScreenAccess() if(KErrNone == err) m_dsaActive = true; else - setError(NormalError); + setError(tr("Video display error"), err); } } @@ -424,7 +424,7 @@ bool MMF::VideoPlayer::stopDirectScreenAccess() if(KErrNone == err) m_dsaActive = false; else - setError(NormalError); + setError(tr("Video display error"), err); } return dsaWasActive; } @@ -600,7 +600,7 @@ void MMF::VideoPlayer::applyVideoWindowChange() TRAPD(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (1) err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } if(KErrNone == err) { @@ -615,13 +615,13 @@ void MMF::VideoPlayer::applyVideoWindowChange() if (KErrNone != err) { TRACE("SetDisplayWindowL err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } else { m_dsaActive = true; TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (2) err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } } } diff --git a/src/3rdparty/phonon/mmf/utils.cpp b/src/3rdparty/phonon/mmf/utils.cpp index d728fcf..75fec9f 100644 --- a/src/3rdparty/phonon/mmf/utils.cpp +++ b/src/3rdparty/phonon/mmf/utils.cpp @@ -18,6 +18,7 @@ along with this library. If not, see . #include "utils.h" #include +#include QT_BEGIN_NAMESPACE @@ -69,6 +70,103 @@ MMF::MediaType MMF::Utils::mimeTypeToMediaType(const TDesC& mimeType) return result; } +QString MMF::Utils::symbianErrorToString(int errorCode) +{ + /** + * Here we translate only the error codes which are likely to be + * meaningful to the user. For example, when an error occurs + * during opening of a media file, displaying "not found" or + * "permission denied" is informative. On the other hand, + * differentiating between KErrGeneral and KErrArgument at the UI + * level does not make sense. + */ + switch (errorCode) + { + // System-wide errors + case KErrNone: + return tr("no error"); + case KErrNotFound: + return tr("not found"); + case KErrNoMemory: + return tr("out of memory"); + case KErrNotSupported: + return tr("not supported"); + case KErrOverflow: + return tr("overflow"); + case KErrUnderflow: + return tr("underflow"); + case KErrAlreadyExists: + return tr("already exists"); + case KErrPathNotFound: + return tr("path not found"); + case KErrInUse: + return tr("in use"); + case KErrNotReady: + return tr("not ready"); + case KErrAccessDenied: + return tr("access denied"); + case KErrCouldNotConnect: + return tr("could not connect"); + case KErrDisconnected: + return tr("disconnected"); + case KErrPermissionDenied: + return tr("permission denied"); + + // Multimedia framework errors + case KErrMMNotEnoughBandwidth: + return tr("insufficient bandwidth"); + case KErrMMSocketServiceNotFound: + case KErrMMServerSocket: + return tr("network unavailable"); + case KErrMMNetworkRead: + case KErrMMNetworkWrite: + case KErrMMUDPReceive: + return tr("network communication error"); + case KErrMMServerNotSupported: + return tr("streaming not supported"); + case KErrMMServerAlert: + return tr("server alert"); + case KErrMMInvalidProtocol: + return tr("invalid protocol"); + case KErrMMInvalidURL: + return tr("invalid URL"); + case KErrMMMulticast: + return tr("multicast error"); + case KErrMMProxyServer: + case KErrMMProxyServerConnect: + return tr("proxy server error"); + case KErrMMProxyServerNotSupported: + return tr("proxy server not supported"); + case KErrMMAudioDevice: + return tr("audio output error"); + case KErrMMVideoDevice: + return tr("video output error"); + case KErrMMDecoder: + return tr("decoder error"); + case KErrMMPartialPlayback: + return tr("audio or video components could not be played"); + case KErrMMDRMNotAuthorized: + return tr("DRM error"); + + /* + // We don't use QoS settings + case KErrMMQosLowBandwidth: + case KErrMMQosUnsupportedTrafficClass: + case KErrMMQosPoorTrafficClass: + case KErrMMQosUnsupportedParameters: + case KErrMMQosPoorParameters: + case KErrMMQosNotSupported: + */ + + // Catch-all for errors other than those above + default: + { + QString errorString; + errorString.setNum(errorCode); + return tr("unknown error") + " (" + errorString + ")"; + } + } +} #ifndef QT_NO_DEBUG diff --git a/src/3rdparty/phonon/mmf/utils.h b/src/3rdparty/phonon/mmf/utils.h index 7e363e8..60c03a5 100644 --- a/src/3rdparty/phonon/mmf/utils.h +++ b/src/3rdparty/phonon/mmf/utils.h @@ -21,7 +21,7 @@ along with this library. If not, see . #include #include // for RDebug - +#include // for Q_DECLARE_TR_FUNCTIONS #include #include "defs.h" @@ -41,32 +41,40 @@ enum PanicCode { InvalidBackendInterfaceClass = 3 }; -namespace Utils +class Utils { + Q_DECLARE_TR_FUNCTIONS(Utils) + +public: /** * Raise a fatal exception */ -void panic(PanicCode code); +static void panic(PanicCode code); /** * Determines whether the provided MIME type is an audio or video * type. If it is neither, the function returns MediaTypeUnknown. */ -MediaType mimeTypeToMediaType(const TDesC& mimeType); +static MediaType mimeTypeToMediaType(const TDesC& mimeType); + +/** + * Translates a Symbian error code into a user-readable string. + */ +static QString symbianErrorToString(int errorCode); #ifndef QT_NO_DEBUG /** * Retrieve color of specified pixel from the screen. */ -QColor getScreenPixel(const QPoint& pos); +static QColor getScreenPixel(const QPoint& pos); /** * Samples a small number of pixels from the screen, and dumps their * colors to the debug log. */ -void dumpScreenPixelSample(); +static void dumpScreenPixelSample(); #endif -} +}; /** * Available trace categories; -- cgit v0.12 From dfa9343cc1e634eebdb0f3a2cf931ada9829ae6b Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 1 Dec 2009 14:35:43 +0000 Subject: Fixed bug which caused Phonon backend error messages to be suppressed When the mediaplayer receives a state change into the ErrorState, it calls pause() on the media object. Previously, this caused the backend to transition into PausedState. When the mediaplayer subsequently called errorString() to retrieve the error message, an empty string was returned because the backend was no longer in the ErrorState. Task-number: QTBUG-4994 Reviewed-by: trustme --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 11 ++++++----- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index bc38513..adade9c 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -104,21 +104,22 @@ void MMF::AbstractMediaPlayer::pause() TRACE_ENTRY("state %d", privateState()); m_playPending = false; + stopTickTimer(); switch (privateState()) { case GroundState: case LoadingState: case PausedState: + case StoppedState: // Do nothing break; - case StoppedState: case PlayingState: - case ErrorState: case BufferingState: - doPause(); - stopTickTimer(); changeState(PausedState); + // Fall through + case ErrorState: + doPause(); break; // Protection against adding new states and forgetting to update this switch @@ -135,6 +136,7 @@ void MMF::AbstractMediaPlayer::stop() TRACE_ENTRY("state %d", privateState()); m_playPending = false; + stopTickTimer(); switch (privateState()) { case GroundState: @@ -148,7 +150,6 @@ void MMF::AbstractMediaPlayer::stop() case BufferingState: case PausedState: doStop(); - stopTickTimer(); changeState(StoppedState); break; diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 4619f54..eb6f690 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -127,7 +127,7 @@ void MMF::VideoPlayer::doPause() TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi); TRAPD(err, m_player->PauseL()); - if (KErrNone != err) { + if (KErrNone != err && state() != ErrorState) { TRACE("PauseL error %d", err); setError(tr("Pause failed"), err); } -- cgit v0.12 From db782f7ab22241d8161190b95c41af4d56c05b82 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Mon, 7 Dec 2009 15:09:33 +0100 Subject: Symbian: More i18n strings work. * Consistently capitalize error sentences * Simplify & fix code/documentation. Task-number: QTBUG-4994 Reviewed-by: TrustMe --- src/3rdparty/phonon/mmf/abstractplayer.h | 4 +- src/3rdparty/phonon/mmf/utils.cpp | 64 ++++++++++++++++---------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 9af1362..cd15baf 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -96,7 +96,9 @@ public: * * Appends a human-readable version of symbianErrorCode to the error message, * e.g. - * setError(NormalError, "Opening file failed", KErrPermissionDenied) + * @code + * setError("Opening file failed", KErrPermissionDenied) + * @endcode * results in the following error message: * "Opening file failed: permission denied" */ diff --git a/src/3rdparty/phonon/mmf/utils.cpp b/src/3rdparty/phonon/mmf/utils.cpp index 75fec9f..2d17bd2 100644 --- a/src/3rdparty/phonon/mmf/utils.cpp +++ b/src/3rdparty/phonon/mmf/utils.cpp @@ -84,67 +84,67 @@ QString MMF::Utils::symbianErrorToString(int errorCode) { // System-wide errors case KErrNone: - return tr("no error"); + return tr("No error"); case KErrNotFound: - return tr("not found"); + return tr("Not found"); case KErrNoMemory: - return tr("out of memory"); + return tr("Out of memory"); case KErrNotSupported: - return tr("not supported"); + return tr("Not supported"); case KErrOverflow: - return tr("overflow"); + return tr("Overflow"); case KErrUnderflow: - return tr("underflow"); + return tr("Underflow"); case KErrAlreadyExists: - return tr("already exists"); + return tr("Already exists"); case KErrPathNotFound: - return tr("path not found"); + return tr("Path not found"); case KErrInUse: - return tr("in use"); + return tr("In use"); case KErrNotReady: - return tr("not ready"); + return tr("Not ready"); case KErrAccessDenied: - return tr("access denied"); + return tr("Access denied"); case KErrCouldNotConnect: - return tr("could not connect"); + return tr("Could not connect"); case KErrDisconnected: - return tr("disconnected"); + return tr("Disconnected"); case KErrPermissionDenied: - return tr("permission denied"); + return tr("Permission denied"); // Multimedia framework errors case KErrMMNotEnoughBandwidth: - return tr("insufficient bandwidth"); + return tr("Insufficient bandwidth"); case KErrMMSocketServiceNotFound: case KErrMMServerSocket: - return tr("network unavailable"); + return tr("Network unavailable"); case KErrMMNetworkRead: case KErrMMNetworkWrite: case KErrMMUDPReceive: - return tr("network communication error"); + return tr("Network communication error"); case KErrMMServerNotSupported: - return tr("streaming not supported"); + return tr("Streaming not supported"); case KErrMMServerAlert: - return tr("server alert"); + return tr("Server alert"); case KErrMMInvalidProtocol: - return tr("invalid protocol"); + return tr("Invalid protocol"); case KErrMMInvalidURL: - return tr("invalid URL"); + return tr("Invalid URL"); case KErrMMMulticast: - return tr("multicast error"); + return tr("Multicast error"); case KErrMMProxyServer: case KErrMMProxyServerConnect: - return tr("proxy server error"); + return tr("Proxy server error"); case KErrMMProxyServerNotSupported: - return tr("proxy server not supported"); + return tr("Proxy server not supported"); case KErrMMAudioDevice: - return tr("audio output error"); + return tr("Audio output error"); case KErrMMVideoDevice: - return tr("video output error"); + return tr("Video output error"); case KErrMMDecoder: - return tr("decoder error"); + return tr("Decoder error"); case KErrMMPartialPlayback: - return tr("audio or video components could not be played"); + return tr("Audio or video components could not be played"); case KErrMMDRMNotAuthorized: return tr("DRM error"); @@ -160,11 +160,9 @@ QString MMF::Utils::symbianErrorToString(int errorCode) // Catch-all for errors other than those above default: - { - QString errorString; - errorString.setNum(errorCode); - return tr("unknown error") + " (" + errorString + ")"; - } + { + return tr("Unknown error (%1)").arg(errorCode); + } } } -- cgit v0.12 From 99b10b64fd5f68c63e0c406558b507e429eea248 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 2 Dec 2009 16:59:46 +0000 Subject: Removed stale TODO comments from Phonon MMF backend Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/mediaobject.h | 1 - src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 2 -- src/3rdparty/phonon/mmf/objectdump.cpp | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index ee94ea2..d6f4c7b 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -98,7 +98,6 @@ Q_SIGNALS: void aboutToFinish(); // TODO: emit prefinishMarkReached from MediaObject void prefinishMarkReached(qint32); - // TODO: emit metaDataChanged from MediaObject void metaDataChanged(const QMultiMap& metaData); void currentSourceChanged(const MediaSource& source); void stateChanged(Phonon::State oldState, diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index eb6f690..66bbe38 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -277,7 +277,6 @@ void MMF::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError) TRACE_CONTEXT(VideoPlayer::MvpuoFrameReady, EVideoApi); TRACE_ENTRY("state %d error %d", state(), aError); - // TODO Q_UNUSED(aFrame); Q_UNUSED(aError); // suppress warnings in release builds @@ -300,7 +299,6 @@ void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi); TRACE_ENTRY("state %d", state()); - // TODO Q_UNUSED(aEvent); TRACE_EXIT_0(); diff --git a/src/3rdparty/phonon/mmf/objectdump.cpp b/src/3rdparty/phonon/mmf/objectdump.cpp index 3d10be4..778cde9 100644 --- a/src/3rdparty/phonon/mmf/objectdump.cpp +++ b/src/3rdparty/phonon/mmf/objectdump.cpp @@ -390,7 +390,7 @@ void QVisitorPrivate::dumpNode // No annotations - just dump the object pointer const bool isNodeLine = true; QByteArray buffer = branchBuffer(branches, isNodeLine, isLastChild); - qDebug() << 0; // TODO + qDebug() << 0; } else { // Dump annotations -- cgit v0.12 From bbab8eabb91b95dcd946c94b5f0ac59413e7a929 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 3 Dec 2009 15:44:55 +0000 Subject: Phonon MMF: leaves during object construction throw exceptions Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/audioplayer.cpp | 6 +++--- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 72d6684..2ce10db 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -50,9 +50,9 @@ void MMF::AudioPlayer::construct() TRACE_CONTEXT(AudioPlayer::AudioPlayer, EAudioApi); TRACE_ENTRY_0(); - TRAPD(err, m_player.reset(CPlayerType::NewL(*this, 0, EMdaPriorityPreferenceNone))); - if (KErrNone != err) - setError("Creation of audio player failed", err); + CPlayerType *player = 0; + QT_TRAP_THROWING(player = CPlayerType::NewL(*this, 0, EMdaPriorityPreferenceNone)); + m_player.reset(player); TRACE_EXIT_0(); } diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 66bbe38..0a1c78f 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -78,23 +78,21 @@ void MMF::VideoPlayer::construct() const TInt priority = 0; const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone; - TRAPD(err, - m_player.reset(CVideoPlayerUtility::NewL + CVideoPlayerUtility *player = 0; + QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL ( *this, priority, preference, m_wsSession, m_screenDevice, *m_window, m_videoRect, m_videoRect - )) + ) ); + m_player.reset(player); // CVideoPlayerUtility::NewL starts DSA m_dsaActive = true; - if (KErrNone != err) - setError("Creation of video player failed", err); - TRACE_EXIT_0(); } -- cgit v0.12 From 3117e3a6a9c1bf95fc30ebee4d8d11b646cb7125 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 5 Nov 2009 18:13:47 +0000 Subject: Added support for streaming playback to Phonon MMF backend Because the MIME type of the stream cannot always be deduced from the URL, we assume that it is a video stream. This is based on the assumption that the video controllers will be capable of parsing the container formats for audio-only, as well as video clips. Note that this assumption may not hold on all devices. Note that most implementations of the MMF client APIs do not support HTTP streaming (a.k.a. progressive download). The backend has therefore only been tested with RTSP streams - see the JIRA entry for further details. Task-number: QTBUG-4660 Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 8 ++++---- src/3rdparty/phonon/mmf/abstractmediaplayer.h | 1 + src/3rdparty/phonon/mmf/audioplayer.cpp | 11 +++++++++++ src/3rdparty/phonon/mmf/audioplayer.h | 1 + src/3rdparty/phonon/mmf/mediaobject.cpp | 5 ++++- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 6 ++++++ src/3rdparty/phonon/mmf/mmf_videoplayer.h | 1 + src/3rdparty/phonon/mmf/utils.h | 3 ++- 8 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index adade9c..260d8e6 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -243,12 +243,12 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f if (url.scheme() == QLatin1String("file")) { symbianErr = openFile(file); if (KErrNone != symbianErr) + errorMessage = tr("Error opening file"); + } else { + symbianErr = openUrl(url.toString()); + if (KErrNone != symbianErr) errorMessage = tr("Error opening URL"); } - else { - TRACE_0("Error opening URL: protocol not supported"); - errorMessage = tr("Error opening URL: protocol not supported"); - } break; } diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index cb6e437..0432b07 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -68,6 +68,7 @@ protected: virtual void doSeek(qint64 pos) = 0; virtual int setDeviceVolume(int mmfVolume) = 0; virtual int openFile(RFile& file) = 0; + virtual int openUrl(const QString& url) = 0; virtual void close() = 0; virtual void changeState(PrivateState newState); diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 2ce10db..2d618b8 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -124,6 +124,17 @@ int MMF::AudioPlayer::openFile(RFile& file) return err; } +int MMF::AudioPlayer::openUrl(const QString& /*url*/) +{ + // Streaming playback is generally not supported by the implementation + // of the audio player API, so we use CVideoPlayerUtility for both + // audio and video streaming. + Utils::panic(AudioUtilityUrlNotSupported); + + // Silence warning + return 0; +} + void MMF::AudioPlayer::close() { m_player->Close(); diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h index bc60076..4674afc 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.h +++ b/src/3rdparty/phonon/mmf/audioplayer.h @@ -63,6 +63,7 @@ public: virtual void doSeek(qint64 milliseconds); virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile& file); + virtual int openUrl(const QString& url); virtual void close(); // MediaObjectInterface diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index 6158ca1..ca3e837 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -253,7 +253,10 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) mediaType = fileMediaType(url.toLocalFile()); } else { - errorMessage = QLatin1String("Network streaming not supported yet"); + // Streaming playback is generally not supported by the implementation + // of the audio player API, so we use CVideoPlayerUtility for both + // audio and video streaming. + mediaType = MediaTypeVideo; } } break; diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 0a1c78f..62bbdef 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -172,6 +172,12 @@ int MMF::VideoPlayer::openFile(RFile& file) return err; } +int MMF::VideoPlayer::openUrl(const QString& url) +{ + TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url))); + return err; +} + void MMF::VideoPlayer::close() { m_player->Close(); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index abb1da8..7c42991 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -54,6 +54,7 @@ public: virtual void doSeek(qint64 milliseconds); virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile& file); + virtual int openUrl(const QString& url); virtual void close(); // MediaObjectInterface diff --git a/src/3rdparty/phonon/mmf/utils.h b/src/3rdparty/phonon/mmf/utils.h index 60c03a5..56ccafc 100644 --- a/src/3rdparty/phonon/mmf/utils.h +++ b/src/3rdparty/phonon/mmf/utils.h @@ -38,7 +38,8 @@ namespace MMF enum PanicCode { InvalidStatePanic = 1, InvalidMediaTypePanic = 2, - InvalidBackendInterfaceClass = 3 + InvalidBackendInterfaceClass = 3, + AudioUtilityUrlNotSupported = 4 }; class Utils -- cgit v0.12 From bed33ac62d87073120d56ff75a3d2356c99c64ea Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 1 Dec 2009 17:55:30 +0000 Subject: Implemented buffer status notifications in Phonon MMF backend When clips are buffering (either at the start of playback, or during playback, when buffer levels drop due to e.g. CPU, file system or network load), the backend receives notification from the MMF. While buffering is ongoing, the backend periodically queries the filling status and emits a signal. Task-number: QTBUG-4660 Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 80 +++++++++++++++++++------ src/3rdparty/phonon/mmf/abstractmediaplayer.h | 23 ++++--- src/3rdparty/phonon/mmf/abstractplayer.h | 1 + src/3rdparty/phonon/mmf/audioplayer.cpp | 25 +++++++- src/3rdparty/phonon/mmf/audioplayer.h | 34 +++++------ src/3rdparty/phonon/mmf/mediaobject.cpp | 1 + src/3rdparty/phonon/mmf/mediaobject.h | 1 - src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 27 ++++++++- src/3rdparty/phonon/mmf/mmf_videoplayer.h | 32 ++++++---- 9 files changed, 162 insertions(+), 62 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 260d8e6..6e7f458 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -36,6 +36,7 @@ using namespace Phonon::MMF; //----------------------------------------------------------------------------- const int NullMaxVolume = -1; +const int BufferStatusTimerInterval = 100; // ms //----------------------------------------------------------------------------- @@ -44,19 +45,23 @@ const int NullMaxVolume = -1; MMF::AbstractMediaPlayer::AbstractMediaPlayer() : m_playPending(false) - , m_tickTimer(new QTimer(this)) + , m_positionTimer(new QTimer(this)) + , m_bufferStatusTimer(new QTimer(this)) , m_mmfMaxVolume(NullMaxVolume) { - connect(m_tickTimer.data(), SIGNAL(timeout()), this, SLOT(tick())); + connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick())); + connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick())); } MMF::AbstractMediaPlayer::AbstractMediaPlayer(const AbstractPlayer& player) : AbstractPlayer(player) , m_playPending(false) - , m_tickTimer(new QTimer(this)) + , m_positionTimer(new QTimer(this)) + , m_bufferStatusTimer(new QTimer(this)) , m_mmfMaxVolume(NullMaxVolume) { - connect(m_tickTimer.data(), SIGNAL(timeout()), this, SLOT(tick())); + connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick())); + connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick())); } //----------------------------------------------------------------------------- @@ -80,7 +85,7 @@ void MMF::AbstractMediaPlayer::play() case StoppedState: case PausedState: doPlay(); - startTickTimer(); + startPositionTimer(); changeState(PlayingState); break; @@ -104,7 +109,7 @@ void MMF::AbstractMediaPlayer::pause() TRACE_ENTRY("state %d", privateState()); m_playPending = false; - stopTickTimer(); + stopTimers(); switch (privateState()) { case GroundState: @@ -136,7 +141,7 @@ void MMF::AbstractMediaPlayer::stop() TRACE_ENTRY("state %d", privateState()); m_playPending = false; - stopTickTimer(); + stopTimers(); switch (privateState()) { case GroundState: @@ -174,14 +179,13 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms) case PlayingState: case LoadingState: { - const bool tickTimerWasRunning = m_tickTimer->isActive(); - stopTickTimer(); + const bool positionTimerWasRunning = m_positionTimer->isActive(); + stopPositionTimer(); doSeek(ms); - if (tickTimerWasRunning) { - startTickTimer(); - } + if (positionTimerWasRunning) + startPositionTimer(); break; } case BufferingState: @@ -204,7 +208,7 @@ void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval) TRACE_CONTEXT(AbstractMediaPlayer::doSetTickInterval, EAudioApi); TRACE_ENTRY("state %d m_interval %d interval %d", privateState(), tickInterval(), interval); - m_tickTimer->setInterval(interval); + m_positionTimer->setInterval(interval); TRACE_EXIT_0(); } @@ -307,6 +311,35 @@ void MMF::AbstractMediaPlayer::volumeChanged(qreal volume) TRACE_EXIT_0(); } +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- + +void MMF::AbstractMediaPlayer::startPositionTimer() +{ + m_positionTimer->start(tickInterval()); +} + +void MMF::AbstractMediaPlayer::stopPositionTimer() +{ + m_positionTimer->stop(); +} + +void MMF::AbstractMediaPlayer::startBufferStatusTimer() +{ + m_bufferStatusTimer->start(BufferStatusTimerInterval); +} + +void MMF::AbstractMediaPlayer::stopBufferStatusTimer() +{ + m_bufferStatusTimer->stop(); +} + +void MMF::AbstractMediaPlayer::stopTimers() +{ + stopPositionTimer(); + stopBufferStatusTimer(); +} void MMF::AbstractMediaPlayer::doVolumeChanged() { @@ -342,14 +375,19 @@ void MMF::AbstractMediaPlayer::doVolumeChanged() // Protected functions //----------------------------------------------------------------------------- -void MMF::AbstractMediaPlayer::startTickTimer() +void MMF::AbstractMediaPlayer::bufferingStarted() { - m_tickTimer->start(tickInterval()); + m_stateBeforeBuffering = privateState(); + changeState(BufferingState); + bufferStatusTick(); + startBufferStatusTimer(); } -void MMF::AbstractMediaPlayer::stopTickTimer() +void MMF::AbstractMediaPlayer::bufferingComplete() { - m_tickTimer->stop(); + stopBufferStatusTimer(); + emit MMF::AbstractPlayer::bufferStatus(100); + changeState(m_stateBeforeBuffering); } void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume) @@ -367,12 +405,16 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds // Slots //----------------------------------------------------------------------------- -void MMF::AbstractMediaPlayer::tick() +void MMF::AbstractMediaPlayer::positionTick() { - // For the MWC compiler, we need to qualify the base class. emit MMF::AbstractPlayer::tick(currentTime()); } +void MMF::AbstractMediaPlayer::bufferStatusTick() +{ + emit MMF::AbstractPlayer::bufferStatus(bufferStatus()); +} + void MMF::AbstractMediaPlayer::changeState(PrivateState newState) { TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal); diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index 0432b07..7c11ec7 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -69,6 +69,7 @@ protected: virtual int setDeviceVolume(int mmfVolume) = 0; virtual int openFile(RFile& file) = 0; virtual int openUrl(const QString& url) = 0; + virtual int bufferStatus() const = 0; virtual void close() = 0; virtual void changeState(PrivateState newState); @@ -77,21 +78,22 @@ protected: virtual QPair metaDataEntry(int index) const = 0; protected: - bool tickTimerRunning() const; - void startTickTimer(); - void stopTickTimer(); + void bufferingStarted(); + void bufferingComplete(); void maxVolumeChanged(int maxVolume); - static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); private: + void startPositionTimer(); + void stopPositionTimer(); + void startBufferStatusTimer(); + void stopBufferStatusTimer(); + void stopTimers(); void doVolumeChanged(); private Q_SLOTS: - /** - * Receives signal from m_tickTimer - */ - void tick(); + void positionTick(); + void bufferStatusTick(); private: /** @@ -101,7 +103,10 @@ private: */ bool m_playPending; - QScopedPointer m_tickTimer; + QScopedPointer m_positionTimer; + + QScopedPointer m_bufferStatusTimer; + PrivateState m_stateBeforeBuffering; int m_mmfMaxVolume; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index cd15baf..5aaae3c 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -110,6 +110,7 @@ Q_SIGNALS: void totalTimeChanged(qint64 length); void finished(); void tick(qint64 time); + void bufferStatus(int percentFilled); void stateChanged(Phonon::State oldState, Phonon::State newState); void metaDataChanged(const QMultiMap& metaData); diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 2d618b8..0967a27 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -53,6 +53,7 @@ void MMF::AudioPlayer::construct() CPlayerType *player = 0; QT_TRAP_THROWING(player = CPlayerType::NewL(*this, 0, EMdaPriorityPreferenceNone)); m_player.reset(player); + m_player->RegisterForAudioLoadingNotification(*this); TRACE_EXIT_0(); } @@ -135,6 +136,13 @@ int MMF::AudioPlayer::openUrl(const QString& /*url*/) return 0; } +int MMF::AudioPlayer::bufferStatus() const +{ + int result = 0; + TRAP_IGNORE(m_player->GetAudioLoadingProgressL(result)); + return result; +} + void MMF::AudioPlayer::close() { m_player->Close(); @@ -211,8 +219,6 @@ void MMF::AudioPlayer::MapcPlayComplete(TInt aError) TRACE_CONTEXT(AudioPlayer::MapcPlayComplete, EAudioInternal); TRACE_ENTRY("state %d error %d", state(), aError); - stopTickTimer(); - if (KErrNone == aError) { changeState(StoppedState); // TODO: move on to m_nextSource @@ -260,6 +266,21 @@ void MMF::AudioPlayer::MaloLoadingComplete() //----------------------------------------------------------------------------- +// MAudioLoadingObserver callbacks +//----------------------------------------------------------------------------- + +void MMF::AudioPlayer::MaloLoadingStarted() +{ + bufferingStarted(); +} + +void MMF::AudioPlayer::MaloLoadingComplete() +{ + bufferingComplete(); +} + + +//----------------------------------------------------------------------------- // Private functions //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h index 4674afc..5c7cfc1 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.h +++ b/src/3rdparty/phonon/mmf/audioplayer.h @@ -45,9 +45,7 @@ namespace MMF */ class AudioPlayer : public AbstractMediaPlayer , public MPlayerObserverType // typedef -#ifdef QT_PHONON_MMF_AUDIO_DRM , public MAudioLoadingObserver -#endif { Q_OBJECT @@ -64,6 +62,7 @@ public: virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile& file); virtual int openUrl(const QString& url); + virtual int bufferStatus() const; virtual void close(); // MediaObjectInterface @@ -71,15 +70,24 @@ public: virtual qint64 currentTime() const; virtual qint64 totalTime() const; + // AbstractMediaPlayer + virtual int numberOfMetaDataEntries() const; + virtual QPair metaDataEntry(int index) const; + + /** + * This class owns the pointer. + */ + CPlayerType *player() const; + +private: + void construct(); + +private: #ifdef QT_PHONON_MMF_AUDIO_DRM // MDrmAudioPlayerCallback virtual void MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds &aDuration); virtual void MdapcPlayComplete(TInt aError); - - // MAudioLoadingObserver - virtual void MaloLoadingStarted(); - virtual void MaloLoadingComplete(); #else // MMdaAudioPlayerCallback virtual void MapcInitComplete(TInt aError, @@ -87,17 +95,9 @@ public: virtual void MapcPlayComplete(TInt aError); #endif - /** - * This class owns the pointer. - */ - CPlayerType *player() const; - -private: - void construct(); - - // AbstractMediaPlayer - virtual int numberOfMetaDataEntries() const; - virtual QPair metaDataEntry(int index) const; + // MAudioLoadingObserver + virtual void MaloLoadingStarted(); + virtual void MaloLoadingComplete(); private: /** diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index ca3e837..bf1f268 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -321,6 +321,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) connect(m_player.data(), SIGNAL(stateChanged(Phonon::State,Phonon::State)), SIGNAL(stateChanged(Phonon::State,Phonon::State))); connect(m_player.data(), SIGNAL(finished()), SIGNAL(finished())); connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64))); + connect(m_player.data(), SIGNAL(bufferStatus(int)), SIGNAL(bufferStatus(int))); connect(m_player.data(), SIGNAL(metaDataChanged(QMultiMap)), SIGNAL(metaDataChanged(QMultiMap))); // We need to call setError() after doing the connects, otherwise the diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index d6f4c7b..07baad0 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -92,7 +92,6 @@ Q_SIGNALS: void totalTimeChanged(qint64 length); void hasVideoChanged(bool hasVideo); void seekableChanged(bool seekable); - // TODO: emit bufferStatus from MediaObject void bufferStatus(int); // TODO: emit aboutToFinish from MediaObject void aboutToFinish(); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 62bbdef..4a70d58 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -93,6 +93,8 @@ void MMF::VideoPlayer::construct() // CVideoPlayerUtility::NewL starts DSA m_dsaActive = true; + m_player->RegisterForVideoLoadingNotification(*this); + TRACE_EXIT_0(); } @@ -178,6 +180,13 @@ int MMF::VideoPlayer::openUrl(const QString& url) return err; } +int MMF::VideoPlayer::bufferStatus() const +{ + int result = 0; + TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result)); + return result; +} + void MMF::VideoPlayer::close() { m_player->Close(); @@ -292,7 +301,8 @@ void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError) TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi) TRACE_ENTRY("state %d error %d", state(), aError); - Q_UNUSED(aError); // suppress warnings in release builds + // TODO: handle aError + Q_UNUSED(aError); changeState(StoppedState); TRACE_EXIT_0(); @@ -310,6 +320,21 @@ void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) //----------------------------------------------------------------------------- +// MVideoLoadingObserver callbacks +//----------------------------------------------------------------------------- + +void MMF::VideoPlayer::MvloLoadingStarted() +{ + bufferingStarted(); +} + +void MMF::VideoPlayer::MvloLoadingComplete() +{ + bufferingComplete(); +} + + +//----------------------------------------------------------------------------- // Video window updates //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index 7c42991..3ece19c 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -39,6 +39,7 @@ namespace MMF */ class VideoPlayer : public AbstractMediaPlayer , public MVideoPlayerUtilityObserver + , public MVideoLoadingObserver { Q_OBJECT @@ -55,6 +56,7 @@ public: virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile& file); virtual int openUrl(const QString& url); + virtual int bufferStatus() const; virtual void close(); // MediaObjectInterface @@ -62,12 +64,12 @@ public: virtual qint64 currentTime() const; virtual qint64 totalTime() const; - // MVideoPlayerUtilityObserver - virtual void MvpuoOpenComplete(TInt aError); - virtual void MvpuoPrepareComplete(TInt aError); - virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError); - virtual void MvpuoPlayComplete(TInt aError); - virtual void MvpuoEvent(const TMMFEvent &aEvent); + // AbstractPlayer + virtual void videoOutputChanged(); + + // AbstractMediaPlayer + virtual int numberOfMetaDataEntries() const; + virtual QPair metaDataEntry(int index) const; public Q_SLOTS: void videoWindowChanged(); @@ -81,12 +83,8 @@ private: void doPrepareCompleteL(TInt aError); - // AbstractPlayer - virtual void videoOutputChanged(); - void getVideoWindow(); void initVideoOutput(); - void updateVideoRect(); void applyPendingChanges(); @@ -95,9 +93,17 @@ private: void startDirectScreenAccess(); bool stopDirectScreenAccess(); - // AbstractMediaPlayer - virtual int numberOfMetaDataEntries() const; - virtual QPair metaDataEntry(int index) const; +private: + // MVideoPlayerUtilityObserver + virtual void MvpuoOpenComplete(TInt aError); + virtual void MvpuoPrepareComplete(TInt aError); + virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError); + virtual void MvpuoPlayComplete(TInt aError); + virtual void MvpuoEvent(const TMMFEvent &aEvent); + + // MVideoLoadingObserver + virtual void MvloLoadingStarted(); + virtual void MvloLoadingComplete(); private: QScopedPointer m_player; -- cgit v0.12 From 66b765734585971dd9d248059701fdecebbccd78 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 1 Dec 2009 18:51:45 +0000 Subject: Changed call sequence of seeking in Phonon MMF backend, for streaming Modified the sequence of calls made to the MMF APIs when seeking during ongoing playback. This fixes a bug found during early testing of streaming playback, whereby playback would not resume following the seeking operation. This was due to an interaction between the pause / seek / play operations, and the buffering callbacks received from the MMF, which caused the backend to enter an incorrect state. Task-number: QTBUG-4660 Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 14 ++++++++++---- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 16 +--------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 6e7f458..83c534a 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -179,13 +179,20 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms) case PlayingState: case LoadingState: { - const bool positionTimerWasRunning = m_positionTimer->isActive(); - stopPositionTimer(); + bool wasPlaying = false; + if (state() == PlayingState) { + stopPositionTimer(); + doPause(); + wasPlaying = true; + } doSeek(ms); - if (positionTimerWasRunning) + if(wasPlaying && state() != ErrorState) { + doPlay(); startPositionTimer(); + } + break; } case BufferingState: @@ -370,7 +377,6 @@ void MMF::AbstractMediaPlayer::doVolumeChanged() } } - //----------------------------------------------------------------------------- // Protected functions //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 4a70d58..dab7505 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -142,24 +142,10 @@ void MMF::VideoPlayer::doSeek(qint64 ms) { TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi); - bool wasPlaying = false; - if (state() == PlayingState) { - // The call to SetPositionL does not have any effect if playback is - // ongoing, so we pause before seeking. - doPause(); - wasPlaying = true; - } - TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000))); - if (KErrNone == err) { - if (wasPlaying) - doPlay(); - } - else { - TRACE("SetPositionL error %d", err); + if(KErrNone != err) setError(tr("Seek failed"), err); - } } int MMF::VideoPlayer::setDeviceVolume(int mmfVolume) -- cgit v0.12 From 946dede337f0a43ccb394c10aa2045bc9ef59301 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 2 Dec 2009 16:11:29 +0000 Subject: Mediaplayer: enqueue all entries from .ram file before starting playback This ensures that Phonon::MediaObject::setNextSource is called before the first clip finishes playback, and therefore that the next clip is played once the first finishes. Reviewed-by: Frans Englich --- demos/qmediaplayer/mediaplayer.cpp | 16 +++++++++++----- demos/qmediaplayer/mediaplayer.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index 8f6848f..8471ebd 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -673,6 +673,13 @@ void MediaPlayer::setFile(const QString &fileName) m_MediaObject.play(); } +void MediaPlayer::setLocation(const QString& location) +{ + setWindowTitle(location.right(location.length() - location.lastIndexOf('/') - 1)); + m_MediaObject.setCurrentSource(Phonon::MediaSource(QUrl::fromEncoded(location.toUtf8()))); + m_MediaObject.play(); +} + bool MediaPlayer::playPauseForDialog() { // If we're running on a small screen, we want to pause the video when @@ -850,9 +857,7 @@ void MediaPlayer::openUrl() bool ok = false; sourceURL = QInputDialog::getText(this, tr("Open Location"), tr("Please enter a valid address here:"), QLineEdit::Normal, sourceURL, &ok); if (ok && !sourceURL.isEmpty()) { - setWindowTitle(sourceURL.right(sourceURL.length() - sourceURL.lastIndexOf('/') - 1)); - m_MediaObject.setCurrentSource(Phonon::MediaSource(QUrl::fromEncoded(sourceURL.toUtf8()))); - m_MediaObject.play(); + setLocation(sourceURL); settings.setValue("location", sourceURL); } } @@ -892,10 +897,11 @@ void MediaPlayer::openRamFile() } if (!list.isEmpty()) { - m_MediaObject.setCurrentSource(Phonon::MediaSource(list[0])); - m_MediaObject.play(); + m_MediaObject.clearQueue(); + setLocation(list[0].toString()); for (int i = 1; i < list.count(); i++) m_MediaObject.enqueue(Phonon::MediaSource(list[i])); + m_MediaObject.play(); } forwardButton->setEnabled(!m_MediaObject.queue().isEmpty()); diff --git a/demos/qmediaplayer/mediaplayer.h b/demos/qmediaplayer/mediaplayer.h index 14ed4ac..fc1bd90 100644 --- a/demos/qmediaplayer/mediaplayer.h +++ b/demos/qmediaplayer/mediaplayer.h @@ -112,6 +112,7 @@ public: void dropEvent(QDropEvent *e); void handleDrop(QDropEvent *e); void setFile(const QString &text); + void setLocation(const QString &location); void initVideoWindow(); void initSettingsDialog(); -- cgit v0.12 From 89e1e7fcbcbe93d8096afe0f7c240fe706cc9069 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 2 Dec 2009 16:20:00 +0000 Subject: Implemented support for playlist handling in Phonon MMF backend The main changes are: 1. MediaObject emits prefinishMark at the appropriate instant 2. MediaObject emits aboutToFinish at the appropriate instant 3. MediaObject switches to next source when playback completes Task-number: QTBUG-6214 Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 84 ++++++++++++++----------- src/3rdparty/phonon/mmf/abstractmediaplayer.h | 17 ++--- src/3rdparty/phonon/mmf/abstractplayer.cpp | 22 +++---- src/3rdparty/phonon/mmf/abstractplayer.h | 13 ++-- src/3rdparty/phonon/mmf/audioplayer.cpp | 41 +++--------- src/3rdparty/phonon/mmf/audioplayer.h | 5 +- src/3rdparty/phonon/mmf/dummyplayer.cpp | 19 +----- src/3rdparty/phonon/mmf/dummyplayer.h | 8 +-- src/3rdparty/phonon/mmf/mediaobject.cpp | 54 +++++++++------- src/3rdparty/phonon/mmf/mediaobject.h | 11 +++- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 22 ++----- src/3rdparty/phonon/mmf/mmf_videoplayer.h | 3 +- 12 files changed, 129 insertions(+), 170 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 83c534a..18f96cc 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -20,6 +20,7 @@ along with this library. If not, see . #include "abstractmediaplayer.h" #include "defs.h" +#include "mediaobject.h" #include "utils.h" QT_BEGIN_NAMESPACE @@ -43,22 +44,16 @@ const int BufferStatusTimerInterval = 100; // ms // Constructor / destructor //----------------------------------------------------------------------------- -MMF::AbstractMediaPlayer::AbstractMediaPlayer() : - m_playPending(false) - , m_positionTimer(new QTimer(this)) - , m_bufferStatusTimer(new QTimer(this)) - , m_mmfMaxVolume(NullMaxVolume) -{ - connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick())); - connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick())); -} - -MMF::AbstractMediaPlayer::AbstractMediaPlayer(const AbstractPlayer& player) : - AbstractPlayer(player) +MMF::AbstractMediaPlayer::AbstractMediaPlayer + (MediaObject *parent, const AbstractPlayer *player) + : AbstractPlayer(player) + , m_parent(parent) , m_playPending(false) , m_positionTimer(new QTimer(this)) , m_bufferStatusTimer(new QTimer(this)) , m_mmfMaxVolume(NullMaxVolume) + , m_prefinishMarkSent(false) + , m_aboutToFinishSent(false) { connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick())); connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick())); @@ -220,12 +215,7 @@ void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval) TRACE_EXIT_0(); } -MediaSource MMF::AbstractMediaPlayer::source() const -{ - return m_source; -} - -void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& file) +void MMF::AbstractMediaPlayer::open(const MediaSource &source, RFile& file) { TRACE_CONTEXT(AbstractMediaPlayer::setFileSource, EAudioApi); TRACE_ENTRY("state %d source.type %d", privateState(), source.type()); @@ -233,14 +223,10 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f close(); changeState(GroundState); - // TODO: is it correct to assign even if the media type is not supported in - // the switch statement below? - m_source = source; - TInt symbianErr = KErrNone; QString errorMessage; - switch (m_source.type()) { + switch (source.type()) { case MediaSource::LocalFile: { symbianErr = openFile(file); if (KErrNone != symbianErr) @@ -293,20 +279,6 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f TRACE_EXIT_0(); } -void MMF::AbstractMediaPlayer::setNextSource(const MediaSource &source) -{ - TRACE_CONTEXT(AbstractMediaPlayer::setNextSource, EAudioApi); - TRACE_ENTRY("state %d", privateState()); - - // TODO: handle 'next source' - - m_nextSource = source; - Q_UNUSED(source); - - TRACE_EXIT_0(); -} - - void MMF::AbstractMediaPlayer::volumeChanged(qreal volume) { TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal); @@ -402,6 +374,23 @@ void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume) doVolumeChanged(); } +void MMF::AbstractMediaPlayer::playbackComplete(int error) +{ + stopTimers(); + + if (KErrNone == error) { + changeState(StoppedState); + + // MediaObject::switchToNextSource deletes the current player, so we + // call it via delayed slot invokation to ensure that this object does + // not get deleted during execution of a member function. + QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection); + } + else { + setError(tr("Playback complete"), error); + } +} + qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in) { return in.Int64() / 1000; @@ -413,7 +402,26 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds void MMF::AbstractMediaPlayer::positionTick() { - emit MMF::AbstractPlayer::tick(currentTime()); + const qint64 current = currentTime(); + const qint64 total = totalTime(); + const qint64 remaining = total - current; + + if (prefinishMark() && !m_prefinishMarkSent) { + if (remaining < (prefinishMark() + tickInterval()/2)) { + m_prefinishMarkSent = true; + emit prefinishMarkReached(remaining); + } + } + + if (!m_aboutToFinishSent) { + if (remaining < tickInterval()) { + m_aboutToFinishSent = true; + emit aboutToFinish(); + } + } + + // For the MWC compiler, we need to qualify the base class. + emit MMF::AbstractPlayer::tick(current); } void MMF::AbstractMediaPlayer::bufferStatusTick() diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index 7c11ec7..24fa228 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -33,6 +33,7 @@ namespace Phonon namespace MMF { class AudioOutput; +class MediaObject; /** * Interface via which MMF client APIs for both audio and video can be @@ -43,19 +44,17 @@ class AbstractMediaPlayer : public AbstractPlayer Q_OBJECT protected: - AbstractMediaPlayer(); - explicit AbstractMediaPlayer(const AbstractPlayer& player); + AbstractMediaPlayer(MediaObject *parent, const AbstractPlayer *player); public: + virtual void open(const Phonon::MediaSource&, RFile&); + // MediaObjectInterface virtual void play(); virtual void pause(); virtual void stop(); virtual void seek(qint64 milliseconds); virtual bool isSeekable() const; - virtual MediaSource source() const; - virtual void setFileSource(const Phonon::MediaSource&, RFile&); - virtual void setNextSource(const MediaSource &source); virtual void volumeChanged(qreal volume); protected: @@ -81,6 +80,8 @@ protected: void bufferingStarted(); void bufferingComplete(); void maxVolumeChanged(int maxVolume); + void playbackComplete(int error); + static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); private: @@ -96,6 +97,8 @@ private Q_SLOTS: void bufferStatusTick(); private: + MediaObject *const m_parent; + /** * This flag is set to true if play is called when the object is * in a Loading state. Once loading is complete, playback will @@ -110,8 +113,8 @@ private: int m_mmfMaxVolume; - MediaSource m_source; - MediaSource m_nextSource; + bool m_prefinishMarkSent; + bool m_aboutToFinishSent; QMultiMap m_metaData; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index 13ff5fb..53973eb 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -33,7 +33,7 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::AbstractPlayer::AbstractPlayer() +MMF::AbstractPlayer::AbstractPlayer(const AbstractPlayer *player) : m_videoOutput(0) , m_volume(InitialVolume) , m_state(GroundState) @@ -42,19 +42,13 @@ MMF::AbstractPlayer::AbstractPlayer() , m_transitionTime(0) , m_prefinishMark(0) { - -} - -MMF::AbstractPlayer::AbstractPlayer(const AbstractPlayer& player) - : m_videoOutput(player.m_videoOutput) - , m_volume(player.m_volume) - , m_state(GroundState) - , m_error(NoError) - , m_tickInterval(player.tickInterval()) - , m_transitionTime(player.transitionTime()) - , m_prefinishMark(player.prefinishMark()) -{ - + if(player) { + m_videoOutput = player->m_videoOutput; + m_volume = player->m_volume; + m_tickInterval = player->m_tickInterval; + m_transitionTime = player->m_transitionTime; + m_prefinishMark = player->m_prefinishMark; + } } //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 5aaae3c..40ad7f8 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -53,8 +53,9 @@ class AbstractPlayer : public QObject Q_OBJECT public: - AbstractPlayer(); - explicit AbstractPlayer(const AbstractPlayer& player); + AbstractPlayer(const AbstractPlayer *player); + + virtual void open(const Phonon::MediaSource&, RFile&) = 0; // MediaObjectInterface (implemented) qint32 tickInterval() const; @@ -75,12 +76,6 @@ public: virtual Phonon::ErrorType errorType() const; virtual QString errorString() const; virtual qint64 totalTime() const = 0; - virtual Phonon::MediaSource source() const = 0; - // This is a temporary hack to work around KErrInUse from MMF - // client utility OpenFileL calls - //virtual void setSource(const Phonon::MediaSource &) = 0; - virtual void setFileSource(const Phonon::MediaSource&, RFile&) = 0; - virtual void setNextSource(const Phonon::MediaSource &) = 0; virtual void volumeChanged(qreal volume); @@ -114,6 +109,8 @@ Q_SIGNALS: void stateChanged(Phonon::State oldState, Phonon::State newState); void metaDataChanged(const QMultiMap& metaData); + void aboutToFinish(); + void prefinishMarkReached(qint32 remaining); protected: /** diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 0967a27..77488f4 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -34,13 +34,9 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::AudioPlayer::AudioPlayer() -{ - construct(); -} - -MMF::AudioPlayer::AudioPlayer(const AbstractPlayer& player) - : AbstractMediaPlayer(player) +MMF::AudioPlayer::AudioPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractMediaPlayer(parent, player) + , m_totalTime(0) { construct(); } @@ -177,7 +173,7 @@ qint64 MMF::AudioPlayer::currentTime() const qint64 MMF::AudioPlayer::totalTime() const { - return toMilliSeconds(m_player->Duration()); + return m_totalTime; } @@ -200,7 +196,8 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError, if (KErrNone == aError) { maxVolumeChanged(m_player->MaxVolume()); - emit totalTimeChanged(totalTime()); + m_totalTime = toMilliSeconds(m_player->Duration()); + emit totalTimeChanged(m_totalTime); updateMetaData(); changeState(StoppedState); } else { @@ -219,29 +216,9 @@ void MMF::AudioPlayer::MapcPlayComplete(TInt aError) TRACE_CONTEXT(AudioPlayer::MapcPlayComplete, EAudioInternal); TRACE_ENTRY("state %d error %d", state(), aError); - if (KErrNone == aError) { - changeState(StoppedState); - // TODO: move on to m_nextSource - } else { - setError(tr("Playback complete"), aError); - } - - /* - if (aError == KErrNone) { - if (m_nextSource.type() == MediaSource::Empty) { - emit finished(); - } else { - setSource(m_nextSource); - m_nextSource = MediaSource(); - } - - changeState(StoppedState); - } - else { - m_error = NormalError; - changeState(ErrorState); - } - */ + // Call base class function which handles end of playback for both + // audio and video clips. + playbackComplete(aError); TRACE_EXIT_0(); } diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h index 5c7cfc1..4c4bcd0 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.h +++ b/src/3rdparty/phonon/mmf/audioplayer.h @@ -50,8 +50,7 @@ class AudioPlayer : public AbstractMediaPlayer Q_OBJECT public: - AudioPlayer(); - explicit AudioPlayer(const AbstractPlayer& player); + AudioPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); virtual ~AudioPlayer(); // AbstractMediaPlayer @@ -105,6 +104,8 @@ private: * CMdaAudioPlayerUtility and CDrmPlayerUtility */ QScopedPointer m_player; + + qint64 m_totalTime; }; } } diff --git a/src/3rdparty/phonon/mmf/dummyplayer.cpp b/src/3rdparty/phonon/mmf/dummyplayer.cpp index e6f3855..6970088 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.cpp +++ b/src/3rdparty/phonon/mmf/dummyplayer.cpp @@ -31,12 +31,7 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::DummyPlayer::DummyPlayer() -{ - -} - -MMF::DummyPlayer::DummyPlayer(const AbstractPlayer& player) +MMF::DummyPlayer::DummyPlayer(const AbstractPlayer *player) : AbstractPlayer(player) { @@ -97,17 +92,7 @@ qint64 MMF::DummyPlayer::totalTime() const return 0; } -MediaSource MMF::DummyPlayer::source() const -{ - return MediaSource(); -} - -void MMF::DummyPlayer::setFileSource(const Phonon::MediaSource &, RFile &) -{ - -} - -void MMF::DummyPlayer::setNextSource(const MediaSource &) +void MMF::DummyPlayer::open(const Phonon::MediaSource &, RFile &) { } diff --git a/src/3rdparty/phonon/mmf/dummyplayer.h b/src/3rdparty/phonon/mmf/dummyplayer.h index c6270c9..6841b5d 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.h +++ b/src/3rdparty/phonon/mmf/dummyplayer.h @@ -42,8 +42,7 @@ class AudioOutput; class DummyPlayer : public AbstractPlayer { public: - DummyPlayer(); - DummyPlayer(const AbstractPlayer& player); + DummyPlayer(const AbstractPlayer *player = 0); // MediaObjectInterface virtual void play(); @@ -56,12 +55,9 @@ public: virtual Phonon::State state() const; virtual Phonon::ErrorType errorType() const; virtual qint64 totalTime() const; - virtual MediaSource source() const; - // virtual void setSource(const MediaSource &); - virtual void setFileSource(const Phonon::MediaSource&, RFile&); - virtual void setNextSource(const MediaSource &source); // AbstractPlayer + virtual void open(const Phonon::MediaSource&, RFile&); virtual void doSetTickInterval(qint32 interval); }; } diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index bf1f268..a9a012f 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -45,6 +45,7 @@ using namespace Phonon::MMF; MMF::MediaObject::MediaObject(QObject *parent) : MMF::MediaNode::MediaNode(parent) , m_recognizerOpened(false) + , m_nextSourceSet(false) { m_player.reset(new DummyPlayer()); @@ -211,18 +212,20 @@ qint64 MMF::MediaObject::totalTime() const MediaSource MMF::MediaObject::source() const { - return m_player->source(); + return m_source; } void MMF::MediaObject::setSource(const MediaSource &source) { - createPlayer(source); - - // This is a hack to work around KErrInUse from MMF client utility - // OpenFileL calls - m_player->setFileSource(source, m_file); + switchToSource(source); +} - emit currentSourceChanged(source); +void MMF::MediaObject::switchToSource(const MediaSource &source) +{ + createPlayer(source); + m_source = source; + m_player->open(m_source, m_file); + emit currentSourceChanged(m_source); } void MMF::MediaObject::createPlayer(const MediaSource &source) @@ -281,29 +284,16 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) switch (mediaType) { case MediaTypeUnknown: TRACE_0("Media type could not be determined"); - if (oldPlayer) { - newPlayer = new DummyPlayer(*oldPlayer); - } else { - newPlayer = new DummyPlayer(); - } - + newPlayer = new DummyPlayer(oldPlayer); errorMessage = tr("Error opening source: media type could not be determined"); break; case MediaTypeAudio: - if (oldPlayer) { - newPlayer = new AudioPlayer(*oldPlayer); - } else { - newPlayer = new AudioPlayer(); - } + newPlayer = new AudioPlayer(this, oldPlayer); break; case MediaTypeVideo: - if (oldPlayer) { - newPlayer = new VideoPlayer(*oldPlayer); - } else { - newPlayer = new VideoPlayer(); - } + newPlayer = new VideoPlayer(this, oldPlayer); break; } @@ -323,6 +313,8 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64))); connect(m_player.data(), SIGNAL(bufferStatus(int)), SIGNAL(bufferStatus(int))); connect(m_player.data(), SIGNAL(metaDataChanged(QMultiMap)), SIGNAL(metaDataChanged(QMultiMap))); + connect(m_player.data(), SIGNAL(aboutToFinish()), SIGNAL(aboutToFinish())); + connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SIGNAL(tick(qint32))); // We need to call setError() after doing the connects, otherwise the // error won't be received. @@ -336,7 +328,8 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) void MMF::MediaObject::setNextSource(const MediaSource &source) { - m_player->setNextSource(source); + m_nextSource = source; + m_nextSourceSet = true; } qint32 MMF::MediaObject::prefinishMark() const @@ -385,5 +378,18 @@ bool MMF::MediaObject::activateOnMediaObject(MediaObject *) return true; } +//----------------------------------------------------------------------------- +// Playlist support +//----------------------------------------------------------------------------- + +void MMF::MediaObject::switchToNextSource() +{ + if (m_nextSourceSet) { + m_nextSourceSet = false; + switchToSource(m_nextSource); + play(); + } +} + QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index 07baad0..7c39598 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -87,16 +87,16 @@ public: public Q_SLOTS: void volumeChanged(qreal volume); + void switchToNextSource(); Q_SIGNALS: void totalTimeChanged(qint64 length); void hasVideoChanged(bool hasVideo); void seekableChanged(bool seekable); void bufferStatus(int); - // TODO: emit aboutToFinish from MediaObject void aboutToFinish(); - // TODO: emit prefinishMarkReached from MediaObject - void prefinishMarkReached(qint32); + void prefinishMarkReached(qint32 remaining); + // TODO: emit metaDataChanged from MediaObject void metaDataChanged(const QMultiMap& metaData); void currentSourceChanged(const MediaSource& source); void stateChanged(Phonon::State oldState, @@ -105,6 +105,7 @@ Q_SIGNALS: void tick(qint64 time); private: + void switchToSource(const MediaSource &source); void createPlayer(const MediaSource &source); bool openRecognizer(); @@ -121,6 +122,10 @@ private: RApaLsSession m_recognizer; RFs m_fileServer; + MediaSource m_source; + MediaSource m_nextSource; + bool m_nextSourceSet; + // Storing the file handle here to work around KErrInUse error // from MMF player utility OpenFileL functions RFile m_file; diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index dab7505..877dfb3 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -44,20 +44,8 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::VideoPlayer::VideoPlayer() - : m_wsSession(CCoeEnv::Static()->WsSession()) - , m_screenDevice(*CCoeEnv::Static()->ScreenDevice()) - , m_window(0) - , m_totalTime(0) - , m_pendingChanges(false) - , m_dsaActive(false) - , m_dsaWasActive(false) -{ - construct(); -} - -MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player) - : AbstractMediaPlayer(player) +MMF::VideoPlayer::VideoPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractMediaPlayer(parent, player) , m_wsSession(CCoeEnv::Static()->WsSession()) , m_screenDevice(*CCoeEnv::Static()->ScreenDevice()) , m_window(0) @@ -287,9 +275,9 @@ void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError) TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi) TRACE_ENTRY("state %d error %d", state(), aError); - // TODO: handle aError - Q_UNUSED(aError); - changeState(StoppedState); + // Call base class function which handles end of playback for both + // audio and video clips. + playbackComplete(aError); TRACE_EXIT_0(); } diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index 3ece19c..6200e39 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -44,8 +44,7 @@ class VideoPlayer : public AbstractMediaPlayer Q_OBJECT public: - VideoPlayer(); - explicit VideoPlayer(const AbstractPlayer& player); + VideoPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); virtual ~VideoPlayer(); // AbstractPlayer -- cgit v0.12 From fe5b275bfab1605da3ee95b6eb1d976aecb0a8a8 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 8 Dec 2009 10:31:26 +0000 Subject: Re-emit prefinishMarkReached and aboutToFinish if rewound back past mark. Task-number: QTBUG-6214 Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 25 +++++++++++++++++++++++-- src/3rdparty/phonon/mmf/abstractmediaplayer.h | 2 ++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 18f96cc..344413d 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -182,6 +182,7 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms) } doSeek(ms); + resetMarksIfRewound(); if(wasPlaying && state() != ErrorState) { doPlay(); @@ -402,6 +403,14 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds void MMF::AbstractMediaPlayer::positionTick() { + emitMarksIfReached(); + + const qint64 current = currentTime(); + emit MMF::AbstractPlayer::tick(current); +} + +void MMF::AbstractMediaPlayer::emitMarksIfReached() +{ const qint64 current = currentTime(); const qint64 total = totalTime(); const qint64 remaining = total - current; @@ -419,9 +428,21 @@ void MMF::AbstractMediaPlayer::positionTick() emit aboutToFinish(); } } +} - // For the MWC compiler, we need to qualify the base class. - emit MMF::AbstractPlayer::tick(current); +void MMF::AbstractMediaPlayer::resetMarksIfRewound() +{ + const qint64 current = currentTime(); + const qint64 total = totalTime(); + const qint64 remaining = total - current; + + if (prefinishMark() && m_prefinishMarkSent) + if (remaining >= (prefinishMark() + tickInterval()/2)) + m_prefinishMarkSent = false; + + if (m_aboutToFinishSent) + if (remaining >= tickInterval()) + m_aboutToFinishSent = false; } void MMF::AbstractMediaPlayer::bufferStatusTick() diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index 24fa228..abd6bff 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -91,6 +91,8 @@ private: void stopBufferStatusTimer(); void stopTimers(); void doVolumeChanged(); + void emitMarksIfReached(); + void resetMarksIfRewound(); private Q_SLOTS: void positionTick(); -- cgit v0.12 From 8e21fc62fe40c8e393007516958c216ad8dbd629 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 2 Dec 2009 17:03:48 +0000 Subject: Removed dead code from Phonon MMF backend The following source types are handled in MediaObject::createPlayer Invalid, Disc, Stream, Empty The code removed in this patch is therefore never executed. Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 344413d..544762a 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -251,19 +251,9 @@ void MMF::AbstractMediaPlayer::open(const MediaSource &source, RFile& file) break; } - case MediaSource::Invalid: - case MediaSource::Disc: - case MediaSource::Stream: - TRACE_0("Error opening source: type not supported"); - errorMessage = tr("Error opening source: type not supported"); - break; - - case MediaSource::Empty: - TRACE_0("Empty source - doing nothing"); - TRACE_EXIT_0(); - return; + // Other source types are handled in MediaObject::createPlayer - // Protection against adding new media types and forgetting to update this switch + // Protection against adding new media types and forgetting to update this switch default: TRACE_PANIC(InvalidMediaTypePanic); } -- cgit v0.12 From 3f648dc075689e2ffedda2769cc76b4a56fb1073 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Fri, 4 Dec 2009 11:49:12 +0000 Subject: Implemented node disconnection in Phonon MMF backend Task-number: QTBUG-4663 Reviewed-by: Frans Englich --- src/3rdparty/phonon/mmf/abstractaudioeffect.cpp | 58 ++++++--- src/3rdparty/phonon/mmf/abstractaudioeffect.h | 27 +++-- src/3rdparty/phonon/mmf/audioequalizer.cpp | 38 +++++- src/3rdparty/phonon/mmf/audioequalizer.h | 13 +- src/3rdparty/phonon/mmf/audiooutput.cpp | 13 +- src/3rdparty/phonon/mmf/audiooutput.h | 4 +- src/3rdparty/phonon/mmf/audioplayer.cpp | 15 ++- src/3rdparty/phonon/mmf/audioplayer.h | 21 ++-- src/3rdparty/phonon/mmf/backend.cpp | 29 +++-- src/3rdparty/phonon/mmf/bassboost.cpp | 22 +++- src/3rdparty/phonon/mmf/bassboost.h | 12 +- src/3rdparty/phonon/mmf/effectfactory.cpp | 2 +- src/3rdparty/phonon/mmf/mediaobject.cpp | 25 +++- src/3rdparty/phonon/mmf/mediaobject.h | 6 +- src/3rdparty/phonon/mmf/mmf_medianode.cpp | 153 ++++++++++++++---------- src/3rdparty/phonon/mmf/mmf_medianode.h | 76 ++++++------ src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 5 + src/3rdparty/phonon/mmf/mmf_videoplayer.h | 5 +- src/3rdparty/phonon/mmf/videowidget.cpp | 14 ++- src/3rdparty/phonon/mmf/videowidget.h | 4 +- 20 files changed, 348 insertions(+), 194 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index a559249..8c73027 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -19,6 +19,8 @@ along with this library. If not, see . #include "mediaobject.h" #include "abstractaudioeffect.h" +#include "audioplayer.h" +#include "mmf_videoplayer.h" QT_BEGIN_NAMESPACE @@ -34,18 +36,13 @@ using namespace Phonon::MMF; */ AbstractAudioEffect::AbstractAudioEffect(QObject *parent, - const QList ¶ms) : MediaNode::MediaNode(parent) - , m_params(params) + const QList ¶ms) + : MediaNode::MediaNode(parent) + , m_player(0) + , m_params(params) { } -bool AbstractAudioEffect::disconnectMediaNode(MediaNode *target) -{ - MediaNode::disconnectMediaNode(target); - m_effect.reset(); - return true; -} - QList AbstractAudioEffect::parameters() const { return m_params; @@ -61,21 +58,44 @@ QVariant AbstractAudioEffect::parameterValue(const EffectParameter &queriedParam return val; } -bool AbstractAudioEffect::activateOnMediaObject(MediaObject *mo) -{ - AudioPlayer *const ap = qobject_cast(mo->abstractPlayer()); - - if (ap) - return activateOn(ap->player()); - else - return true; -} - void AbstractAudioEffect::setParameterValue(const EffectParameter ¶m, const QVariant &newValue) { m_values.insert(param.id(), newValue); parameterChanged(param.id(), newValue); + // TODO: handle audio effect errors + TRAP_IGNORE(m_effect->ApplyL()); +} + +void AbstractAudioEffect::connectMediaObject(MediaObject *mediaObject) +{ + Q_ASSERT_X(!m_player, Q_FUNC_INFO, "Player already connected"); + Q_ASSERT_X(!m_effect.data(), Q_FUNC_INFO, "Effect already created"); + + AbstractMediaPlayer *const player = + qobject_cast(mediaObject->abstractPlayer()); + + if (player) { + m_player = player; + + if (AudioPlayer *audioPlayer = qobject_cast(player)) { + connectAudioPlayer(audioPlayer->nativePlayer()); + } else { + VideoPlayer *videoPlayer = qobject_cast(player); + Q_ASSERT_X(videoPlayer, Q_FUNC_INFO, "Player type not recognised"); + connectVideoPlayer(videoPlayer->nativePlayer()); + } + + applyParameters(); + // TODO: handle audio effect errors + TRAP_IGNORE(m_effect->EnableL()); + } +} + +void AbstractAudioEffect::disconnectMediaObject(MediaObject * /*mediaObject*/) +{ + m_player = 0; + m_effect.reset(); } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 01542c9..10578af 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -19,15 +19,16 @@ along with this library. If not, see . #ifndef PHONON_MMF_ABSTRACTEFFECT_H #define PHONON_MMF_ABSTRACTEFFECT_H -#include "mmf_medianode.h" - #include #include #include #include + #include "audioplayer.h" +#include "mmf_medianode.h" +#include "mmf_videoplayer.h" QT_BEGIN_NAMESPACE @@ -35,6 +36,7 @@ namespace Phonon { namespace MMF { +class AbstractMediaPlayer; /** * @short Base class for all effects for MMF. @@ -66,8 +68,6 @@ public: virtual void setParameterValue(const EffectParameter &, const QVariant &newValue); - virtual bool disconnectMediaNode(MediaNode *target); - enum Type { EffectAudioEqualizer = 1, @@ -81,21 +81,26 @@ public: }; protected: - virtual bool activateOn(CPlayerType *player) = 0; + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); + + virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player) = 0; + virtual void connectVideoPlayer(VideoPlayer::NativePlayer *player) = 0; + virtual void applyParameters() = 0; + virtual void parameterChanged(const int id, const QVariant &value) = 0; - /** - * Part of the implementation of AbstractAudioEffect. Forwards the call to - * activateOn(), essentially. - */ - virtual bool activateOnMediaObject(MediaObject *mo); - +protected: QScopedPointer m_effect; + private: + AbstractMediaPlayer * m_player; const QList m_params; QHash m_values; }; + } } diff --git a/src/3rdparty/phonon/mmf/audioequalizer.cpp b/src/3rdparty/phonon/mmf/audioequalizer.cpp index 7cc9bc7..51f1c32 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.cpp +++ b/src/3rdparty/phonon/mmf/audioequalizer.cpp @@ -16,6 +16,7 @@ along with this library. If not, see . */ +#include #include "audioequalizer.h" QT_BEGIN_NAMESPACE @@ -34,18 +35,43 @@ AudioEqualizer::AudioEqualizer(QObject *parent) : AbstractAudioEffect::AbstractA void AudioEqualizer::parameterChanged(const int pid, const QVariant &value) { - // There is no way to return an error from this function, so we just - // have to trap and ignore exceptions. - TRAP_IGNORE(static_cast(m_effect.data())->SetBandLevelL(pid, value.toInt())); + if (m_effect.data()) { + const int band = pid; + const int level = value.toInt(); + setBandLevel(band, level); + } } -bool AudioEqualizer::activateOn(CPlayerType *player) +void AudioEqualizer::connectAudioPlayer(AudioPlayer::NativePlayer *player) { CAudioEqualizer *ptr = 0; QT_TRAP_THROWING(ptr = CAudioEqualizer::NewL(*player)); m_effect.reset(ptr); +} - return true; +void AudioEqualizer::connectVideoPlayer(VideoPlayer::NativePlayer *player) +{ + CAudioEqualizer *ptr = 0; + QT_TRAP_THROWING(ptr = CAudioEqualizer::NewL(*player)); + m_effect.reset(ptr); +} + +void AudioEqualizer::applyParameters() +{ + Q_ASSERT_X(m_effect.data(), Q_FUNC_INFO, "Effect not created"); + EffectParameter param; + foreach (param, parameters()) { + const int band = param.id(); + const int level = parameterValue(param).toInt(); + setBandLevel(band, level); + } +} + +void AudioEqualizer::setBandLevel(int band, int level) +{ + CAudioEqualizer *const effect = static_cast(m_effect.data()); + // TODO: handle audio effect errors + TRAP_IGNORE(effect->SetBandLevelL(band, level)); } QList AudioEqualizer::createParams() @@ -57,7 +83,7 @@ QList AudioEqualizer::createParams() AudioPlayer dummyPlayer; CAudioEqualizer *eqPtr = 0; - QT_TRAP_THROWING(eqPtr = CAudioEqualizer::NewL(*dummyPlayer.player());) + QT_TRAP_THROWING(eqPtr = CAudioEqualizer::NewL(*dummyPlayer.nativePlayer())); QScopedPointer e(eqPtr); TInt32 dbMin; diff --git a/src/3rdparty/phonon/mmf/audioequalizer.h b/src/3rdparty/phonon/mmf/audioequalizer.h index d4c8165..9910ea4 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.h +++ b/src/3rdparty/phonon/mmf/audioequalizer.h @@ -19,7 +19,6 @@ along with this library. If not, see . #ifndef PHONON_MMF_AUDIOEQUALIZER_H #define PHONON_MMF_AUDIOEQUALIZER_H -#include #include "abstractaudioeffect.h" QT_BEGIN_NAMESPACE @@ -43,14 +42,18 @@ public: AudioEqualizer(QObject *parent); protected: - virtual void parameterChanged(const int id, - const QVariant &value); + // AbstractAudioEffect + virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player); + virtual void connectVideoPlayer(VideoPlayer::NativePlayer *player); + virtual void applyParameters(); + virtual void parameterChanged(const int id, const QVariant &value); - virtual bool activateOn(CPlayerType *player); +private: + void setBandLevel(int band, int level); private: static QList createParams(); - QScopedPointer m_bassBoost; + }; } } diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index d6e0c13..c6be20b 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -81,13 +81,18 @@ bool MMF::AudioOutput::setOutputDevice(int index) return true; } -bool MMF::AudioOutput::activateOnMediaObject(MediaObject *mo) +void MMF::AudioOutput::connectMediaObject(MediaObject *mediaObject) { // Ensure that the MediaObject has the correct initial volume - mo->volumeChanged(m_volume); + mediaObject->volumeChanged(m_volume); // Connect MediaObject to receive future volume changes - connect(this, SIGNAL(volumeChanged(qreal)), mo, SLOT(volumeChanged(qreal))); - return true; + connect(this, SIGNAL(volumeChanged(qreal)), mediaObject, SLOT(volumeChanged(qreal))); +} + +void MMF::AudioOutput::disconnectMediaObject(MediaObject *mediaObject) +{ + // Disconnect all signal-slot connections + disconnect(this, 0, mediaObject, 0); } QHash MMF::AudioOutput::audioOutputDescription(int index) diff --git a/src/3rdparty/phonon/mmf/audiooutput.h b/src/3rdparty/phonon/mmf/audiooutput.h index 1e1e134..67aaa38 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.h +++ b/src/3rdparty/phonon/mmf/audiooutput.h @@ -74,7 +74,9 @@ public: }; protected: - virtual bool activateOnMediaObject(MediaObject *mo); + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); Q_SIGNALS: void volumeChanged(qreal volume); diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 77488f4..ee07229 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -46,8 +46,8 @@ void MMF::AudioPlayer::construct() TRACE_CONTEXT(AudioPlayer::AudioPlayer, EAudioApi); TRACE_ENTRY_0(); - CPlayerType *player = 0; - QT_TRAP_THROWING(player = CPlayerType::NewL(*this, 0, EMdaPriorityPreferenceNone)); + NativePlayer *player = 0; + QT_TRAP_THROWING(player = NativePlayer::NewL(*this, 0, EMdaPriorityPreferenceNone)); m_player.reset(player); m_player->RegisterForAudioLoadingNotification(*this); @@ -62,6 +62,11 @@ MMF::AudioPlayer::~AudioPlayer() TRACE_EXIT_0(); } +MMF::AudioPlayer::NativePlayer *MMF::AudioPlayer::nativePlayer() const +{ + return m_player.data(); +} + //----------------------------------------------------------------------------- // Public API //----------------------------------------------------------------------------- @@ -223,12 +228,6 @@ void MMF::AudioPlayer::MapcPlayComplete(TInt aError) TRACE_EXIT_0(); } -CPlayerType *MMF::AudioPlayer::player() const -{ - return m_player.data(); -} - - #ifdef QT_PHONON_MMF_AUDIO_DRM void MMF::AudioPlayer::MaloLoadingStarted() { diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h index 4c4bcd0..0eb8bb7 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.h +++ b/src/3rdparty/phonon/mmf/audioplayer.h @@ -26,12 +26,10 @@ class TTimeIntervalMicroSeconds; #ifdef QT_PHONON_MMF_AUDIO_DRM #include -typedef CDrmPlayerUtility CPlayerType; -typedef MDrmAudioPlayerCallback MPlayerObserverType; +typedef MDrmAudioPlayerCallback NativePlayerObserver; #else #include -typedef CMdaAudioPlayerUtility CPlayerType; -typedef MMdaAudioPlayerCallback MPlayerObserverType; +typedef MMdaAudioPlayerCallback NativePlayerObserver; #endif QT_BEGIN_NAMESPACE @@ -44,7 +42,7 @@ namespace MMF * @short Wrapper over MMF audio client utility */ class AudioPlayer : public AbstractMediaPlayer - , public MPlayerObserverType // typedef + , public NativePlayerObserver , public MAudioLoadingObserver { Q_OBJECT @@ -53,6 +51,14 @@ public: AudioPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); virtual ~AudioPlayer(); +#ifdef QT_PHONON_MMF_AUDIO_DRM +typedef CDrmPlayerUtility NativePlayer; +#else +typedef CMdaAudioPlayerUtility NativePlayer; +#endif + + NativePlayer *nativePlayer() const; + // AbstractMediaPlayer virtual void doPlay(); virtual void doPause(); @@ -76,7 +82,7 @@ public: /** * This class owns the pointer. */ - CPlayerType *player() const; + NativePlayer *player() const; private: void construct(); @@ -103,9 +109,10 @@ private: * Using CPlayerType typedef in order to be able to easily switch between * CMdaAudioPlayerUtility and CDrmPlayerUtility */ - QScopedPointer m_player; + QScopedPointer m_player; qint64 m_totalTime; + }; } } diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index 7e3a67f..0c07f66 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -139,29 +139,32 @@ bool Backend::startConnectionChange(QSet) return true; } -bool Backend::connectNodes(QObject *source, QObject *target) +bool Backend::connectNodes(QObject *sourceObject, QObject *targetObject) { TRACE_CONTEXT(Backend::connectNodes, EBackend); - TRACE_ENTRY("source 0x%08x target 0x%08x", source, target); - Q_ASSERT(qobject_cast(source)); - Q_ASSERT(qobject_cast(target)); + TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject); - MediaNode *const mediaSource = static_cast(source); - MediaNode *const mediaTarget = static_cast(target); + MediaNode *const source = qobject_cast(sourceObject); + MediaNode *const target = qobject_cast(targetObject); - return mediaSource->connectMediaNode(mediaTarget); + Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode"); + Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode"); + + return source->connectOutput(target); } -bool Backend::disconnectNodes(QObject *source, QObject *target) +bool Backend::disconnectNodes(QObject *sourceObject, QObject *targetObject) { TRACE_CONTEXT(Backend::disconnectNodes, EBackend); - TRACE_ENTRY("source 0x%08x target 0x%08x", source, target); - Q_ASSERT(qobject_cast(source)); - Q_ASSERT(qobject_cast(target)); + TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject); + + MediaNode *const source = qobject_cast(sourceObject); + MediaNode *const target = qobject_cast(targetObject); - const bool result = static_cast(source)->disconnectMediaNode(static_cast(target)); + Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode"); + Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode"); - TRACE_RETURN("%d", result); + return source->disconnectOutput(target); } bool Backend::endConnectionChange(QSet) diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp index e34f9e7..36069fb 100644 --- a/src/3rdparty/phonon/mmf/bassboost.cpp +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -16,6 +16,7 @@ along with this library. If not, see . */ +#include #include "bassboost.h" QT_BEGIN_NAMESPACE @@ -35,13 +36,26 @@ BassBoost::BassBoost(QObject *parent) : AbstractAudioEffect::AbstractAudioEffect void BassBoost::parameterChanged(const int, const QVariant &) { - // We should never be called, because we have no parameters. + Q_ASSERT_X(false, Q_FUNC_INFO, "BassBoost has not parameters"); } -bool BassBoost::activateOn(CPlayerType *player) +void BassBoost::connectAudioPlayer(AudioPlayer::NativePlayer *player) { - m_effect.reset(CBassBoost::NewL(*player, true)); - return true; + CBassBoost *ptr = 0; + QT_TRAP_THROWING(ptr = CBassBoost::NewL(*player)); + m_effect.reset(ptr); +} + +void BassBoost::connectVideoPlayer(VideoPlayer::NativePlayer *player) +{ + CBassBoost *ptr = 0; + QT_TRAP_THROWING(ptr = CBassBoost::NewL(*player)); + m_effect.reset(ptr); +} + +void BassBoost::applyParameters() +{ + // No parameters to apply } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/bassboost.h b/src/3rdparty/phonon/mmf/bassboost.h index c16393a..1b893db 100644 --- a/src/3rdparty/phonon/mmf/bassboost.h +++ b/src/3rdparty/phonon/mmf/bassboost.h @@ -19,7 +19,6 @@ along with this library. If not, see . #ifndef PHONON_MMF_BASSBOOST_H #define PHONON_MMF_BASSBOOST_H -#include #include "abstractaudioeffect.h" QT_BEGIN_NAMESPACE @@ -41,13 +40,12 @@ public: BassBoost(QObject *parent); protected: - virtual void parameterChanged(const int id, - const QVariant &value); + // AbstractAudioEffect + virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player); + virtual void connectVideoPlayer(VideoPlayer::NativePlayer *player); + virtual void applyParameters(); + virtual void parameterChanged(const int id, const QVariant &value); - virtual bool activateOn(CPlayerType *player); - -private: - QScopedPointer m_bassBoost; }; } } diff --git a/src/3rdparty/phonon/mmf/effectfactory.cpp b/src/3rdparty/phonon/mmf/effectfactory.cpp index e9c5e27..cc94367 100644 --- a/src/3rdparty/phonon/mmf/effectfactory.cpp +++ b/src/3rdparty/phonon/mmf/effectfactory.cpp @@ -113,7 +113,7 @@ bool isEffectSupported() AudioPlayer audioPlayer; QScopedPointer eff; - TRAPD(errorCode, eff.reset(TEffect::NewL(*audioPlayer.player()))); + TRAPD(errorCode, eff.reset(TEffect::NewL(*audioPlayer.nativePlayer()))); return errorCode != KErrNone; } diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index a9a012f..4653fee 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -358,6 +358,25 @@ void MMF::MediaObject::volumeChanged(qreal volume) } //----------------------------------------------------------------------------- +// MediaNode +//----------------------------------------------------------------------------- + +void MMF::MediaObject::connectMediaObject(MediaObject * /*mediaObject*/) +{ + // This function should never be called - see MediaNode::setMediaObject() + Q_ASSERT_X(false, Q_FUNC_INFO, + "Connection of MediaObject to MediaObject"); +} + +void MMF::MediaObject::disconnectMediaObject(MediaObject * /*mediaObject*/) +{ + // This function should never be called - see MediaNode::setMediaObject() + Q_ASSERT_X(false, Q_FUNC_INFO, + "Disconnection of MediaObject from MediaObject"); +} + + +//----------------------------------------------------------------------------- // Video output //----------------------------------------------------------------------------- @@ -372,12 +391,6 @@ AbstractPlayer *MMF::MediaObject::abstractPlayer() const return m_player.data(); } -bool MMF::MediaObject::activateOnMediaObject(MediaObject *) -{ - // Guess what, we do nothing. - return true; -} - //----------------------------------------------------------------------------- // Playlist support //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index 7c39598..668b953 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -75,6 +75,10 @@ public: virtual qint32 transitionTime() const; virtual void setTransitionTime(qint32); + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); + /** * This class owns the AbstractPlayer, and will delete it upon * destruction. @@ -83,8 +87,6 @@ public: void setVideoOutput(VideoOutput* videoOutput); - virtual bool activateOnMediaObject(MediaObject *); - public Q_SLOTS: void volumeChanged(qreal volume); void switchToNextSource(); diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.cpp b/src/3rdparty/phonon/mmf/mmf_medianode.cpp index 253c5e7..ca413d9 100644 --- a/src/3rdparty/phonon/mmf/mmf_medianode.cpp +++ b/src/3rdparty/phonon/mmf/mmf_medianode.cpp @@ -29,92 +29,123 @@ using namespace Phonon::MMF; \internal */ -MMF::MediaNode::MediaNode(QObject *parent) : QObject::QObject(parent) - , m_source(0) - , m_target(0) - , m_isApplied(false) +MMF::MediaNode::MediaNode(QObject *parent) + : QObject(parent) + , m_mediaObject(qobject_cast(this)) + , m_input(0) { -} - -bool MMF::MediaNode::connectMediaNode(MediaNode *target) -{ - m_target = target; - m_target->setSource(this); - return applyNodesOnMediaObject(target); } -bool MMF::MediaNode::disconnectMediaNode(MediaNode *target) +MMF::MediaNode::~MediaNode() { - Q_UNUSED(target); - m_target = 0; - m_isApplied = false; - return true; + // Phonon framework ensures nodes are disconnected before being destroyed. + Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO, + "Media node not disconnected before destruction"); } -void MMF::MediaNode::setSource(MediaNode *source) +bool MMF::MediaNode::connectOutput(MediaNode *output) { - m_source = source; + Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer"); + + bool connected = false; + + // Check that this connection will not result in a graph which + // containing more than one MediaObject + const bool mediaObjectMisMatch = + m_mediaObject + && output->m_mediaObject + && m_mediaObject != output->m_mediaObject; + + const bool canConnect = + !output->isMediaObject() + && !output->m_input + && !m_outputs.contains(output); + + if (canConnect && !mediaObjectMisMatch) { + output->m_input = this; + m_outputs += output; + updateMediaObject(); + connected = true; + } + + return connected; } -MMF::MediaNode *MMF::MediaNode::source() const +bool MMF::MediaNode::disconnectOutput(MediaNode *output) { - return m_source; + Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer"); + + bool disconnected = false; + + if (m_outputs.contains(output) && this == output->m_input) { + output->m_input = 0; + const bool removed = m_outputs.removeOne(output); + Q_ASSERT_X(removed, Q_FUNC_INFO, "Output removal failed"); + + Q_ASSERT_X(!m_outputs.contains(output), Q_FUNC_INFO, + "Output list contains duplicate entries"); + + // Perform traversal across each of the two graphs separately + updateMediaObject(); + output->updateMediaObject(); + + disconnected = true; + } + + return disconnected; } -MMF::MediaNode *MMF::MediaNode::target() const +bool MMF::MediaNode::isMediaObject() const { - return m_target; + return (qobject_cast(this) != 0); } -bool MMF::MediaNode::applyNodesOnMediaObject(MediaNode *) +void MMF::MediaNode::updateMediaObject() { - // Algorithmically, this can be expressed in a more efficient way by - // exercising available assumptions, but it complicates code for input - // data(length of the graph) which typically is very small. - - // First, we go to the very beginning of the graph. - MMF::MediaNode *current = this; - do { - MediaNode *const candidate = current->source(); - if (candidate) - current = candidate; - else - break; - } - while (current); - - // Now we do two things, while walking to the other end: - // 1. Find the MediaObject, if present - // 2. Collect a list of all unapplied MediaNodes - - QList unapplied; - MMF::MediaObject *mo = 0; + QList nodes; + MediaObject *mediaObject = 0; - do { - if (!current->m_isApplied) - unapplied.append(current); + // Traverse the graph, collecting a list of nodes, and locating + // the MediaObject node, if present + visit(nodes, mediaObject); - if (!mo) - mo = qobject_cast(current); + MediaNode *node = 0; + foreach(node, nodes) + node->setMediaObject(mediaObject); +} - current = current->target(); +void MMF::MediaNode::setMediaObject(MediaObject *mediaObject) +{ + if(!isMediaObject() && m_mediaObject != mediaObject) { + if (!mediaObject) + disconnectMediaObject(m_mediaObject); + else { + Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO, "MediaObject already set"); + connectMediaObject(mediaObject); + } + m_mediaObject = mediaObject; } - while (current); +} - // Now, lets activate all the objects, if we found the MediaObject. +void MMF::MediaNode::visit(QList& visited, MediaObject*& mediaObject) +{ + if (isMediaObject()) { + // There can never be more than one MediaObject per graph, due to the + // mediaObjectMisMatch test in connectOutput(). + Q_ASSERT_X(!mediaObject, Q_FUNC_INFO, "MediaObject already found"); + mediaObject = static_cast(this); + } - if (mo) { - for (int i = 0; i < unapplied.count(); ++i) { - MediaNode *const at = unapplied.at(i); + visited += this; - // We don't want to apply MediaObject on itself. - if (at != mo) - at->activateOnMediaObject(mo); - } - } + if (m_input && !visited.contains(m_input)) + m_input->visit(visited, mediaObject); - return true; + MediaNode *output = 0; + foreach (output, m_outputs) + if (!visited.contains(output)) + output->visit(visited, mediaObject); } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.h b/src/3rdparty/phonon/mmf/mmf_medianode.h index 4616ff1..0ed21c4 100644 --- a/src/3rdparty/phonon/mmf/mmf_medianode.h +++ b/src/3rdparty/phonon/mmf/mmf_medianode.h @@ -43,54 +43,62 @@ class MediaObject; /** * @short Base class for all nodes in the MMF backend. * - * MediaNode is the base class for all nodes in the chain for MMF. Currently - * they are: + * MediaNode is the base class for all nodes created by the MMF + * backend. * - * - MediaObject: a source of media - * - AbstractEffect: supplying audio effects - * - AudioOutput: pretty much a dummy interface, but is also MediaNode in order - * to simplify connection/disconnection. + * These nodes may be one of the following types: * - * MediaNode provides spectatability into the chain, and also allows the - * connection code to be written in a polymorphic manner, instead of putting it - * all in the Backend class. Due to that MMF has no concept of chaining, the - * order of the nodes in the graph has no meaning. + * - MediaObject + * This represents the source of media data. It encapsulates the + * appropriate MMF client API for playing audio or video. + * - AudioOutput + * This represents the audio output device. Since the MMF client API + * does not expose the output device directly, this backend node + * simply forwards volume control commands to the MediaObject. + * - VideoWidget + * A native widget on which video will be rendered. + * - An audio effect, derived form AbstractAudioEffect + * + * Because the MMF API does not support the concept of a media filter graph, + * this class must ensure the following: + * + * - Each media graph contains at most one MediaObject instance. + * - Every non-MediaObject node holds a reference to the MediaObject. This + * allows commands to be sent through the graph to the encapsulated MMF client + * API. */ class MediaNode : public QObject { Q_OBJECT public: MediaNode(QObject *parent); + ~MediaNode(); + + bool connectOutput(MediaNode *output); + bool disconnectOutput(MediaNode *output); + + virtual void connectMediaObject(MediaObject *mediaObject) = 0; + virtual void disconnectMediaObject(MediaObject *mediaObject) = 0; - virtual bool connectMediaNode(MediaNode *target); - virtual bool disconnectMediaNode(MediaNode *target); - void setSource(MediaNode *source); +private: + bool isMediaObject() const; - MediaNode *source() const; - MediaNode *target() const; + void updateMediaObject(); + void setMediaObject(MediaObject *mediaObject); -protected: - /** - * When connectMediaNode() is called and a MediaObject is part of - * the its graph, this function will be called for each MediaNode in the - * graph for which it hasn't been called yet. - * - * The caller guarantees that @p mo is always non-null. - */ - virtual bool activateOnMediaObject(MediaObject *mo) = 0; + typedef QList NodeList; + void visit(QList& visited, MediaObject*& mediaObject); private: - /** - * Finds a MediaObject anywhere in the graph @p target is apart of, and - * calls activateOnMediaObject() for all MediaNodes in the graph for which - * it hasn't been applied to already. - */ - bool applyNodesOnMediaObject(MediaNode *target); - - MediaNode * m_source; - MediaNode * m_target; - bool m_isApplied; + MediaObject * m_mediaObject; + + // All nodes except MediaObject may have an input + MediaNode * m_input; + + // Only MediaObject can have more than one output + QList m_outputs; }; + } } diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 877dfb3..127edb4 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -97,6 +97,11 @@ MMF::VideoPlayer::~VideoPlayer() TRACE_EXIT_0(); } +CVideoPlayerUtility* MMF::VideoPlayer::nativePlayer() const +{ + return m_player.data(); +} + //----------------------------------------------------------------------------- // Public API //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index 6200e39..0253ab9 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -47,6 +47,9 @@ public: VideoPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); virtual ~VideoPlayer(); + typedef CVideoPlayerUtility NativePlayer; + NativePlayer *nativePlayer() const; + // AbstractPlayer virtual void doPlay(); virtual void doPause(); @@ -105,7 +108,7 @@ private: virtual void MvloLoadingComplete(); private: - QScopedPointer m_player; + QScopedPointer m_player; // Not owned RWsSession& m_wsSession; diff --git a/src/3rdparty/phonon/mmf/videowidget.cpp b/src/3rdparty/phonon/mmf/videowidget.cpp index bd22307..bc9acfd 100644 --- a/src/3rdparty/phonon/mmf/videowidget.cpp +++ b/src/3rdparty/phonon/mmf/videowidget.cpp @@ -157,10 +157,18 @@ QWidget* MMF::VideoWidget::widget() return m_videoOutput.data(); } -bool MMF::VideoWidget::activateOnMediaObject(MediaObject *mo) +//----------------------------------------------------------------------------- +// MediaNode +//----------------------------------------------------------------------------- + +void MMF::VideoWidget::connectMediaObject(MediaObject *mediaObject) +{ + mediaObject->setVideoOutput(m_videoOutput.data()); +} + +void MMF::VideoWidget::disconnectMediaObject(MediaObject *mediaObject) { - mo->setVideoOutput(m_videoOutput.data()); - return true; + mediaObject->setVideoOutput(0); } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h index 2f0978b..a876748 100644 --- a/src/3rdparty/phonon/mmf/videowidget.h +++ b/src/3rdparty/phonon/mmf/videowidget.h @@ -61,7 +61,9 @@ public: virtual QWidget *widget(); protected: - virtual bool activateOnMediaObject(MediaObject *mo); + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); private: QScopedPointer m_videoOutput; -- cgit v0.12 From f124538ef4840c3d24b4c7e9e7221adb52bdee2c Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Wed, 6 Jan 2010 10:16:02 +1000 Subject: Added setChannelCount() to QAudioFormat. Added setChannelCount() and updated docs/examples/tests to use it instead of setChannels(). Reviewed-by:Justin McPherson --- doc/src/snippets/audio/main.cpp | 2 +- examples/multimedia/audiodevices/audiodevices.cpp | 4 ++-- examples/multimedia/audioinput/audioinput.cpp | 2 +- examples/multimedia/audiooutput/audiooutput.cpp | 2 +- src/multimedia/audio/qaudio_mac.cpp | 2 +- src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 6 +++--- src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp | 2 +- src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp | 4 ++-- src/multimedia/audio/qaudioformat.cpp | 9 +++++++++ src/multimedia/audio/qaudioformat.h | 1 + src/multimedia/audio/qaudioinput.cpp | 2 +- src/multimedia/audio/qaudiooutput.cpp | 2 +- tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp | 2 +- tests/auto/qaudioformat/tst_qaudioformat.cpp | 10 +++++----- tests/auto/qaudioinput/tst_qaudioinput.cpp | 2 +- tests/auto/qaudiooutput/tst_qaudiooutput.cpp | 2 +- 16 files changed, 32 insertions(+), 22 deletions(-) diff --git a/doc/src/snippets/audio/main.cpp b/doc/src/snippets/audio/main.cpp index 0910865..1e6242d 100644 --- a/doc/src/snippets/audio/main.cpp +++ b/doc/src/snippets/audio/main.cpp @@ -91,7 +91,7 @@ private: QAudioFormat format; format.setFrequency(44100); //![1] - format.setChannels(2); + format.setChannelCount(2); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/examples/multimedia/audiodevices/audiodevices.cpp b/examples/multimedia/audiodevices/audiodevices.cpp index e205e03..4f4a95f 100644 --- a/examples/multimedia/audiodevices/audiodevices.cpp +++ b/examples/multimedia/audiodevices/audiodevices.cpp @@ -172,7 +172,7 @@ void AudioTest::deviceChanged(int idx) for(int i = 0; i < chz.size(); ++i) channelsBox->addItem(QString("%1").arg(chz.at(i))); if(chz.size()) - settings.setChannels(chz.at(0)); + settings.setChannelCount(chz.at(0)); codecsBox->clear(); QStringList codecz = deviceInfo.supportedCodecs(); @@ -234,7 +234,7 @@ void AudioTest::freqChanged(int idx) void AudioTest::channelChanged(int idx) { - settings.setChannels(channelsBox->itemText(idx).toInt()); + settings.setChannelCount(channelsBox->itemText(idx).toInt()); } void AudioTest::codecChanged(int idx) diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp index 75bddd6..e6ebe95 100644 --- a/examples/multimedia/audioinput/audioinput.cpp +++ b/examples/multimedia/audioinput/audioinput.cpp @@ -196,7 +196,7 @@ InputTest::InputTest() pullMode = true; format.setFrequency(8000); - format.setChannels(1); + format.setChannelCount(1); format.setSampleSize(16); format.setSampleType(QAudioFormat::SignedInt); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp index b6047db..e822064 100644 --- a/examples/multimedia/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audiooutput/audiooutput.cpp @@ -165,7 +165,7 @@ AudioTest::AudioTest() gen->start(); settings.setFrequency(SYSTEM_FREQ); - settings.setChannels(1); + settings.setChannelCount(1); settings.setSampleSize(16); settings.setCodec("audio/pcm"); settings.setByteOrder(QAudioFormat::LittleEndian); diff --git a/src/multimedia/audio/qaudio_mac.cpp b/src/multimedia/audio/qaudio_mac.cpp index 1cd9225..635377c 100644 --- a/src/multimedia/audio/qaudio_mac.cpp +++ b/src/multimedia/audio/qaudio_mac.cpp @@ -65,7 +65,7 @@ QAudioFormat toQAudioFormat(AudioStreamBasicDescription const& sf) QAudioFormat audioFormat; audioFormat.setFrequency(sf.mSampleRate); - audioFormat.setChannels(sf.mChannelsPerFrame); + audioFormat.setChannelCount(sf.mChannelsPerFrame); audioFormat.setSampleSize(sf.mBitsPerChannel); audioFormat.setCodec(QString::fromLatin1("audio/pcm")); audioFormat.setByteOrder(sf.mFormatFlags & kLinearPCMFormatFlagIsBigEndian != 0 ? QAudioFormat::BigEndian : QAudioFormat::LittleEndian); diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index f58f5be..3bcf05b 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -79,19 +79,19 @@ QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const QAudioFormat nearest; if(mode == QAudio::AudioOutput) { nearest.setFrequency(44100); - nearest.setChannels(2); + nearest.setChannelCount(2); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(16); nearest.setCodec(QLatin1String("audio/pcm")); } else { nearest.setFrequency(8000); - nearest.setChannels(1); + nearest.setChannelCount(1); nearest.setSampleType(QAudioFormat::UnSignedInt); nearest.setSampleSize(8); nearest.setCodec(QLatin1String("audio/pcm")); if(!testSettings(nearest)) { - nearest.setChannels(2); + nearest.setChannelCount(2); nearest.setSampleSize(16); nearest.setSampleType(QAudioFormat::SignedInt); } diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index 8905119..c8b0196 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -147,7 +147,7 @@ QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat& format) if (rc.frequency() != target.frequency()) rc.setFrequency(target.frequency()); if (rc.channels() != target.channels()) - rc.setChannels(target.channels()); + rc.setChannelCount(target.channels()); if (rc.sampleSize() != target.sampleSize()) rc.setSampleSize(target.sampleSize()); if (rc.byteOrder() != target.byteOrder()) diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp index 33af022..3c5b129 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -95,14 +95,14 @@ QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const QAudioFormat nearest; if(mode == QAudio::AudioOutput) { nearest.setFrequency(44100); - nearest.setChannels(2); + nearest.setChannelCount(2); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(16); nearest.setCodec(QLatin1String("audio/pcm")); } else { nearest.setFrequency(11025); - nearest.setChannels(1); + nearest.setChannelCount(1); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(8); diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp index b2bbe14..b8e0851 100644 --- a/src/multimedia/audio/qaudioformat.cpp +++ b/src/multimedia/audio/qaudioformat.cpp @@ -245,6 +245,15 @@ int QAudioFormat::frequency() const Sets the channels to \a channels. */ +void QAudioFormat::setChannelCount(int channels) +{ + d->channels = channels; +} + +/*! + \internal +*/ + void QAudioFormat::setChannels(int channels) { d->channels = channels; diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h index 7e92c2f..88241df 100644 --- a/src/multimedia/audio/qaudioformat.h +++ b/src/multimedia/audio/qaudioformat.h @@ -76,6 +76,7 @@ public: void setFrequency(int frequency); int frequency() const; + void setChannelCount(int channels); void setChannels(int channels); int channels() const; diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index d81df7a..0d43ce4 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -89,7 +89,7 @@ QT_BEGIN_NAMESPACE QAudioFormat format; // set up the format you want, eg. format.setFrequency(8000); - format.setChannels(1); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index 1c7b617..2f1ad3b 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -84,7 +84,7 @@ QT_BEGIN_NAMESPACE QAudioFormat format; // Set up the format, eg. format.setFrequency(8000); - format.setChannels(1); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp index 715f219..14cf6b3 100644 --- a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp +++ b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp @@ -170,7 +170,7 @@ void tst_QAudioDeviceInfo::isformat() if(available) { QAudioFormat format; format.setFrequency(44100); - format.setChannels(2); + format.setChannelCount(2); format.setSampleType(QAudioFormat::SignedInt); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleSize(16); diff --git a/tests/auto/qaudioformat/tst_qaudioformat.cpp b/tests/auto/qaudioformat/tst_qaudioformat.cpp index 0778a8e..2742dd7 100644 --- a/tests/auto/qaudioformat/tst_qaudioformat.cpp +++ b/tests/auto/qaudioformat/tst_qaudioformat.cpp @@ -78,7 +78,7 @@ void tst_QAudioFormat::checkNull() QVERIFY(!audioFormat1.isValid()); audioFormat0.setFrequency(44100); - audioFormat0.setChannels(2); + audioFormat0.setChannelCount(2); audioFormat0.setSampleSize(16); audioFormat0.setCodec("audio/pcm"); audioFormat0.setSampleType(QAudioFormat::SignedInt); @@ -95,7 +95,7 @@ void tst_QAudioFormat::checkFrequency() void tst_QAudioFormat::checkChannels() { QAudioFormat audioFormat; - audioFormat.setChannels(2); + audioFormat.setChannelCount(2); QVERIFY(audioFormat.channels() == 2); } @@ -138,14 +138,14 @@ void tst_QAudioFormat::checkEquality() // on filled formats audioFormat0.setFrequency(8000); - audioFormat0.setChannels(1); + audioFormat0.setChannelCount(1); audioFormat0.setSampleSize(8); audioFormat0.setCodec("audio/pcm"); audioFormat0.setByteOrder(QAudioFormat::LittleEndian); audioFormat0.setSampleType(QAudioFormat::UnSignedInt); audioFormat1.setFrequency(8000); - audioFormat1.setChannels(1); + audioFormat1.setChannelCount(1); audioFormat1.setSampleSize(8); audioFormat1.setCodec("audio/pcm"); audioFormat1.setByteOrder(QAudioFormat::LittleEndian); @@ -165,7 +165,7 @@ void tst_QAudioFormat::checkAssignment() QAudioFormat audioFormat1; audioFormat0.setFrequency(8000); - audioFormat0.setChannels(1); + audioFormat0.setChannelCount(1); audioFormat0.setSampleSize(8); audioFormat0.setCodec("audio/pcm"); audioFormat0.setByteOrder(QAudioFormat::LittleEndian); diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp index 744ce38..40bf01f 100644 --- a/tests/auto/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -69,7 +69,7 @@ private: void tst_QAudioInput::initTestCase() { format.setFrequency(8000); - format.setChannels(1); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index 26694cc..f3feec1 100644 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -72,7 +72,7 @@ private: void tst_QAudioOutput::initTestCase() { format.setFrequency(8000); - format.setChannels(1); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); -- cgit v0.12 From 80d4a4945d3273a4b2ce91e34597533f661af320 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Wed, 6 Jan 2010 13:45:05 +1000 Subject: Frequency to SampleRate and channels to channelCount. -Added channelCount(), changed everything to use this instead of channels() in QAudioFormat class. -Added setSampleRate() and sampleRate(), changed everthing to use these instead of setFrequency() and frequency() in QAudioFormat class. -Added supportedSampleRates() and supportedChannelCounts(), changed everything to use these instead of supportedFrequencies() and supportedChannels() in QAudioDeviceInfo class. Reviewed-by:Justin McPherson --- doc/src/snippets/audio/main.cpp | 2 +- examples/multimedia/audiodevices/audiodevices.cpp | 12 +++---- examples/multimedia/audioinput/audioinput.cpp | 2 +- examples/multimedia/audiooutput/audiooutput.cpp | 2 +- src/multimedia/audio/qaudio_mac.cpp | 10 +++--- src/multimedia/audio/qaudiodeviceinfo.cpp | 26 ++++++++++++--- src/multimedia/audio/qaudiodeviceinfo.h | 2 ++ src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp | 20 ++++++------ src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp | 8 ++--- src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp | 10 +++--- src/multimedia/audio/qaudioformat.cpp | 37 +++++++++++++++++++--- src/multimedia/audio/qaudioformat.h | 5 +++ src/multimedia/audio/qaudioinput.cpp | 2 +- src/multimedia/audio/qaudioinput_alsa_p.cpp | 8 ++--- src/multimedia/audio/qaudioinput_mac_p.cpp | 2 +- src/multimedia/audio/qaudioinput_win32_p.cpp | 14 ++++---- src/multimedia/audio/qaudiooutput.cpp | 2 +- src/multimedia/audio/qaudiooutput_alsa_p.cpp | 6 ++-- src/multimedia/audio/qaudiooutput_mac_p.cpp | 6 ++-- src/multimedia/audio/qaudiooutput_win32_p.cpp | 14 ++++---- .../auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp | 14 ++++---- tests/auto/qaudioformat/tst_qaudioformat.cpp | 16 +++++----- tests/auto/qaudioinput/tst_qaudioinput.cpp | 6 ++-- tests/auto/qaudiooutput/tst_qaudiooutput.cpp | 6 ++-- 24 files changed, 142 insertions(+), 90 deletions(-) diff --git a/doc/src/snippets/audio/main.cpp b/doc/src/snippets/audio/main.cpp index 1e6242d..bf4b145 100644 --- a/doc/src/snippets/audio/main.cpp +++ b/doc/src/snippets/audio/main.cpp @@ -89,7 +89,7 @@ private: { //![1] QAudioFormat format; - format.setFrequency(44100); + format.setSampleRate(44100); //![1] format.setChannelCount(2); format.setSampleSize(16); diff --git a/examples/multimedia/audiodevices/audiodevices.cpp b/examples/multimedia/audiodevices/audiodevices.cpp index 4f4a95f..beb31b4 100644 --- a/examples/multimedia/audiodevices/audiodevices.cpp +++ b/examples/multimedia/audiodevices/audiodevices.cpp @@ -108,8 +108,8 @@ void AudioTest::test() } else { QAudioFormat nearest = deviceInfo.nearestFormat(settings); logOutput->append(tr("Failed")); - nearestFreq->setText(QString("%1").arg(nearest.frequency())); - nearestChannel->setText(QString("%1").arg(nearest.channels())); + nearestFreq->setText(QString("%1").arg(nearest.sampleRate())); + nearestChannel->setText(QString("%1").arg(nearest.channelCount())); nearestCodec->setText(nearest.codec()); nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize())); @@ -161,14 +161,14 @@ void AudioTest::deviceChanged(int idx) deviceInfo = deviceBox->itemData(idx).value(); frequencyBox->clear(); - QList freqz = deviceInfo.supportedFrequencies(); + QList freqz = deviceInfo.supportedSampleRates(); for(int i = 0; i < freqz.size(); ++i) frequencyBox->addItem(QString("%1").arg(freqz.at(i))); if(freqz.size()) - settings.setFrequency(freqz.at(0)); + settings.setSampleRate(freqz.at(0)); channelsBox->clear(); - QList chz = deviceInfo.supportedChannels(); + QList chz = deviceInfo.supportedChannelCounts(); for(int i = 0; i < chz.size(); ++i) channelsBox->addItem(QString("%1").arg(chz.at(i))); if(chz.size()) @@ -229,7 +229,7 @@ void AudioTest::deviceChanged(int idx) void AudioTest::freqChanged(int idx) { // freq has changed - settings.setFrequency(frequencyBox->itemText(idx).toInt()); + settings.setSampleRate(frequencyBox->itemText(idx).toInt()); } void AudioTest::channelChanged(int idx) diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp index e6ebe95..dbf460b 100644 --- a/examples/multimedia/audioinput/audioinput.cpp +++ b/examples/multimedia/audioinput/audioinput.cpp @@ -195,7 +195,7 @@ InputTest::InputTest() pullMode = true; - format.setFrequency(8000); + format.setSampleRate(8000); format.setChannelCount(1); format.setSampleSize(16); format.setSampleType(QAudioFormat::SignedInt); diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp index e822064..7d60cd4 100644 --- a/examples/multimedia/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audiooutput/audiooutput.cpp @@ -164,7 +164,7 @@ AudioTest::AudioTest() gen->start(); - settings.setFrequency(SYSTEM_FREQ); + settings.setSampleRate(SYSTEM_FREQ); settings.setChannelCount(1); settings.setSampleSize(16); settings.setCodec("audio/pcm"); diff --git a/src/multimedia/audio/qaudio_mac.cpp b/src/multimedia/audio/qaudio_mac.cpp index 635377c..d876745 100644 --- a/src/multimedia/audio/qaudio_mac.cpp +++ b/src/multimedia/audio/qaudio_mac.cpp @@ -48,8 +48,8 @@ QT_BEGIN_NAMESPACE QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat) { dbg.nospace() << "QAudioFormat(" << - audioFormat.frequency() << "," << - audioFormat.channels() << "," << + audioFormat.sampleRate() << "," << + audioFormat.channelCount() << "," << audioFormat.sampleSize()<< "," << audioFormat.codec() << "," << audioFormat.byteOrder() << "," << @@ -64,7 +64,7 @@ QAudioFormat toQAudioFormat(AudioStreamBasicDescription const& sf) { QAudioFormat audioFormat; - audioFormat.setFrequency(sf.mSampleRate); + audioFormat.setSampleRate(sf.mSampleRate); audioFormat.setChannelCount(sf.mChannelsPerFrame); audioFormat.setSampleSize(sf.mBitsPerChannel); audioFormat.setCodec(QString::fromLatin1("audio/pcm")); @@ -84,9 +84,9 @@ AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& au AudioStreamBasicDescription sf; sf.mFormatFlags = kAudioFormatFlagIsPacked; - sf.mSampleRate = audioFormat.frequency(); + sf.mSampleRate = audioFormat.sampleRate(); sf.mFramesPerPacket = 1; - sf.mChannelsPerFrame = audioFormat.channels(); + sf.mChannelsPerFrame = audioFormat.channelCount(); sf.mBitsPerChannel = audioFormat.sampleSize(); sf.mBytesPerFrame = sf.mChannelsPerFrame * (sf.mBitsPerChannel / 8); sf.mBytesPerPacket = sf.mFramesPerPacket * sf.mBytesPerFrame; diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp index 5e3adcb..226d723 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo.cpp @@ -100,13 +100,13 @@ public: You can also query each device for the formats it supports. A format in this context is a set consisting of a specific byte - order, channel, codec, frequency, sample rate, and sample type. A + order, channel, codec, sample rate, sample size and sample type. A format is represented by the QAudioFormat class. The values supported by the the device for each of these parameters can be fetched with supportedByteOrders(), supportedChannels(), supportedCodecs(), - supportedFrequencies(), supportedSampleSizes(), and + supportedSampleRates(), supportedSampleSizes(), and supportedSampleTypes(). The combinations supported are dependent on the platform, audio plugins installed and the audio device capabilities. If you need a specific format, you can check if the device supports it with isFormatSupported(), or fetch a @@ -259,7 +259,16 @@ QStringList QAudioDeviceInfo::supportedCodecs() const } /*! - Returns a list of supported frequencies. + Returns a list of supported sample rates. +*/ + +QList QAudioDeviceInfo::supportedSampleRates() const +{ + return supportedFrequencies(); +} + +/*! + \internal */ QList QAudioDeviceInfo::supportedFrequencies() const @@ -268,7 +277,16 @@ QList QAudioDeviceInfo::supportedFrequencies() const } /*! - Returns a list of supported channels. + Returns a list of supported channel counts. +*/ + +QList QAudioDeviceInfo::supportedChannelCounts() const +{ + return supportedChannels(); +} + +/*! + \internal */ QList QAudioDeviceInfo::supportedChannels() const diff --git a/src/multimedia/audio/qaudiodeviceinfo.h b/src/multimedia/audio/qaudiodeviceinfo.h index 5c7cb98..78b1e69 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.h +++ b/src/multimedia/audio/qaudiodeviceinfo.h @@ -84,7 +84,9 @@ public: QStringList supportedCodecs() const; QList supportedFrequencies() const; + QList supportedSampleRates() const; QList supportedChannels() const; + QList supportedChannelCounts() const; QList supportedSampleSizes() const; QList supportedByteOrders() const; QList supportedSampleTypes() const; diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index 3bcf05b..9187264 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -78,14 +78,14 @@ QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const { QAudioFormat nearest; if(mode == QAudio::AudioOutput) { - nearest.setFrequency(44100); + nearest.setSampleRate(44100); nearest.setChannelCount(2); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(16); nearest.setCodec(QLatin1String("audio/pcm")); } else { - nearest.setFrequency(8000); + nearest.setSampleRate(8000); nearest.setChannelCount(1); nearest.setSampleType(QAudioFormat::UnSignedInt); nearest.setSampleSize(8); @@ -253,8 +253,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const snd_pcm_hw_params_any( handle, params ); // set the values! - snd_pcm_hw_params_set_channels(handle,params,format.channels()); - snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + snd_pcm_hw_params_set_channels(handle,params,format.channelCount()); + snd_pcm_hw_params_set_rate(handle,params,format.sampleRate(),dir); switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) @@ -295,18 +295,18 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const } else testCodec = true; - if(err>=0 && format.channels() != -1) { - err = snd_pcm_hw_params_test_channels(handle,params,format.channels()); + if(err>=0 && format.channelCount() != -1) { + err = snd_pcm_hw_params_test_channels(handle,params,format.channelCount()); if(err>=0) - err = snd_pcm_hw_params_set_channels(handle,params,format.channels()); + err = snd_pcm_hw_params_set_channels(handle,params,format.channelCount()); if(err>=0) testChannel = true; } - if(err>=0 && format.frequency() != -1) { - err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0); + if(err>=0 && format.sampleRate() != -1) { + err = snd_pcm_hw_params_test_rate(handle,params,format.sampleRate(),0); if(err>=0) - err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + err = snd_pcm_hw_params_set_rate(handle,params,format.sampleRate(),dir); if(err>=0) testFreq = true; } diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index c8b0196..8e19b12 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -144,10 +144,10 @@ QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat& format) rc.setCodec(QString::fromLatin1("audio/pcm")); - if (rc.frequency() != target.frequency()) - rc.setFrequency(target.frequency()); - if (rc.channels() != target.channels()) - rc.setChannelCount(target.channels()); + if (rc.sampleRate() != target.sampleRate()) + rc.setSampleRate(target.sampleRate()); + if (rc.channelCount() != target.channelCount()) + rc.setChannelCount(target.channelCount()); if (rc.sampleSize() != target.sampleSize()) rc.setSampleSize(target.sampleSize()); if (rc.byteOrder() != target.byteOrder()) diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp index 3c5b129..739b0d0 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -94,14 +94,14 @@ QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const { QAudioFormat nearest; if(mode == QAudio::AudioOutput) { - nearest.setFrequency(44100); + nearest.setSampleRate(44100); nearest.setChannelCount(2); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(16); nearest.setCodec(QLatin1String("audio/pcm")); } else { - nearest.setFrequency(11025); + nearest.setSampleRate(11025); nearest.setChannelCount(1); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); @@ -181,12 +181,12 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const if(!format.codec().startsWith(QLatin1String("audio/pcm"))) failed = true; - if(!failed && !(format.channels() == 1 || format.channels() == 2)) + if(!failed && !(format.channelCount() == 1 || format.channelCount() == 2)) failed = true; if(!failed) { - if(!(format.frequency() == 8000 || format.frequency() == 11025 || format.frequency() == 22050 || - format.frequency() == 44100 || format.frequency() == 48000 || format.frequency() == 96000)) + if(!(format.sampleRate() == 8000 || format.sampleRate() == 11025 || format.sampleRate() == 22050 || + format.sampleRate() == 44100 || format.sampleRate() == 48000 || format.sampleRate() == 96000)) failed = true; } diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp index b8e0851..f7867f4 100644 --- a/src/multimedia/audio/qaudioformat.cpp +++ b/src/multimedia/audio/qaudioformat.cpp @@ -144,7 +144,7 @@ public: Values are initialized as follows: \list \o frequency() = -1 - \o channels() = -1 + \o channelCount() = -1 \o sampleSize() = -1 \o byteOrder() = QAudioFormat::Endian(QSysInfo::ByteOrder) \o sampleType() = QAudioFormat::Unknown @@ -224,7 +224,16 @@ bool QAudioFormat::isValid() const } /*! - Sets the frequency to \a frequency. + Sets the sample rate to \a samplerate Hertz. +*/ + +void QAudioFormat::setSampleRate(int samplerate) +{ + d->frequency = samplerate; +} + +/*! + \internal */ void QAudioFormat::setFrequency(int frequency) @@ -233,7 +242,16 @@ void QAudioFormat::setFrequency(int frequency) } /*! - Returns the current frequency value. + Returns the current sample rate in Hertz. +*/ + +int QAudioFormat::sampleRate() const +{ + return d->frequency; +} + +/*! + \internal */ int QAudioFormat::frequency() const @@ -242,7 +260,7 @@ int QAudioFormat::frequency() const } /*! - Sets the channels to \a channels. + Sets the channel count to \a channels. */ void QAudioFormat::setChannelCount(int channels) @@ -260,7 +278,16 @@ void QAudioFormat::setChannels(int channels) } /*! - Returns the current channel value. + Returns the current channel count value. +*/ + +int QAudioFormat::channelCount() const +{ + return d->channels; +} + +/*! + \internal */ int QAudioFormat::channels() const diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h index 88241df..efc247f 100644 --- a/src/multimedia/audio/qaudioformat.h +++ b/src/multimedia/audio/qaudioformat.h @@ -76,7 +76,12 @@ public: void setFrequency(int frequency); int frequency() const; + void setSampleRate(int samplerate); + int sampleRate() const; + void setChannelCount(int channels); + int channelCount() const; + void setChannels(int channels); int channels() const; diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 0d43ce4..733ff4e 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -88,7 +88,7 @@ QT_BEGIN_NAMESPACE QAudioFormat format; // set up the format you want, eg. - format.setFrequency(8000); + format.setSampleRate(8000); format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index 3dbe66c..096b7ca 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -256,7 +256,7 @@ bool QAudioInputPrivate::open() int dir; int err=-1; int count=0; - unsigned int freakuency=settings.frequency(); + unsigned int freakuency=settings.sampleRate(); QString dev = QString(QLatin1String(m_device.constData())); QList devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput); @@ -332,7 +332,7 @@ bool QAudioInputPrivate::open() } } if ( !fatal ) { - err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() ); + err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err); @@ -505,7 +505,7 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) errorState = QAudio::NoError; deviceState = QAudio::IdleState; } else { - totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.frequency(); + totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.sampleRate(); resuming = false; errorState = QAudio::NoError; deviceState = QAudio::ActiveState; @@ -702,7 +702,7 @@ qint64 InputPrivate::readData( char* data, qint64 len) count++; } if(err > 0 && readFrames > 0) { - audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.frequency()*1000; + audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.sampleRate()*1000; audioDevice->deviceState = QAudio::ActiveState; return err; } diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp index d63045f..7c856f4 100644 --- a/src/multimedia/audio/qaudioinput_mac_p.cpp +++ b/src/multimedia/audio/qaudioinput_mac_p.cpp @@ -814,7 +814,7 @@ int QAudioInputPrivate::notifyInterval() const qint64 QAudioInputPrivate::processedUSecs() const { - return totalFrames * 1000000 / audioFormat.frequency(); + return totalFrames * 1000000 / audioFormat.sampleRate(); } qint64 QAudioInputPrivate::elapsedUSecs() const diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp index f50a547..f98ecc6 100644 --- a/src/multimedia/audio/qaudioinput_win32_p.cpp +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -225,16 +225,16 @@ bool QAudioInputPrivate::open() header = 0; if(buffer_size == 0) { // Default buffer size, 100ms, default period size is 20ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.1; + buffer_size = settings.sampleRate()*settings.channelCount()*(settings.sampleSize()/8)*0.1; period_size = buffer_size/5; } else { period_size = buffer_size/5; } timeStamp.restart(); elapsedTimeOffset = 0; - wfx.nSamplesPerSec = settings.frequency(); + wfx.nSamplesPerSec = settings.sampleRate(); wfx.wBitsPerSample = settings.sampleSize(); - wfx.nChannels = settings.channels(); + wfx.nChannels = settings.channelCount(); wfx.cbSize = 0; wfx.wFormatTag = WAVE_FORMAT_PCM; @@ -374,8 +374,8 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) } else { totalTimeValue += waveBlocks[header].dwBytesRecorded - /((settings.channels()*settings.sampleSize()/8)) - *10000/settings.frequency()*100; + /((settings.channelCount()*settings.sampleSize()/8)) + *10000/settings.sampleRate()*100; errorState = QAudio::NoError; deviceState = QAudio::ActiveState; resuming = false; @@ -388,8 +388,8 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) qDebug()<<"IN: "< devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); @@ -354,7 +354,7 @@ bool QAudioOutputPrivate::open() } } if ( !fatal ) { - err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() ); + err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_channels: err = %1").arg(err); @@ -494,7 +494,7 @@ qint64 QAudioOutputPrivate::write( const char *data, qint64 len ) err = snd_pcm_writei( handle, data, frames ); } if(err > 0) { - totalTimeValue += err*1000000/settings.frequency(); + totalTimeValue += err*1000000/settings.sampleRate(); resuming = false; errorState = QAudio::NoError; deviceState = QAudio::ActiveState; diff --git a/src/multimedia/audio/qaudiooutput_mac_p.cpp b/src/multimedia/audio/qaudiooutput_mac_p.cpp index e0651bf..2dec43d 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.cpp +++ b/src/multimedia/audio/qaudiooutput_mac_p.cpp @@ -87,8 +87,8 @@ public: m_device(0) { m_buffer = new QAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize))); - m_bytesPerFrame = (audioFormat.sampleSize() / 8) * audioFormat.channels(); - m_periodTime = m_maxPeriodSize / m_bytesPerFrame * 1000 / audioFormat.frequency(); + m_bytesPerFrame = (audioFormat.sampleSize() / 8) * audioFormat.channelCount(); + m_periodTime = m_maxPeriodSize / m_bytesPerFrame * 1000 / audioFormat.sampleRate(); m_fillTimer = new QTimer(this); connect(m_fillTimer, SIGNAL(timeout()), SLOT(fillBuffer())); @@ -546,7 +546,7 @@ int QAudioOutputPrivate::notifyInterval() const qint64 QAudioOutputPrivate::processedUSecs() const { - return totalFrames * 1000000 / audioFormat.frequency(); + return totalFrames * 1000000 / audioFormat.sampleRate(); } qint64 QAudioOutputPrivate::elapsedUSecs() const diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index 02c8cfe..389aef9 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -213,7 +213,7 @@ bool QAudioOutputPrivate::open() #endif if(buffer_size == 0) { // Default buffer size, 200ms, default period size is 40ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2; + buffer_size = settings.sampleRate()*settings.channelCount()*(settings.sampleSize()/8)*0.2; period_size = buffer_size/5; } else { period_size = buffer_size/5; @@ -232,9 +232,9 @@ bool QAudioOutputPrivate::open() timeStamp.restart(); elapsedTimeOffset = 0; - wfx.nSamplesPerSec = settings.frequency(); + wfx.nSamplesPerSec = settings.sampleRate(); wfx.wBitsPerSample = settings.sampleSize(); - wfx.nChannels = settings.channels(); + wfx.nChannels = settings.channelCount(); wfx.cbSize = 0; wfx.wFormatTag = WAVE_FORMAT_PCM; @@ -289,8 +289,8 @@ void QAudioOutputPrivate::close() return; deviceState = QAudio::StoppedState; - int delay = (buffer_size-bytesFree())*1000/(settings.frequency() - *settings.channels()*(settings.sampleSize()/8)); + int delay = (buffer_size-bytesFree())*1000/(settings.sampleRate() + *settings.channelCount()*(settings.sampleSize()/8)); waveOutReset(hWaveOut); Sleep(delay+10); @@ -386,8 +386,8 @@ qint64 QAudioOutputPrivate::write( const char *data, qint64 len ) LeaveCriticalSection(&waveOutCriticalSection); #endif totalTimeValue += current->dwBufferLength - /(settings.channels()*(settings.sampleSize()/8)) - *1000000/settings.frequency();; + /(settings.channelCount()*(settings.sampleSize()/8)) + *1000000/settings.sampleRate();; waveCurrentBlock++; waveCurrentBlock %= buffer_size/period_size; current = &waveBlocks[waveCurrentBlock]; diff --git a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp index 14cf6b3..2270eb2 100644 --- a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp +++ b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp @@ -128,7 +128,7 @@ void tst_QAudioDeviceInfo::codecs() void tst_QAudioDeviceInfo::channels() { if(available) { - QList avail = device->supportedChannels(); + QList avail = device->supportedChannelCounts(); QVERIFY(avail.size() > 0); } } @@ -160,7 +160,7 @@ void tst_QAudioDeviceInfo::sampleTypes() void tst_QAudioDeviceInfo::frequencies() { if(available) { - QList avail = device->supportedFrequencies(); + QList avail = device->supportedSampleRates(); QVERIFY(avail.size() > 0); } } @@ -169,7 +169,7 @@ void tst_QAudioDeviceInfo::isformat() { if(available) { QAudioFormat format; - format.setFrequency(44100); + format.setSampleRate(44100); format.setChannelCount(2); format.setSampleType(QAudioFormat::SignedInt); format.setByteOrder(QAudioFormat::LittleEndian); @@ -185,8 +185,8 @@ void tst_QAudioDeviceInfo::preferred() { if(available) { QAudioFormat format = device->preferredFormat(); - QVERIFY(format.frequency() == 44100); - QVERIFY(format.channels() == 2); + QVERIFY(format.sampleRate() == 44100); + QVERIFY(format.channelCount() == 2); } } @@ -194,9 +194,9 @@ void tst_QAudioDeviceInfo::nearest() { if(available) { QAudioFormat format1, format2; - format1.setFrequency(8000); + format1.setSampleRate(8000); format2 = device->nearestFormat(format1); - QVERIFY(format2.frequency() == 44100); + QVERIFY(format2.sampleRate() == 44100); } } diff --git a/tests/auto/qaudioformat/tst_qaudioformat.cpp b/tests/auto/qaudioformat/tst_qaudioformat.cpp index 2742dd7..5237dca 100644 --- a/tests/auto/qaudioformat/tst_qaudioformat.cpp +++ b/tests/auto/qaudioformat/tst_qaudioformat.cpp @@ -77,7 +77,7 @@ void tst_QAudioFormat::checkNull() QAudioFormat audioFormat1(audioFormat0); QVERIFY(!audioFormat1.isValid()); - audioFormat0.setFrequency(44100); + audioFormat0.setSampleRate(44100); audioFormat0.setChannelCount(2); audioFormat0.setSampleSize(16); audioFormat0.setCodec("audio/pcm"); @@ -88,15 +88,15 @@ void tst_QAudioFormat::checkNull() void tst_QAudioFormat::checkFrequency() { QAudioFormat audioFormat; - audioFormat.setFrequency(44100); - QVERIFY(audioFormat.frequency() == 44100); + audioFormat.setSampleRate(44100); + QVERIFY(audioFormat.sampleRate() == 44100); } void tst_QAudioFormat::checkChannels() { QAudioFormat audioFormat; audioFormat.setChannelCount(2); - QVERIFY(audioFormat.channels() == 2); + QVERIFY(audioFormat.channelCount() == 2); } void tst_QAudioFormat::checkSampleSize() @@ -137,14 +137,14 @@ void tst_QAudioFormat::checkEquality() QVERIFY(!(audioFormat0 != audioFormat1)); // on filled formats - audioFormat0.setFrequency(8000); + audioFormat0.setSampleRate(8000); audioFormat0.setChannelCount(1); audioFormat0.setSampleSize(8); audioFormat0.setCodec("audio/pcm"); audioFormat0.setByteOrder(QAudioFormat::LittleEndian); audioFormat0.setSampleType(QAudioFormat::UnSignedInt); - audioFormat1.setFrequency(8000); + audioFormat1.setSampleRate(8000); audioFormat1.setChannelCount(1); audioFormat1.setSampleSize(8); audioFormat1.setCodec("audio/pcm"); @@ -154,7 +154,7 @@ void tst_QAudioFormat::checkEquality() QVERIFY(audioFormat0 == audioFormat1); QVERIFY(!(audioFormat0 != audioFormat1)); - audioFormat0.setFrequency(44100); + audioFormat0.setSampleRate(44100); QVERIFY(audioFormat0 != audioFormat1); QVERIFY(!(audioFormat0 == audioFormat1)); } @@ -164,7 +164,7 @@ void tst_QAudioFormat::checkAssignment() QAudioFormat audioFormat0; QAudioFormat audioFormat1; - audioFormat0.setFrequency(8000); + audioFormat0.setSampleRate(8000); audioFormat0.setChannelCount(1); audioFormat0.setSampleSize(8); audioFormat0.setCodec("audio/pcm"); diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp index 40bf01f..994e9ef 100644 --- a/tests/auto/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -68,7 +68,7 @@ private: void tst_QAudioInput::initTestCase() { - format.setFrequency(8000); + format.setSampleRate(8000); format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); @@ -94,8 +94,8 @@ void tst_QAudioInput::settings() // Confirm the setting we added in the init function. QAudioFormat f = audio->format(); - QVERIFY(format.channels() == f.channels()); - QVERIFY(format.frequency() == f.frequency()); + QVERIFY(format.channelCount() == f.channelCount()); + QVERIFY(format.sampleRate() == f.sampleRate()); QVERIFY(format.sampleSize() == f.sampleSize()); QVERIFY(format.codec() == f.codec()); QVERIFY(format.byteOrder() == f.byteOrder()); diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index f3feec1..60d0124 100644 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -71,7 +71,7 @@ private: void tst_QAudioOutput::initTestCase() { - format.setFrequency(8000); + format.setSampleRate(8000); format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); @@ -95,8 +95,8 @@ void tst_QAudioOutput::settings() // Confirm the setting we added in the init function. QAudioFormat f = audio->format(); - QVERIFY(format.channels() == f.channels()); - QVERIFY(format.frequency() == f.frequency()); + QVERIFY(format.channelCount() == f.channelCount()); + QVERIFY(format.sampleRate() == f.sampleRate()); QVERIFY(format.sampleSize() == f.sampleSize()); QVERIFY(format.codec() == f.codec()); QVERIFY(format.byteOrder() == f.byteOrder()); -- cgit v0.12 From 80e6ea3e871fa9f0e5a21d48ad893d4ec59c5c1c Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 7 Jan 2010 08:38:35 +1000 Subject: Avoid a deep copy of QImage::bits() in the png writer Task-number: QTBUG-7161 Reviewed-by: Daniel Pope --- src/gui/image/qpnghandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 1de0f32..42c48a9 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -855,7 +855,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); - const uchar *data = image.bits(); + const uchar *data = (static_cast(&image))->bits(); int bpl = image.bytesPerLine(); row_pointers = new png_bytep[height]; uint y; -- cgit v0.12 From f9ffe24a87d67f39bb877224f7e2b6f7b3ad6c02 Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 7 Jan 2010 11:34:30 +1000 Subject: Fix warning in qfilesystemmodel_p.h Reviewed-by: Rhys Weatherley --- src/gui/dialogs/qfilesystemmodel_p.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/gui/dialogs/qfilesystemmodel_p.h index 175159f..68e19dc 100644 --- a/src/gui/dialogs/qfilesystemmodel_p.h +++ b/src/gui/dialogs/qfilesystemmodel_p.h @@ -238,15 +238,15 @@ public: void sortChildren(int column, const QModelIndex &parent); inline int translateVisibleLocation(QFileSystemNode *parent, int row) const { - if (sortOrder == Qt::AscendingOrder) - return row; - if (parent->dirtyChildrenIndex == -1 || row < parent->dirtyChildrenIndex) - if (parent->dirtyChildrenIndex != -1) - return parent->dirtyChildrenIndex - row - 1; - else + if (sortOrder != Qt::AscendingOrder) { + if (parent->dirtyChildrenIndex == -1) return parent->visibleChildren.count() - row - 1; - else - return row; + + if (row < parent->dirtyChildrenIndex) + return parent->dirtyChildrenIndex - row - 1; + } + + return row; } inline static QString myComputer() { -- cgit v0.12 From 2e4c7797144ff2487eadd4c4ae076943c1b7d409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 7 Jan 2010 10:34:14 +0100 Subject: Remove unnecessary call to QWidget::setAttribute(). This is already done in the QGLWidget constructor. Reviewed-by: Kim --- src/opengl/qgl.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index c3e4a2e..4a79427 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4952,8 +4952,6 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi if (!glcx) glcx = new QGLContext(QGLFormat::defaultFormat(), q); - - q->setAttribute(Qt::WA_NoSystemBackground); } #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) -- cgit v0.12 From 443d2f28f5ee83c4ab8353c2c8608139735e1f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 7 Jan 2010 12:26:38 +0100 Subject: Fixed bug in boxes demo occuring with certain OpenGL drivers. Apparently glLoadMatrixf doesn't load the supplied data synchronously in certain drivers, so we make the arrays static to work around this issue. Really a GL driver bug but it's quite simple to work around it in this case. Reviewed-by: Kim --- demos/boxes/scene.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/demos/boxes/scene.cpp b/demos/boxes/scene.cpp index 452f4ef..9b36b81 100644 --- a/demos/boxes/scene.cpp +++ b/demos/boxes/scene.cpp @@ -653,7 +653,8 @@ void Scene::initGL() static void loadMatrix(const QMatrix4x4& m) { - GLfloat mat[16]; + // static to prevent glLoadMatrixf to fail on certain drivers + static GLfloat mat[16]; const qreal *data = m.constData(); for (int index = 0; index < 16; ++index) mat[index] = data[index]; @@ -662,7 +663,8 @@ static void loadMatrix(const QMatrix4x4& m) static void multMatrix(const QMatrix4x4& m) { - GLfloat mat[16]; + // static to prevent glMultMatrixf to fail on certain drivers + static GLfloat mat[16]; const qreal *data = m.constData(); for (int index = 0; index < 16; ++index) mat[index] = data[index]; -- cgit v0.12 From 60d27f4b9fd2dbed204260334b817ce41788cb3e Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 7 Jan 2010 13:42:05 +0200 Subject: Added UIDs and icons to some webkit examples Reviewed-by: TrustMe --- examples/webkit/domtraversal/domtraversal.pro | 5 +++++ examples/webkit/fancybrowser/fancybrowser.pro | 5 ++++- examples/webkit/googlechat/googlechat.pro | 5 ++++- examples/webkit/simpleselector/simpleselector.pro | 5 +++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/examples/webkit/domtraversal/domtraversal.pro b/examples/webkit/domtraversal/domtraversal.pro index 49400de..ba5f2d8 100644 --- a/examples/webkit/domtraversal/domtraversal.pro +++ b/examples/webkit/domtraversal/domtraversal.pro @@ -9,3 +9,8 @@ target.path = $$[QT_INSTALL_EXAMPLES]/webkit/domtraversal sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/domtraversal INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000D7CB + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/webkit/fancybrowser/fancybrowser.pro b/examples/webkit/fancybrowser/fancybrowser.pro index e496241..3786d9c 100644 --- a/examples/webkit/fancybrowser/fancybrowser.pro +++ b/examples/webkit/fancybrowser/fancybrowser.pro @@ -10,4 +10,7 @@ sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/fancybrowser INSTALLS += target sources -symbian:TARGET.UID3 = 0xA000CF6C +symbian { + TARGET.UID3 = 0xA000CF6C + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/webkit/googlechat/googlechat.pro b/examples/webkit/googlechat/googlechat.pro index 8e4f9a6..3d32c1b 100644 --- a/examples/webkit/googlechat/googlechat.pro +++ b/examples/webkit/googlechat/googlechat.pro @@ -10,4 +10,7 @@ sources.files = $$SOURCES $$HEADERS $$FORMS *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/googlechat INSTALLS += target sources -symbian:TARGET.UID3 = 0xA000CF6E +symbian { + TARGET.UID3 = 0xA000CF6E + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/webkit/simpleselector/simpleselector.pro b/examples/webkit/simpleselector/simpleselector.pro index 3f3037f..acd0ae7 100644 --- a/examples/webkit/simpleselector/simpleselector.pro +++ b/examples/webkit/simpleselector/simpleselector.pro @@ -9,3 +9,8 @@ target.path = $$[QT_INSTALL_EXAMPLES]/webkit/simpleselector sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/simpleselector INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000D7CC + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} -- cgit v0.12 From e2f2765b52508515874edea7015c01eb95ff89be Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 7 Jan 2010 15:10:07 +0200 Subject: Separated "make run" and "make runonphone" targets Reviewed-by: axis --- doc/src/platforms/symbian-introduction.qdoc | 28 ++++++++++++++++++++++------ qmake/generators/symbian/symmake.cpp | 7 +------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index 477e629..4d06bbc 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -124,12 +124,8 @@ \row \o \c release-gcce \o Build release binaries for hardware using GCCE. \row \o \c debug-armv5 \o Build debug binaries for hardware using RVCT. \row \o \c release-armv5 \o Build release binaries for hardware using RVCT. - \row \o \c run \o Run the application. Environment variable - \c QT_SIS_TARGET (see below) can be used to specify which - build target is run. By default it is the last build target. - Note that running the application on real device - using this command requires \c TRK application to be running - on the device. + \row \o \c run \o Run the application on the emulator. + \row \o \c runonphone \o Run the application on a device. \row \o \c sis \o Create signed \c .sis file for project. \endtable @@ -199,4 +195,24 @@ with the \c QT_SIS_OPTIONS=-i, like this: \snippet doc/src/snippets/code/doc_src_symbian-introduction.qdoc 5 + + \section1 Running applications from command line + + The application can be launched on the emulator using \c{make run} command. + + The application can be launched on a device using \c{make runonphone} command. + When this command is invoked, a \c .sis file is first created as if \c{make sis} + command was invoked (see above for details). + \bold{Note:} Running the application on a device using this command requires + \c TRK application to be running on the device. + + Additional environment variables that can be utilized with these commands are: + \table + \row \o \c QT_RUN_OPTIONS \o Any command line parameters you wish to pass + to your application. + \row \o \c QT_RUN_ON_PHONE_OPTIONS \o Options for runonphone application. + Execute \c runonphone from command line for + more information about available options. + \c{make runonphone} only. + \endtable */ diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index b2709d1..81f2d15 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -1857,16 +1857,11 @@ void SymbianMakefileGenerator::generateExecutionTargets(QTextStream& t, const QS // create execution targets if (targetType == TypeExe) { if (platforms.contains("winscw")) { - t << "ifeq (\"DEBUG-winscw\", \"$(QT_SIS_TARGET)\")" << endl; t << "run:" << endl; t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl; - t << "else" << endl; } - t << "run: sis" << endl; + t << "runonphone: sis" << endl; t << "\trunonphone $(QT_RUN_ON_PHONE_OPTIONS) --sis " << fixedTarget << "_$(QT_SIS_TARGET).sis " << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl; - if (platforms.contains("winscw")) { - t << "endif" << endl; - } t << endl; } } -- cgit v0.12 From f4e633af484b1016bed5935e29f99a49dc403e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 7 Jan 2010 14:48:34 +0100 Subject: Fixed indentation and typo. Reviewed-by: TrustMe --- src/opengl/qgl_x11egl.cpp | 134 +++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 271f4de..d6281f7 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -56,9 +56,9 @@ QT_BEGIN_NAMESPACE bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual); // -// QGLTempContext is a lass for creating a temporary GL context (which is -// needed during QGLWidget initialization to retrieve GL extension info). -// Faster to construct than a full QGLWidget. +// QGLTempContext is a class for creating a temporary GL context +// (which is needed during QGLWidget initialization to retrieve GL +// extension info). Faster to construct than a full QGLWidget. // class QGLTempContext { @@ -68,82 +68,82 @@ public: window(0), context(0), surface(0) - { - display = eglGetDisplay(EGLNativeDisplayType(X11->display)); + { + display = eglGetDisplay(EGLNativeDisplayType(X11->display)); - if (!eglInitialize(display, NULL, NULL)) { - qWarning("QGLTempContext: Unable to initialize EGL display."); - return; - } + if (!eglInitialize(display, NULL, NULL)) { + qWarning("QGLTempContext: Unable to initialize EGL display."); + return; + } - EGLConfig config; - int numConfigs = 0; - EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGLConfig config; + int numConfigs = 0; + EGLint attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, #ifdef QT_OPENGL_ES_2 - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #endif - EGL_NONE - }; + EGL_NONE + }; - eglChooseConfig(display, attribs, &config, 1, &numConfigs); - if (!numConfigs) { - qWarning("QGLTempContext: No EGL configurations available."); - return; - } + eglChooseConfig(display, attribs, &config, 1, &numConfigs); + if (!numConfigs) { + qWarning("QGLTempContext: No EGL configurations available."); + return; + } - XVisualInfo visualInfo; - XVisualInfo *vi; - int numVisuals; - EGLint id = 0; - - eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &id); - if (id == 0) { - // EGL_NATIVE_VISUAL_ID is optional and might not be supported - // on some implementations - we'll have to do it the hard way - QX11Info xinfo; - qt_egl_setup_x11_visual(visualInfo, display, config, xinfo, false); - } else { - visualInfo.visualid = id; - } - vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); - if (!vi || numVisuals < 1) { - qWarning("QGLTempContext: Unable to get X11 visual info id."); - return; - } + XVisualInfo visualInfo; + XVisualInfo *vi; + int numVisuals; + EGLint id = 0; + + eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &id); + if (id == 0) { + // EGL_NATIVE_VISUAL_ID is optional and might not be supported + // on some implementations - we'll have to do it the hard way + QX11Info xinfo; + qt_egl_setup_x11_visual(visualInfo, display, config, xinfo, false); + } else { + visualInfo.visualid = id; + } + vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); + if (!vi || numVisuals < 1) { + qWarning("QGLTempContext: Unable to get X11 visual info id."); + return; + } - window = XCreateWindow(X11->display, RootWindow(X11->display, screen), - 0, 0, 1, 1, 0, - vi->depth, InputOutput, vi->visual, - 0, 0); + window = XCreateWindow(X11->display, RootWindow(X11->display, screen), + 0, 0, 1, 1, 0, + vi->depth, InputOutput, vi->visual, + 0, 0); - surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType) window, NULL); + surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType) window, NULL); - if (surface == EGL_NO_SURFACE) { - qWarning("QGLTempContext: Error creating EGL surface."); - XFree(vi); - XDestroyWindow(X11->display, window); - return; - } + if (surface == EGL_NO_SURFACE) { + qWarning("QGLTempContext: Error creating EGL surface."); + XFree(vi); + XDestroyWindow(X11->display, window); + return; + } - EGLint contextAttribs[] = { + EGLint contextAttribs[] = { #ifdef QT_OPENGL_ES_2 - EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_CLIENT_VERSION, 2, #endif - EGL_NONE - }; - context = eglCreateContext(display, config, 0, contextAttribs); - if (context != EGL_NO_CONTEXT - && eglMakeCurrent(display, surface, surface, context)) - { - initialized = true; - } else { - qWarning("QGLTempContext: Error creating EGL context."); - eglDestroySurface(display, surface); - XDestroyWindow(X11->display, window); - } - XFree(vi); + EGL_NONE + }; + context = eglCreateContext(display, config, 0, contextAttribs); + if (context != EGL_NO_CONTEXT + && eglMakeCurrent(display, surface, surface, context)) + { + initialized = true; + } else { + qWarning("QGLTempContext: Error creating EGL context."); + eglDestroySurface(display, surface); + XDestroyWindow(X11->display, window); } + XFree(vi); + } ~QGLTempContext() { if (initialized) { @@ -349,7 +349,7 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo - + #if !defined(QT_NO_XRENDER) if (vi.visualid == 0 && useArgbVisual) { // Try to use XRender to find an ARGB visual we can use -- cgit v0.12 From 6026436f0de6020252410c021e0745a22599b159 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Thu, 7 Jan 2010 16:13:14 +0100 Subject: Fix performance regression in _q_polishItems. QSet is a hash internally, using Iterator::begin while erasing elements inside the set might create holes and then the complexity increase. We now use the return value of erase (the next element) so the complexity is linear. For those who create/delete item in the polish event (BAD), _q_polishItem might be slower than the normal call. Task-number:QTBUG-6958 Reviewed-by:olivier --- src/gui/graphicsview/qgraphicsscene.cpp | 17 +++++++++++------ src/gui/graphicsview/qgraphicsscene_p.h | 1 + tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 774a6d3..ceb810b 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -292,6 +292,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() processDirtyItemsEmitted(false), selectionChanging(0), needSortTopLevelItems(true), + unpolishedItemsModified(true), holesInTopLevelSiblingIndex(false), topLevelSequentialOrdering(true), scenePosDescendantsUpdatePending(false), @@ -428,12 +429,12 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) */ void QGraphicsScenePrivate::_q_polishItems() { - QSet::Iterator it; + QSet::Iterator it = unpolishedItems.begin(); const QVariant booleanTrueVariant(true); while (!unpolishedItems.isEmpty()) { - it = unpolishedItems.begin(); QGraphicsItem *item = *it; - unpolishedItems.erase(it); + it = unpolishedItems.erase(it); + unpolishedItemsModified = false; if (!item->d_ptr->explicitlyHidden) { item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); @@ -442,6 +443,8 @@ void QGraphicsScenePrivate::_q_polishItems() QEvent event(QEvent::Polish); QApplication::sendEvent((QGraphicsWidget *)item, &event); } + if (unpolishedItemsModified) + it = unpolishedItems.begin(); } } @@ -636,6 +639,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) hoverItems.removeAll(item); cachedItemsUnderMouse.removeAll(item); unpolishedItems.remove(item); + unpolishedItemsModified = true; resetDirtyItem(item); //We remove all references of item from the sceneEventFilter arrays @@ -2577,9 +2581,10 @@ void QGraphicsScene::addItem(QGraphicsItem *item) item->d_ptr->resolveFont(d->font.resolve()); item->d_ptr->resolvePalette(d->palette.resolve()); - if (d->unpolishedItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); - d->unpolishedItems.insert(item); + if (d->unpolishedItems.isEmpty()) + QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); + d->unpolishedItems.insert(item); + d->unpolishedItemsModified = true; // Reenable selectionChanged() for individual items --d->selectionChanging; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 69e4d5b..f6ec0aa 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -111,6 +111,7 @@ public: QSet unpolishedItems; QList topLevelItems; bool needSortTopLevelItems; + bool unpolishedItemsModified; bool holesInTopLevelSiblingIndex; bool topLevelSequentialOrdering; diff --git a/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp index 1944219..53fd9b6 100644 --- a/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp @@ -64,6 +64,7 @@ private slots: void addItem(); void itemAt_data(); void itemAt(); + void initialShow(); }; tst_QGraphicsScene::tst_QGraphicsScene() @@ -227,5 +228,21 @@ void tst_QGraphicsScene::itemAt() qApp->processEvents(); } +void tst_QGraphicsScene::initialShow() +{ + QGraphicsScene scene; + + QBENCHMARK { + for (int y = 0; y < 30000; ++y) { + QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 50, 50); + item->setPos((y/2) * item->rect().width(), (y/2) * item->rect().height()); + scene.addItem(item); + } + scene.itemAt(0, 0); // triggers indexing + //This call polish the items so we bench their processing too. + qApp->processEvents(); + } +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" -- cgit v0.12 From f8e08419c78e94d32273c8b039dd48dc9d5e3433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Thu, 7 Jan 2010 16:14:07 +0100 Subject: Reset the GL stencil mask, op and function in resetGLState(). Task-number: QTBUG-7203 Reviewed-by: Samuel --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5901601..ff096c2 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -559,6 +559,9 @@ void QGL2PaintEngineExPrivate::resetGLState() glDepthMask(true); glDepthFunc(GL_LESS); glClearDepth(1); + glStencilMask(0xff); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_ALWAYS, 0, 0xff); } void QGL2PaintEngineEx::endNativePainting() -- cgit v0.12 From 784374ac949ecf2fdc6895908e1e4dfe938931b8 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 7 Jan 2010 17:25:13 +0200 Subject: Deploy sqlite3.sis instead of sqlite3.dll in Symbian Task-number: QTBUG-4879 Reviewed-by: Shane Kearns --- src/s60installs/s60installs.pro | 7 +++---- src/s60installs/sqlite3.sis | Bin 0 -> 286192 bytes 2 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 src/s60installs/sqlite3.sis diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index e024396..eb35419 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -35,10 +35,8 @@ symbian: { qtlibraries.pkg_postrules += qts60plugindeployment sqlitedeployment = \ - "; Deploy sqlite onto phone that does not have it (this should be replaced with embedded sis file when available)" \ - "IF NOT package(0x2002533b) " \ - "\"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/sqlite3.dll\" - \"c:\\sys\\bin\\sqlite3.dll\"" \ - "ENDIF" + "; Deploy sqlite onto phone that does not have it already" \ + "@\"sqlite3.sis\", (0x2002af5f)" qtlibraries.pkg_postrules += sqlitedeployment qtlibraries.path = c:/sys/bin @@ -61,6 +59,7 @@ symbian: { contains(CONFIG, stl) { qtlibraries.pkg_prerules += "(0x2000F866), 1, 0, 0, {\"Standard C++ Library Common\"}" } + qtlibraries.pkg_prerules += "(0x2002af5f), 0, 5, 0, {\"sqlite3\"}" !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += qjpeg.dll !contains(QT_CONFIG, no-gif): imageformats_plugins.sources += qgif.dll diff --git a/src/s60installs/sqlite3.sis b/src/s60installs/sqlite3.sis new file mode 100644 index 0000000..1785365 Binary files /dev/null and b/src/s60installs/sqlite3.sis differ -- cgit v0.12 From a010d26629e8aa5aaa14a7e57ace06708fc903d6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 7 Jan 2010 18:32:45 +0100 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( 99ccc1c3e4db5354246720f9b9aa3d282e64497d ) Changes in WebKit/qt since the last update: ++ b/WebKit/qt/ChangeLog 2010-01-07 Yael Aharon Reviewed by Kenneth Rohde Christiansen. [Qt] Allow the application to override online/offline network status https://bugs.webkit.org/show_bug.cgi?id=32684 Add a setting so that applications can overide the network status. Applications that use this setting still need to block network access through QNAM. * Api/qwebsettings.cpp: (qt_networkAccessAllowed): --- .../webkit/JavaScriptCore/API/JSClassRef.cpp | 17 ++++++------ src/3rdparty/webkit/JavaScriptCore/ChangeLog | 23 +++++++++++++++++ .../webkit/JavaScriptCore/runtime/Structure.h | 6 +++++ src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 30 ++++++++++++++++++++++ src/3rdparty/webkit/WebCore/WebCore.pro | 4 +-- .../platform/network/NetworkStateNotifier.h | 6 ++++- .../network/qt/NetworkStateNotifierPrivate.h | 2 ++ .../platform/network/qt/NetworkStateNotifierQt.cpp | 25 +++++++++++++++--- src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp | 11 ++++++++ src/3rdparty/webkit/WebKit/qt/ChangeLog | 14 ++++++++++ 11 files changed, 124 insertions(+), 16 deletions(-) diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp b/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp index afde7ce..3785bab 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp @@ -61,8 +61,8 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (const JSStaticValue* staticValue = definition->staticValues) { m_staticValues = new OpaqueJSClassStaticValuesTable(); while (staticValue->name) { - m_staticValues->add(UString::Rep::createFromUTF8(staticValue->name), - new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes)); + StaticValueEntry* e = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes); + m_staticValues->add(UString::Rep::createFromUTF8(staticValue->name), e); ++staticValue; } } @@ -70,8 +70,8 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (const JSStaticFunction* staticFunction = definition->staticFunctions) { m_staticFunctions = new OpaqueJSClassStaticFunctionsTable(); while (staticFunction->name) { - m_staticFunctions->add(UString::Rep::createFromUTF8(staticFunction->name), - new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes)); + StaticFunctionEntry* e = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes); + m_staticFunctions->add(UString::Rep::createFromUTF8(staticFunction->name), e); ++staticFunction; } } @@ -149,8 +149,9 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end(); for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) { ASSERT(!it->first->identifierTable()); - staticValues->add(UString::Rep::createCopying(it->first->data(), it->first->size()), - new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes)); + StaticValueEntry* e = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes); + staticValues->add(UString::Rep::createCopying(it->first->data(), it->first->size()), e); + } } else @@ -162,8 +163,8 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end(); for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) { ASSERT(!it->first->identifierTable()); - staticFunctions->add(UString::Rep::createCopying(it->first->data(), it->first->size()), - new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes)); + StaticFunctionEntry* e = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes); + staticFunctions->add(UString::Rep::createCopying(it->first->data(), it->first->size()), e); } } else diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 1694966..e292418 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,26 @@ +2010-01-07 Norbert Leser + + Reviewed by NOBODY (OOPS!). + + RVCT compiler with "-Otime -O3" optimization tries to optimize out + inline new'ed pointers that are passed as arguments. + Proposed patch assigns new'ed pointer explicitly outside function call. + + * API/JSClassRef.cpp: + (OpaqueJSClass::OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + +2010-01-07 Norbert Leser + + Reviewed by NOBODY (OOPS!). + + Added time-based optimization and increased optimization level to O3, + conditionally for COMPILER(RVCT), + for increasing performance of JavaScript execution. + (Default settings are Ospace and O2) + + * runtime/Structure.h: + 2009-11-19 Thiago Macieira Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h index f355c53..ecdd997 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h @@ -45,6 +45,12 @@ #define DUMP_PROPERTYMAP_STATS 0 #endif +#if COMPILER(RVCT) +#pragma arm +#pragma Otime +#pragma O3 +#endif + namespace JSC { class MarkStack; diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 6b107cd..0b88429 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - b217cdfedc7b5e7581325bda718192247f03dd5d + 99ccc1c3e4db5354246720f9b9aa3d282e64497d diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index acc8a6a..516fadd 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,33 @@ +2010-01-07 Yael Aharon + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Allow the application to override online/offline network status + https://bugs.webkit.org/show_bug.cgi?id=32684 + + Added API to NetworkStateNotifier for forcing network status. + + * platform/network/NetworkStateNotifier.h: + * platform/network/qt/NetworkStateNotifierPrivate.h: + * platform/network/qt/NetworkStateNotifierQt.cpp: + (WebCore::NetworkStateNotifierPrivate::NetworkStateNotifierPrivate): + (WebCore::NetworkStateNotifierPrivate::onlineStateChanged): + (WebCore::NetworkStateNotifierPrivate::networkAccessPermissionChanged): + (WebCore::NetworkStateNotifier::updateState): + (WebCore::NetworkStateNotifier::NetworkStateNotifier): + (WebCore::NetworkStateNotifier::setNetworkAccessAllowed): + +2010-01-07 Simon Hausmann + + Reviewed by Tor Arne Vestbø. + + [Qt] Fix linkage against Qt mobility API bearer management module + + Use the documented .pro file syntax to link against the correct + library and (more importantly) get the include paths correct. + + * WebCore.pro: + 2010-01-07 Laszlo Gombos Reviewed by NOBODY (OOPS!). diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index be64e3b..3eba696 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -2876,8 +2876,8 @@ contains(DEFINES, ENABLE_QT_BEARER=1) { SOURCES += \ platform/network/qt/NetworkStateNotifierQt.cpp - LIBS += -lQtBearer - + CONFIG += mobility + MOBILITY += bearer } contains(DEFINES, ENABLE_SVG=1) { diff --git a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h index f8c5654..700a062 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h +++ b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h @@ -56,7 +56,11 @@ public: void setNetworkStateChangedFunction(void (*)()); bool onLine() const { return m_isOnLine; } - + +#if (PLATFORM(QT) && ENABLE(QT_BEARER)) + void setNetworkAccessAllowed(bool); +#endif + private: bool m_isOnLine; void (*m_networkStateChangedFunction)(); diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h index 7af6392..536b06a 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h @@ -37,10 +37,12 @@ public: ~NetworkStateNotifierPrivate(); public slots: void onlineStateChanged(bool); + void networkAccessPermissionChanged(bool); public: QtMobility::QNetworkConfigurationManager* m_configurationManager; bool m_online; + bool m_networkAccessAllowed; NetworkStateNotifier* m_notifier; }; diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp index f74398b..e694264 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp @@ -30,6 +30,7 @@ namespace WebCore { NetworkStateNotifierPrivate::NetworkStateNotifierPrivate(NetworkStateNotifier* notifier) : m_configurationManager(new QNetworkConfigurationManager()) , m_online(m_configurationManager->isOnline()) + , m_networkAccessAllowed(true) , m_notifier(notifier) { Q_ASSERT(notifier); @@ -42,7 +43,18 @@ void NetworkStateNotifierPrivate::onlineStateChanged(bool isOnline) return; m_online = isOnline; - m_notifier->updateState(); + if (m_networkAccessAllowed) + m_notifier->updateState(); +} + +void NetworkStateNotifierPrivate::networkAccessPermissionChanged(bool isAllowed) +{ + if (isAllowed == m_networkAccessAllowed) + return; + + m_networkAccessAllowed = isAllowed; + if (m_online) + m_notifier->updateState(); } NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate() @@ -52,10 +64,10 @@ NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate() void NetworkStateNotifier::updateState() { - if (m_isOnLine == p->m_online) + if (m_isOnLine == (p->m_online && p->m_networkAccessAllowed)) return; - m_isOnLine = p->m_online; + m_isOnLine = p->m_online && p->m_networkAccessAllowed; if (m_networkStateChangedFunction) m_networkStateChangedFunction(); } @@ -65,7 +77,12 @@ NetworkStateNotifier::NetworkStateNotifier() , m_networkStateChangedFunction(0) { p = new NetworkStateNotifierPrivate(this); - m_isOnLine = p->m_online; + m_isOnLine = p->m_online && p->m_networkAccessAllowed; +} + +void NetworkStateNotifier::setNetworkAccessAllowed(bool isAllowed) +{ + p->networkAccessPermissionChanged(isAllowed); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp index b637d04..79ef16f 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp @@ -47,6 +47,17 @@ #include #include +#if ENABLE(QT_BEARER) +#include "NetworkStateNotifier.h" +#endif + +void QWEBKIT_EXPORT qt_networkAccessAllowed(bool isAllowed) +{ +#if ENABLE(QT_BEARER) + WebCore::networkStateNotifier().setNetworkAccessAllowed(isAllowed); +#endif +} + class QWebSettingsPrivate { public: QWebSettingsPrivate(WebCore::Settings* wcSettings = 0) diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index d7c3c52..31fad69 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,17 @@ +2010-01-07 Yael Aharon + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Allow the application to override online/offline network status + https://bugs.webkit.org/show_bug.cgi?id=32684 + + Add a setting so that applications can overide the network status. + Applications that use this setting still need to block network access + through QNAM. + + * Api/qwebsettings.cpp: + (qt_networkAccessAllowed): + 2010-01-07 Yongjun Zhang , Laszlo Gombos Reviewed by Simon Hausmann. -- cgit v0.12 From 23f9444055edcaeb79fa680523800ad11671cece Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Thu, 7 Jan 2010 19:28:51 +0100 Subject: make it possible to retrieve name of the user who owns the file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QFSFileEngine::owner(OwnerUser) now works as expected Merge-request: 815 Reviewed-by: João Abecasis --- src/corelib/io/qfsfileengine_win.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index d8b6b00..1c0d5cf 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1731,7 +1731,8 @@ QString QFSFileEngine::owner(FileOwner own) const if(ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { if(ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT, own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, - NULL, &pOwner, NULL, NULL, &pSD) == ERROR_SUCCESS) { + own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, + 0, 0, &pSD) == ERROR_SUCCESS) { DWORD lowner = 0, ldomain = 0; SID_NAME_USE use; // First call, to determine size of the strings (with '\0'). -- cgit v0.12 From c24d7011e3e0cd84ce5bce4755ee9a6473bd60c0 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Thu, 7 Jan 2010 19:28:52 +0100 Subject: fix styling; improve readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * tabs -> spaces; * if( -> if ( * some strings rearranged. no code changes! Merge-request: 815 Reviewed-by: João Abecasis --- src/corelib/io/qfsfileengine_win.cpp | 69 +++++++++++++++++------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 1c0d5cf..1c3c801 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1419,22 +1419,20 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const #if !defined(QT_NO_LIBRARY) if((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { - PSID pOwner = 0; - PSID pGroup = 0; - PACL pDacl; - PSECURITY_DESCRIPTOR pSD; - ACCESS_MASK access_mask; - - enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 }; resolveLibs(); if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) { + enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 }; QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; + PSID pOwner = 0; + PSID pGroup = 0; + PACL pDacl; + PSECURITY_DESCRIPTOR pSD; DWORD res = ptrGetNamedSecurityInfoW((wchar_t*)fname.utf16(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &pOwner, &pGroup, &pDacl, 0, &pSD); - if(res == ERROR_SUCCESS) { + ACCESS_MASK access_mask; TRUSTEE_W trustee; { //user if(ptrGetEffectiveRightsFromAclW(pDacl, ¤tUserTrusteeW, &access_mask) != ERROR_SUCCESS) @@ -1722,34 +1720,33 @@ QString QFSFileEngine::owner(FileOwner own) const { #if !defined(QT_NO_LIBRARY) Q_D(const QFSFileEngine); - if((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { - PSID pOwner = 0; - PSECURITY_DESCRIPTOR pSD; - QString name; - QFSFileEnginePrivate::resolveLibs(); - - if(ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { - if(ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT, - own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, - own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, - 0, 0, &pSD) == ERROR_SUCCESS) { - DWORD lowner = 0, ldomain = 0; - SID_NAME_USE use; - // First call, to determine size of the strings (with '\0'). - ptrLookupAccountSidW(NULL, pOwner, NULL, &lowner, NULL, &ldomain, (SID_NAME_USE*)&use); - wchar_t *owner = new wchar_t[lowner]; - wchar_t *domain = new wchar_t[ldomain]; - // Second call, size is without '\0' - if(ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner, &lowner, - (LPWSTR)domain, &ldomain, (SID_NAME_USE*)&use)) { - name = QString::fromUtf16((ushort*)owner); - } - LocalFree(pSD); - delete [] owner; - delete [] domain; - } - } - return name; + if ((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { + QString name; + QFSFileEnginePrivate::resolveLibs(); + if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { + PSID pOwner = 0; + PSECURITY_DESCRIPTOR pSD; + if (ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT, + own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, + own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, + 0, 0, &pSD) == ERROR_SUCCESS) { + DWORD lowner = 0, ldomain = 0; + SID_NAME_USE use; + // First call, to determine size of the strings (with '\0'). + ptrLookupAccountSidW(NULL, pOwner, NULL, &lowner, NULL, &ldomain, (SID_NAME_USE*)&use); + wchar_t *owner = new wchar_t[lowner]; + wchar_t *domain = new wchar_t[ldomain]; + // Second call, size is without '\0' + if (ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner, &lowner, + (LPWSTR)domain, &ldomain, (SID_NAME_USE*)&use)) { + name = QString::fromUtf16((ushort*)owner); + } + LocalFree(pSD); + delete [] owner; + delete [] domain; + } + } + return name; } #else Q_UNUSED(own); -- cgit v0.12 From 428a624f73ed03a311f572386de1a518ad3d5d5a Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Thu, 7 Jan 2010 19:28:52 +0100 Subject: improve readability a bit more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 815 Reviewed-by: João Abecasis --- src/corelib/io/qfsfileengine_win.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 1c3c801..c3ea08a 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1718,27 +1718,28 @@ uint QFSFileEngine::ownerId(FileOwner /*own*/) const QString QFSFileEngine::owner(FileOwner own) const { + QString name; #if !defined(QT_NO_LIBRARY) Q_D(const QFSFileEngine); + if ((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { - QString name; QFSFileEnginePrivate::resolveLibs(); if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { PSID pOwner = 0; PSECURITY_DESCRIPTOR pSD; if (ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT, - own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, - own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, - 0, 0, &pSD) == ERROR_SUCCESS) { + own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, + own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, + 0, 0, &pSD) == ERROR_SUCCESS) { DWORD lowner = 0, ldomain = 0; - SID_NAME_USE use; + SID_NAME_USE use = SidTypeUnknown; // First call, to determine size of the strings (with '\0'). ptrLookupAccountSidW(NULL, pOwner, NULL, &lowner, NULL, &ldomain, (SID_NAME_USE*)&use); wchar_t *owner = new wchar_t[lowner]; wchar_t *domain = new wchar_t[ldomain]; // Second call, size is without '\0' if (ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner, &lowner, - (LPWSTR)domain, &ldomain, (SID_NAME_USE*)&use)) { + (LPWSTR)domain, &ldomain, (SID_NAME_USE*)&use)) { name = QString::fromUtf16((ushort*)owner); } LocalFree(pSD); @@ -1746,12 +1747,11 @@ QString QFSFileEngine::owner(FileOwner own) const delete [] domain; } } - return name; } #else Q_UNUSED(own); #endif - return QString(); + return name; } bool QFSFileEngine::setPermissions(uint perms) -- cgit v0.12 From 751de8211033b40c66d88140137eef76e6b20cfa Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Thu, 7 Jan 2010 19:28:53 +0100 Subject: Avoid repeatedly calling LookupAccountSid in QFSFileEngine::owner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to retrieve user/group name in a single call to LookupAccountSid, by using pre-allocated buffers. Only call a second time if the buffer size is insufficient. 64 bytes should be enough in common case. Previously, we would always call LookupAccountSid twice, even if ERROR_NONE_MAPPED occured first time. Merge-request: 815 Reviewed-by: João Abecasis --- src/corelib/io/qfsfileengine_win.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index c3ea08a..bec0075 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1731,20 +1731,31 @@ QString QFSFileEngine::owner(FileOwner own) const own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, 0, 0, &pSD) == ERROR_SUCCESS) { - DWORD lowner = 0, ldomain = 0; + DWORD lowner = 64; + DWORD ldomain = 64; + QVarLengthArray owner(lowner); + QVarLengthArray domain(ldomain); SID_NAME_USE use = SidTypeUnknown; // First call, to determine size of the strings (with '\0'). - ptrLookupAccountSidW(NULL, pOwner, NULL, &lowner, NULL, &ldomain, (SID_NAME_USE*)&use); - wchar_t *owner = new wchar_t[lowner]; - wchar_t *domain = new wchar_t[ldomain]; - // Second call, size is without '\0' - if (ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner, &lowner, - (LPWSTR)domain, &ldomain, (SID_NAME_USE*)&use)) { - name = QString::fromUtf16((ushort*)owner); + if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, + (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + if (lowner > (DWORD)owner.size()) + owner.resize(lowner); + if (ldomain > (DWORD)domain.size()) + domain.resize(ldomain); + // Second call, try on resized buf-s + if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, + (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { + lowner = 0; + } + } else { + lowner = 0; + } } + if (lowner != 0) + name = QString::fromWCharArray(owner.data()); LocalFree(pSD); - delete [] owner; - delete [] domain; } } } -- cgit v0.12 From 785767e1f965a904765bab5dbfff1a21240dcc88 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Thu, 7 Jan 2010 20:15:14 +0100 Subject: Fix a painter warning when using a treewidget with animations in a splitter and the tree is collapsed, and then select an item in the tree that requires expanding, it might end up trying to paint to an invalid pixmap Reviewed-by: Gabi --- src/gui/itemviews/qtreeview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index bcf9cfb..bf88a75 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -3064,6 +3064,8 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons { Q_Q(const QTreeView); QPixmap pixmap(rect.size()); + if (rect.size().isEmpty()) + return pixmap; pixmap.fill(Qt::transparent); //the base might not be opaque, and we don't want uninitialized pixels. QPainter painter(&pixmap); painter.fillRect(QRect(QPoint(0,0), rect.size()), q->palette().base()); -- cgit v0.12 From dbbf451755d34be44f6b7ac2e7c03ffe5528fb1b Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Fri, 8 Jan 2010 09:27:09 +1000 Subject: QAudioInput loses data on Maemo5/other linux platforms. The alsa backend was calculating sample timer on resume using buffer_time instead of period_time. Task-number:QTBUG-7044 Reviewed-by:Justin McPherson --- src/multimedia/audio/qaudioinput_alsa_p.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index 096b7ca..fc612fe 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -534,7 +534,7 @@ void QAudioInputPrivate::resume() resuming = true; deviceState = QAudio::ActiveState; int chunks = buffer_size/period_size; - timer->start(buffer_time*chunks/2000); + timer->start(period_time*chunks/2000); emit stateChanged(deviceState); } } -- cgit v0.12 From 4378b168ad289e1acbde9580b750ce04b51260c3 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Fri, 8 Jan 2010 09:54:48 +0200 Subject: Fix for QTBUG-5870 QGraphicsProxyWidget does not show children on Symbian. QS60PaintEngine returned wrong device in QPaintEngine::paintDevice(). Task-number: QTBUG-5870 Reviewed-by: Jason Barron --- src/gui/painting/qpaintengine_s60.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp index 6f4f398..c5840f1 100644 --- a/src/gui/painting/qpaintengine_s60.cpp +++ b/src/gui/painting/qpaintengine_s60.cpp @@ -47,18 +47,25 @@ QT_BEGIN_NAMESPACE class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate { public: - QS60PaintEnginePrivate(QS60PaintEngine *engine) { Q_UNUSED(engine); } + QS60PaintEnginePrivate() {} }; QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PixmapData *data) - : QRasterPaintEngine(*(new QS60PaintEnginePrivate(this)), device), pixmapData(data) + : QRasterPaintEngine(*(new QS60PaintEnginePrivate), device), pixmapData(data) { } bool QS60PaintEngine::begin(QPaintDevice *device) { + Q_D(QS60PaintEngine); + pixmapData->beginDataAccess(); - return QRasterPaintEngine::begin(device); + bool ret = QRasterPaintEngine::begin(device); + // Make sure QPaintEngine::paintDevice() returns the proper device. + // QRasterPaintEngine changes pdev to QImage in case of RasterClass QPixmapData + // which is incorrect in Symbian. + d->pdev = device; + return ret; } bool QS60PaintEngine::end() -- cgit v0.12 From 73f7772da8271428ec80efed00c8881638149e46 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 7 Jan 2010 13:50:41 +0100 Subject: QNAM HTTP: fix the caching algorithm from RFC 2616 Reviewed-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index dda799d..efd0a93 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -419,17 +419,21 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, int age_value = 0; it = cacheHeaders.findRawHeader("age"); if (it != cacheHeaders.rawHeaders.constEnd()) - age_value = QNetworkHeadersPrivate::fromHttpDate(it->second).toTime_t(); + age_value = it->second.toInt(); + QDateTime dateHeader; int date_value = 0; it = cacheHeaders.findRawHeader("date"); - if (it != cacheHeaders.rawHeaders.constEnd()) - date_value = QNetworkHeadersPrivate::fromHttpDate(it->second).toTime_t(); + if (it != cacheHeaders.rawHeaders.constEnd()) { + dateHeader = QNetworkHeadersPrivate::fromHttpDate(it->second); + date_value = dateHeader.toTime_t(); + } int now = currentDateTime.toUTC().toTime_t(); int request_time = now; int response_time = now; + // Algorithm from RFC 2616 section 13.2.3 int apparent_age = qMax(0, response_time - date_value); int corrected_received_age = qMax(apparent_age, age_value); int response_delay = response_time - request_time; @@ -453,7 +457,9 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, } } - int freshness_lifetime = currentDateTime.secsTo(expirationDate); + // the cache-saving code below sets the expirationDate with date+max_age + // if "max-age" is present, or to Expires otherwise + int freshness_lifetime = dateHeader.secsTo(expirationDate); bool response_is_fresh = (freshness_lifetime > current_age); if (!response_is_fresh && CacheLoadControlAttribute == QNetworkRequest::PreferNetwork) -- cgit v0.12 From e49aee9f7f82a004f41dc83ac1139e1897fa90ee Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 7 Jan 2010 13:51:48 +0100 Subject: QNAM HTTP: change the caching semantics to match documentation PreferCache should not use the network even if must-revalidate is set. But if it is not fresh enough, then it should use the network. Reviewed-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index efd0a93..c2a4079 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -385,6 +385,15 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, QNetworkHeadersPrivate::RawHeadersList::ConstIterator it; cacheHeaders.setAllRawHeaders(metaData.rawHeaders()); + if (CacheLoadControlAttribute == QNetworkRequest::PreferNetwork) { + it = cacheHeaders.findRawHeader("Cache-Control"); + if (it != cacheHeaders.rawHeaders.constEnd()) { + QHash cacheControl = parseHttpOptionHeader(it->second); + if (cacheControl.contains("must-revalidate")) + return; + } + } + it = cacheHeaders.findRawHeader("etag"); if (it != cacheHeaders.rawHeaders.constEnd()) httpRequest.setHeaderField("If-None-Match", it->second); @@ -393,12 +402,6 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, if (lastModified.isValid()) httpRequest.setHeaderField("If-Modified-Since", QNetworkHeadersPrivate::toHttpDate(lastModified)); - it = cacheHeaders.findRawHeader("Cache-Control"); - if (it != cacheHeaders.rawHeaders.constEnd()) { - QHash cacheControl = parseHttpOptionHeader(it->second); - if (cacheControl.contains("must-revalidate")) - return; - } /* * age_value @@ -462,7 +465,7 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, int freshness_lifetime = dateHeader.secsTo(expirationDate); bool response_is_fresh = (freshness_lifetime > current_age); - if (!response_is_fresh && CacheLoadControlAttribute == QNetworkRequest::PreferNetwork) + if (!response_is_fresh) return; loadedFromCache = true; -- cgit v0.12 From 2f10f91596b12b5b0c7d57b4575ea4e3b232ee0a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 7 Jan 2010 13:54:28 +0100 Subject: QNAM HTTP: just use the expirationDate in the code that validates the cache The max-age handling is already done in the cache-saving code. Reviewed-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index c2a4079..12b10f9 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -402,7 +402,10 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, if (lastModified.isValid()) httpRequest.setHeaderField("If-Modified-Since", QNetworkHeadersPrivate::toHttpDate(lastModified)); + QDateTime currentDateTime = QDateTime::currentDateTime(); + QDateTime expirationDate = metaData.expirationDate(); +#if 0 /* * age_value * is the value of Age: header received by the cache with @@ -418,7 +421,6 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, * now * is the current (local) time */ - QDateTime currentDateTime = QDateTime::currentDateTime(); int age_value = 0; it = cacheHeaders.findRawHeader("age"); if (it != cacheHeaders.rawHeaders.constEnd()) @@ -445,7 +447,6 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, int current_age = corrected_initial_age + resident_time; // RFC 2616 13.2.4 Expiration Calculations - QDateTime expirationDate = metaData.expirationDate(); if (!expirationDate.isValid()) { if (lastModified.isValid()) { int diff = currentDateTime.secsTo(lastModified); @@ -464,6 +465,9 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, // if "max-age" is present, or to Expires otherwise int freshness_lifetime = dateHeader.secsTo(expirationDate); bool response_is_fresh = (freshness_lifetime > current_age); +#else + bool response_is_fresh = currentDateTime.secsTo(expirationDate) >= 0; +#endif if (!response_is_fresh) return; -- cgit v0.12 From 1484008e831a6b18272babb17992c4de686da045 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 8 Jan 2010 10:57:43 +0100 Subject: Make sure the rect in QPixmap::copy() doesn't exceed the boundingRect. Task: http://bugreports.qt.nokia.com/browse/QTBUG-6303 Reviewed-by: Samuel --- src/gui/image/qpixmap.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 7e4597e..7b522f5 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -357,7 +357,9 @@ QPixmap QPixmap::copy(const QRect &rect) const if (isNull()) return QPixmap(); - const QRect r = rect.isEmpty() ? QRect(0, 0, width(), height()) : rect; + QRect r(0, 0, width(), height()); + if (!rect.isEmpty()) + r = r.intersected(rect); QPixmapData *d = data->createCompatiblePixmapData(); d->copy(data.data(), r); -- cgit v0.12 From 1f8fa41e78b4174ab64953dd80a1d562b0afc5aa Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 8 Jan 2010 12:30:43 +0200 Subject: Added mention of Symbian binary packages to INSTALL file Task-number: QTBUG-6162 Reviewed-by: TrustMe --- dist/README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dist/README b/dist/README index e7dfb19..73c8be1 100644 --- a/dist/README +++ b/dist/README @@ -26,6 +26,10 @@ For Mac OS X Cocoa, the binary package requires Mac OS X 10.5 (Leopard) or later and GCC 4.0.1 to develop applications. Its applications will run on Mac OS X 10.5 and above. +If you want to install the precompiled binary package for Symbian, +follow these instructions: +http://qt.nokia.com/doc/%SHORTVERSION%/install-symbian-installer.html + DEMOS AND EXAMPLES -- cgit v0.12 From 7e5861de8019b7d383e2b2ad8cc3c46f1c3ef0bd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 7 Jan 2010 13:55:19 +0100 Subject: Autotest: add a test for QNAM's HTTP cache handling code --- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 203 ++++++++++++++++++++++++- 1 file changed, 202 insertions(+), 1 deletion(-) diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 20cf922..33753f1 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -198,6 +199,8 @@ private Q_SLOTS: #endif void ioGetFromHttpBrokenServer_data(); void ioGetFromHttpBrokenServer(); + void ioGetFromHttpWithCache_data(); + void ioGetFromHttpWithCache(); void ioGetWithManyProxies_data(); void ioGetWithManyProxies(); @@ -318,8 +321,9 @@ public: QByteArray dataToTransmit; QByteArray receivedData; bool doClose; + int totalConnections; - MiniHttpServer(const QByteArray &data) : client(0), dataToTransmit(data), doClose(true) + MiniHttpServer(const QByteArray &data) : client(0), dataToTransmit(data), doClose(true), totalConnections(0) { listen(); connect(this, SIGNAL(newConnection()), this, SLOT(doAccept())); @@ -329,6 +333,7 @@ public slots: void doAccept() { client = nextPendingConnection(); + ++totalConnections; connect(client, SIGNAL(readyRead()), this, SLOT(sendData())); } @@ -379,6 +384,61 @@ public: } }; +class MyMemoryCache: public QAbstractNetworkCache +{ +public: + typedef QPair CachedContent; + typedef QHash CacheData; + CacheData cache; + + MyMemoryCache(QObject *parent) : QAbstractNetworkCache(parent) {} + + QNetworkCacheMetaData metaData(const QUrl &url) + { + return cache.value(url.toEncoded()).first; + } + + void updateMetaData(const QNetworkCacheMetaData &metaData) + { + cache[metaData.url().toEncoded()].first = metaData; + } + + QIODevice *data(const QUrl &url) + { + CacheData::ConstIterator it = cache.find(url.toEncoded()); + if (it == cache.constEnd()) + return 0; + QBuffer *io = new QBuffer(this); + io->setData(it->second); + io->open(QIODevice::ReadOnly); + io->seek(0); + return io; + } + + bool remove(const QUrl &url) + { + cache.remove(url.toEncoded()); + return true; + } + + qint64 cacheSize() const + { + qint64 total = 0; + foreach (const CachedContent &entry, cache) + total += entry.second.size(); + return total; + } + + QIODevice *prepare(const QNetworkCacheMetaData &) + { Q_ASSERT(0 && "Should not have tried to add to the cache"); return 0; } + void insert(QIODevice *) + { Q_ASSERT(0 && "Should not have tried to add to the cache"); } + + void clear() { cache.clear(); } +}; +Q_DECLARE_METATYPE(MyMemoryCache::CachedContent) +Q_DECLARE_METATYPE(MyMemoryCache::CacheData) + class DataReader: public QObject { Q_OBJECT @@ -762,6 +822,7 @@ void tst_QNetworkReply::cleanup() // clear the internal cache QNetworkAccessManagerPrivate::clearCache(&manager); manager.setProxy(QNetworkProxy()); + manager.setCache(0); // clear cookies cookieJar->setAllCookies(QList()); @@ -1984,6 +2045,146 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer() QVERIFY(reply->error() != QNetworkReply::NoError); } +void tst_QNetworkReply::ioGetFromHttpWithCache_data() +{ + qRegisterMetaType(); + QTest::addColumn("dataToSend"); + QTest::addColumn("body"); + QTest::addColumn("cachedReply"); + QTest::addColumn("cacheMode"); + QTest::addColumn("loadedFromCache"); + QTest::addColumn("networkUsed"); + + QByteArray reply200 = + "HTTP/1.0 200\r\n" + "Connection: keep-alive\r\n" + "Content-Type: text/plain\r\n" + "Cache-control: no-cache\r\n" + "Content-length: 8\r\n" + "\r\n" + "Reloaded"; + QByteArray reply304 = + "HTTP/1.0 304 Use Cache\r\n" + "Connection: keep-alive\r\n" + "\r\n"; + + QTest::newRow("not-cached,always-network") + << reply200 << "Reloaded" << MyMemoryCache::CachedContent() << int(QNetworkRequest::AlwaysNetwork) << false << true; + QTest::newRow("not-cached,prefer-network") + << reply200 << "Reloaded" << MyMemoryCache::CachedContent() << int(QNetworkRequest::PreferNetwork) << false << true; + QTest::newRow("not-cached,prefer-cache") + << reply200 << "Reloaded" << MyMemoryCache::CachedContent() << int(QNetworkRequest::PreferCache) << false << true; + + QDateTime present = QDateTime::currentDateTime().toUTC(); + QDateTime past = present.addSecs(-3600); + QDateTime future = present.addSecs(3600); + static const char dateFormat[] = "ddd, dd MMM yyyy hh:mm:ss 'GMT'"; + + QNetworkCacheMetaData::RawHeaderList rawHeaders; + MyMemoryCache::CachedContent content; + content.second = "Not-reloaded"; + content.first.setLastModified(past); + + // + // Set to expired + // + rawHeaders.clear(); + rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1()) + << QNetworkCacheMetaData::RawHeader("Cache-control", "max-age=0"); // isn't used in cache loading + content.first.setRawHeaders(rawHeaders); + content.first.setLastModified(past); + + QTest::newRow("expired,200,prefer-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << false << true; + QTest::newRow("expired,200,prefer-cache") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferCache) << false << true; + + QTest::newRow("expired,304,prefer-network") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << true; + QTest::newRow("expired,304,prefer-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << true; + + // + // Set to not-expired + // + rawHeaders.clear(); + rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1()) + << QNetworkCacheMetaData::RawHeader("Cache-control", "max-age=7200"); // isn't used in cache loading + content.first.setRawHeaders(rawHeaders); + content.first.setExpirationDate(future); + + QTest::newRow("not-expired,200,always-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::AlwaysNetwork) << false << true; + QTest::newRow("not-expired,200,prefer-network") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << false; + QTest::newRow("not-expired,200,prefer-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("not-expired,200,always-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; + + QTest::newRow("not-expired,304,prefer-network") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << false; + QTest::newRow("not-expired,304,prefer-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("not-expired,304,always-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; + + // + // Set must-revalidate now + // + rawHeaders.clear(); + rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1()) + << QNetworkCacheMetaData::RawHeader("Cache-control", "max-age=7200, must-revalidate"); // must-revalidate is used + content.first.setRawHeaders(rawHeaders); + + QTest::newRow("must-revalidate,200,always-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::AlwaysNetwork) << false << true; + QTest::newRow("must-revalidate,200,prefer-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << false << true; + QTest::newRow("must-revalidate,200,prefer-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("must-revalidate,200,always-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; + + QTest::newRow("must-revalidate,304,prefer-network") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << true; + QTest::newRow("must-revalidate,304,prefer-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("must-revalidate,304,always-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; +} + +void tst_QNetworkReply::ioGetFromHttpWithCache() +{ + QFETCH(QByteArray, dataToSend); + MiniHttpServer server(dataToSend); + server.doClose = false; + + MyMemoryCache *memoryCache = new MyMemoryCache(&manager); + manager.setCache(memoryCache); + + QFETCH(MyMemoryCache::CachedContent, cachedReply); + QUrl url = "http://localhost:" + QString::number(server.serverPort()); + cachedReply.first.setUrl(url); + if (!cachedReply.second.isNull()) + memoryCache->cache.insert(url.toEncoded(), cachedReply); + + QFETCH(int, cacheMode); + QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, cacheMode); + request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QTEST(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), "loadedFromCache"); + QTEST(server.totalConnections > 0, "networkUsed"); + QFETCH(QString, body); + QCOMPARE(reply->readAll().constData(), qPrintable(body)); +} + void tst_QNetworkReply::ioGetWithManyProxies_data() { QTest::addColumn >("proxyList"); -- cgit v0.12 From 73629458a18ce577e0a46e61335ef92d18dac7be Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Fri, 8 Jan 2010 11:44:59 +0100 Subject: Fixes: MenuItem size fixes and missing separator with Gtk+ Task: QTBUG-6522 RevBy: thorbjorn Details: This fixes missing separator line in the Dust theme. The patch also significantly improves the accuracy of menu item size metrics by making use of gtk_widget_size_request to query things like default heights. - More accurate offset and size of separators - Fixed item height of menu items using size_request - Fixed vertical offset of label and check boxes - Fixed clipping issue on last menu item --- src/gui/styles/qgtkstyle.cpp | 51 ++++++++++++++++++++---------------------- src/gui/styles/qgtkstyle_p.cpp | 7 +++++- src/gui/styles/qgtkstyle_p.h | 3 +++ 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 41efaa3..920a0f7 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2495,7 +2495,6 @@ void QGtkStyle::drawControl(ControlElement element, const int windowsItemHMargin = 3; // menu item hor text margin const int windowsItemVMargin = 26; // menu item ver text margin const int windowsRightBorder = 15; // right border on windows - GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu")); GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")) : d->gtkWidget(QLS("GtkMenu.GtkMenuItem")); @@ -2509,6 +2508,7 @@ void QGtkStyle::drawControl(ControlElement element, gboolean wide_separators = 0; gint separator_height = 0; guint horizontal_padding = 3; + QRect separatorRect = option->rect; if (!d->gtk_check_version(2, 10, 0)) { d->gtk_widget_style_get(gtkMenuSeparator, "wide-separators", &wide_separators, @@ -2516,13 +2516,16 @@ void QGtkStyle::drawControl(ControlElement element, "horizontal-padding", &horizontal_padding, NULL); } + separatorRect.setHeight(option->rect.height() - 2 * gtkMenuSeparator->style->ythickness); + separatorRect.setWidth(option->rect.width() - 2 * (horizontal_padding + gtkMenuSeparator->style->xthickness)); + separatorRect.moveCenter(option->rect.center()); if (wide_separators) - gtkPainter.paintBox( gtkMenuSeparator, "hseparator", - option->rect.adjusted(0, 0, 0, -1), GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenu->style); + gtkPainter.paintBox( gtkMenuSeparator, "hseparator", + separatorRect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenuSeparator->style); else gtkPainter.paintHline( gtkMenuSeparator, "hseparator", - menuItem->rect, GTK_STATE_NORMAL, gtkMenu->style, - option->rect.left() + horizontal_padding, option->rect.width() - 2*horizontal_padding, 2); + separatorRect, GTK_STATE_NORMAL, gtkMenuSeparator->style, + 0, option->rect.right() - 1, 1); painter->restore(); break; } @@ -2530,7 +2533,7 @@ void QGtkStyle::drawControl(ControlElement element, bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled; if (selected) { - QRect rect = option->rect.adjusted(0, 0, 0, -1); + QRect rect = option->rect; #ifndef QT_NO_COMBOBOX if (qobject_cast(widget)) rect = option->rect; @@ -2556,7 +2559,7 @@ void QGtkStyle::drawControl(ControlElement element, #endif if (!ignoreCheckMark) { // Check - QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2, checkSize, checkSize); + QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2 + 1, checkSize, checkSize); checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect); if (checkable && menuItem->icon.isNull()) { @@ -2680,7 +2683,7 @@ void QGtkStyle::drawControl(ControlElement element, int tab = menuitem->tabWidth; int xm = windowsItemFrame + checkcol + windowsItemHMargin; int xpos = menuitem->rect.x() + xm + 1; - QRect textRect(xpos, y + windowsItemVMargin - 1, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); + QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect); QString s = menuitem->text; @@ -3150,44 +3153,38 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, newSize += QSize(6, 0); } break; - case CT_MenuItem: if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast(option)) { int textMargin = 8; if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { GtkWidget *gtkMenuSeparator = d->gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem")); - gboolean wide_separators; - gint separator_height; - d->gtk_widget_style_get(gtkMenuSeparator, - "wide-separators", &wide_separators, - "separator-height", &separator_height, - NULL); - newSize = QSize(size.width(), wide_separators ? separator_height - 1 : 7 ); - + GtkRequisition sizeReq = {0, 0}; + d->gtk_widget_size_request(gtkMenuSeparator, &sizeReq); + newSize = QSize(size.width(), sizeReq.height); break; } - GtkWidget *gtkMenuItem = d->gtkWidget(QLS("GtkMenu.GtkMenuItem")); + GtkWidget *gtkMenuItem = d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")); GtkStyle* style = gtkMenuItem->style; - newSize += QSize(textMargin + style->xthickness - 1, style->ythickness - 3); + + // Note we get the perfect height for the default font since we + // set a fake text label on the gtkMenuItem + // But if custom fonts are used on the widget we need a minimum size + GtkRequisition sizeReq = {0, 0}; + d->gtk_widget_size_request(gtkMenuItem, &sizeReq); + newSize.setHeight(qMax(newSize.height() - 4, sizeReq.height)); + newSize += QSize(textMargin + style->xthickness - 1, 0); // Cleanlooks assumes a check column of 20 pixels so we need to // expand it a bit gint checkSize; - d->gtk_widget_style_get(d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")), "indicator-size", &checkSize, NULL); - newSize.setHeight(qMax(newSize.height(), checkSize + 2)); + d->gtk_widget_style_get(gtkMenuItem, "indicator-size", &checkSize, NULL); newSize.setWidth(newSize.width() + qMax(0, checkSize - 20)); } break; - case CT_Menu: - // This is evil, but QMenu adds 1 pixel too much - newSize -= QSize(0, 1); - - break; - case CT_SpinBox: // QSpinBox does some nasty things that depends on CT_LineEdit newSize = size + QSize(0, -d->gtkWidget(QLS("GtkSpinButton"))->style->ythickness * 2); diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp index 5060be2..a033407 100644 --- a/src/gui/styles/qgtkstyle_p.cpp +++ b/src/gui/styles/qgtkstyle_p.cpp @@ -151,6 +151,7 @@ Ptr_gtk_menu_item_set_submenu QGtkStylePrivate::gtk_menu_item_set_submenu = 0; Ptr_gtk_settings_get_default QGtkStylePrivate::gtk_settings_get_default = 0; Ptr_gtk_separator_menu_item_new QGtkStylePrivate::gtk_separator_menu_item_new = 0; Ptr_gtk_widget_size_allocate QGtkStylePrivate::gtk_widget_size_allocate = 0; +Ptr_gtk_widget_size_request QGtkStylePrivate::gtk_widget_size_request = 0; Ptr_gtk_widget_set_direction QGtkStylePrivate::gtk_widget_set_direction = 0; Ptr_gtk_widget_path QGtkStylePrivate::gtk_widget_path = 0; Ptr_gtk_container_get_type QGtkStylePrivate::gtk_container_get_type = 0; @@ -159,7 +160,6 @@ Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0; Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0; Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0; Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0; - Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0; Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0; Ptr_pango_font_description_get_family QGtkStylePrivate::pango_font_description_get_family = 0; @@ -410,11 +410,13 @@ void QGtkStylePrivate::resolveGtk() const gtk_combo_box_entry_new = (Ptr_gtk_combo_box_entry_new)libgtk.resolve("gtk_combo_box_entry_new"); gtk_container_forall = (Ptr_gtk_container_forall)libgtk.resolve("gtk_container_forall"); gtk_widget_size_allocate =(Ptr_gtk_widget_size_allocate)libgtk.resolve("gtk_widget_size_allocate"); + gtk_widget_size_request =(Ptr_gtk_widget_size_request)libgtk.resolve("gtk_widget_size_request"); gtk_widget_set_direction =(Ptr_gtk_widget_set_direction)libgtk.resolve("gtk_widget_set_direction"); gtk_widget_path =(Ptr_gtk_widget_path)libgtk.resolve("gtk_widget_path"); gtk_container_get_type =(Ptr_gtk_container_get_type)libgtk.resolve("gtk_container_get_type"); gtk_window_get_type =(Ptr_gtk_window_get_type)libgtk.resolve("gtk_window_get_type"); gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type"); + gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths"); gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version"); gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free"); @@ -447,10 +449,13 @@ void QGtkStylePrivate::initGtkMenu() const gtk_widget_realize(gtkMenu); GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new(); + g_object_set(gtkMenuItem, "label", "X", NULL); + gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem); gtk_widget_realize(gtkMenuItem); GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new(); + g_object_set(gtkCheckMenuItem, "label", "X", NULL); gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem); gtk_widget_realize(gtkCheckMenuItem); diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h index ad672db..db5b9b9 100644 --- a/src/gui/styles/qgtkstyle_p.h +++ b/src/gui/styles/qgtkstyle_p.h @@ -147,8 +147,10 @@ typedef void (*Ptr_gtk_paint_vline) (GtkStyle *, GdkWindow *, GtkStateType, co typedef void (*Ptr_gtk_menu_item_set_submenu) (GtkMenuItem *, GtkWidget *); typedef void (*Ptr_gtk_container_forall) (GtkContainer *, GtkCallback, gpointer); typedef void (*Ptr_gtk_widget_size_allocate) (GtkWidget *, GtkAllocation*); +typedef void (*Ptr_gtk_widget_size_request) (GtkWidget *widget, GtkRequisition *requisition); typedef void (*Ptr_gtk_widget_set_direction) (GtkWidget *, GtkTextDirection); typedef void (*Ptr_gtk_widget_path) (GtkWidget *, guint *, gchar **, gchar**); + typedef void (*Ptr_gtk_toolbar_insert) (GtkToolbar *toolbar, GtkToolItem *item, int pos); typedef void (*Ptr_gtk_menu_shell_append)(GtkMenuShell *, GtkWidget *); typedef GtkType (*Ptr_gtk_container_get_type) (void); @@ -365,6 +367,7 @@ public: static Ptr_gtk_settings_get_default gtk_settings_get_default; static Ptr_gtk_separator_menu_item_new gtk_separator_menu_item_new; static Ptr_gtk_widget_size_allocate gtk_widget_size_allocate; + static Ptr_gtk_widget_size_request gtk_widget_size_request; static Ptr_gtk_widget_set_direction gtk_widget_set_direction; static Ptr_gtk_widget_path gtk_widget_path; static Ptr_gtk_container_get_type gtk_container_get_type; -- cgit v0.12 From f90472009c928b3f599c182dfbab91390fdafdd9 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Fri, 8 Jan 2010 12:03:48 +0100 Subject: Fixes: Setting any style sheet breaks checkbox positioning Task: QTBUG-7198 RevBy: ogoffart Details: It was impossible to override the checkbox positioning in a custom style if any style sheet was set on the application of widget. This was because the style sheet never passed control to the base style. We now fix it by checking if the style sheet has the appropriate style rules. --- src/gui/styles/qstylesheetstyle.cpp | 12 +++++++----- tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index cf27eac..498313b 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -5611,9 +5611,6 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c case SE_ItemViewItemFocusRect: if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast(opt)) { QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem); - QStyleOptionViewItemV4 optCopy(*vopt); - optCopy.rect = subRule.contentsRect(vopt->rect); - QRect rect = ParentStyle::subElementRect(se, &optCopy, w); PseudoElement pe = PseudoElement_None; if (se == SE_ItemViewItemText || se == SE_ItemViewItemFocusRect) pe = PseudoElement_ViewItemText; @@ -5623,8 +5620,13 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c pe = PseudoElement_ViewItemIndicator; else break; - QRenderRule subRule2 = renderRule(w, opt, pe); - return positionRect(w, subRule2, pe, rect, opt->direction); + if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder() || hasStyleRule(w, pe)) { + QRenderRule subRule2 = renderRule(w, opt, pe); + QStyleOptionViewItemV4 optCopy(*vopt); + optCopy.rect = subRule.contentsRect(vopt->rect); + QRect rect = ParentStyle::subElementRect(se, &optCopy, w); + return positionRect(w, subRule2, pe, rect, opt->direction); + } } break; #endif // QT_NO_ITEMVIEWS diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index 1b2f268..e0512a9 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -1114,7 +1114,10 @@ class ProxyStyle : public QStyle const QStyleOption* opt, const QWidget* w) const { - return style->subElementRect(se, opt, w); + Q_UNUSED(se); + Q_UNUSED(opt); + Q_UNUSED(w); + return QRect(0, 0, 3, 3); } void drawComplexControl(QStyle::ComplexControl cc, @@ -1232,7 +1235,7 @@ void tst_QStyleSheetStyle::proxyStyle() pb4->setStyleSheet(styleSheet); // We are creating our Proxy based on current style... - // In this case it would be the QStyleSheetStyle that is delete + // In this case it would be the QStyleSheetStyle that is deleted // later on. We need to get access to the "real" QStyle to be able to // draw correctly. ProxyStyle* newProxy = new ProxyStyle(qApp->style()); @@ -1248,6 +1251,13 @@ void tst_QStyleSheetStyle::proxyStyle() w->show(); QTest::qWait(100); + + // Test for QTBUG-7198 - style sheet overrides custom element size + QStyleOptionViewItemV4 opt; + opt.initFrom(w); + opt.features |= QStyleOptionViewItemV2::HasCheckIndicator; + QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, + &opt, pb5).width() == 3); delete w; delete proxy; delete newProxy; -- cgit v0.12 From 32419380bdd11e7db401fd37a840e0ec4f5b6845 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 7 Jan 2010 17:46:16 +0000 Subject: Enable building with MSVC2008 Removed the alternate implementation of the registry reading, although the new API is simpler, the old XP method is not deprecated. Added an extra library that is needed according to API documentation, but is omittable on MinGW. Also gave a better error message when serial port detection fails. Reviewed-by: Miikka Heikkinen --- tools/runonphone/main.cpp | 4 ++++ tools/runonphone/runonphone.pro | 3 ++- tools/runonphone/serenum_win.cpp | 11 +---------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index e2f6758..6081e67 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -155,6 +155,10 @@ int main(int argc, char *argv[]) serialPortName = id.portName; } } + if(serialPortName.isEmpty()) { + errstream << "No phone found, ensure USB cable is connected or specify manually with -p" << endl; + return 1; + } } QScopedPointer launcher; diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro index d243121..cf0c055 100644 --- a/tools/runonphone/runonphone.pro +++ b/tools/runonphone/runonphone.pro @@ -15,5 +15,6 @@ HEADERS += trksignalhandler.h \ windows { SOURCES += serenum_win.cpp LIBS += -lsetupapi \ - -luuid + -luuid \ + -ladvapi32 } diff --git a/tools/runonphone/serenum_win.cpp b/tools/runonphone/serenum_win.cpp index ec11c3c..23e3862 100644 --- a/tools/runonphone/serenum_win.cpp +++ b/tools/runonphone/serenum_win.cpp @@ -77,8 +77,7 @@ QList enumerateSerialPorts() } HKEY key = SetupDiOpenDevRegKey(infoset, &info, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if(key != INVALID_HANDLE_VALUE) { -#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 - //RegGetValue not supported on XP, SHRegGetValue not supported by mingw :( + //RegGetValue not supported on XP, SHRegGetValue not supported by mingw, so use the old method of enumerating all the values for (DWORD dwi=0;;dwi++) { DWORD vsize = valueName.size(); if (ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, 0, &size)) { @@ -93,14 +92,6 @@ QList enumerateSerialPorts() break; } } -#else - if (ERROR_SUCCESS == SHRegGetValue(key, 0, "PortName", SRRF_RT_REG_SZ, 0, &size)) { - QByteArray ba(size, 0); - if (ERROR_SUCCESS == RegGetValue(key, 0, "PortName", SRRF_RT_REG_SZ, (BYTE*)(ba.data()), &size)) { - portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); - } - } -#endif RegCloseKey(key); } SerialPortId id; -- cgit v0.12 From bdef1a949ea32c5fe0bd2926171b813cff0cee2a Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Fri, 8 Jan 2010 12:30:14 +0100 Subject: Update changes file Task-number: QTBUG-6580 --- dist/changes-4.6.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dist/changes-4.6.1 b/dist/changes-4.6.1 index 2397228..145e09e 100644 --- a/dist/changes-4.6.1 +++ b/dist/changes-4.6.1 @@ -51,6 +51,8 @@ QtGui in the DDS, ETC1, PVRTC2, and PVRTC4 formats if the OpenGL graphics system is active and the appropriate extensions are present in the GL implementation. + - QGraphicsObject + * 'id' property was removed. Use the 'objectName' property instead. QtDBus ------ -- cgit v0.12 From a54b606aef73f49dac451a35b29456bc1584a47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 8 Jan 2010 12:31:03 +0100 Subject: Fix broken QGLWidget::renderPixmap on Mac/Carbon Task: ed2a03b3bc85be056eca87928d18a746faa07bca Reviewed-by: Trond Commit ed2a03b3bc85be056eca87928d18a746faa07bca removed all QuickDraw code and made QPixmap::macQDHandle() return 0 in all cases. Unfortunately QGLWidget::renderPixmap() depended on macQDHandle returning a valid handle, causing it to break. Fix this by inserting the macQDHandle implementation were we would call macQDHandle before. This is the only place in Qt where macQDHandle is used. --- src/opengl/qgl_mac.mm | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index ef2fa6c..6ed07e5 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -606,10 +606,22 @@ void QGLContext::updatePaintDevice() } } } else if (d->paintDevice->devType() == QInternal::Pixmap) { - QPixmap *pm = (QPixmap *)d->paintDevice; - PixMapHandle mac_pm = GetGWorldPixMap((GWorldPtr)pm->macQDHandle()); - aglSetOffScreen((AGLContext)d->cx, pm->width(), pm->height(), - GetPixRowBytes(mac_pm), GetPixBaseAddr(mac_pm)); + QPixmap *pm = reinterpret_cast(d->paintDevice); + + unsigned long qdformat = k32ARGBPixelFormat; + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) + qdformat = k32BGRAPixelFormat; + Rect rect; + SetRect(&rect, 0, 0, pm->width(), pm->height()); + + GWorldPtr gworld; + NewGWorldFromPtr(&gworld, qdformat, &rect, 0, 0, 0, + reinterpret_cast(qt_mac_pixmap_get_base(pm)), + qt_mac_pixmap_get_bytes_per_line(pm)); + + PixMapHandle pixmapHandle = GetGWorldPixMap(gworld); + aglSetOffScreen(reinterpret_cast(d->cx), pm->width(), pm->height(), + GetPixRowBytes(pixmapHandle), GetPixBaseAddr(pixmapHandle)); } else { qWarning("QGLContext::updatePaintDevice(): Not sure how to render OpenGL on this device!"); } -- cgit v0.12 From 4ba439f78aec1caef268dba0f229b8a0242e4c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 8 Jan 2010 12:33:52 +0100 Subject: Cocoa: Fix painting errors on QGLWidget resizing. Revby: Trond We need to update the GL context syncronously during the resize to prevent flicker. Use the existing MacGLWindowChange machinery to do that. --- src/gui/kernel/qcocoaview_mac.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 9950697..c14798a 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -508,6 +508,13 @@ extern "C" { } else { [self setNeedsDisplay:YES]; } + + // Make sure the opengl context is updated on resize. + if (0 && qwidgetprivate->isGLWidget) { + qwidgetprivate->needWindowChange = true; + QEvent event(QEvent::MacGLWindowChange); + qApp->sendEvent(qwidget, &event); + } } - (void)drawRect:(NSRect)aRect -- cgit v0.12 From 3aa77d64608f944592939c5d673f1b7dabec730f Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 8 Jan 2010 12:47:14 +0100 Subject: doc: Explained parameter value defaults where appropriate. Task-number: QTBUG-6607 --- doc/src/development/rcc.qdoc | 50 ++++++++++++++++++++++++-------------------- src/tools/rcc/rcc.cpp | 25 +++++++++++++++++----- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/doc/src/development/rcc.qdoc b/doc/src/development/rcc.qdoc index ff82674..8c6c8fb 100644 --- a/doc/src/development/rcc.qdoc +++ b/doc/src/development/rcc.qdoc @@ -57,37 +57,41 @@ \table \header \o Option \o Argument \o Description - \row \o \c{-o} \o \o Writes output to file rather than - stdout. + \row \o \c{-o} \o \c{file} \o Writes output to \c{file} rather than + stdout. - \row \o \c{-name} \o \c name \o Creates an external initialization - function with name. + \row \o \c{-name} \o \c{name} \o Creates an external initialization + function with \c{name}. - \row \o \c{-threshold} \o \c level \o Specifies a threshold (in bytes) - to use when compressing files. If - the file is smaller than the - threshold, it will not be - compressed, independent of what - the compression level is. + \row \o \c{-threshold} \o \c{level} \o Specifies a threshold \c{level} (in + bytes) to use when deciding whether + to compress a file. If the file is + smaller than the threshold \c{level}, + it is not compressed. The default + threshold level is 70 bytes. - \row \o \c{-compress} \o \c level \o Compresses input files with the - given level. Level is an integer - from 1 to 9 - 1 being the fastest, - producing the least compression; - 9 being the slowest, producing - the most compression. + \row \o \c{-compress} \o \c{level} \o Compress input files to the given + compression \{level}, which is an + integer in the range 1 to 9. Level 1 + does the least compression but is + fastest. Level 9 does the most + compression but is slowest. To turn + off compression, use \c{-no-compress}. + The default value for \c{level} is -1, + which means use zlib's default + compression level. - \row \o \c{-root} \o \c path \o Prefixes the resource access path - with root path. + \row \o \c{-root} \o \c{path} \o Prefix the resource access path with \c{path}. + The default is no prefix. - \row \o \c{-no-compress} \o \o Disables all compression. + \row \o \c{-no-compress} \o \o Disables all compression. - \row \o \c{-binary} \o \o Outputs a binary file for use as - a dynamic resource. + \row \o \c{-binary} \o \o Outputs a binary file for use as a dynamic resource. - \row \o \c{-version} \o \o Displays version information. + \row \o \c{-version} \o \o Displays version information. + + \row \o \c{-help} \o \o Displays usage information. - \row \o \c{-help} \o \o Displays usage information. \endtable See also \l{The Qt Resource System} for more information about embedding diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 33653d6..e41cd55 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -452,8 +452,16 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, else return false; } else if (file.isFile()) { - const bool arc = addFile(alias, RCCFileInfo(alias.section(slash, -1), file, language, country, - RCCFileInfo::NoFlags, compressLevel, compressThreshold)); + const bool arc = + addFile(alias, + RCCFileInfo(alias.section(slash, -1), + file, + language, + country, + RCCFileInfo::NoFlags, + compressLevel, + compressThreshold) + ); if (!arc) m_failedResources.push_back(absFileName); } else { @@ -473,9 +481,16 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, it.next(); QFileInfo child(it.fileInfo()); if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) { - const bool arc = addFile(alias + child.fileName(), - RCCFileInfo(child.fileName(), child, language, country, - RCCFileInfo::NoFlags, compressLevel, compressThreshold)); + const bool arc = + addFile(alias + child.fileName(), + RCCFileInfo(child.fileName(), + child, + language, + country, + RCCFileInfo::NoFlags, + compressLevel, + compressThreshold) + ); if (!arc) m_failedResources.push_back(child.fileName()); } -- cgit v0.12 From d40219cc9e0a5e078a9c9e874dc4d5f3efb98e3e Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Fri, 8 Jan 2010 12:55:20 +0100 Subject: Fixes: Fix spinbox with NoButton style in QGtkStyle Task: QTBUG-6952 RevBy: ogoffart Details: We simply need to handle this case explicitly to draw like a GtkEntry. --- src/gui/styles/qgtkstyle.cpp | 97 ++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 920a0f7..abb9e1e 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -1736,7 +1736,11 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom case CC_SpinBox: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { - GtkWidget *gtkSpinButton = d->gtkWidget(QLS("GtkSpinButton")); + + GtkWidget *gtkSpinButton = d->gtkWidget( + spinBox->buttonSymbols == QAbstractSpinBox::NoButtons ? + QLS("GtkEntry") : + QLS("GtkSpinButton")); bool isEnabled = (spinBox->state & State_Enabled); bool hover = isEnabled && (spinBox->state & State_MouseOver); bool sunken = (spinBox->state & State_Sunken); @@ -1744,32 +1748,35 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown); bool reverse = (spinBox->direction == Qt::RightToLeft); - //### Move this to subControlRect - QRect upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget); - upRect.setTop(option->rect.top()); + QRect editArea = option->rect; + QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget); + QRect upRect, downRect, buttonRect; + if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) { + upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget); + downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget); - if (reverse) - upRect.setLeft(option->rect.left()); - else - upRect.setRight(option->rect.right()); + //### Move this to subControlRect + upRect.setTop(option->rect.top()); - QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget); - QRect downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget); - downRect.setBottom(option->rect.bottom()); + if (reverse) + upRect.setLeft(option->rect.left()); + else + upRect.setRight(option->rect.right()); - if (reverse) - downRect.setLeft(option->rect.left()); - else - downRect.setRight(option->rect.right()); + downRect.setBottom(option->rect.bottom()); - QRect buttonRect = upRect | downRect; - QRect editArea = option->rect; + if (reverse) + downRect.setLeft(option->rect.left()); + else + downRect.setRight(option->rect.right()); - if (reverse) - editArea.setLeft(upRect.right()); - else - editArea.setRight(upRect.left()); + buttonRect = upRect | downRect; + if (reverse) + editArea.setLeft(upRect.right()); + else + editArea.setRight(upRect.left()); + } if (spinBox->frame) { GtkShadowType shadow = GTK_SHADOW_OUT; GtkStateType state = gtkPainter.gtkState(option); @@ -1803,29 +1810,31 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, style, key); gtkPainter.paintShadow(gtkSpinButton, "entry", editArea, state, GTK_SHADOW_IN, gtkSpinButton->style, key); - gtkPainter.paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key); - - upRect.setSize(downRect.size()); - if (!(option->state & State_Enabled)) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); - else if (upIsActive && sunken) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); - else if (upIsActive && hover) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); - else - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); - - if (!(option->state & State_Enabled)) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); - else if (downIsActive && sunken) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); - else if (downIsActive && hover) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); - else - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); + if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) { + gtkPainter.paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key); + + upRect.setSize(downRect.size()); + if (!(option->state & State_Enabled)) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); + else if (upIsActive && sunken) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); + else if (upIsActive && hover) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); + else + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); + + if (!(option->state & State_Enabled)) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); + else if (downIsActive && sunken) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); + else if (downIsActive && hover) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); + else + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); - if (option->state & State_HasFocus) - GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); + if (option->state & State_HasFocus) + GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); + } } if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) { @@ -1850,7 +1859,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom painter->drawLine(centerX - 2, centerY, centerX + 2, centerY); } - } else { + } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows) { int size = d->getSpinboxArrowSize(); int w = size / 2 - 1; w -= w % 2 - 1; // force odd -- cgit v0.12 From 8894467656973bd311bcc5822a38bdd0e171da51 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 8 Jan 2010 12:58:18 +0100 Subject: doc: Fixed typos. Task-number: QTBUG-6607 --- doc/src/development/rcc.qdoc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/doc/src/development/rcc.qdoc b/doc/src/development/rcc.qdoc index 8c6c8fb..1541e11 100644 --- a/doc/src/development/rcc.qdoc +++ b/doc/src/development/rcc.qdoc @@ -57,10 +57,9 @@ \table \header \o Option \o Argument \o Description - \row \o \c{-o} \o \c{file} \o Writes output to \c{file} rather than - stdout. + \row \o \c{-o} \o \c{file} \o Write output to \c{file} rather than to stdout. - \row \o \c{-name} \o \c{name} \o Creates an external initialization + \row \o \c{-name} \o \c{name} \o Create an external initialization function with \c{name}. \row \o \c{-threshold} \o \c{level} \o Specifies a threshold \c{level} (in @@ -71,7 +70,7 @@ threshold level is 70 bytes. \row \o \c{-compress} \o \c{level} \o Compress input files to the given - compression \{level}, which is an + compression \c{level}, which is an integer in the range 1 to 9. Level 1 does the least compression but is fastest. Level 9 does the most @@ -84,13 +83,13 @@ \row \o \c{-root} \o \c{path} \o Prefix the resource access path with \c{path}. The default is no prefix. - \row \o \c{-no-compress} \o \o Disables all compression. + \row \o \c{-no-compress} \o \o Disable compression. - \row \o \c{-binary} \o \o Outputs a binary file for use as a dynamic resource. + \row \o \c{-binary} \o \o Output a binary file for use as a dynamic resource. - \row \o \c{-version} \o \o Displays version information. + \row \o \c{-version} \o \o Display version information. - \row \o \c{-help} \o \o Displays usage information. + \row \o \c{-help} \o \o Display usage information. \endtable -- cgit v0.12 From bf4ed81813518abd9da23aec632a2d5ecc4d186d Mon Sep 17 00:00:00 2001 From: Stefano Pironato Date: Fri, 8 Jan 2010 14:22:50 +0200 Subject: Add texture glyph width cache default. For maemo6 need to increase the cache width to 1024 to avoid text corruption using SGX 1.4. Reviewed-by: Tom Cooksey Reviewed-by: Harald Fernengel --- src/gui/painting/qtextureglyphcache.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 46fbaa9..27dbcf9 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -47,6 +47,10 @@ #include "private/qnativeimage_p.h" #include "private/qfontengine_ft_p.h" +#ifndef QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH +#define QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH 256 +#endif + QT_BEGIN_NAMESPACE // #define CACHE_DEBUG @@ -112,7 +116,7 @@ void QTextureGlyphCache::populate(const QTextItemInt &ti, rowHeight += margin * 2; if (isNull()) - createCache(256, rowHeight); + createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, rowHeight); // now actually use the coords and paint the wanted glyps into cache. QHash::iterator iter = listItemCoordinates.begin(); -- cgit v0.12 From cfc1020453de7dd93760a7e94ca6d8461e6dc203 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 8 Jan 2010 13:14:09 +0100 Subject: Add new benchmark for some qtext features. I test loading some html into a qtextdocument and doing of shaping on an unformatted text of different scripts and bidiness. --- tests/benchmarks/benchmarks.pro | 1 + tests/benchmarks/qtext/bidi.txt | 4 ++ tests/benchmarks/qtext/main.cpp | 125 +++++++++++++++++++++++++++++++++++++++ tests/benchmarks/qtext/qtext.pro | 7 +++ 4 files changed, 137 insertions(+) create mode 100644 tests/benchmarks/qtext/bidi.txt create mode 100644 tests/benchmarks/qtext/main.cpp create mode 100644 tests/benchmarks/qtext/qtext.pro diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 7bb4bb1..1c78f1f 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -8,6 +8,7 @@ SUBDIRS = containers-associative \ qhostinfo \ qpainter \ qtestlib-simple events \ + qtext \ qiodevice \ qpixmap \ blendbench \ diff --git a/tests/benchmarks/qtext/bidi.txt b/tests/benchmarks/qtext/bidi.txt new file mode 100644 index 0000000..7c74cb4 --- /dev/null +++ b/tests/benchmarks/qtext/bidi.txt @@ -0,0 +1,4 @@ +chinese +欧洲,软件+互联网 
 用统一码 (Unicode) 走遍世界
将于1997年 3 月10日-12日在德国 Mainz 市举行的第十届统一码国际研讨会现在开始注册。 本次会议将汇集各方面的专家。 涉及的领域包括: 国际互联网和统一码 ,国际化和本地化 ,统一码在操作系统和应用软件中的实现 ,字型 ,文本格式以及多文种计算等。 
当世界需要沟通时,请用Unicode! +hebrew-bidi +אײראָפּע: פּראָגראַמװאַרג און די װעלטנעץ: אוניקאָד איבער דער גאָרער װעלט פֿאַרשרײַבט זיך שױן אױף דער צענטער אינטערנאַציאָנאַלער אוניקאָד-קאָנפֿערענץ, װאָס װעט פֿאָרקומען דעם 10טן ביזן 12טן מאַרץ, 1997, אין מײַנץ, דײַטשלאַנד. די קאָנפֿערענץ װעט צוזאַמענברענגן מבֿינים פֿון װעלטנעץ, אוניקאָד, אי אַלװעלטלעכן אי סבֿיבֿהדיקן פּראָגראַמװאַרג, אַרײַנשטעלן אוניקאָד אין אָפּעריר-סיסטעמען און אָנװענדונגען, שריפֿטן, טעקסט-אױסשטעל, און מערשפּראַכיקע קאָמפּיוטערײַ. diff --git a/tests/benchmarks/qtext/main.cpp b/tests/benchmarks/qtext/main.cpp new file mode 100644 index 0000000..3c973b6 --- /dev/null +++ b/tests/benchmarks/qtext/main.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +class tst_QText: public QObject +{ + Q_OBJECT +private slots: + void loadHtml_data(); + void loadHtml(); + + void shaping_data(); + void shaping(); +}; + +void tst_QText::loadHtml_data() +{ + QTest::addColumn("source"); + QTest::newRow("empty") << QString(); + QTest::newRow("simple") << QString::fromLatin1("Foo"); + QTest::newRow("simple2") << QString::fromLatin1("Foo"); + + QString parag = QString::fromLatin1("

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

"); + QString header = QString::fromLatin1("test"); + QTest::newRow("long") << QString::fromLatin1("test") + parag + parag + parag + + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + + QString::fromLatin1(""); + QTest::newRow("table") << header + QLatin1String("
xx
") + + parag + QLatin1String("
xx") + + parag; +} + +void tst_QText::loadHtml() +{ + QFETCH(QString, source); + QTextDocument doc; + QBENCHMARK { + doc.setHtml(source); + } +} + +void tst_QText::shaping_data() +{ + QTest::addColumn("parag"); + QTest::newRow("empty") << QString(); + QTest::newRow("lorem") << QString::fromLatin1("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."); + QTest::newRow("short") << QString::fromLatin1("Lorem ipsum dolor sit amet"); + + QFile file(QString::fromLatin1(SRCDIR) + QLatin1String("/bidi.txt")); + QVERIFY(file.open(QFile::ReadOnly)); + QByteArray data = file.readAll(); + QVERIFY(data.count() > 1000); + QStringList list = QString::fromUtf8(data.data()).split(QLatin1Char('\n'), QString::SkipEmptyParts); + QVERIFY(list.count() %2 == 0); // even amount as we have title and then content. + for (int i=0; i < list.count(); i+=2) { + QTest::newRow(list.at(i).toLatin1()) << list.at(i+1); + } +} + +void tst_QText::shaping() +{ + QFETCH(QString, parag); + + QTextLayout lay(parag); + lay.setCacheEnabled(false); + + // do one run to make sure any fonts are loaded. + lay.beginLayout(); + lay.createLine(); + lay.endLayout(); + + QBENCHMARK { + lay.beginLayout(); + lay.createLine(); + lay.endLayout(); + } +} + +QTEST_MAIN(tst_QText) + +#include "main.moc" diff --git a/tests/benchmarks/qtext/qtext.pro b/tests/benchmarks/qtext/qtext.pro new file mode 100644 index 0000000..ce4f604 --- /dev/null +++ b/tests/benchmarks/qtext/qtext.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_QText + +SOURCES += main.cpp + +DEFINES += SRCDIR=\\\"$$PWD/\\\" -- cgit v0.12 From 583b3f55ad12846a25598cb0b9442294cabafd96 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 8 Jan 2010 11:22:14 +0100 Subject: Fix passing of arguments to syncqt Escape the arguments variable properly. Reviewed-by: Thiago --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 612a3da..81872f9 100755 --- a/configure +++ b/configure @@ -2257,7 +2257,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then mkdir -p "$outpath/bin" echo "#!/bin/sh" >"$outpath/bin/syncqt" echo "QTDIR=\"$relpath\"; export QTDIR" >>"$outpath/bin/syncqt" - echo "perl \"$relpath/bin/syncqt\" -outdir \"$outpath\" $*" >>"$outpath/bin/syncqt" + echo "perl \"$relpath/bin/syncqt\" -outdir \"$outpath\" \"\$@\"" >>"$outpath/bin/syncqt" chmod 755 "$outpath/bin/syncqt" fi -- cgit v0.12 From 5f27c542e3d471427e77f1ab6a4a689a8ad2f813 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 8 Jan 2010 12:44:00 +0100 Subject: added CONFIG += console to qlalr.pro Otherwise we don't see any console output on Windows. Reviewed-by: Roberto Raggi --- util/qlalr/qlalr.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/util/qlalr/qlalr.pro b/util/qlalr/qlalr.pro index 881a36a..1994a73 100644 --- a/util/qlalr/qlalr.pro +++ b/util/qlalr/qlalr.pro @@ -1,6 +1,7 @@ TEMPLATE = app QT = core +CONFIG += console TARGET = qlalr mac:CONFIG -= app_bundle -- cgit v0.12 From 7fb78e7f60ea72e9e471d6cbc4403d490581df17 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 8 Jan 2010 15:10:31 +0100 Subject: Added new functions to QTextCodec that accept ConversionFlags. In some cases the user might want to pass initial conversion flags that should be used by the QTextEncoder and QTextDecoder, so added convenience QTextCodec::makeDecoder and makeEncoder functions that accept those flags as an argument. Task-number: QTBUG-7180 Reviewed-by: Thiago --- src/corelib/codecs/qtextcodec.cpp | 49 +++++++++++++++++++++++++++++++++++++++ src/corelib/codecs/qtextcodec.h | 11 ++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 698ca9e..86845c7 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -1163,6 +1163,19 @@ QTextDecoder* QTextCodec::makeDecoder() const return new QTextDecoder(this); } +/*! + Creates a QTextDecoder with a specified \a flags to decode chunks + of \c{char *} data to create chunks of Unicode data. + + The caller is responsible for deleting the returned object. + + \since 4.7 +*/ +QTextDecoder* QTextCodec::makeDecoder(QTextCodec::ConversionFlags flags) const +{ + return new QTextDecoder(this, flags); +} + /*! Creates a QTextEncoder which stores enough state to encode chunks @@ -1176,6 +1189,19 @@ QTextEncoder* QTextCodec::makeEncoder() const } /*! + Creates a QTextEncoder with a specified \a flags to encode chunks + of Unicode data as \c{char *} data. + + The caller is responsible for deleting the returned object. + + \since 4.7 +*/ +QTextEncoder* QTextCodec::makeEncoder(QTextCodec::ConversionFlags flags) const +{ + return new QTextEncoder(this, flags); +} + +/*! \fn QByteArray QTextCodec::fromUnicode(const QChar *input, int number, ConverterState *state) const @@ -1316,6 +1342,17 @@ QString QTextCodec::toUnicode(const char *chars) const */ /*! + Constructs a text encoder for the given \a codec and conversion \a flags. + + \since 4.7 +*/ +QTextEncoder::QTextEncoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags) + : c(codec), state() +{ + state.flags = flags; +} + +/*! Destroys the encoder. */ QTextEncoder::~QTextEncoder() @@ -1392,6 +1429,18 @@ QByteArray QTextEncoder::fromUnicode(const QString& uc, int& lenInOut) */ /*! + Constructs a text decoder for the given \a codec and conversion \a flags. + + \since 4.7 +*/ + +QTextDecoder::QTextDecoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags) + : c(codec), state() +{ + state.flags = flags; +} + +/*! Destroys the decoder. */ QTextDecoder::~QTextDecoder() diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index a099dd9..5012b42 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -85,9 +85,6 @@ public: static QTextCodec *codecForUtfText(const QByteArray &ba); static QTextCodec *codecForUtfText(const QByteArray &ba, QTextCodec *defaultCodec); - QTextDecoder* makeDecoder() const; - QTextEncoder* makeEncoder() const; - bool canEncode(QChar) const; bool canEncode(const QString&) const; @@ -120,6 +117,12 @@ public: QByteArray fromUnicode(const QChar *in, int length, ConverterState *state = 0) const { return convertFromUnicode(in, length, state); } + // ### Qt 5: merge these functions. + QTextDecoder* makeDecoder() const; + QTextDecoder* makeDecoder(ConversionFlags flags) const; + QTextEncoder* makeEncoder() const; + QTextEncoder* makeEncoder(ConversionFlags flags) const; + virtual QByteArray name() const = 0; virtual QList aliases() const; virtual int mibEnum() const = 0; @@ -157,6 +160,7 @@ class Q_CORE_EXPORT QTextEncoder { Q_DISABLE_COPY(QTextEncoder) public: explicit QTextEncoder(const QTextCodec *codec) : c(codec), state() {} + QTextEncoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags); ~QTextEncoder(); QByteArray fromUnicode(const QString& str); QByteArray fromUnicode(const QChar *uc, int len); @@ -178,6 +182,7 @@ class Q_CORE_EXPORT QTextDecoder { Q_DISABLE_COPY(QTextDecoder) public: explicit QTextDecoder(const QTextCodec *codec) : c(codec), state() {} + QTextDecoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags); ~QTextDecoder(); QString toUnicode(const char* chars, int len); QString toUnicode(const QByteArray &ba); -- cgit v0.12 From fdac6df6d46e6d4f00763365de5a4437ad06ba39 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 8 Jan 2010 15:15:16 +0100 Subject: Use the new QTextCodec api in the QXmlStreamWriter. Instead of accesing private data, use the QTextCodec::makeEncoder() to pass the initial conversion flags to the codec. Also improved the behavior - we shouldn't add BOM in the middle of the data when dumping xml in all encodings, not only for utf8. Task-number: QTBUG-7180 Reviewed-by: Thiago --- src/corelib/codecs/qtextcodec.h | 5 ----- src/corelib/xml/qxmlstream.cpp | 7 ++----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index 5012b42..e37527d 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -171,11 +171,6 @@ public: private: const QTextCodec *c; QTextCodec::ConverterState state; - - friend class QXmlStreamWriter; - friend class QXmlStreamWriterPrivate; - friend class QCoreXmlStreamWriter; - friend class QCoreXmlStreamWriterPrivate; }; class Q_CORE_EXPORT QTextDecoder { diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 5717ca2..1bf00b8 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -3003,8 +3003,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) deleteDevice = false; #ifndef QT_NO_TEXTCODEC codec = QTextCodec::codecForMib(106); // utf8 - encoder = codec->makeEncoder(); - encoder->state.flags |= QTextCodec::IgnoreHeader; // no byte order mark for utf8 + encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8 #endif inStartElement = inEmptyElement = false; wroteSomething = false; @@ -3278,9 +3277,7 @@ void QXmlStreamWriter::setCodec(QTextCodec *codec) if (codec) { d->codec = codec; delete d->encoder; - d->encoder = codec->makeEncoder(); - if (codec->mibEnum() == 106) - d->encoder->state.flags |= QTextCodec::IgnoreHeader; // no byte order mark for utf8 + d->encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8 } } -- cgit v0.12 From 3b62b3384e0008ab1dba210f55b70d666924d06e Mon Sep 17 00:00:00 2001 From: axis Date: Thu, 7 Jan 2010 14:45:59 +0100 Subject: Fixed a doc error. The extra line would make qdoc treat the next text as a separate paragraph, but it should be part of the description for the previous value. --- src/corelib/global/qnamespace.qdoc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 7ee7a76..70ca507 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -134,7 +134,6 @@ \value AA_DontShowIconsInMenus Actions with the Icon property won't be shown in any menus unless specifically set by the QAction::iconVisibleInMenu property. - Menus that are currently open or menus already created in the native Mac OS X menubar \e{may not} pick up a change in this attribute. Changes in the QAction::iconVisibleInMenu property will always be picked up. -- cgit v0.12 From 07b484b7c4685cfc2187be840a01e15f0fe08ff5 Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 8 Jan 2010 15:50:03 +0100 Subject: Fixed QDesktopWidget autotest. The error would happen because Qt would attempt to do focus handling on the desktop widget which eventually resulted in an assert on the Created status of the widget. RevBy: Jani Hautakangas AutoTest: Passed --- src/gui/kernel/qapplication_s60.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 27f2644..aee4324 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -930,7 +930,7 @@ void QSymbianControl::PositionChanged() void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) { - if (m_ignoreFocusChanged) + if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop) return; // Popups never get focused, but still receive the FocusChanged when they are hidden. -- cgit v0.12 From 4a84b272459160780529f654e6aee3abf8569b51 Mon Sep 17 00:00:00 2001 From: axis Date: Thu, 7 Jan 2010 16:01:58 +0100 Subject: Added a flag to avoid construction of application panes. This is purely an optimization for fullscreen-only apps. Task: QTBUG-6098 RevBy: Jason Barron RevBy: mread AutoTest: Included --- src/corelib/global/qnamespace.h | 1 + src/corelib/global/qnamespace.qdoc | 6 ++ src/gui/dialogs/qdialog.cpp | 9 ++- src/gui/kernel/qsoftkeymanager.cpp | 3 +- src/gui/s60framework/qs60mainappui.cpp | 12 +++- tests/auto/qapplication/heart.svg | 55 +++++++++++++++++ tests/auto/qapplication/test/test.pro | 4 +- tests/auto/qapplication/tst_qapplication.cpp | 88 ++++++++++++++++++++++++++++ 8 files changed, 172 insertions(+), 6 deletions(-) create mode 100644 tests/auto/qapplication/heart.svg diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 0ee9cd2..c40308c 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -511,6 +511,7 @@ public: AA_MacPluginApplication = 5, AA_DontUseNativeMenuBar = 6, AA_MacDontSwapCtrlAndMeta = 7, + AA_S60DontConstructApplicationPanes = 8, // Add new attributes before this line AA_AttributeCount diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 70ca507..5a80d56 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -163,6 +163,12 @@ Command+C on the keyboard regardless of the value set, though what is output for QKeySequence::toString(QKeySequence::PortableText) will be different). + \value AA_S60DontConstructApplicationPanes Stops Qt from initializing the S60 status + pane and softkey pane on Symbian. This is useful to save memory and reduce + startup time for applications that will run in fullscreen mode during their + whole lifetime. This attribute must be set before QApplication is + constructed. + \omitvalue AA_AttributeCount */ diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index ed2d676..d7653e5 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -888,7 +888,14 @@ bool QDialog::s60AdjustedPosition() if (doS60Positioning) { // naive way to deduce screen orientation if (S60->screenHeightInPixels > S60->screenWidthInPixels) { - p.setY(S60->screenHeightInPixels-height()-qt_TSize2QSize(S60->buttonGroupContainer()->Size()).height()); + int cbaHeight; + const CEikButtonGroupContainer* bgContainer = S60->buttonGroupContainer(); + if (!bgContainer) { + cbaHeight = 0; + } else { + cbaHeight = qt_TSize2QSize(bgContainer->Size()).height(); + } + p.setY(S60->screenHeightInPixels-height()-cbaHeight); p.setX(0); } else { const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent); diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 0e98f39..b09ab8f 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -211,7 +211,8 @@ bool QSoftKeyManager::event(QEvent *e) void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList &softkeys) { // lets not update softkeys if s60 native dialog or menu is shown - if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) + if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes) + || CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) return; CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer(); diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp index 4c4c994..4813fb2 100644 --- a/src/gui/s60framework/qs60mainappui.cpp +++ b/src/gui/s60framework/qs60mainappui.cpp @@ -104,10 +104,16 @@ void QS60MainAppUi::ConstructL() // ENoAppResourceFile and ENonStandardResourceFile makes UI to work without // resource files in most SDKs. S60 3rd FP1 public seems to require resource file // even these flags are defined - BaseConstructL(CAknAppUi::EAknEnableSkin); + TInt flags = CAknAppUi::EAknEnableSkin; + if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) { + flags |= CAknAppUi::ENoScreenFurniture | CAknAppUi::ENonStandardResourceFile; + } + BaseConstructL(flags); - CEikButtonGroupContainer* nativeContainer = Cba(); - nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); + if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) { + CEikButtonGroupContainer* nativeContainer = Cba(); + nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); + } } /*! diff --git a/tests/auto/qapplication/heart.svg b/tests/auto/qapplication/heart.svg new file mode 100644 index 0000000..8c982cd --- /dev/null +++ b/tests/auto/qapplication/heart.svg @@ -0,0 +1,55 @@ + + + + + +Heart Left-Highlight +This is a normal valentines day heart. + + +holiday +valentines + +valentine +hash(0x8a091c0) +hash(0x8a0916c) +signs_and_symbols +hash(0x8a091f0) +day + + + + +Jon Phillips + + + + +Jon Phillips + + + + +Jon Phillips + + + +image/svg+xml + + +en + + + + + + + + + + + + + + + diff --git a/tests/auto/qapplication/test/test.pro b/tests/auto/qapplication/test/test.pro index 7c3de3c..e68af26 100644 --- a/tests/auto/qapplication/test/test.pro +++ b/tests/auto/qapplication/test/test.pro @@ -16,7 +16,9 @@ symbian*: { additional.path = desktopsettingsaware someTest.sources = test.pro someTest.path = test - DEPLOYMENT = additional deploy someTest + windowIcon.sources = ../heart.svg + DEPLOYMENT = additional deploy someTest windowIcon + LIBS += -lcone -lavkon } win32 { diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 5888866..ed614e15 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -53,6 +53,9 @@ #ifdef Q_OS_WINCE #include #endif +#ifdef Q_OS_SYMBIAN +#include +#endif //TESTED_CLASS= //TESTED_FILES= @@ -138,6 +141,8 @@ private slots: void touchEventPropagation(); + void symbianNoApplicationPanes(); + void symbianNeedForTraps(); void symbianLeaveThroughMain(); }; @@ -2036,6 +2041,89 @@ void tst_QApplication::touchEventPropagation() } } +void tst_QApplication::symbianNoApplicationPanes() +{ +#ifndef Q_OS_SYMBIAN + QSKIP("This is a Symbian only test", SkipAll); +#else + QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes); + + // Run in a block so that QApplication is destroyed before resetting the attribute. + { + // Actually I wasn't able to get the forced orientation change to work properly, + // but I'll leave the code here for the future in case we manage to test that + // later. If someone knows how to force an orientation switch in an autotest, do + // feel free to fix this testcase. + int argc = 0; + QApplication app(argc, 0); + QWidget *w; + + w = new QWidget; + w->show(); + QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); + app.processEvents(); + delete w; + + w = new QWidget; + w->show(); + QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showMaximized(); + QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showMaximized(); + QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showFullScreen(); + QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showFullScreen(); + QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); + app.processEvents(); + delete w; + + // These will have no effect, since there is no status pane, but they shouldn't + // crash either. + w = new QWidget; + w->show(); + w->setWindowTitle("Testing title"); + app.processEvents(); + delete w; + + w = new QWidget; + w->show(); + w->setWindowIcon(QIcon(QPixmap("heart.svg"))); + app.processEvents(); + delete w; + + QDesktopWidget desktop; + QCOMPARE(desktop.availableGeometry(), desktop.screenGeometry()); + } + + QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes, false); + + // No other error condition. Program will crash if unsuccessful. +#endif +} + #ifdef Q_OS_SYMBIAN class CBaseDummy : public CBase { -- cgit v0.12 From f0d2a0d7a9ed0500a1423bbf1362b234525f8be7 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 8 Jan 2010 16:13:28 +0100 Subject: Reverted two commits that were pushed to the wrong branch. Revert "Use the new QTextCodec api in the QXmlStreamWriter." This reverts commit fdac6df6d46e6d4f00763365de5a4437ad06ba39. Revert "Added new functions to QTextCodec that accept ConversionFlags." This reverts commit 7fb78e7f60ea72e9e471d6cbc4403d490581df17. --- src/corelib/codecs/qtextcodec.cpp | 49 --------------------------------------- src/corelib/codecs/qtextcodec.h | 16 ++++++------- src/corelib/xml/qxmlstream.cpp | 7 ++++-- 3 files changed, 13 insertions(+), 59 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 86845c7..698ca9e 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -1163,19 +1163,6 @@ QTextDecoder* QTextCodec::makeDecoder() const return new QTextDecoder(this); } -/*! - Creates a QTextDecoder with a specified \a flags to decode chunks - of \c{char *} data to create chunks of Unicode data. - - The caller is responsible for deleting the returned object. - - \since 4.7 -*/ -QTextDecoder* QTextCodec::makeDecoder(QTextCodec::ConversionFlags flags) const -{ - return new QTextDecoder(this, flags); -} - /*! Creates a QTextEncoder which stores enough state to encode chunks @@ -1189,19 +1176,6 @@ QTextEncoder* QTextCodec::makeEncoder() const } /*! - Creates a QTextEncoder with a specified \a flags to encode chunks - of Unicode data as \c{char *} data. - - The caller is responsible for deleting the returned object. - - \since 4.7 -*/ -QTextEncoder* QTextCodec::makeEncoder(QTextCodec::ConversionFlags flags) const -{ - return new QTextEncoder(this, flags); -} - -/*! \fn QByteArray QTextCodec::fromUnicode(const QChar *input, int number, ConverterState *state) const @@ -1342,17 +1316,6 @@ QString QTextCodec::toUnicode(const char *chars) const */ /*! - Constructs a text encoder for the given \a codec and conversion \a flags. - - \since 4.7 -*/ -QTextEncoder::QTextEncoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags) - : c(codec), state() -{ - state.flags = flags; -} - -/*! Destroys the encoder. */ QTextEncoder::~QTextEncoder() @@ -1429,18 +1392,6 @@ QByteArray QTextEncoder::fromUnicode(const QString& uc, int& lenInOut) */ /*! - Constructs a text decoder for the given \a codec and conversion \a flags. - - \since 4.7 -*/ - -QTextDecoder::QTextDecoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags) - : c(codec), state() -{ - state.flags = flags; -} - -/*! Destroys the decoder. */ QTextDecoder::~QTextDecoder() diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index e37527d..a099dd9 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -85,6 +85,9 @@ public: static QTextCodec *codecForUtfText(const QByteArray &ba); static QTextCodec *codecForUtfText(const QByteArray &ba, QTextCodec *defaultCodec); + QTextDecoder* makeDecoder() const; + QTextEncoder* makeEncoder() const; + bool canEncode(QChar) const; bool canEncode(const QString&) const; @@ -117,12 +120,6 @@ public: QByteArray fromUnicode(const QChar *in, int length, ConverterState *state = 0) const { return convertFromUnicode(in, length, state); } - // ### Qt 5: merge these functions. - QTextDecoder* makeDecoder() const; - QTextDecoder* makeDecoder(ConversionFlags flags) const; - QTextEncoder* makeEncoder() const; - QTextEncoder* makeEncoder(ConversionFlags flags) const; - virtual QByteArray name() const = 0; virtual QList aliases() const; virtual int mibEnum() const = 0; @@ -160,7 +157,6 @@ class Q_CORE_EXPORT QTextEncoder { Q_DISABLE_COPY(QTextEncoder) public: explicit QTextEncoder(const QTextCodec *codec) : c(codec), state() {} - QTextEncoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags); ~QTextEncoder(); QByteArray fromUnicode(const QString& str); QByteArray fromUnicode(const QChar *uc, int len); @@ -171,13 +167,17 @@ public: private: const QTextCodec *c; QTextCodec::ConverterState state; + + friend class QXmlStreamWriter; + friend class QXmlStreamWriterPrivate; + friend class QCoreXmlStreamWriter; + friend class QCoreXmlStreamWriterPrivate; }; class Q_CORE_EXPORT QTextDecoder { Q_DISABLE_COPY(QTextDecoder) public: explicit QTextDecoder(const QTextCodec *codec) : c(codec), state() {} - QTextDecoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags); ~QTextDecoder(); QString toUnicode(const char* chars, int len); QString toUnicode(const QByteArray &ba); diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 1bf00b8..5717ca2 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -3003,7 +3003,8 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) deleteDevice = false; #ifndef QT_NO_TEXTCODEC codec = QTextCodec::codecForMib(106); // utf8 - encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8 + encoder = codec->makeEncoder(); + encoder->state.flags |= QTextCodec::IgnoreHeader; // no byte order mark for utf8 #endif inStartElement = inEmptyElement = false; wroteSomething = false; @@ -3277,7 +3278,9 @@ void QXmlStreamWriter::setCodec(QTextCodec *codec) if (codec) { d->codec = codec; delete d->encoder; - d->encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8 + d->encoder = codec->makeEncoder(); + if (codec->mibEnum() == 106) + d->encoder->state.flags |= QTextCodec::IgnoreHeader; // no byte order mark for utf8 } } -- cgit v0.12 From a3e6a04448979aaa6ada7aa434de3137f6cf0563 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Fri, 8 Jan 2010 15:07:36 +0000 Subject: Fixed build breakage on S60 3.1 due to audio effects changes Removed calls to the video overload of the audio effect constructors, e.g. CAudioEqualizer::NewL(VideoPlayerUtility&) Task-number: QTBUG-7223 Reviewed-by: trustme --- src/3rdparty/phonon/mmf/abstractaudioeffect.cpp | 11 +++-------- src/3rdparty/phonon/mmf/abstractaudioeffect.h | 1 - src/3rdparty/phonon/mmf/audioequalizer.cpp | 20 +++++++------------- src/3rdparty/phonon/mmf/audioequalizer.h | 1 - src/3rdparty/phonon/mmf/bassboost.cpp | 7 ------- src/3rdparty/phonon/mmf/bassboost.h | 1 - 6 files changed, 10 insertions(+), 31 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index 8c73027..e7ef9b2 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -80,15 +80,10 @@ void AbstractAudioEffect::connectMediaObject(MediaObject *mediaObject) if (AudioPlayer *audioPlayer = qobject_cast(player)) { connectAudioPlayer(audioPlayer->nativePlayer()); - } else { - VideoPlayer *videoPlayer = qobject_cast(player); - Q_ASSERT_X(videoPlayer, Q_FUNC_INFO, "Player type not recognised"); - connectVideoPlayer(videoPlayer->nativePlayer()); + applyParameters(); + // TODO: handle audio effect errors + TRAP_IGNORE(m_effect->EnableL()); } - - applyParameters(); - // TODO: handle audio effect errors - TRAP_IGNORE(m_effect->EnableL()); } } diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 10578af..6f74a73 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -86,7 +86,6 @@ protected: void disconnectMediaObject(MediaObject *mediaObject); virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player) = 0; - virtual void connectVideoPlayer(VideoPlayer::NativePlayer *player) = 0; virtual void applyParameters() = 0; virtual void parameterChanged(const int id, diff --git a/src/3rdparty/phonon/mmf/audioequalizer.cpp b/src/3rdparty/phonon/mmf/audioequalizer.cpp index 51f1c32..c2936c5 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.cpp +++ b/src/3rdparty/phonon/mmf/audioequalizer.cpp @@ -49,21 +49,15 @@ void AudioEqualizer::connectAudioPlayer(AudioPlayer::NativePlayer *player) m_effect.reset(ptr); } -void AudioEqualizer::connectVideoPlayer(VideoPlayer::NativePlayer *player) -{ - CAudioEqualizer *ptr = 0; - QT_TRAP_THROWING(ptr = CAudioEqualizer::NewL(*player)); - m_effect.reset(ptr); -} - void AudioEqualizer::applyParameters() { - Q_ASSERT_X(m_effect.data(), Q_FUNC_INFO, "Effect not created"); - EffectParameter param; - foreach (param, parameters()) { - const int band = param.id(); - const int level = parameterValue(param).toInt(); - setBandLevel(band, level); + if (m_effect.data()) { + EffectParameter param; + foreach (param, parameters()) { + const int band = param.id(); + const int level = parameterValue(param).toInt(); + setBandLevel(band, level); + } } } diff --git a/src/3rdparty/phonon/mmf/audioequalizer.h b/src/3rdparty/phonon/mmf/audioequalizer.h index 9910ea4..10fe9ad 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.h +++ b/src/3rdparty/phonon/mmf/audioequalizer.h @@ -44,7 +44,6 @@ public: protected: // AbstractAudioEffect virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player); - virtual void connectVideoPlayer(VideoPlayer::NativePlayer *player); virtual void applyParameters(); virtual void parameterChanged(const int id, const QVariant &value); diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp index 36069fb..ae96b45 100644 --- a/src/3rdparty/phonon/mmf/bassboost.cpp +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -46,13 +46,6 @@ void BassBoost::connectAudioPlayer(AudioPlayer::NativePlayer *player) m_effect.reset(ptr); } -void BassBoost::connectVideoPlayer(VideoPlayer::NativePlayer *player) -{ - CBassBoost *ptr = 0; - QT_TRAP_THROWING(ptr = CBassBoost::NewL(*player)); - m_effect.reset(ptr); -} - void BassBoost::applyParameters() { // No parameters to apply diff --git a/src/3rdparty/phonon/mmf/bassboost.h b/src/3rdparty/phonon/mmf/bassboost.h index 1b893db..4ad0a6c 100644 --- a/src/3rdparty/phonon/mmf/bassboost.h +++ b/src/3rdparty/phonon/mmf/bassboost.h @@ -42,7 +42,6 @@ public: protected: // AbstractAudioEffect virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player); - virtual void connectVideoPlayer(VideoPlayer::NativePlayer *player); virtual void applyParameters(); virtual void parameterChanged(const int id, const QVariant &value); -- cgit v0.12 From 48cce37f6faa2aae9b15edc9543f0e7e08236bb1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 8 Jan 2010 17:59:22 +0100 Subject: Doc: the QTextDecoder need to be destroyed, reflect that in the example Reviewed-by: Denis --- doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp b/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp index 4e77e04..2fd723e 100644 --- a/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp +++ b/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp @@ -62,6 +62,7 @@ while (new_data_available()) { QByteArray chunk = get_new_data(); string += decoder->toUnicode(chunk); } +delete decoder; //! [2] -- cgit v0.12 From 9a820c4219c67aa401f0ac99d7bcc966c249d637 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 11 Jan 2010 10:26:34 +0100 Subject: Fix regression introduced in e49aee9f: set If-Modified-Since. I moved the code above the other tests because it's more complex. But, of course, that's wrong because it returns without setting the necessary headers. Reviewed-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 12b10f9..5a2cce4 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -385,6 +385,14 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, QNetworkHeadersPrivate::RawHeadersList::ConstIterator it; cacheHeaders.setAllRawHeaders(metaData.rawHeaders()); + it = cacheHeaders.findRawHeader("etag"); + if (it != cacheHeaders.rawHeaders.constEnd()) + httpRequest.setHeaderField("If-None-Match", it->second); + + QDateTime lastModified = metaData.lastModified(); + if (lastModified.isValid()) + httpRequest.setHeaderField("If-Modified-Since", QNetworkHeadersPrivate::toHttpDate(lastModified)); + if (CacheLoadControlAttribute == QNetworkRequest::PreferNetwork) { it = cacheHeaders.findRawHeader("Cache-Control"); if (it != cacheHeaders.rawHeaders.constEnd()) { @@ -394,14 +402,6 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, } } - it = cacheHeaders.findRawHeader("etag"); - if (it != cacheHeaders.rawHeaders.constEnd()) - httpRequest.setHeaderField("If-None-Match", it->second); - - QDateTime lastModified = metaData.lastModified(); - if (lastModified.isValid()) - httpRequest.setHeaderField("If-Modified-Since", QNetworkHeadersPrivate::toHttpDate(lastModified)); - QDateTime currentDateTime = QDateTime::currentDateTime(); QDateTime expirationDate = metaData.expirationDate(); -- cgit v0.12 From ef5a985cf47c32bac0ddd3bae1edb7e922e7ec69 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 11 Jan 2010 10:27:48 +0100 Subject: Autotest: the cache code no longer returns expired pages. Returning expired changes is wrong. The documentation says we never do that. Now we really never return expired pages. Reviewed-by: Peter Hartmann --- tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index 7fd994d..e5646c1 100644 --- a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -136,7 +136,7 @@ void tst_QAbstractNetworkCache::expires_data() QTest::newRow("200-0") << QNetworkRequest::AlwaysNetwork << "httpcachetest_expires200.cgi" << AlwaysFalse; QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_expires200.cgi" << false; QTest::newRow("200-2") << QNetworkRequest::AlwaysCache << "httpcachetest_expires200.cgi" << AlwaysTrue; - QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_expires200.cgi" << true; + QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_expires200.cgi" << false; } void tst_QAbstractNetworkCache::expires() @@ -158,7 +158,7 @@ void tst_QAbstractNetworkCache::lastModified_data() QTest::newRow("200-0") << QNetworkRequest::AlwaysNetwork << "httpcachetest_lastModified200.cgi" << AlwaysFalse; QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_lastModified200.cgi" << false; QTest::newRow("200-2") << QNetworkRequest::AlwaysCache << "httpcachetest_lastModified200.cgi" << AlwaysTrue; - QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_lastModified200.cgi" << true; + QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_lastModified200.cgi" << false; } void tst_QAbstractNetworkCache::lastModified() @@ -180,7 +180,7 @@ void tst_QAbstractNetworkCache::etag_data() QTest::newRow("200-0") << QNetworkRequest::AlwaysNetwork << "httpcachetest_etag200.cgi" << AlwaysFalse; QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_etag200.cgi" << false; QTest::newRow("200-2") << QNetworkRequest::AlwaysCache << "httpcachetest_etag200.cgi" << AlwaysTrue; - QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_etag200.cgi" << true; + QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_etag200.cgi" << false; } void tst_QAbstractNetworkCache::etag() -- cgit v0.12 From 145fecc833926c307819752912e6833169799a53 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 15 Dec 2009 10:52:52 +0100 Subject: network internals: start HTTP GET requests right away when called on the code path from QNetworkAccessManager::get() to QTcpSocket::write() there were two calls involved that were invoked via a QueuedConnection, which would in some occasions delay writing the data to the socket. This patch makes sure the data is written to the socket immediately, without returning to the event loop (only the HTTP backend was changed for that event, the other backends were not changed) Reviewed-by: Thiago Macieira Reviewed-by: Markus Goetz --- src/network/access/qhttpnetworkconnection.cpp | 8 ++++---- src/network/access/qhttpnetworkconnectionchannel.cpp | 12 +++++++----- src/network/access/qhttpnetworkconnectionchannel_p.h | 2 +- src/network/access/qnetworkaccesshttpbackend.cpp | 7 ++++--- src/network/access/qnetworkaccesshttpbackend_p.h | 2 +- src/network/access/qnetworkaccessmanager.cpp | 4 ++-- src/network/access/qnetworkreplyimpl.cpp | 13 +++++++++++-- 7 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 44a0a79..2c56524 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -415,14 +415,13 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor lowPriorityQueue.prepend(pair); break; } - QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); + // this used to be called via invokeMethod and a QueuedConnection + _q_startNextRequest(); return reply; } void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair) { - Q_Q(QHttpNetworkConnection); - QHttpNetworkRequest request = pair.first; switch (request.priority()) { case QHttpNetworkRequest::HighPriority: @@ -433,7 +432,8 @@ void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair) lowPriorityQueue.prepend(pair); break; } - QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); + // this used to be called via invokeMethod and a QueuedConnection + _q_startNextRequest(); } void QHttpNetworkConnectionPrivate::dequeueAndSendRequest(QAbstractSocket *socket) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 1a68e97..7cf632f 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -166,6 +166,8 @@ bool QHttpNetworkConnectionChannel::sendRequest() QByteArray header = QHttpNetworkRequestPrivate::header(request, false); #endif socket->write(header); + // flushing is dangerous (QSslSocket calls transmit which might read or error) +// socket->flush(); QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice(); if (uploadByteDevice) { // connect the signals so this function gets called again @@ -258,7 +260,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called // this is needed if the sends an reply before we have finished sending the request. In that // case receiveReply had been called before but ignored the server reply - receiveReply(); + QMetaObject::invokeMethod(connection, "_q_receiveReply", Qt::QueuedConnection); break; } case QHttpNetworkConnectionChannel::ReadingState: @@ -272,7 +274,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() } -void QHttpNetworkConnectionChannel::receiveReply() +void QHttpNetworkConnectionChannel::_q_receiveReply() { Q_ASSERT(socket); @@ -567,7 +569,7 @@ void QHttpNetworkConnectionChannel::allDone() connection->d_func()->fillPipeline(socket); // continue reading - receiveReply(); + _q_receiveReply(); } } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) { eatWhitespace(); @@ -739,7 +741,7 @@ void QHttpNetworkConnectionChannel::_q_readyRead() if (isSocketWaiting() || isSocketReading()) { state = QHttpNetworkConnectionChannel::ReadingState; if (reply) - receiveReply(); + _q_receiveReply(); } } @@ -758,7 +760,7 @@ void QHttpNetworkConnectionChannel::_q_disconnected() if (isSocketWaiting() || isSocketReading()) { state = QHttpNetworkConnectionChannel::ReadingState; if (reply) - receiveReply(); + _q_receiveReply(); } else if (state == QHttpNetworkConnectionChannel::IdleState && resendCurrent) { // re-sending request because the socket was in ClosingState QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index bbe43cd..c30c236 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -144,7 +144,6 @@ public: void close(); bool sendRequest(); - void receiveReply(); bool ensureConnection(); @@ -166,6 +165,7 @@ public: bool isSocketReading() const; protected slots: + void _q_receiveReply(); void _q_bytesWritten(qint64 bytes); // proceed sending void _q_readyRead(); // pending data to read void _q_disconnected(); // disconnected from host diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 5a2cce4..ada00df 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -594,9 +594,10 @@ void QNetworkAccessHttpBackend::open() if (transparentProxy.type() == QNetworkProxy::DefaultProxy && cacheProxy.type() == QNetworkProxy::DefaultProxy) { // unsuitable proxies - error(QNetworkReply::ProxyNotFoundError, - tr("No suitable proxy found")); - finished(); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), + Q_ARG(QString, QCoreApplication::translate("QNetworkAccessHttpBackend", "No suitable proxy found"))); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } #endif diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index bc3980d..705323d 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -104,6 +104,7 @@ private slots: void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth); void httpError(QNetworkReply::NetworkError error, const QString &errorString); bool sendCacheContents(const QNetworkCacheMetaData &metaData); + void finished(); // override private: QHttpNetworkReply *httpReply; @@ -118,7 +119,6 @@ private: #endif void disconnectFromHttp(); - void finished(); // override void setupConnection(); void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache); void invalidateCache(); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 2f57fee..d27fbe7 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -723,8 +723,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // third step: find a backend priv->backend = d->findBackend(op, request); - // fourth step: setup the reply - priv->setup(op, request, outgoingData); #ifndef QT_NO_NETWORKPROXY QList proxyList = d->queryProxy(QNetworkProxyQuery(request.url())); priv->proxyList = proxyList; @@ -733,6 +731,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera priv->backend->setParent(reply); priv->backend->reply = priv; } + // fourth step: setup the reply + priv->setup(op, request, outgoingData); #ifndef QT_NO_OPENSSL reply->setSslConfiguration(request.sslConfiguration()); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 42e802f..285864d 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -72,6 +72,9 @@ void QNetworkReplyImplPrivate::_q_startOperation() } state = Working; + // note: if that method is called directly, it cannot happen that the backend is 0, + // because we just checked via a qobject_cast that we got a http backend (see + // QNetworkReplyImplPrivate::setup()) if (!backend) { error(QNetworkReplyImpl::ProtocolUnknownError, QCoreApplication::translate("QNetworkReply", "Protocol \"%1\" is unknown").arg(url.scheme())); // not really true!; @@ -203,7 +206,6 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData() } } - void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *data) { @@ -246,7 +248,14 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const // No outgoing data (e.g. HTTP GET request) // or no backend // if no backend, _q_startOperation will handle the error of this - QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + + // for HTTP, we want to send out the request as fast as possible to the network, without + // invoking methods in a QueuedConnection + if (qobject_cast(backend)) { + _q_startOperation(); + } else { + QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + } } q->QIODevice::open(QIODevice::ReadOnly); -- cgit v0.12 From b3ffbdc0334c24d5d90ca3227a765fbd1e09bbc3 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 8 Jan 2010 13:59:52 +0100 Subject: [syncqt] Make it possible to override the base directory This removes the need to set the QTDIR environment variable and makes it possible to call syncqt conveniently when creating webkit packages. Reviewed-by: Thiago --- bin/syncqt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bin/syncqt b/bin/syncqt index 6c1a438..be0a019 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -15,6 +15,13 @@ use Cwd; use Config; use strict; +for (my $i = 0; $i < $#ARGV; $i++) { + if ($ARGV[$i] eq "-base-dir" && $i < $#ARGV - 1) { + $ENV{"QTDIR"} = $ARGV[$i + 1]; + last; + } +} + die "syncqt: QTDIR not defined" if ! $ENV{"QTDIR"}; # sanity check # global variables @@ -579,6 +586,10 @@ while ( @ARGV ) { } elsif("$arg" eq "-show") { $var = "showonly"; $val = "yes"; + } elsif("$arg" eq "-base-dir") { + # skip, it's been dealt with at the top of the file + shift @ARGV; + next; } elsif("$arg" eq '*') { # workaround for windows 9x where "%*" expands to "*" $var = 1; -- cgit v0.12 From 64ce2950db4e140d1e65da632acbc812cabc6e03 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 8 Jan 2010 14:30:18 +0100 Subject: [syncqt] Make it possible to synchronize headers for a separate module Added a -separate-module commandline option to syncqt that allows calling syncqt from outside of Qt to create header files. For WebKit package we call syncqt with -separate-module QtWebKit:WebKit/qt/Api to generate headers for the "QtWebKit" module for the headers in WebKit/qt/Api/*.h Reviewed-by: Thiago --- bin/syncqt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/bin/syncqt b/bin/syncqt index be0a019..3ac70a4 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -68,6 +68,8 @@ my $force_win = 0; my $force_relative = 0; my $check_includes = 0; my $copy_headers = 0; +my $create_uic_class_map = 1; +my $create_private_headers = 1; my @modules_to_sync ; $force_relative = 1 if ( -d "/System/Library/Frameworks" ); my $out_basedir = $basedir; @@ -91,6 +93,7 @@ sub showUsage print " -windows Force platform to Windows (default: " . ($force_win ? "yes" : "no") . ")\n"; print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n"; print " -outdir Specify output directory for sync (default: $out_basedir)\n"; + print " -separate-module : Create headers for with original headers in \n"; print " -help This help\n"; exit 0; } @@ -583,6 +586,9 @@ while ( @ARGV ) { } elsif("$arg" eq "-module") { $var = "module"; $val = shift @ARGV; + } elsif("$arg" eq "-separate-module") { + $var = "separate-module"; + $val = shift @ARGV; } elsif("$arg" eq "-show") { $var = "showonly"; $val = "yes"; @@ -639,6 +645,13 @@ while ( @ARGV ) { print "module :$val:\n"; die "No such module: $val" unless(defined $modules{$val}); push @modules_to_sync, $val; + } elsif ("$var" eq "separate-module") { + my ($module, $srcdir) = split(/:/, $val); + $modules{$module} = $srcdir; + push @modules_to_sync, $module; + delete $moduleheaders{$module} if ($moduleheaders{$module}); + $create_uic_class_map = 0; + $create_private_headers = 0; } elsif ("$var" eq "output") { my $outdir = $val; if(checkRelative($outdir)) { @@ -824,7 +837,7 @@ foreach (@modules_to_sync) { $header_copies++ if (syncHeader("$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0)); } } - } else { + } elsif ($create_private_headers) { @headers = ( "$out_basedir/include/$lib/private/$header" ); push @headers, "$out_basedir/include/Qt/private/$header" if ("$lib" ne "phonon"); @@ -920,7 +933,7 @@ foreach (@modules_to_sync) { } } } -unless($showonly) { +unless($showonly || !$create_uic_class_map) { my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h"; if(-e "$class_lib_map") { open CLASS_LIB_MAP, "<$class_lib_map"; -- cgit v0.12 From 039387d498f4ca0125938c7c79c5aff29dab5361 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 11 Jan 2010 12:51:15 +0100 Subject: Add a way to access the normalised URL in QUrl. This is private API for now. For 4.7, decide whether to have a public method for this. Also investigate whether to provide a qHash function. Adding one to Qt would break source- and binary-compatibility with code that already has that (like Soprano). Patch-By: Warwick Allison Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 1ba5e3f..74e5f74 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -350,8 +350,8 @@ public: }; int stateFlags; - QByteArray encodedNormalized; - const QByteArray & normalized(); + mutable QByteArray encodedNormalized; + const QByteArray & normalized() const; mutable QUrlErrorInfo errorInfo; QString createErrorString(); @@ -3850,6 +3850,9 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const if (!QURL_HASFLAG(stateFlags, Parsed)) parse(); else ensureEncodedParts(); + if (options==0x100) // private - see qHash(QUrl) + return normalized(); + QByteArray url; if (!(options & QUrl::RemoveScheme) && !scheme.isEmpty()) { @@ -3920,12 +3923,13 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const #define qToLower(ch) (((ch|32) >= 'a' && (ch|32) <= 'z') ? (ch|32) : ch) -const QByteArray &QUrlPrivate::normalized() +const QByteArray &QUrlPrivate::normalized() const { if (QURL_HASFLAG(stateFlags, QUrlPrivate::Normalized)) return encodedNormalized; - QURL_SETFLAG(stateFlags, QUrlPrivate::Normalized); + QUrlPrivate *that = const_cast(this); + QURL_SETFLAG(that->stateFlags, QUrlPrivate::Normalized); QUrlPrivate tmp = *this; tmp.scheme = tmp.scheme.toLower(); -- cgit v0.12 From 51078f1ef008c8395ddb76ac2f444daa511a4507 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 11 Jan 2010 13:24:27 +0100 Subject: doc: Added clarification about allocating space for the 0 terminator. Task-number: QTBUG-5121 --- doc/src/snippets/code/src_corelib_tools_qbytearray.cpp | 17 +++++++++++++++++ src/corelib/tools/qbytearray.cpp | 18 +++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp b/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp index 736394f..3cd3db8 100644 --- a/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp +++ b/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp @@ -401,5 +401,22 @@ QByteArray text = QByteArray::fromHex("517420697320677265617421"); text.data(); // returns "Qt is great!" //! [45] +//! [46] +QString tmp = "test"; +QByteArray text = tmp.toLocal8Bit(); +char *data = new char[text.size()] +strcpy(data, text.data()); +delete [] data; +//! [46] + +//! [47] +QString tmp = "test"; +QByteArray text = tmp.toLocal8Bit(); +char *data = new char[text.size() + 1] +strcpy(data, text.data()); +delete [] data; +//! [47] + } + diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index c4a84fc..f4a81f2 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -903,8 +903,8 @@ QByteArray &QByteArray::operator=(const char *str) The last byte in the byte array is at position size() - 1. In addition, QByteArray ensures that the byte at position size() is always '\\0', so that you can use the return value of data() and - constData() as arguments to functions that expect - '\\0'-terminated strings. + constData() as arguments to functions that expect '\\0'-terminated + strings. Example: \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 6 @@ -997,7 +997,9 @@ QByteArray &QByteArray::operator=(const char *str) Returns a pointer to the data stored in the byte array. The pointer can be used to access and modify the bytes that compose - the array. The data is '\\0'-terminated. + the array. The data is '\\0'-terminated, i.e. the number of + bytes in the returned character string is size() + 1 for the + '\\0' terminator. Example: \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 8 @@ -1009,6 +1011,16 @@ QByteArray &QByteArray::operator=(const char *str) This function is mostly useful to pass a byte array to a function that accepts a \c{const char *}. + The following example makes a copy of the char* returned by + data(), but it will corrupt the heap and cause a crash because it + does not allocate a byte for the '\\0' at the end: + + \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 46 + + This one allocates the correct amount of space: + + \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 47 + Note: A QByteArray can store any byte values including '\\0's, but most functions that take \c{char *} arguments assume that the data ends at the first '\\0' they encounter. -- cgit v0.12 From 8e2c575f6383a69e9c1d4f069e3c8e3b219197b5 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 11 Jan 2010 13:43:31 +0100 Subject: doc: Corrected explanation of when append() does nothing. Task-number: QTBUG-7246 --- src/corelib/tools/qbytearray.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index f4a81f2..d2fbf5a 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1603,8 +1603,9 @@ QByteArray& QByteArray::append(const char *str) array and returns a reference to this byte array. If \a len is negative, the length of the string will be determined - automatically using qstrlen(). If \a len is zero or the length of the - string is zero, nothing will be appended to the byte array. + automatically using qstrlen(). If \a len is zero or \a str is + null, nothing is appended to the byte array. Ensure that \a len is + \e not longer than \a str. */ QByteArray &QByteArray::append(const char *str, int len) -- cgit v0.12 From 22d30bd6c1e8355cb4520885b0d0fef3526cc4e9 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 11 Jan 2010 14:09:44 +0100 Subject: [syncqt] Make -separate-module work with WebKit's directory structure Changed the syntax to allow for the situation where the .pro file is in a different directory than the header files to install. In this case the resulting Makefile is in WebCore/Makefile, so the references in headers.pri to for example qwebview.h has to be ../WebKit/qt/Api/qwebview.h. This doesn't affect any existing syncqt operations inside of Qt. Reviewed-by: Trust me --- bin/syncqt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/syncqt b/bin/syncqt index 3ac70a4..1fb5304 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -93,7 +93,7 @@ sub showUsage print " -windows Force platform to Windows (default: " . ($force_win ? "yes" : "no") . ")\n"; print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n"; print " -outdir Specify output directory for sync (default: $out_basedir)\n"; - print " -separate-module : Create headers for with original headers in \n"; + print " -separate-module :: Create headers for with original headers in relative to \n"; print " -help This help\n"; exit 0; } @@ -646,10 +646,10 @@ while ( @ARGV ) { die "No such module: $val" unless(defined $modules{$val}); push @modules_to_sync, $val; } elsif ("$var" eq "separate-module") { - my ($module, $srcdir) = split(/:/, $val); - $modules{$module} = $srcdir; + my ($module, $prodir, $headerdir) = split(/:/, $val); + $modules{$module} = $prodir; push @modules_to_sync, $module; - delete $moduleheaders{$module} if ($moduleheaders{$module}); + $moduleheaders{$module} = $headerdir; $create_uic_class_map = 0; $create_private_headers = 0; } elsif ("$var" eq "output") { -- cgit v0.12