diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-04-17 11:24:09 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-04-17 11:24:09 (GMT) |
commit | fd36b47e8758562fc9ff350f292fc9ae9ed91d4e (patch) | |
tree | 139e2fc6ee4e1c52bb7f283250d5d72c58617a42 | |
parent | 140a96d0b860b045c18d53c1ac96e77b3893d31c (diff) | |
parent | 0ab8fabe3d36f752ce7fdcc0d7e9fe9a4f03e928 (diff) | |
download | Qt-fd36b47e8758562fc9ff350f292fc9ae9ed91d4e.zip Qt-fd36b47e8758562fc9ff350f292fc9ae9ed91d4e.tar.gz Qt-fd36b47e8758562fc9ff350f292fc9ae9ed91d4e.tar.bz2 |
Merge branch 'qt-4.7-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration into 4.7-integration
* 'qt-4.7-from-4.6' of scm.dev.nokia.troll.no:qt/qt-integration: (50 commits)
Fix mismatched import declarations
Doc
create magic comment messages in "finished" state
make QT_TR_NOOP work in static initializers
make HashString and HashStringList objects smaller
remove pointless manual assignments from token type enum
Update EABI and BWINS DEF files for Symbian
Update WebKit DEF files on Symbian
Add translation context to qsTr() benchmark
QtScript: Add autotest for enumeration of QMetaObject properties
Symbol visibility fixes for RVCT4 on Symbian
Symbol visibility fixes for RVCT4 on Symbian
Symbol visibility fixes for RVCT4 on Symbian
Fixes auto-test failure for 9da13ea53aec6d841ba7f416531d6c52d4368df4.
QNAM HTTP: Pipelining changes
'#' gets inserted to editor when changing FEP modes
ComboBox popuplist is not correctly layouted in fullscreen mode
Dialogs in landscape mode are not correctly positioned
Slider graphics does not look correct in N95 (part2)
Fixes tooltips for QGraphicsProxyWidget.
...
80 files changed, 891 insertions, 352 deletions
diff --git a/doc/src/howtos/openvg.qdoc b/doc/src/howtos/openvg.qdoc index 9c805bb..f70ed54 100644 --- a/doc/src/howtos/openvg.qdoc +++ b/doc/src/howtos/openvg.qdoc @@ -295,6 +295,16 @@ Convolution, colorize, drop shadow, and blur filters are accelerated using OpenVG operations. + \section2 Scrolling + + By default, accelerated scrolling is not enabled because the impact on + performance is very much tied to the hardware platform. To enable + accelerated scrolling, you should ensure that QVG_BUFFER_SCROLLING is + defined when compiling the QtOpenVG module. + + You should only enable this feature if vgCopyPixels() is known to be + efficient on your hardware platform. + \section1 Known issues Performance of copying the contents of an OpenVG-rendered window to the diff --git a/doc/src/platforms/emb-openvg.qdocinc b/doc/src/platforms/emb-openvg.qdocinc index 37ccb9c..2f9cc21 100644 --- a/doc/src/platforms/emb-openvg.qdocinc +++ b/doc/src/platforms/emb-openvg.qdocinc @@ -259,6 +259,12 @@ at present. \o Convolution, colorize, drop shadow, and blur filters are accelerated using OpenVG operations. + \row + \o Scrolling + \o Accelerated scrolling is implemented but disabled by default +unless QVG_BUFFER_SCROLLING is defined. This should only be enabled on +OpenVG engines where vgCopyPixels() is known to be efficient. + \endtable \section2 Known issues diff --git a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp index 2d86f8c..77c67ab 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qobject.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qobject.cpp @@ -374,10 +374,13 @@ Q_PROPERTY(type name READ getFunction [WRITE setFunction] [RESET resetFunction] + [NOTIFY notifySignal] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] - [USER bool]) + [USER bool] + [CONSTANT] + [FINAL]) //! [36] diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp index 3c9df93..4d8418b 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp @@ -1107,6 +1107,7 @@ static inline void splitMatra(unsigned short *reordered, int matra, int &len) #ifndef NO_OPENTYPE static const HB_OpenTypeFeature indic_features[] = { + { HB_MAKE_TAG('l', 'o', 'c', 'a'), LocaProperty }, { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, { HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty }, @@ -1115,12 +1116,14 @@ static const HB_OpenTypeFeature indic_features[] = { { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty }, { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty }, { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty }, + { HB_MAKE_TAG('c', 'j', 'c', 't'), ConjunctFormProperty }, { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty }, { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty }, { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty }, { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty }, { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty }, { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty }, + { HB_MAKE_TAG('c', 'a', 'l', 't'), IndicCaltProperty }, { 0, 0 } }; #endif @@ -1148,6 +1151,8 @@ static QString propertiesToString(int properties) { QString res; properties = ~properties; + if (properties & LocaProperty) + res += "Loca "; if (properties & CcmpProperty) res += "Ccmp "; if (properties & InitProperty) @@ -1168,6 +1173,8 @@ static QString propertiesToString(int properties) res += "HalfForm "; if (properties & PostFormProperty) res += "PostForm "; + if (properties & ConjunctFormProperty) + res += "PostForm "; if (properties & VattuProperty) res += "Vattu "; if (properties & PreSubstProperty) @@ -1182,6 +1189,8 @@ static QString propertiesToString(int properties) res += "Halant "; if (properties & CligProperty) res += "Clig "; + if (properties & IndicCaltProperty) + res += "Calt "; return res; } #endif @@ -1296,10 +1305,15 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv } int skipped = 0; Position pos = Post; - for (i = len-1; i > base; i--) { + for (i = len-1; i >= base; i--) { if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada)) continue; + if (i < len-1 && position[i] == Control && position[i+1] == Consonant) { + base = i+1; + break; + } + Position charPosition = indic_position(uc[i]); if (pos == Post && charPosition == Post) { pos = Post; @@ -1545,16 +1559,20 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv // features we should always apply for (i = 0; i < len; ++i) - properties[i] = ~(CcmpProperty + properties[i] = ~(LocaProperty + | CcmpProperty | NuktaProperty | VattuProperty + | ConjunctFormProperty | PreSubstProperty | BelowSubstProperty | AboveSubstProperty | PostSubstProperty | HalantProperty + | IndicCaltProperty | PositioningProperties); + // Loca always applies // Ccmp always applies // Init if (item->item.pos == 0 @@ -1611,6 +1629,7 @@ static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool inv // abvs always applies // psts always applies // halant always applies + // calt always applies #ifdef INDIC_DEBUG // { diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h b/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h index 11ed753..e1360c7 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h @@ -57,34 +57,37 @@ typedef enum } HB_CombiningClass; typedef enum { - CcmpProperty = 0x1, - InitProperty = 0x2, - IsolProperty = 0x4, - FinaProperty = 0x8, - MediProperty = 0x10, - RligProperty = 0x20, - CaltProperty = 0x40, - LigaProperty = 0x80, - DligProperty = 0x100, - CswhProperty = 0x200, - MsetProperty = 0x400, + LocaProperty = 0x1, + CcmpProperty = 0x2, + InitProperty = 0x4, + IsolProperty = 0x8, + FinaProperty = 0x10, + MediProperty = 0x20, + RligProperty = 0x40, + CaltProperty = 0x80, + LigaProperty = 0x100, + DligProperty = 0x200, + CswhProperty = 0x400, + MsetProperty = 0x800, /* used by indic and myanmar shaper */ - NuktaProperty = 0x4, - AkhantProperty = 0x8, - RephProperty = 0x10, - PreFormProperty = 0x20, - BelowFormProperty = 0x40, - AboveFormProperty = 0x80, - HalfFormProperty = 0x100, - PostFormProperty = 0x200, - VattuProperty = 0x400, - PreSubstProperty = 0x800, - BelowSubstProperty = 0x1000, - AboveSubstProperty = 0x2000, - PostSubstProperty = 0x4000, - HalantProperty = 0x8000, - CligProperty = 0x10000 + NuktaProperty = 0x8, + AkhantProperty = 0x10, + RephProperty = 0x20, + PreFormProperty = 0x40, + BelowFormProperty = 0x80, + AboveFormProperty = 0x100, + HalfFormProperty = 0x200, + PostFormProperty = 0x400, + ConjunctFormProperty = 0x800, + VattuProperty = 0x1000, + PreSubstProperty = 0x2000, + BelowSubstProperty = 0x4000, + AboveSubstProperty = 0x8000, + PostSubstProperty = 0x10000, + HalantProperty = 0x20000, + CligProperty = 0x40000, + IndicCaltProperty = 0x80000 } HB_OpenTypeProperty; diff --git a/src/3rdparty/harfbuzz/tests/shaping/main.cpp b/src/3rdparty/harfbuzz/tests/shaping/main.cpp index 320e8ee..28f8e07 100644 --- a/src/3rdparty/harfbuzz/tests/shaping/main.cpp +++ b/src/3rdparty/harfbuzz/tests/shaping/main.cpp @@ -1130,6 +1130,8 @@ void tst_QScriptEngine::malayalam() { 0x3f8, 0x0 } }, { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 }, { 0x2ff, 0x0 } }, + { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 }, + { 0xf3, 0x350, 0x0 } }, { {0}, {0} } }; diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 6356c21..be2a568 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -48,7 +48,7 @@ MMF::AbstractMediaPlayer::AbstractMediaPlayer (MediaObject *parent, const AbstractPlayer *player) : AbstractPlayer(player) , m_parent(parent) - , m_playPending(false) + , m_pending(NothingPending) , m_positionTimer(new QTimer(this)) , m_bufferStatusTimer(new QTimer(this)) , m_mmfMaxVolume(NullMaxVolume) @@ -74,14 +74,12 @@ void MMF::AbstractMediaPlayer::play() break; case LoadingState: - m_playPending = true; + setPending(PlayPending); break; case StoppedState: case PausedState: - doPlay(); - startPositionTimer(); - changeState(PlayingState); + startPlayback(); break; case PlayingState: @@ -103,14 +101,16 @@ void MMF::AbstractMediaPlayer::pause() TRACE_CONTEXT(AbstractMediaPlayer::pause, EAudioApi); TRACE_ENTRY("state %d", privateState()); - m_playPending = false; stopTimers(); switch (privateState()) { case GroundState: case LoadingState: - case PausedState: case StoppedState: + setPending(PausePending); + break; + + case PausedState: // Do nothing break; @@ -135,7 +135,7 @@ void MMF::AbstractMediaPlayer::stop() TRACE_CONTEXT(AbstractMediaPlayer::stop, EAudioApi); TRACE_ENTRY("state %d", privateState()); - m_playPending = false; + setPending(NothingPending); stopTimers(); switch (privateState()) { @@ -365,6 +365,18 @@ void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume) doVolumeChanged(); } +void MMF::AbstractMediaPlayer::loadingComplete(int error) +{ + Q_ASSERT(Phonon::LoadingState == state()); + + if (KErrNone == error) { + updateMetaData(); + changeState(StoppedState); + } else { + setError(tr("Loading clip failed"), error); + } +} + void MMF::AbstractMediaPlayer::playbackComplete(int error) { stopTimers(); @@ -377,7 +389,7 @@ void MMF::AbstractMediaPlayer::playbackComplete(int error) } if (KErrNone == error) { - changeState(StoppedState); + changeState(PausedState); // MediaObject::switchToNextSource deletes the current player, so we // call it via delayed slot invokation to ensure that this object does @@ -386,6 +398,7 @@ void MMF::AbstractMediaPlayer::playbackComplete(int error) } else { setError(tr("Playback complete"), error); + emit finished(); } } @@ -440,11 +453,39 @@ void MMF::AbstractMediaPlayer::resetMarksIfRewound() m_aboutToFinishSent = false; } +void MMF::AbstractMediaPlayer::setPending(Pending pending) +{ + const Phonon::State oldState = state(); + m_pending = pending; + const Phonon::State newState = state(); + if (newState != oldState) + emit stateChanged(newState, oldState); +} + +void MMF::AbstractMediaPlayer::startPlayback() +{ + doPlay(); + startPositionTimer(); + changeState(PlayingState); +} + void MMF::AbstractMediaPlayer::bufferStatusTick() { emit MMF::AbstractPlayer::bufferStatus(bufferStatus()); } +Phonon::State MMF::AbstractMediaPlayer::phononState(PrivateState state) const +{ + Phonon::State result = AbstractPlayer::phononState(state); + + if (PausePending == m_pending) { + Q_ASSERT(Phonon::StoppedState == result || Phonon::LoadingState == result); + result = Phonon::PausedState; + } + + return result; +} + void MMF::AbstractMediaPlayer::changeState(PrivateState newState) { TRACE_CONTEXT(AbstractMediaPlayer::changeState, EAudioInternal); @@ -452,20 +493,26 @@ void MMF::AbstractMediaPlayer::changeState(PrivateState newState) const Phonon::State oldPhononState = phononState(privateState()); const Phonon::State newPhononState = phononState(newState); - // TODO: add some invariants to check that the transition is valid - AbstractPlayer::changeState(newState); - if (LoadingState == oldPhononState && StoppedState == newPhononState) { - // Ensure initial volume is set on MMF API before starting playback - doVolumeChanged(); - - // Check whether play() was called while clip was being loaded. If so, - // playback should be started now - if (m_playPending) { - TRACE_0("play was called while loading; starting playback now"); - m_playPending = false; - play(); + switch (m_pending) { + case NothingPending: + AbstractPlayer::changeState(newState); + break; + + case PlayPending: + changeState(PlayingState); // necessary in order to apply initial volume + doVolumeChanged(); + startPlayback(); + break; + + case PausePending: + AbstractPlayer::changeState(PausedState); + break; } + + setPending(NothingPending); + } else { + AbstractPlayer::changeState(newState); } } diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index 308b5af..23a8233 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -60,6 +60,8 @@ public: protected: // AbstractPlayer virtual void doSetTickInterval(qint32 interval); + virtual Phonon::State phononState(PrivateState state) const; + virtual void changeState(PrivateState newState); virtual void doPlay() = 0; virtual void doPause() = 0; @@ -70,7 +72,6 @@ protected: virtual int openUrl(const QString& url) = 0; virtual int bufferStatus() const = 0; virtual void close() = 0; - virtual void changeState(PrivateState newState); void updateMetaData(); virtual int numberOfMetaDataEntries() const = 0; @@ -80,6 +81,7 @@ protected: void bufferingStarted(); void bufferingComplete(); void maxVolumeChanged(int maxVolume); + void loadingComplete(int error); void playbackComplete(int error); static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); @@ -93,6 +95,15 @@ private: void doVolumeChanged(); void emitMarksIfReached(qint64 position); void resetMarksIfRewound(); + void startPlayback(); + + enum Pending { + NothingPending, + PausePending, + PlayPending + }; + + void setPending(Pending pending); private Q_SLOTS: void positionTick(); @@ -101,12 +112,7 @@ private Q_SLOTS: 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 - * be started. - */ - bool m_playPending; + Pending m_pending; QScopedPointer<QTimer> m_positionTimer; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index 421155b..77d7ae0 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -48,6 +48,11 @@ MMF::AbstractPlayer::AbstractPlayer(const AbstractPlayer *player) m_tickInterval = player->m_tickInterval; m_transitionTime = player->m_transitionTime; m_prefinishMark = player->m_prefinishMark; + + // This is to prevent unwanted state transitions occurring as a result + // of MediaObject::switchToNextSource() during playlist playback. + if (StoppedState == player->m_state) + m_state = player->m_state; } } @@ -141,7 +146,7 @@ Phonon::State MMF::AbstractPlayer::phononState() const return phononState(m_state); } -Phonon::State MMF::AbstractPlayer::phononState(PrivateState state) +Phonon::State MMF::AbstractPlayer::phononState(PrivateState state) const { const Phonon::State phononState = GroundState == state diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 92bd87e..ab892f5 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -133,7 +133,7 @@ protected: /** * Converts PrivateState into the corresponding Phonon::State */ - static Phonon::State phononState(PrivateState state); + virtual Phonon::State phononState(PrivateState state) const; virtual void videoOutputChanged(); diff --git a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp index c2bcce0..2e0ab1c 100644 --- a/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractvideoplayer.cpp @@ -268,11 +268,10 @@ void MMF::AbstractVideoPlayer::MvpuoPrepareComplete(TInt aError) handlePendingParametersChanged(); emit totalTimeChanged(totalTime()); - changeState(StoppedState); - } else { - setError(tr("Buffering clip failed"), err); } + loadingComplete(aError); + TRACE_EXIT_0(); } diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index ee07229..77a0964 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -203,12 +203,10 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError, maxVolumeChanged(m_player->MaxVolume()); m_totalTime = toMilliSeconds(m_player->Duration()); emit totalTimeChanged(m_totalTime); - updateMetaData(); - changeState(StoppedState); - } else { - setError(tr("Opening clip failed"), aError); } + loadingComplete(aError); + TRACE_EXIT_0(); } diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index ee459e6..e1b921b 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -323,11 +323,12 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) connect(m_player.data(), SIGNAL(totalTimeChanged(qint64)), SIGNAL(totalTimeChanged(qint64))); 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<QString,QString>)), SIGNAL(metaDataChanged(QMultiMap<QString,QString>))); connect(m_player.data(), SIGNAL(aboutToFinish()), SIGNAL(aboutToFinish())); - connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SIGNAL(tick(qint32))); + connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SIGNAL(prefinishMarkReached(qint32))); + connect(m_player.data(), SIGNAL(prefinishMarkReached(qint32)), SLOT(handlePrefinishMarkReached(qint32))); + connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64))); // We need to call setError() after doing the connects, otherwise the // error won't be received. @@ -414,8 +415,20 @@ void MMF::MediaObject::switchToNextSource() m_nextSourceSet = false; switchToSource(m_nextSource); play(); + } else { + emit finished(); } } +//----------------------------------------------------------------------------- +// Other private functions +//----------------------------------------------------------------------------- + +void MMF::MediaObject::handlePrefinishMarkReached(qint32 time) +{ + emit tick(time); +} + + QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index 62e0a0e..f15eb21 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -107,6 +107,9 @@ Q_SIGNALS: void finished(); void tick(qint64 time); +private Q_SLOTS: + void handlePrefinishMarkReached(qint32); + private: void switchToSource(const MediaSource &source); void createPlayer(const MediaSource &source); diff --git a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp index d607f1d..1925471 100644 --- a/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp +++ b/src/3rdparty/phonon/mmf/videoplayer_dsa.cpp @@ -226,38 +226,40 @@ void MMF::DsaVideoPlayer::handleParametersChanged(VideoParameters parameters) getDsaRegion(m_wsSession, *m_window); #endif - static const TBool antialias = ETrue; - int err = KErrNone; - - if (parameters & ScaleFactors) { - TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, - antialias)); - if(KErrNone != err) { - TRACE("SetScaleFactorL (1) err %d", err); - setError(tr("Video display error"), err); + if (m_player) { + static const TBool antialias = ETrue; + int err = KErrNone; + + if (parameters & ScaleFactors) { + TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, + antialias)); + if(KErrNone != err) { + TRACE("SetScaleFactorL (1) err %d", err); + setError(tr("Video display error"), err); + } } - } - if (KErrNone == err) { - if (parameters & WindowHandle || parameters & WindowScreenRect) { - TRAP(err, - m_player->SetDisplayWindowL(m_wsSession, m_screenDevice, - *m_window, - m_videoScreenRect, - m_videoScreenRect)); - } + if (KErrNone == err) { + if (parameters & WindowHandle || parameters & WindowScreenRect) { + TRAP(err, + m_player->SetDisplayWindowL(m_wsSession, m_screenDevice, + *m_window, + m_videoScreenRect, + m_videoScreenRect)); + } - if (KErrNone != err) { - TRACE("SetDisplayWindowL err %d", err); - setError(tr("Video display error"), err); - } else { - m_dsaActive = true; - if (parameters & ScaleFactors) { - TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, - antialias)); - if (KErrNone != err) { - TRACE("SetScaleFactorL (2) err %d", err); - setError(tr("Video display error"), err); + if (KErrNone != err) { + TRACE("SetDisplayWindowL err %d", err); + setError(tr("Video display error"), err); + } else { + m_dsaActive = true; + if (parameters & ScaleFactors) { + TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, + antialias)); + if (KErrNone != err) { + TRACE("SetScaleFactorL (2) err %d", err); + setError(tr("Video display error"), err); + } } } } @@ -296,7 +298,7 @@ bool MMF::DsaVideoPlayer::stopDirectScreenAccess() const bool dsaWasActive = m_dsaActive; if (m_dsaActive) { - TRAPD(err, m_player->StopDirectScreenAccessL()); + TRAP(err, m_player->StopDirectScreenAccessL()); if (KErrNone == err) m_dsaActive = false; else diff --git a/src/3rdparty/phonon/mmf/videoplayer_surface.cpp b/src/3rdparty/phonon/mmf/videoplayer_surface.cpp index 5f234e5..fda7342 100644 --- a/src/3rdparty/phonon/mmf/videoplayer_surface.cpp +++ b/src/3rdparty/phonon/mmf/videoplayer_surface.cpp @@ -104,44 +104,43 @@ void MMF::SurfaceVideoPlayer::handleVideoWindowChanged() void MMF::SurfaceVideoPlayer::handleParametersChanged(VideoParameters parameters) { - CVideoPlayerUtility2 *player = static_cast<CVideoPlayerUtility2 *>(m_player.data()); - - int err = KErrNone; - TRect rect; - if (m_videoOutput) { m_videoOutput->dump(); const QSize size = m_videoOutput->videoWindowSize(); rect.SetSize(TSize(size.width(), size.height())); } - if (parameters & WindowHandle) { - if (m_displayWindow) - player->RemoveDisplayWindow(*m_displayWindow); - - RWindow *window = static_cast<RWindow *>(m_window); - if (window) { - window->SetBackgroundColor(TRgb(0, 0, 0, 255)); - TRAP(err, player->AddDisplayWindowL(m_wsSession, m_screenDevice, *window, rect, rect)); - if (KErrNone != err) { - setError(tr("Video display error"), err); - window = 0; + CVideoPlayerUtility2 *player = static_cast<CVideoPlayerUtility2 *>(m_player.data()); + if (player) { + int err = KErrNone; + if (parameters & WindowHandle) { + if (m_displayWindow) + player->RemoveDisplayWindow(*m_displayWindow); + + RWindow *window = static_cast<RWindow *>(m_window); + if (window) { + window->SetBackgroundColor(TRgb(0, 0, 0, 255)); + TRAP(err, player->AddDisplayWindowL(m_wsSession, m_screenDevice, *window, rect, rect)); + if (KErrNone != err) { + setError(tr("Video display error"), err); + window = 0; + } } + m_displayWindow = window; } - m_displayWindow = window; - } - if (KErrNone == err) { - if (parameters & ScaleFactors) { - Q_ASSERT(m_displayWindow); - TRAP(err, player->SetVideoExtentL(*m_displayWindow, rect)); - if (KErrNone == err) - TRAP(err, player->SetWindowClipRectL(*m_displayWindow, rect)); - if (KErrNone == err) - TRAP(err, player->SetScaleFactorL(*m_displayWindow, m_scaleWidth, m_scaleHeight)); - if (KErrNone != err) - setError(tr("Video display error"), err); + if (KErrNone == err) { + if (parameters & ScaleFactors) { + Q_ASSERT(m_displayWindow); + TRAP(err, player->SetVideoExtentL(*m_displayWindow, rect)); + if (KErrNone == err) + TRAP(err, player->SetWindowClipRectL(*m_displayWindow, rect)); + if (KErrNone == err) + TRAP(err, player->SetScaleFactorL(*m_displayWindow, m_scaleWidth, m_scaleHeight)); + if (KErrNone != err) + setError(tr("Video display error"), err); + } } } } diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index f83c142..f2cef4e1 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -755,6 +755,7 @@ qint64 QIODevice::bytesToWrite() const qint64 QIODevice::read(char *data, qint64 maxSize) { Q_D(QIODevice); + CHECK_READABLE(read, qint64(-1)); #if defined QIODEVICE_DEBUG printf("%p QIODevice::read(%p, %d), d->pos = %d, d->buffer.size() = %d\n", diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index c9129c1..a6bd78a 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -905,26 +905,33 @@ bool QDialog::s60AdjustedPosition() } else { cbaHeight = qt_TSize2QSize(bgContainer->Size()).height(); } - p.setY(S60->screenHeightInPixels-height()-cbaHeight); + p.setY(S60->screenHeightInPixels - height() - cbaHeight); p.setX(0); } else { const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent); - TRect cbaRect = TRect(); - AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect); - AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation(); - switch (cbaLocation) { - case AknLayoutUtils::EAknCbaLocationBottom: - p.setY(S60->screenHeightInPixels - height()-cbaRect.Height()); - p.setX((S60->screenWidthInPixels - width())>>1); - break; - case AknLayoutUtils::EAknCbaLocationRight: - p.setY((S60->screenHeightInPixels - height())>>1); - p.setX(qMax(0,S60->screenWidthInPixels-width()-scrollbarWidth-cbaRect.Width())); - break; - case AknLayoutUtils::EAknCbaLocationLeft: - p.setY((S60->screenHeightInPixels - height())>>1); - p.setX(qMax(0,scrollbarWidth+cbaRect.Width())); - break; + TRect staConTopRect = TRect(); + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect); + if (staConTopRect.IsEmpty()) { + TRect cbaRect = TRect(); + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect); + AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation(); + switch (cbaLocation) { + case AknLayoutUtils::EAknCbaLocationBottom: + p.setY(S60->screenHeightInPixels - height() - cbaRect.Height()); + p.setX((S60->screenWidthInPixels - width()) >> 1); + break; + case AknLayoutUtils::EAknCbaLocationRight: + p.setY((S60->screenHeightInPixels - height()) >> 1); + p.setX(qMax(0,S60->screenWidthInPixels - width() - scrollbarWidth - cbaRect.Width())); + break; + case AknLayoutUtils::EAknCbaLocationLeft: + p.setY((S60->screenHeightInPixels - height()) >> 1); + p.setX(qMax(0,scrollbarWidth + cbaRect.Width())); + break; + } + } else { + p.setY((S60->screenHeightInPixels - height()) >> 1); + p.setX(qMax(0,S60->screenWidthInPixels - width())); } } move(p); diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 2132526..ad7cf5d 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -189,7 +189,7 @@ QT_BEGIN_NAMESPACE */ extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); -extern bool qt_tab_all_widgets; +Q_GUI_EXPORT extern bool qt_tab_all_widgets; /*! \internal @@ -897,6 +897,29 @@ bool QGraphicsProxyWidget::event(QEvent *event) } break; } +#ifndef QT_NO_TOOLTIP + case QEvent::GraphicsSceneHelp: { + // Propagate the help event (for tooltip) to the widget under mouse + if (d->lastWidgetUnderMouse) { + QGraphicsSceneHelpEvent *he = static_cast<QGraphicsSceneHelpEvent *>(event); + QPoint pos = d->mapToReceiver(mapFromScene(he->scenePos()), d->lastWidgetUnderMouse).toPoint(); + QHelpEvent e(QEvent::ToolTip, pos, he->screenPos()); + QApplication::sendEvent(d->lastWidgetUnderMouse, &e); + event->setAccepted(e.isAccepted()); + return e.isAccepted(); + } + break; + } + case QEvent::ToolTipChange: { + // Propagate tooltip change to the widget + if (!d->tooltipChangeMode) { + d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::ProxyToWidgetMode; + d->widget->setToolTip(toolTip()); + d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode; + } + break; + } +#endif default: break; } @@ -952,6 +975,14 @@ bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event) d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode; } break; + case QEvent::ToolTipChange: + // Propagate tooltip change to the proxy. + if (!d->tooltipChangeMode) { + d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::WidgetToProxyMode; + setToolTip(d->widget->toolTip()); + d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode; + } + break; default: break; } diff --git a/src/gui/graphicsview/qgraphicsproxywidget_p.h b/src/gui/graphicsview/qgraphicsproxywidget_p.h index 8aed363..0e29a7e 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget_p.h +++ b/src/gui/graphicsview/qgraphicsproxywidget_p.h @@ -72,6 +72,7 @@ public: enabledChangeMode(NoMode), styleChangeMode(NoMode), paletteChangeMode(NoMode), + tooltipChangeMode(NoMode), focusFromWidgetToProxy(0) { } void init(); @@ -117,6 +118,7 @@ public: quint32 enabledChangeMode : 2; quint32 styleChangeMode : 2; quint32 paletteChangeMode : 2; + quint32 tooltipChangeMode : 2; quint32 focusFromWidgetToProxy : 1; quint32 proxyIsGivingFocus : 1; }; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 4b612f4..bd0f0d8 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -3786,6 +3786,12 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent) QGraphicsItem *toolTipItem = 0; for (int i = 0; i < itemsAtPos.size(); ++i) { QGraphicsItem *tmp = itemsAtPos.at(i); + if (tmp->d_func()->isProxyWidget()) { + // if the item is a proxy widget, the event is forwarded to it + sendEvent(tmp, helpEvent); + if (helpEvent->isAccepted()) + return; + } if (!tmp->toolTip().isEmpty()) { toolTipItem = tmp; break; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index d226baf..85be5b1 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -118,8 +118,8 @@ const QVector<QRgb> *qt_image_colortable(const QImage &image) return &image.d->colortable; } -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); +Q_GUI_EXPORT extern int qt_defaultDpiX(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); QBasicAtomicInt qimage_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1); diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp index 029154b..fd1ee6a 100644 --- a/src/gui/image/qpaintengine_pic.cpp +++ b/src/gui/image/qpaintengine_pic.cpp @@ -477,7 +477,7 @@ void QPicturePaintEngine::drawImage(const QRectF &r, const QImage &image, const writeCmdLength(pos, r, false); } -extern int qt_defaultDpi(); +Q_GUI_EXPORT extern int qt_defaultDpi(); void QPicturePaintEngine::drawTextItem(const QPointF &p , const QTextItem &ti) { diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 45b3ed0..20a1dce 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -108,8 +108,8 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, const char *qt_mfhdr_tag = "QPIC"; // header tag static const quint16 mfhdr_maj = 11; // major version # static const quint16 mfhdr_min = 0; // minor version # -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); +Q_GUI_EXPORT extern int qt_defaultDpiX(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); /*! Constructs an empty picture. diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index b183d0d..9dc15fc 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -361,8 +361,8 @@ QPaintEngine* QRasterPixmapData::paintEngine() const return image.paintEngine(); } -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); +Q_GUI_EXPORT extern int qt_defaultDpiX(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const { diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 5355ad3..70770c4 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -898,7 +898,7 @@ Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, in expblur<12, 10, false>(blurImage, radius, quality, transposed); } -bool qt_scaleForTransform(const QTransform &transform, qreal *scale); +Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); /*! \internal diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 94036d0..b42e0ab 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -782,7 +782,6 @@ void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction) if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos) longPress = 1; } - return; } QList<QInputMethodEvent::Attribute> attributes; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 62e99e9..ec635d4 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -142,7 +142,7 @@ static void initResources() QT_BEGIN_NAMESPACE -extern void qt_call_post_routines(); +Q_DECL_IMPORT extern void qt_call_post_routines(); int QApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0 diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp index 1343959..c8fcf45 100644 --- a/src/gui/kernel/qtooltip.cpp +++ b/src/gui/kernel/qtooltip.cpp @@ -168,9 +168,9 @@ QTipLabel *QTipLabel::instance = 0; QTipLabel::QTipLabel(const QString &text, QWidget *w) #ifndef QT_NO_STYLE_STYLESHEET - : QLabel(w, Qt::ToolTip), styleSheetParent(0), widget(0) + : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), styleSheetParent(0), widget(0) #else - : QLabel(w, Qt::ToolTip), widget(0) + : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), widget(0) #endif { delete instance; diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp index b877784..6181b62 100644 --- a/src/gui/kernel/qwhatsthis.cpp +++ b/src/gui/kernel/qwhatsthis.cpp @@ -143,7 +143,7 @@ QT_BEGIN_NAMESPACE \sa QToolTip */ -extern void qDeleteInEventHandler(QObject *o); +Q_DECL_IMPORT extern void qDeleteInEventHandler(QObject *o); class QWhatsThat : public QWidget { diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 182cce9..96d547b 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -160,8 +160,7 @@ static void qt_cleanup_brush_pattern_image_cache() qt_brushPatternImageCache()->cleanup(); } -Q_GUI_EXPORT -QImage qt_imageForBrush(int brushStyle, bool invert) +Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert) { return qt_brushPatternImageCache()->getImage(brushStyle, invert); } diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index e1156dc..cd6718d 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -54,8 +54,8 @@ QT_BEGIN_NAMESPACE -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); +Q_GUI_EXPORT extern int qt_defaultDpiX(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); extern void qt_format_text(const QFont &font, const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect, int tabstops, int* tabarray, int tabarraylen, diff --git a/src/gui/painting/qpaintengine_alpha.cpp b/src/gui/painting/qpaintengine_alpha.cpp index 5a3c0cf..4b1c58d 100644 --- a/src/gui/painting/qpaintengine_alpha.cpp +++ b/src/gui/painting/qpaintengine_alpha.cpp @@ -93,8 +93,8 @@ bool QAlphaPaintEngine::begin(QPaintDevice *pdev) return true; } -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); +Q_GUI_EXPORT extern int qt_defaultDpiX(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); bool QAlphaPaintEngine::end() { diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 03d0825..8f14583 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -103,7 +103,7 @@ QT_BEGIN_NAMESPACE -extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp +Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp #define qreal_to_fixed_26_6(f) (int(f * 64)) #define qt_swap_int(x, y) { int tmp = (x); (x) = (y); (y) = tmp; } @@ -4996,7 +4996,7 @@ void QSpanData::init(QRasterBuffer *rb, const QRasterPaintEngine *pe) clip = pe ? pe->d_func()->clip() : 0; } -extern QImage qt_imageForBrush(int brushStyle, bool invert); +Q_GUI_EXPORT extern QImage qt_imageForBrush(int brushStyle, bool invert); void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode) { diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 990e3c4..9366513 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -380,7 +380,7 @@ QPainterState *QPaintEngineEx::createState(QPainterState *orig) const return new QPainterState(orig); } -extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp +Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) { diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index dcf745f..44049c0 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE -extern int qt_defaultDpi(); +Q_GUI_EXPORT extern int qt_defaultDpi(); #ifndef QT_NO_PRINTER diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 9740fce..e43544c 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -825,7 +825,7 @@ qreal qt_t_for_arc_angle(qreal angle) return t; } -void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, +Q_GUI_EXPORT void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, QPointF* startPoint, QPointF *endPoint); /*! diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 28cbc45..7587343 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -552,6 +552,7 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start, QRect endRect; if (orientation == Qt::Horizontal) { + startRect.setHeight(rect.height()); startRect.setWidth(qMin((rect.width() >> 1) - 1, startRect.width())); endRect = startRect.translated(rect.width() - startRect.width(), 0); middleRect.adjust(startRect.width(), 0, -startRect.width(), 0); @@ -561,6 +562,7 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start, endRect.adjust(overlap, 0, 0, 0); } } else { + startRect.setWidth(rect.width()); startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height())); endRect = startRect.translated(0, rect.height() - startRect.height()); middleRect.adjust(0, startRect.height(), 0, -startRect.height()); @@ -1372,14 +1374,13 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, optionComboBox.palette.setColor(QPalette::Inactive, QPalette::WindowText, optionComboBox.palette.text().color() ); QRect editRect = subControlRect(CC_ComboBox, comboBox, SC_ComboBoxEditField, widget); - painter->save(); - painter->setClipRect(editRect); + const int frameW = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); if (!comboBox->currentIcon.isNull()) { - QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; - QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode); + const QIcon::Mode mode = comboBox->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; + const QPixmap pixmap = comboBox->currentIcon.pixmap(comboBox->iconSize, mode); QRect iconRect(editRect); - iconRect.setWidth(comboBox->iconSize.width() + 4); + iconRect.setWidth(comboBox->iconSize.width() + frameW); iconRect = alignedRect(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter, iconRect.size(), editRect); @@ -1388,17 +1389,19 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap); if (comboBox->direction == Qt::RightToLeft) - editRect.translate(-4 - comboBox->iconSize.width(), 0); + editRect.setRight(editRect.right() - frameW - comboBox->iconSize.width()); else - editRect.translate(comboBox->iconSize.width() + 4, 0); + editRect.setLeft(comboBox->iconSize.width() + frameW); } if (!comboBox->currentText.isEmpty() && !comboBox->editable) { + const Qt::TextElideMode elideMode = (comboBox->direction == Qt::LeftToRight) ? Qt::ElideRight : Qt::ElideLeft; + const QString text = comboBox->fontMetrics.elidedText(comboBox->currentText, elideMode, editRect.width()); + QCommonStyle::drawItemText(painter, editRect.adjusted(QS60StylePrivate::pixelMetric(PM_FrameCornerWidth), 0, -1, 0), visualAlignment(comboBox->direction, Qt::AlignLeft | Qt::AlignVCenter), - comboBox->palette, comboBox->state & State_Enabled, comboBox->currentText); + comboBox->palette, comboBox->state & State_Enabled, text); } - painter->restore(); } break; #endif //QT_NO_COMBOBOX @@ -1541,7 +1544,6 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const int tabOverlap = QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness; - //todo: draw navi wipe behind tabbar - must be drawn with first draw if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive|| skinElement==QS60StylePrivate::SE_TabBarTabEastActive|| @@ -1645,7 +1647,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->drawPixmap(tr.left() + tabOverlap, tr.center().y() - (tabIcon.height() >> 1), tabIcon); - tr.setLeft(tr.left() + iconSize.width() + 4); + tr.setLeft(tr.left() + iconSize.width() + 4); //todo: magic four } QCommonStyle::drawItemText(painter, tr, alignment, optionTab.palette, tab->state & State_Enabled, tab->text, QPalette::WindowText); @@ -1964,14 +1966,14 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, // We need to reduce the focus frame size if LayoutSpacing is smaller than FocusFrameMargin // Otherwise, we would overlay adjacent widgets. const int frameHeightReduction = - qMin(0, pixelMetric(QStyle::PM_LayoutVerticalSpacing) - - pixelMetric(QStyle::PM_FocusFrameVMargin)); + qMin(0, pixelMetric(PM_LayoutVerticalSpacing) + - pixelMetric(PM_FocusFrameVMargin)); const int frameWidthReduction = - qMin(0, pixelMetric(QStyle::PM_LayoutHorizontalSpacing) - - pixelMetric(QStyle::PM_FocusFrameHMargin)); + qMin(0, pixelMetric(PM_LayoutHorizontalSpacing) + - pixelMetric(PM_FocusFrameHMargin)); const int rounding = - qMin(pixelMetric(QStyle::PM_FocusFrameVMargin), - pixelMetric(QStyle::PM_LayoutVerticalSpacing)); + qMin(pixelMetric(PM_FocusFrameVMargin), + pixelMetric(PM_LayoutVerticalSpacing)); const QRect frameRect = option->rect.adjusted(-frameWidthReduction, -frameHeightReduction, frameWidthReduction, frameHeightReduction); @@ -2847,7 +2849,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con const int tabOverlapNoBorder = QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap); const int tabOverlap = - tabOverlapNoBorder-QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); + tabOverlapNoBorder - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget); int gain = (tab) ? tabOverlap * tab->count() : 0; switch (twf->shape) { @@ -2913,7 +2915,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con ret = QRect(); } else { if (menuItem->direction == Qt::RightToLeft) - ret.translate(ret.width()-indicatorWidth, 0); + ret.translate(ret.width() - indicatorWidth, 0); ret.setWidth(indicatorWidth); } } else { @@ -3313,8 +3315,10 @@ bool QS60Style::eventFilter(QObject *object, QEvent *event) break; case QEvent::Destroy: case QEvent::Hide: - d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); - d->m_bars.removeAll(reinterpret_cast<QProgressBar *>(object)); + if (QProgressBar *bar = reinterpret_cast<QProgressBar *>(object)) { + d->stopAnimation(QS60StyleEnums::SP_QgnGrafBarWaitAnim); + d->m_bars.removeAll(bar); + } break; default: break; diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index a1a98ba..81b923b 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -4255,8 +4255,15 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w)) { const QAbstractScrollAreaPrivate *sap = sa->d_func(); rule.drawBackground(p, opt->rect, sap->contentsOffset()); - if (rule.hasBorder()) - rule.drawBorder(p, rule.borderRect(opt->rect)); + if (rule.hasBorder()) { + QRect brect = rule.borderRect(opt->rect); + if (styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, opt, w)) { + QRect r = brect.adjusted(0, 0, sa->verticalScrollBar()->isVisible() ? -sa->verticalScrollBar()->width() : 0, + sa->horizontalScrollBar()->isVisible() ? -sa->horizontalScrollBar()->height() : 0); + brect = QStyle::visualRect(opt->direction, brect, r); + } + rule.drawBorder(p, brect); + } break; } #endif @@ -4641,6 +4648,11 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const return msz.width() == -1 ? msz.height() : msz.width(); } break; + + case PM_ScrollView_ScrollBarSpacing: + if(!rule.hasNativeBorder() || rule.hasBox()) + return 0; + break; #endif // QT_NO_SCROLLBAR case PM_ProgressBarChunkWidth: diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 6803120..ae5e9ca 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -83,7 +83,7 @@ QT_BEGIN_NAMESPACE #define SMOOTH_SCALABLE 0xffff -extern int qt_defaultDpiY(); // in qfont.cpp +Q_GUI_EXPORT extern int qt_defaultDpiY(); // in qfont.cpp bool qt_enable_test_font = false; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 3a52e8e..5163c94 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -63,7 +63,7 @@ extern void qt_format_text(const QFont& font, const QRectF &_r, int tf, const QString &text, QRectF *brect, int tabStops, int *tabArray, int tabArrayLen, QPainter *painter); -extern int qt_defaultDpi(); +Q_GUI_EXPORT extern int qt_defaultDpi(); /***************************************************************************** QFontMetrics member functions diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 9a1b70c..3e556a7 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1656,7 +1656,7 @@ static void printPage(int index, QPainter *painter, const QTextDocument *doc, co painter->restore(); } -extern int qt_defaultDpi(); +Q_GUI_EXPORT extern int qt_defaultDpi(); /*! Prints the document to the given \a printer. The QPrinter must be diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index b45fcbb..f12bf0b 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE -extern int qt_defaultDpi(); +Q_GUI_EXPORT extern int qt_defaultDpi(); // ################ should probably add frameFormatChange notification! diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 6485966..d34553f 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -856,7 +856,7 @@ void QTextEngine::shapeLine(const QScriptLine &line) } } -extern int qt_defaultDpiY(); // in qfont.cpp +Q_GUI_EXPORT extern int qt_defaultDpiY(); // in qfont.cpp void QTextEngine::shapeText(int item) const { @@ -2494,7 +2494,7 @@ void QTextEngine::splitItem(int item, int pos) const // qDebug("split at position %d itempos=%d", pos, item); } -extern int qt_defaultDpiY(); +Q_GUI_EXPORT extern int qt_defaultDpiY(); QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const { diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index fa49a32..6733793 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -123,7 +123,7 @@ static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format) qreal scale = 1.0; QPaintDevice *pdev = doc->documentLayout()->paintDevice(); if (pdev) { - extern int qt_defaultDpi(); + Q_GUI_EXPORT extern int qt_defaultDpi(); if (pm.isNull()) pm = getPixmap(doc, format); if (!pm.isNull()) diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp index 5ceb237..995d659 100644 --- a/src/gui/widgets/qabstractbutton.cpp +++ b/src/gui/widgets/qabstractbutton.cpp @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE #define AUTO_REPEAT_DELAY 300 #define AUTO_REPEAT_INTERVAL 100 -extern bool qt_tab_all_widgets; +Q_GUI_EXPORT extern bool qt_tab_all_widgets; /*! \class QAbstractButton diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 1d496d5..73ec53e 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -394,7 +394,7 @@ void QAbstractScrollAreaPrivate::layoutChildren() if ((frameStyle != QFrame::NoFrame) && q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) { controlsRect = widgetRect; - const int extra = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing); + const int extra = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q); const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0); QRect frameRect = widgetRect; frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y()); diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index b1a27f2..ca58e6d 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -76,6 +76,10 @@ #ifndef QT_NO_EFFECTS # include <private/qeffects_p.h> #endif +#if defined(Q_WS_S60) +#include "private/qt_s60_p.h" +#endif + QT_BEGIN_NAMESPACE QComboBoxPrivate::QComboBoxPrivate() @@ -2458,11 +2462,16 @@ void QComboBox::showPopup() // in portait, menu should be positioned above softkeys listRect.moveBottom(screen.bottom()); } else { - // landscape, menu should be at the right and horizontally centered + TRect staConTopRect = TRect(); + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect); listRect.setWidth(listRect.height()); + //by default popup is centered on screen in landscape listRect.moveCenter(screen.center()); - (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : - listRect.setLeft(screen.left()); + if (staConTopRect.IsEmpty()) { + // landscape without stacon, menu should be at the right + (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : + listRect.setLeft(screen.left()); + } } #endif } else if (!boundToScreen || listRect.height() <= belowHeight) { @@ -2690,13 +2699,18 @@ void QComboBox::changeEvent(QEvent *e) // in portait, menu should be positioned above softkeys listRect.moveBottom(screen.bottom()); } else { - // landscape, menu should be at the right and horizontally centered + TRect staConTopRect = TRect(); + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect); listRect.setWidth(listRect.height()); + //by default popup is centered on screen in landscape listRect.moveCenter(screen.center()); - (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : - listRect.setLeft(screen.left()); + if (staConTopRect.IsEmpty()) { + // landscape without stacon, menu should be at the right + (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : + listRect.setLeft(screen.left()); + } + d->container->setGeometry(listRect); } - d->container->setGeometry(listRect); } } #endif diff --git a/src/multimedia/audio/qaudio_symbian_p.cpp b/src/multimedia/audio/qaudio_symbian_p.cpp index 58e3745..afe98f5 100644 --- a/src/multimedia/audio/qaudio_symbian_p.cpp +++ b/src/multimedia/audio/qaudio_symbian_p.cpp @@ -315,7 +315,7 @@ bool isFormatSupported(const QAudioFormat &formatQt, TUint32 fourCC; bool result = false; - if (formatQt.codec() == "audio/pcm" && + if (formatQt.codec() == QString::fromAscii("audio/pcm") && formatQtToNative(formatQt, fourCC, formatNative)) { result = (formatNative.iRate & caps.caps().iRate) @@ -337,7 +337,7 @@ bool formatQtToNative(const QAudioFormat &inputFormat, TMMFMonoStereo outputChannels; TMMFSoundEncoding outputEncoding; - if (inputFormat.codec() == "audio/pcm") { + if (inputFormat.codec() == QString::fromAscii("audio/pcm")) { result = sampleRateQtToNative(inputFormat.frequency(), outputSampleRate) && channelsQtToNative(inputFormat.channels(), outputChannels) diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index efeef4e..7f6df0a 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -2309,6 +2309,12 @@ void QFtpPrivate::_q_piFinished(const QString&) void QFtpPrivate::_q_piError(int errorCode, const QString &text) { Q_Q(QFtp); + + if (pending.isEmpty()) { + qWarning() << "QFtpPrivate::_q_piError was called without pending command!"; + return; + } + QFtpCommand *c = pending.first(); // non-fatal errors diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index a887449..a6322a3 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -71,9 +71,11 @@ const int QHttpNetworkConnectionPrivate::defaultChannelCount = 3; const int QHttpNetworkConnectionPrivate::defaultChannelCount = 6; #endif -// the maximum amount of requests that might be pipelined into a socket -// from what was suggested, 3 seems to be OK +// The pipeline length. So there will be 4 requests in flight. const int QHttpNetworkConnectionPrivate::defaultPipelineLength = 3; +// Only re-fill the pipeline if there's defaultRePipelineLength slots free in the pipeline. +// This means that there are 2 requests in flight and 2 slots free that will be re-filled. +const int QHttpNetworkConnectionPrivate::defaultRePipelineLength = 2; QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt) @@ -487,54 +489,68 @@ void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket) int i = indexOf(socket); - bool highPriorityQueueProcessingDone = false; - bool lowPriorityQueueProcessingDone = false; + if (! (defaultPipelineLength - channels[i].alreadyPipelinedRequests.length() >= 2)) { + return; + } - while (!highPriorityQueueProcessingDone && !lowPriorityQueueProcessingDone) { - // this loop runs once per request we intend to pipeline in. + if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported) + return; - if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported) - return; + // the current request that is in must already support pipelining + if (!channels[i].request.isPipeliningAllowed()) + return; - // the current request that is in must already support pipelining - if (!channels[i].request.isPipeliningAllowed()) - return; + // the current request must be a idempotent (right now we only check GET) + if (channels[i].request.operation() != QHttpNetworkRequest::Get) + return; - // the current request must be a idempotent (right now we only check GET) - if (channels[i].request.operation() != QHttpNetworkRequest::Get) - return; + // check if socket is connected + if (socket->state() != QAbstractSocket::ConnectedState) + return; - // check if socket is connected - if (socket->state() != QAbstractSocket::ConnectedState) - return; + // check for resendCurrent + if (channels[i].resendCurrent) + return; - // check for resendCurrent - if (channels[i].resendCurrent) - return; + // we do not like authentication stuff + // ### make sure to be OK with this in later releases + if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty()) + return; + if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty()) + return; + + // must be in ReadingState or WaitingState + if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState + || channels[i].state == QHttpNetworkConnectionChannel::ReadingState)) + return; - // we do not like authentication stuff - // ### make sure to be OK with this in later releases - if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty()) - return; - if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty()) - return; - // check for pipeline length + //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing highPriorityQueue, size=" << highPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length(); + int lengthBefore; + while (!highPriorityQueue.isEmpty()) { + lengthBefore = channels[i].alreadyPipelinedRequests.length(); + fillPipeline(highPriorityQueue, channels[i]); + if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength) return; - // must be in ReadingState or WaitingState - if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState - || channels[i].state == QHttpNetworkConnectionChannel::ReadingState)) + if (lengthBefore == channels[i].alreadyPipelinedRequests.length()) + break; // did not process anything, now do the low prio queue + } + + //qDebug() << "QHttpNetworkConnectionPrivate::fillPipeline processing lowPriorityQueue, size=" << lowPriorityQueue.size() << " alreadyPipelined=" << channels[i].alreadyPipelinedRequests.length(); + while (!lowPriorityQueue.isEmpty()) { + lengthBefore = channels[i].alreadyPipelinedRequests.length(); + fillPipeline(lowPriorityQueue, channels[i]); + + if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength) return; - highPriorityQueueProcessingDone = fillPipeline(highPriorityQueue, channels[i]); - // not finished with highPriorityQueue? then loop again - if (!highPriorityQueueProcessingDone) - continue; - // highPriorityQueue was processed, now deal with the lowPriorityQueue - lowPriorityQueueProcessingDone = fillPipeline(lowPriorityQueue, channels[i]); + if (lengthBefore == channels[i].alreadyPipelinedRequests.length()) + break; // did not process anything } + + } // returns true when the processing of a queue has been done @@ -707,7 +723,6 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() // if this is not possible, error will be emitted and connection terminated if (!channels[i].resetUploadData()) continue; - channels[i].sendRequest(); } } @@ -747,8 +762,9 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() // return fast if there is nothing to pipeline if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty()) return; - for (int j = 0; j < channelCount; j++) - fillPipeline(channels[j].socket); + for (int i = 0; i < channelCount; i++) + if (channels[i].socket->state() == QAbstractSocket::ConnectedState) + fillPipeline(channels[i].socket); } void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests() diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 823774e..b5bd300 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -156,6 +156,7 @@ class QHttpNetworkConnectionPrivate : public QObjectPrivate public: static const int defaultChannelCount; static const int defaultPipelineLength; + static const int defaultRePipelineLength; QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 4a31b6f..f9a6de8 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -285,8 +285,8 @@ bool QHttpNetworkConnectionChannel::sendRequest() } // HTTP pipelining - connection->d_func()->fillPipeline(socket); - socket->flush(); + //connection->d_func()->fillPipeline(socket); + //socket->flush(); // 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 @@ -661,7 +661,8 @@ void QHttpNetworkConnectionChannel::allDone() connection->d_func()->fillPipeline(socket); // continue reading - _q_receiveReply(); + //_q_receiveReply(); + // this was wrong, allDone gets called from that function anyway. } } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) { eatWhitespace(); diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro index 3790492..883f0f3 100644 --- a/src/openvg/openvg.pro +++ b/src/openvg/openvg.pro @@ -33,7 +33,7 @@ contains(QT_CONFIG, egl) { qwindowsurface_vgegl.cpp } -symbian: DEFINES += QVG_RECREATE_ON_SIZE_CHANGE +symbian: DEFINES += QVG_RECREATE_ON_SIZE_CHANGE QVG_BUFFER_SCROLLING include(../qbase.pri) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index d1e899a..5ae69cd 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -75,8 +75,8 @@ QT_BEGIN_NAMESPACE #if !defined(QVG_NO_DRAW_GLYPHS) -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); +Q_DECL_IMPORT extern int qt_defaultDpiX(); +Q_DECL_IMPORT extern int qt_defaultDpiY(); class QVGPaintEnginePrivate; @@ -496,7 +496,7 @@ void QVGPaintEnginePrivate::setTransform vgLoadMatrix(mat); } -extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); +Q_DECL_IMPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) { @@ -974,7 +974,7 @@ VGPath QVGPaintEnginePrivate::roundedRectPath(const QRectF &rect, qreal xRadius, return vgpath; } -extern QImage qt_imageForBrush(int style, bool invert); +Q_DECL_IMPORT extern QImage qt_imageForBrush(int style, bool invert); static QImage colorizeBitmap(const QImage &image, const QColor &color) { diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 6258e0c..a4afc95 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -347,8 +347,8 @@ void QVGPixmapData::reclaimImages() destroyImages(); } -extern int qt_defaultDpiX(); -extern int qt_defaultDpiY(); +Q_DECL_IMPORT extern int qt_defaultDpiX(); +Q_DECL_IMPORT extern int qt_defaultDpiY(); int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const { diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index 07d9209..55dcef3 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -57,6 +57,7 @@ QVGWindowSurface::QVGWindowSurface(QWidget *window) { // Create the default type of EGL window surface for windows. d_ptr = new QVGEGLWindowSurfaceDirect(this); + setStaticContentsSupport(d_ptr->supportsStaticContents()); } QVGWindowSurface::QVGWindowSurface @@ -89,7 +90,9 @@ void QVGWindowSurface::setGeometry(const QRect &rect) bool QVGWindowSurface::scroll(const QRegion &area, int dx, int dy) { - return QWindowSurface::scroll(area, dx, dy); + if (!d_ptr->scroll(window(), area, dx, dy)) + return QWindowSurface::scroll(area, dx, dy); + return true; } void QVGWindowSurface::beginPaint(const QRegion ®ion) diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 13ae807..92c4371 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -758,6 +758,33 @@ void QVGEGLWindowSurfaceDirect::endPaint } } +bool QVGEGLWindowSurfaceDirect::supportsStaticContents() const +{ +#if defined(QVG_BUFFER_SCROLLING) && !defined(QVG_NO_PRESERVED_SWAP) + return true; +#else + return QVGEGLWindowSurfacePrivate::supportsStaticContents(); +#endif +} + +bool QVGEGLWindowSurfaceDirect::scroll(QWidget *widget, const QRegion& area, int dx, int dy) +{ +#ifdef QVG_BUFFER_SCROLLING + QEglContext *context = ensureContext(widget); + if (context) { + context->makeCurrent(windowSurface); + QRect scrollRect = area.boundingRect(); + int sx = scrollRect.x(); + int sy = size.height() - scrollRect.y() - scrollRect.height(); + vgSeti(VG_SCISSORING, VG_FALSE); + vgCopyPixels(sx + dx, sy - dy, sx, sy, scrollRect.width(), scrollRect.height()); + context->lazyDoneCurrent(); + return true; + } +#endif + return false; +} + QT_END_NAMESPACE #endif diff --git a/src/openvg/qwindowsurface_vgegl_p.h b/src/openvg/qwindowsurface_vgegl_p.h index f6adbf3..fe62ed3 100644 --- a/src/openvg/qwindowsurface_vgegl_p.h +++ b/src/openvg/qwindowsurface_vgegl_p.h @@ -77,6 +77,8 @@ public: (QWidget *widget, const QRegion& region, QImage *image = 0) = 0; virtual VGImage surfaceImage() const; virtual QSize surfaceSize() const = 0; + virtual bool supportsStaticContents() const { return false; } + virtual bool scroll(QWidget *, const QRegion&, int, int) { return false; } private: QVGPaintEngine *engine; @@ -128,6 +130,8 @@ public: void beginPaint(QWidget *widget); void endPaint(QWidget *widget, const QRegion& region, QImage *image); QSize surfaceSize() const { return size; } + bool supportsStaticContents() const; + bool scroll(QWidget *widget, const QRegion& area, int dx, int dy); protected: QEglContext *context; diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 58c8d83..7e83277 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -756,7 +756,7 @@ JSC::JSValue JSC_HOST_CALL functionQsTranslate(JSC::ExecState *exec, JSC::JSObje else if (encStr == "UnicodeUTF8") encoding = QCoreApplication::UnicodeUTF8; else - return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%s'").arg(encStr)); + return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr)); } int n = -1; if (args.size() > 4) @@ -790,7 +790,7 @@ JSC::JSValue JSC_HOST_CALL functionQsTr(JSC::ExecState *exec, JSC::JSObject*, JS if ((args.size() > 1) && !args.at(1).isString()) return JSC::throwError(exec, JSC::GeneralError, "qsTr(): second argument (comment) must be a string"); if ((args.size() > 2) && !args.at(2).isNumber()) - return JSC::throwError(exec, JSC::GeneralError, "qsTranslate(): third argument (n) must be a number"); + return JSC::throwError(exec, JSC::GeneralError, "qsTr(): third argument (n) must be a number"); #ifndef QT_NO_QOBJECT JSC::UString context; // The first non-empty source URL in the call stack determines the translation context. @@ -1511,7 +1511,7 @@ void QScriptEnginePrivate::detachAllRegisteredScriptStrings() #ifndef QT_NO_REGEXP -extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); +Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp ®exp) { @@ -2006,7 +2006,7 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, #ifndef QT_NO_REGEXP -extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); +Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); /*! Creates a QtScript object of class RegExp with the given @@ -3392,7 +3392,7 @@ void QScriptEngine::installTranslatorFunctions(const QScriptValue &object) // unsigned attribs = JSC::DontEnum; JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 5, JSC::Identifier(exec, "qsTranslate"), QScript::functionQsTranslate)); JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 2, JSC::Identifier(exec, "QT_TRANSLATE_NOOP"), QScript::functionQsTranslateNoOp)); - JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr)); + JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::PrototypeFunction(exec, glob->prototypeFunctionStructure(), 3, JSC::Identifier(exec, "qsTr"), QScript::functionQsTr)); JSC::asObject(jscObject)->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "QT_TR_NOOP"), QScript::functionQsTrNoOp)); glob->stringPrototype()->putDirectFunction(exec, new (exec)JSC::NativeFunctionWrapper(exec, glob->prototypeFunctionStructure(), 1, JSC::Identifier(exec, "arg"), QScript::stringProtoFuncArg)); diff --git a/src/script/parser/qscriptlexer.cpp b/src/script/parser/qscriptlexer.cpp index 38ad6ce..ca64776 100644 --- a/src/script/parser/qscriptlexer.cpp +++ b/src/script/parser/qscriptlexer.cpp @@ -31,7 +31,7 @@ QT_BEGIN_NAMESPACE -extern double qstrtod(const char *s00, char const **se, bool *ok); +Q_DECL_IMPORT extern double qstrtod(const char *s00, char const **se, bool *ok); #define shiftWindowsLineBreak() \ do { \ diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index bc4ca76..038aeb4 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE static const char *qt_inherit_text = "inherit"; #define QT_INHERIT QLatin1String(qt_inherit_text) -double qstrtod(const char *s00, char const **se, bool *ok); +Q_DECL_IMPORT double qstrtod(const char *s00, char const **se, bool *ok); // ======== duplicated from qcolor_p diff --git a/src/xmlpatterns/data/qdecimal_p.h b/src/xmlpatterns/data/qdecimal_p.h index b746ff9..d17b647 100644 --- a/src/xmlpatterns/data/qdecimal_p.h +++ b/src/xmlpatterns/data/qdecimal_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE /** * Defined in QtCore's qlocale.cpp. */ -extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); +Q_DECL_IMPORT extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); namespace QPatternist { diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result index 2f21de2..53d7a25 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecontexts/project.ts.result @@ -98,7 +98,7 @@ <location filename="main.cpp" line="238"/> <source></source> <comment>This is a comment to the translator.</comment> - <translation type="unfinished"></translation> + <translation></translation> </message> </context> <context> diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index 6e73d6d..0765bfc 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -252,3 +252,26 @@ class YetAnotherTest : QObject { //: This is a message without a source string QString test = qtTrId("yet_another_id"); + + + +// QTBUG-9276: context in static initializers +class Bogus : QObject { + Q_OBJECT + + static const char * const s_strings[]; +}; + +const char * const Bogus::s_strings[] = { + QT_TR_NOOP("this should be in Bogus") +}; + +const char * const Bogus::s_strings[SIZE] = { + QT_TR_NOOP("this should be in Bogus") +}; + +void bogosity() +{ + // no spaces here. test collateral damage from ignoring equal sign + Class::member=QObject::tr("just QObject"); +} diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 6d50c21..208191d 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -26,6 +26,15 @@ backslashed \ stuff.</source> </message> </context> <context> + <name>Bogus</name> + <message> + <location filename="main.cpp" line="266"/> + <location filename="main.cpp" line="270"/> + <source>this should be in Bogus</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>Dialog2</name> <message numerus="yes"> <location filename="main.cpp" line="70"/> @@ -184,6 +193,14 @@ backslashed \ stuff.</source> </message> </context> <context> + <name>QObject</name> + <message> + <location filename="main.cpp" line="276"/> + <source>just QObject</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>QTranslator</name> <message> <location filename="main.cpp" line="93"/> diff --git a/tests/auto/mediaobject/qtesthelper.h b/tests/auto/mediaobject/qtesthelper.h index f082296..39d5b91 100644 --- a/tests/auto/mediaobject/qtesthelper.h +++ b/tests/auto/mediaobject/qtesthelper.h @@ -215,7 +215,6 @@ namespace QTest default: return 0; } - return 0; } } // namespace QTest QT_END_NAMESPACE diff --git a/tests/auto/mediaobject/tst_mediaobject.cpp b/tests/auto/mediaobject/tst_mediaobject.cpp index 5b0943e..994057b 100644 --- a/tests/auto/mediaobject/tst_mediaobject.cpp +++ b/tests/auto/mediaobject/tst_mediaobject.cpp @@ -193,31 +193,17 @@ static qint32 castQVariantToInt32(const QVariant &variant) return *reinterpret_cast<const qint32 *>(variant.constData()); } -static const char *const red = "\033[0;31m"; -static const char *const green = "\033[0;32m"; -static const char *const yellow = "\033[0;33m"; -static const char *const blue = "\033[0;34m"; -static const char *const purple = "\033[0;35m"; -static const char *const cyan = "\033[0;36m"; -static const char *const white = "\033[0;37m"; -static const char *const normal = "\033[0m"; - void tst_MediaObject::stateChanged(Phonon::State newstate, Phonon::State oldstate) { - if (newstate == Phonon::ErrorState) { - QWARN(QByteArray(QByteArray(red) + ".......................................................... ") + QByteArray(QTest::toString(oldstate)) + " to " + QByteArray(QTest::toString(newstate)) + normal); - } else { - //qDebug() << ".........................................................." << cyan << QTest::toString(oldstate) << "to" << QTest::toString(newstate) << normal; - } + if (newstate == Phonon::ErrorState) + QWARN(QByteArray(QByteArray(QTest::toString(oldstate)) + " to " + QByteArray(QTest::toString(newstate)))); } void tst_MediaObject::testPlayFromResource() { #ifdef Q_OS_SYMBIAN QSKIP("Not implemented yet.", SkipAll); - return; -#endif - +#else QFile file(MEDIA_FILEPATH); MediaObject media; media.setCurrentSource(&file); @@ -229,6 +215,7 @@ void tst_MediaObject::testPlayFromResource() if (media.state() != Phonon::PlayingState) QTest::waitForSignal(&media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), 10000); QCOMPARE(media.state(), Phonon::PlayingState); +#endif } void tst_MediaObject::testPlayIllegalFile() @@ -264,6 +251,13 @@ void tst_MediaObject::init() } m_stateChangedSignalSpy->clear(); } + + // Ensure that m_media is in StoppedState + if (m_media->state() != Phonon::StoppedState) { + m_media->stop(); + QTest::waitForSignal(m_media, SIGNAL(stateChanged(Phonon::State, Phonon::State))); + QCOMPARE(m_media->state(), Phonon::StoppedState); + } } void tst_MediaObject::cleanup() @@ -579,13 +573,18 @@ void tst_MediaObject::playSDP() if (m_media->state() != Phonon::StoppedState) QTest::waitForSignal(m_media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), 10000); - // At this point we're in error state due to absent media, but it has now loaded the SDP: - QCOMPARE(m_media->errorString(), QString::fromLatin1("Buffering clip failed: Unknown error (-39)")); + // MediaObject should have loaded the SDP, but be in error state due to absent media + const bool stateMatch = (m_media->state() == Phonon::ErrorState); + const bool errorStringMatch = (m_media->errorString() == QString::fromLatin1("Loading clip failed: Unknown error (-39)")); - // We cannot play the SDP, we can neither attempt to play it, because we - // won't get a state change from ErrorState to ErrorState, and hence block - // on a never occuring signal. + // Ensure that m_media is back in ground state prior to starting next test step m_media->setCurrentSource(oldSource); + if (m_media->state() != Phonon::StoppedState) + QTest::waitForSignal(m_media, SIGNAL(stateChanged(Phonon::State, Phonon::State))); + QCOMPARE(m_media->state(), Phonon::StoppedState); + + QVERIFY(stateMatch); + QVERIFY(errorStringMatch); #else QSKIP("Unsupported on this platform.", SkipAll); diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index e46709b..d5f63d3 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -43,6 +43,7 @@ #include <QtTest/QtTest> #include <QtGui> #include "../../shared/util.h" +#include <private/qgraphicsproxywidget_p.h> #include <private/qlayoutengine_p.h> // qSmartMin functions... #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) #include <QMacStyle> @@ -2582,33 +2583,68 @@ void tst_QGraphicsProxyWidget::changingCursor_basic() void tst_QGraphicsProxyWidget::tooltip_basic() { - // Confirm that mouse events are working properly by checking that - // when moving the mouse over a label with a tooptip the tooltip appears - QGraphicsScene scene; - QGraphicsView view(&scene); - view.show(); + QString toolTip = "Qt rocks!"; + QString toolTip2 = "Qt rocks even more!"; + + QPushButton *button = new QPushButton("button"); + QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget; + QGraphicsProxyWidgetPrivate *proxyd = static_cast<QGraphicsProxyWidgetPrivate *>(QGraphicsItemPrivate::get(proxy)); + proxy->setWidget(button); + proxyd->lastWidgetUnderMouse = button; // force widget under mouse + + QVERIFY(button->toolTip().isEmpty()); + QVERIFY(proxy->toolTip().isEmpty()); + // Check that setting the tooltip on the proxy also set it on the widget + proxy->setToolTip(toolTip); + QCOMPARE(proxy->toolTip(), toolTip); + QCOMPARE(button->toolTip(), toolTip); + // Check that setting the tooltip on the widget also set it on the proxy + button->setToolTip(toolTip2); + QCOMPARE(proxy->toolTip(), toolTip2); + QCOMPARE(button->toolTip(), toolTip2); - QSKIP("Tooltips don't work yet", SkipAll); - - SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget; - QLabel *widget = new QLabel; - widget->setText("If it ain't tested it's broken"); - widget->setToolTip("When in doubt, test"); - proxy->setWidget(widget); - widget->show(); + QGraphicsScene scene; scene.addItem(proxy); - QTest::qWait(125); - // in - QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()))); + QGraphicsView view(&scene); + view.setFixedSize(200, 200); + view.show(); + QTest::qWaitForWindowShown(&view); + { + QHelpEvent helpEvent(QEvent::ToolTip, view.viewport()->rect().topLeft(), + view.viewport()->mapToGlobal(view.viewport()->rect().topLeft())); + QApplication::sendEvent(view.viewport(), &helpEvent); + QTest::qWait(350); + + bool foundView = false; + bool foundTipLabel = false; + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (widget == &view) + foundView = true; + if (widget->inherits("QTipLabel")) + foundTipLabel = true; + } + QVERIFY(foundView); + QVERIFY(!foundTipLabel); + } - QTRY_COMPARE(proxy->childItems().count(), 1); - QGraphicsProxyWidget *child = (QGraphicsProxyWidget*)(proxy->childItems())[0]; - QVERIFY(child->isWidget()); - QVERIFY(child->widget()); - QCOMPARE(child->widget()->parent(), static_cast<QObject*>(widget)); - QCOMPARE(child->widget()->x(), widget->x()); // ### ??? - QCOMPARE(child->widget()->y(), widget->y() + widget->height()); // ### ??? + { + QHelpEvent helpEvent(QEvent::ToolTip, view.mapFromScene(proxy->boundingRect().center()), + view.viewport()->mapToGlobal(view.mapFromScene(proxy->boundingRect().center()))); + QApplication::sendEvent(view.viewport(), &helpEvent); + QTest::qWait(350); + + bool foundView = false; + bool foundTipLabel = false; + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (widget == &view) + foundView = true; + if (widget->inherits("QTipLabel")) + foundTipLabel = true; + } + QVERIFY(foundView); + QVERIFY(foundTipLabel); + } } void tst_QGraphicsProxyWidget::childPos_data() diff --git a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp index 35ebbd9..0b55390 100644 --- a/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp +++ b/tests/auto/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp @@ -801,7 +801,7 @@ void tst_QHttpNetworkConnection::getMultiple_data() QTest::newRow("6 connections, no pipelining, 100 requests") << quint16(6) << false << 100; QTest::newRow("1 connection, no pipelining, 100 requests") << quint16(1) << false << 100; - QTest::newRow("6 connections, pipelining allowed, 100 requests") << quint16(2) << true << 100; + QTest::newRow("6 connections, pipelining allowed, 100 requests") << quint16(6) << true << 100; QTest::newRow("1 connection, pipelining allowed, 100 requests") << quint16(1) << true << 100; } diff --git a/tests/auto/qscriptengine/translatable.js b/tests/auto/qscriptengine/translatable.js index 0c948e7..30e139a 100644 --- a/tests/auto/qscriptengine/translatable.js +++ b/tests/auto/qscriptengine/translatable.js @@ -5,3 +5,5 @@ var greeting_strings = [ QT_TR_NOOP("Hello"), QT_TRANSLATE_NOOP("FooContext", "Goodbye") ]; + +qsTr("One", "not the same one"); diff --git a/tests/auto/qscriptengine/translatable2.js b/tests/auto/qscriptengine/translatable2.js new file mode 100644 index 0000000..eee66f1 --- /dev/null +++ b/tests/auto/qscriptengine/translatable2.js @@ -0,0 +1,9 @@ +qsTr("Three"); +qsTranslate("BarContext", "Four"); + +var celebration_strings = [ + QT_TR_NOOP("Happy birthday!"), + QT_TRANSLATE_NOOP("BarContext", "Congratulations!") +]; + +qsTr("Three", "not the same three"); diff --git a/tests/auto/qscriptengine/translations/translatable_la.qm b/tests/auto/qscriptengine/translations/translatable_la.qm Binary files differindex 03fcc52..703d0f1 100644 --- a/tests/auto/qscriptengine/translations/translatable_la.qm +++ b/tests/auto/qscriptengine/translations/translatable_la.qm diff --git a/tests/auto/qscriptengine/translations/translatable_la.ts b/tests/auto/qscriptengine/translations/translatable_la.ts index 3f631de..1598f39 100644 --- a/tests/auto/qscriptengine/translations/translatable_la.ts +++ b/tests/auto/qscriptengine/translations/translatable_la.ts @@ -2,6 +2,19 @@ <!DOCTYPE TS> <TS version="2.0" language="nb_NO"> <context> + <name>BarContext</name> + <message> + <location filename="translatable2.js" line="2"/> + <source>Four</source> + <translation>Fire</translation> + </message> + <message> + <location filename="translatable2.js" line="6"/> + <source>Congratulations!</source> + <translation>Gratulerer!</translation> + </message> +</context> +<context> <name>FooContext</name> <message> <location filename="translatable.js" line="2"/> @@ -27,8 +40,33 @@ <translation>Hallo</translation> </message> <message> + <location filename="translatable.js" line="9"/> + <source>One</source> + <comment>not the same one</comment> + <translation>Enda en</translation> + </message> + <message> <source>Goodbye</source> <translation type="obsolete">Farvel</translation> </message> </context> +<context> + <name>translatable2</name> + <message> + <location filename="translatable2.js" line="1"/> + <source>Three</source> + <translation>Tre</translation> + </message> + <message> + <location filename="translatable2.js" line="5"/> + <source>Happy birthday!</source> + <translation>Gratulerer med dagen!</translation> + </message> + <message> + <location filename="translatable2.js" line="9"/> + <source>Three</source> + <comment>not the same three</comment> + <translation>Tre andre</translation> + </message> +</context> </TS> diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index 96043f9..89ea1db 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -156,6 +156,8 @@ private slots: void installTranslatorFunctions_data(); void installTranslatorFunctions(); void translateScript(); + void translateWithInvalidArgs_data(); + void translateWithInvalidArgs(); void functionScopes(); void nativeFunctionScopes(); void evaluateProgram(); @@ -4336,6 +4338,11 @@ void tst_QScriptEngine::installTranslatorFunctions() } } +static QScriptValue callQsTr(QScriptContext *ctx, QScriptEngine *eng) +{ + return eng->globalObject().property("qsTr").call(ctx->thisObject(), ctx->argumentsObject()); +} + void tst_QScriptEngine::translateScript() { QScriptEngine engine; @@ -4362,6 +4369,17 @@ void tst_QScriptEngine::translateScript() QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Two\\')')", fileName).toString(), QString::fromLatin1("To")); QCOMPARE(engine.evaluate("eval('qsTranslate(\\'FooContext\\', \\'Goodbye\\')')", fileName).toString(), QString::fromLatin1("Farvel")); + QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Goodbye', '', 'UnicodeUTF8')", fileName).toString(), QString::fromLatin1("Farvel")); + + QCOMPARE(engine.evaluate("qsTr('One', 'not the same one')", fileName).toString(), QString::fromLatin1("Enda en")); + + QVERIFY(engine.evaluate("QT_TR_NOOP()").isUndefined()); + QCOMPARE(engine.evaluate("QT_TR_NOOP('One')").toString(), QString::fromLatin1("One")); + + QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP()").isUndefined()); + QVERIFY(engine.evaluate("QT_TRANSLATE_NOOP('FooContext')").isUndefined()); + QCOMPARE(engine.evaluate("QT_TRANSLATE_NOOP('FooContext', 'Two')").toString(), QString::fromLatin1("Two")); + // Don't exist in translation QCOMPARE(engine.evaluate("qsTr('Three')", fileName).toString(), QString::fromLatin1("Three")); QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'So long')", fileName).toString(), QString::fromLatin1("So long")); @@ -4372,9 +4390,75 @@ void tst_QScriptEngine::translateScript() QCOMPARE(engine.globalObject().property("qsTr").call( QScriptValue(), QScriptValueList() << "One").toString(), QString::fromLatin1("One")); + // Translate strings from the second script (translatable2.js) + + QString fileName2 = QString::fromLatin1("translatable2.js"); + + QCOMPARE(engine.evaluate("qsTr('Three')", fileName2).toString(), QString::fromLatin1("Tre")); + QCOMPARE(engine.evaluate("qsTr('Happy birthday!')", fileName2).toString(), QString::fromLatin1("Gratulerer med dagen!")); + + // Not translated because translation is only in translatable.js + QCOMPARE(engine.evaluate("qsTr('One')", fileName2).toString(), QString::fromLatin1("One")); + QCOMPARE(engine.evaluate("(function() { return qsTr('One'); })()", fileName2).toString(), QString::fromLatin1("One")); + + // For qsTranslate() the filename shouldn't matter + QCOMPARE(engine.evaluate("qsTranslate('FooContext', 'Two')", fileName2).toString(), QString::fromLatin1("To")); + QCOMPARE(engine.evaluate("qsTranslate('BarContext', 'Congratulations!')", fileName).toString(), QString::fromLatin1("Gratulerer!")); + + // qsTr() should use the innermost filename as context + engine.evaluate("function foo(s) { return bar(s); }", fileName); + engine.evaluate("function bar(s) { return qsTr(s); }", fileName2); + QCOMPARE(engine.evaluate("bar('Three')", fileName2).toString(), QString::fromLatin1("Tre")); + QCOMPARE(engine.evaluate("bar('Three')", fileName).toString(), QString::fromLatin1("Tre")); + QCOMPARE(engine.evaluate("bar('One')", fileName2).toString(), QString::fromLatin1("One")); + + engine.evaluate("function foo(s) { return bar(s); }", fileName2); + engine.evaluate("function bar(s) { return qsTr(s); }", fileName); + QCOMPARE(engine.evaluate("bar('Three')", fileName2).toString(), QString::fromLatin1("Three")); + QCOMPARE(engine.evaluate("bar('One')", fileName).toString(), QString::fromLatin1("En")); + QCOMPARE(engine.evaluate("bar('One')", fileName2).toString(), QString::fromLatin1("En")); + + // Calling qsTr() from a native function + engine.globalObject().setProperty("qsTrProxy", engine.newFunction(callQsTr)); + QCOMPARE(engine.evaluate("qsTrProxy('One')", fileName).toString(), QString::fromLatin1("En")); + QCOMPARE(engine.evaluate("qsTrProxy('One')", fileName2).toString(), QString::fromLatin1("One")); + QCOMPARE(engine.evaluate("qsTrProxy('Three')", fileName).toString(), QString::fromLatin1("Three")); + QCOMPARE(engine.evaluate("qsTrProxy('Three')", fileName2).toString(), QString::fromLatin1("Tre")); + QCoreApplication::instance()->removeTranslator(&translator); } +void tst_QScriptEngine::translateWithInvalidArgs_data() +{ + QTest::addColumn<QString>("expression"); + QTest::addColumn<QString>("expectedError"); + + QTest::newRow("qsTr()") << "qsTr()" << "Error: qsTr() requires at least one argument"; + QTest::newRow("qsTr(123)") << "qsTr(123)" << "Error: qsTr(): first argument (text) must be a string"; + QTest::newRow("qsTr('foo', 123)") << "qsTr('foo', 123)" << "Error: qsTr(): second argument (comment) must be a string"; + QTest::newRow("qsTr('foo', 'bar', 'baz')") << "qsTr('foo', 'bar', 'baz')" << "Error: qsTr(): third argument (n) must be a number"; + QTest::newRow("qsTr('foo', 'bar', true)") << "qsTr('foo', 'bar', true)" << "Error: qsTr(): third argument (n) must be a number"; + + QTest::newRow("qsTranslate()") << "qsTranslate()" << "Error: qsTranslate() requires at least two arguments"; + QTest::newRow("qsTranslate('foo')") << "qsTranslate('foo')" << "Error: qsTranslate() requires at least two arguments"; + QTest::newRow("qsTranslate('foo', 123)") << "qsTranslate('foo', 123)" << "Error: qsTranslate(): second argument (text) must be a string"; + QTest::newRow("qsTranslate('foo', 'bar', 123)") << "qsTranslate('foo', 'bar', 123)" << "Error: qsTranslate(): third argument (comment) must be a string"; + QTest::newRow("qsTranslate('foo', 'bar', 'baz', 123)") << "qsTranslate('foo', 'bar', 'baz', 123)" << "Error: qsTranslate(): fourth argument (encoding) must be a string"; + QTest::newRow("qsTranslate('foo', 'bar', 'baz', 'zab', 'rab')") << "qsTranslate('foo', 'bar', 'baz', 'zab', 'rab')" << "Error: qsTranslate(): fifth argument (n) must be a number"; + QTest::newRow("qsTranslate('foo', 'bar', 'baz', 'zab', 123)") << "qsTranslate('foo', 'bar', 'baz', 'zab', 123)" << "Error: qsTranslate(): invalid encoding 'zab'"; +} + +void tst_QScriptEngine::translateWithInvalidArgs() +{ + QFETCH(QString, expression); + QFETCH(QString, expectedError); + QScriptEngine engine; + engine.installTranslatorFunctions(); + QScriptValue result = engine.evaluate(expression); + QVERIFY(result.isError()); + QCOMPARE(result.toString(), expectedError); +} + void tst_QScriptEngine::functionScopes() { QScriptEngine eng; diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp index c1496f7..09070e6 100644 --- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp +++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp @@ -534,6 +534,7 @@ private slots: void connectToDestroyedSignal(); void emitAfterReceiverDeleted(); void inheritedSlots(); + void enumerateMetaObject(); private: QScriptEngine *m_engine; @@ -3130,5 +3131,38 @@ void tst_QScriptExtQObject::inheritedSlots() QCOMPARE(prototypeButtonClickedSpy.count(), 0); } +void tst_QScriptExtQObject::enumerateMetaObject() +{ + QScriptValue myClass = m_engine->newQMetaObject(m_myObject->metaObject(), m_engine->undefinedValue()); + + QStringList expectedNames; + expectedNames << "FooPolicy" << "BarPolicy" << "BazPolicy" + << "FooStrategy" << "BarStrategy" << "BazStrategy" + << "NoAbility" << "FooAbility" << "BarAbility" << "BazAbility" << "AllAbility"; + + for (int x = 0; x < 2; ++x) { + QSet<QString> actualNames; + if (x == 0) { + // From C++ + QScriptValueIterator it(myClass); + while (it.hasNext()) { + it.next(); + actualNames.insert(it.name()); + } + } else { + // From JS + m_engine->globalObject().setProperty("MyClass", myClass); + QScriptValue ret = m_engine->evaluate("a=[]; for (var p in MyClass) if (MyClass.hasOwnProperty(p)) a.push(p); a"); + QVERIFY(ret.isArray()); + QStringList strings = qscriptvalue_cast<QStringList>(ret); + for (int i = 0; i < strings.size(); ++i) + actualNames.insert(strings.at(i)); + } + QCOMPARE(actualNames.size(), expectedNames.size()); + for (int i = 0; i < expectedNames.size(); ++i) + QVERIFY(actualNames.contains(expectedNames.at(i))); + } +} + QTEST_MAIN(tst_QScriptExtQObject) #include "tst_qscriptextqobject.moc" diff --git a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp index 018c036..0a7458f 100644 --- a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp @@ -871,6 +871,8 @@ void tst_QTextScriptEngine::malayalam() { 0x3f8, 0x0 } }, { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 }, { 0x2ff, 0x0 } }, + { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 }, + { 0xf3, 0x350, 0x0 } }, { {0}, {0} } }; diff --git a/tests/auto/uiloader/baseline/css_scroll.ui b/tests/auto/uiloader/baseline/css_scroll.ui index 0537ab0..6ac6886 100644 --- a/tests/auto/uiloader/baseline/css_scroll.ui +++ b/tests/auto/uiloader/baseline/css_scroll.ui @@ -14,8 +14,10 @@ <string>Form</string> </property> <property name="styleSheet"> - <string notr="true">QScrollArea { background:red; } -QScrollArea .QWidget { background:transparent; } + <string notr="true">QScrollArea { background:red; + border: 5px dashed blue; } +QScrollArea .QWidget { background:transparent; + border: 5px dotted green;} QScrollArea::corner { background:yellow; } @@ -111,10 +113,10 @@ QScrollArea::corner { background:yellow; } <widget class="QWidget" name="scrollAreaWidgetContents"> <property name="geometry"> <rect> - <x>-60</x> - <y>-145</y> - <width>554</width> - <height>575</height> + <x>0</x> + <y>0</y> + <width>520</width> + <height>532</height> </rect> </property> <layout class="QGridLayout" name="gridLayout_3"> diff --git a/tests/benchmarks/script/qscriptengine/tst_qscriptengine.cpp b/tests/benchmarks/script/qscriptengine/tst_qscriptengine.cpp index 6c6f0b1..35e2f28 100644 --- a/tests/benchmarks/script/qscriptengine/tst_qscriptengine.cpp +++ b/tests/benchmarks/script/qscriptengine/tst_qscriptengine.cpp @@ -269,19 +269,22 @@ void tst_QScriptEngine::nativeCall() void tst_QScriptEngine::translation_data() { QTest::addColumn<QString>("text"); - QTest::newRow("no translation") << "\"hello world\""; - QTest::newRow("qsTr") << "qsTr(\"hello world\")"; - QTest::newRow("qsTranslate") << "qsTranslate(\"\", \"hello world\")"; + QTest::addColumn<QString>("fileName"); + QTest::newRow("no translation") << "\"hello world\"" << ""; + QTest::newRow("qsTr") << "qsTr(\"hello world\")" << ""; + QTest::newRow("qsTranslate") << "qsTranslate(\"\", \"hello world\")" << ""; + QTest::newRow("qsTr:script.js") << "qsTr(\"hello world\")" << "script.js"; } void tst_QScriptEngine::translation() { QFETCH(QString, text); + QFETCH(QString, fileName); QScriptEngine engine; engine.installTranslatorFunctions(); QBENCHMARK { - (void)engine.evaluate(text); + (void)engine.evaluate(text, fileName); } } diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 2d5620e..db4bbca 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -65,47 +65,44 @@ static QString MagicComment(QLatin1String("TRANSLATOR")); class HashString { public: - HashString() : m_hashed(false) {} - explicit HashString(const QString &str) : m_str(str), m_hashed(false) {} - void setValue(const QString &str) { m_str = str; m_hashed = false; } + HashString() : m_hash(0x80000000) {} + explicit HashString(const QString &str) : m_str(str), m_hash(0x80000000) {} + void setValue(const QString &str) { m_str = str; m_hash = 0x80000000; } const QString &value() const { return m_str; } bool operator==(const HashString &other) const { return m_str == other.m_str; } private: QString m_str; + // qHash() of a QString is only 28 bits wide, so we can use + // the highest bit(s) as the "hash valid" flag. mutable uint m_hash; - mutable bool m_hashed; friend uint qHash(const HashString &str); }; uint qHash(const HashString &str) { - if (!str.m_hashed) { - str.m_hashed = true; + if (str.m_hash & 0x80000000) str.m_hash = qHash(str.m_str); - } return str.m_hash; } class HashStringList { public: - explicit HashStringList(const QList<HashString> &list) : m_list(list), m_hashed(false) {} + explicit HashStringList(const QList<HashString> &list) : m_list(list), m_hash(0x80000000) {} const QList<HashString> &value() const { return m_list; } bool operator==(const HashStringList &other) const { return m_list == other.m_list; } private: QList<HashString> m_list; mutable uint m_hash; - mutable bool m_hashed; friend uint qHash(const HashStringList &list); }; uint qHash(const HashStringList &list) { - if (!list.m_hashed) { - list.m_hashed = true; + if (list.m_hash & 0x80000000) { uint hash = 0; foreach (const HashString &qs, list.m_list) { - hash ^= qHash(qs) ^ 0xa09df22f; - hash = (hash << 13) | (hash >> 19); + hash ^= qHash(qs) ^ 0x0ad9f526; + hash = ((hash << 13) & 0x0fffffff) | (hash >> 15); } list.m_hash = hash; } @@ -215,13 +212,15 @@ public: private: struct IfdefState { IfdefState() {} - IfdefState(int _braceDepth, int _parenDepth) : + IfdefState(int _bracketDepth, int _braceDepth, int _parenDepth) : + bracketDepth(_bracketDepth), braceDepth(_braceDepth), parenDepth(_parenDepth), elseLine(-1) {} SavedState state; + int bracketDepth, bracketDepth1st; int braceDepth, braceDepth1st; int parenDepth, parenDepth1st; int elseLine; @@ -280,14 +279,14 @@ private: enum { Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return, - Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid, - Tok_Q_OBJECT = 20, Tok_Q_DECLARE_TR_FUNCTIONS, + Tok_tr, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid, + Tok_Q_OBJECT, Tok_Q_DECLARE_TR_FUNCTIONS, Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon, - Tok_Equals, - Tok_LeftBrace = 30, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon, - Tok_Null = 40, Tok_Integer, - Tok_QuotedInclude = 50, Tok_AngledInclude, - Tok_Other = 99 + Tok_Equals, Tok_LeftBracket, Tok_RightBracket, + Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon, + Tok_Null, Tok_Integer, + Tok_QuotedInclude, Tok_AngledInclude, + Tok_Other }; // Tokenizer state @@ -299,10 +298,12 @@ private: QString yyWord; qlonglong yyInteger; QStack<IfdefState> yyIfdefStack; + int yyBracketDepth; int yyBraceDepth; int yyParenDepth; int yyLineNo; int yyCurLineNo; + int yyBracketLineNo; int yyBraceLineNo; int yyParenLineNo; @@ -339,9 +340,11 @@ CppParser::CppParser(ParseResults *_results) results = new ParseResults; directInclude = false; } + yyBracketDepth = 0; yyBraceDepth = 0; yyParenDepth = 0; yyCurLineNo = 1; + yyBracketLineNo = 1; yyBraceLineNo = 1; yyParenLineNo = 1; yyAtNewline = true; @@ -568,7 +571,7 @@ uint CppParser::getToken() yyCh = getChar(); if (yyCh == 'f') { // if, ifdef, ifndef - yyIfdefStack.push(IfdefState(yyBraceDepth, yyParenDepth)); + yyIfdefStack.push(IfdefState(yyBracketDepth, yyBraceDepth, yyParenDepth)); yyCh = getChar(); } else if (yyCh == 'n') { // include @@ -607,16 +610,20 @@ uint CppParser::getToken() if (!yyIfdefStack.isEmpty()) { IfdefState &is = yyIfdefStack.top(); if (is.elseLine != -1) { - if (yyBraceDepth != is.braceDepth1st || yyParenDepth != is.parenDepth1st) - qWarning("%s:%d: Parenthesis/brace mismatch between " + if (yyBracketDepth != is.bracketDepth1st + || yyBraceDepth != is.braceDepth1st + || yyParenDepth != is.parenDepth1st) + qWarning("%s:%d: Parenthesis/bracket/brace mismatch between " "#if and #else branches; using #if branch\n", qPrintable(yyFileName), is.elseLine); } else { + is.bracketDepth1st = yyBracketDepth; is.braceDepth1st = yyBraceDepth; is.parenDepth1st = yyParenDepth; saveState(&is.state); } is.elseLine = yyLineNo; + yyBracketDepth = is.bracketDepth; yyBraceDepth = is.braceDepth; yyParenDepth = is.parenDepth; } @@ -626,10 +633,13 @@ uint CppParser::getToken() if (!yyIfdefStack.isEmpty()) { IfdefState is = yyIfdefStack.pop(); if (is.elseLine != -1) { - if (yyBraceDepth != is.braceDepth1st || yyParenDepth != is.parenDepth1st) + if (yyBracketDepth != is.bracketDepth1st + || yyBraceDepth != is.braceDepth1st + || yyParenDepth != is.parenDepth1st) qWarning("%s:%d: Parenthesis/brace mismatch between " "#if and #else branches; using #if branch\n", qPrintable(yyFileName), is.elseLine); + yyBracketDepth = is.bracketDepth1st; yyBraceDepth = is.braceDepth1st; yyParenDepth = is.parenDepth1st; loadState(&is.state); @@ -902,6 +912,21 @@ uint CppParser::getToken() yyParenDepth--; yyCh = getChar(); return Tok_RightParen; + case '[': + if (yyBracketDepth == 0) + yyBracketLineNo = yyCurLineNo; + yyBracketDepth++; + yyCh = getChar(); + return Tok_LeftBracket; + case ']': + if (yyBracketDepth == 0) + qWarning("%s:%d: Excess closing bracket in C++ code" + " (or abuse of the C++ preprocessor)\n", + qPrintable(yyFileName), yyCurLineNo); + else + yyBracketDepth--; + yyCh = getChar(); + return Tok_RightBracket; case ',': yyCh = getChar(); return Tok_Comma; @@ -1537,6 +1562,12 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) yyCh = getChar(); yyTok = getToken(); while (yyTok != Tok_Eof) { + // these are array indexing operations. we ignore them entirely + // so they don't confuse our scoping of static initializers. + // we enter the loop by either reading a left bracket or by an + // #else popping the state. + while (yyBracketDepth) + yyTok = getToken(); //qDebug() << "TOKEN: " << yyTok; switch (yyTok) { case Tok_QuotedInclude: { @@ -2004,9 +2035,14 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) } else { context = comment.left(k); comment.remove(0, k + 1); - recordMessage(yyLineNo, context, QString(), comment, extracomment, - QString(), TranslatorMessage::ExtraData(), false, false); + TranslatorMessage msg( + transcode(context, false), QString(), + transcode(comment, false), QString(), + yyFileName, yyLineNo, QStringList(), + TranslatorMessage::Finished, false); + msg.setExtraComment(transcode(extracomment.simplified(), false)); extracomment.clear(); + tor->append(msg); tor->setExtras(extra); extra.clear(); } @@ -2077,6 +2113,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) default: if (!yyParenDepth) prospectiveContext.clear(); + // fallthrough + case Tok_Equals: // for static initializers; other cases make no difference + case Tok_RightBracket: // ignoring indexing; same reason case_default: yyTok = getToken(); break; @@ -2091,6 +2130,10 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) qWarning("%s:%d: Unbalanced opening parenthesis in C++ code" " (or abuse of the C++ preprocessor)\n", qPrintable(yyFileName), yyParenLineNo); + else if (yyBracketDepth != 0) + qWarning("%s:%d: Unbalanced opening bracket in C++ code" + " (or abuse of the C++ preprocessor)\n", + qPrintable(yyFileName), yyBracketLineNo); } const ParseResults *CppParser::recordResults(bool isHeader) |