diff options
author | David Boddie <dboddie@trolltech.com> | 2010-01-11 13:27:51 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2010-01-11 13:27:51 (GMT) |
commit | 7f83a227ddfb22a373065c68e903b49ca590cef6 (patch) | |
tree | 7063a643d519d91c5e52d4adfa43579e787c3ca5 | |
parent | bbac0f08d65b54eccadae7629a5eef10da3b3370 (diff) | |
parent | 22d30bd6c1e8355cb4520885b0d0fef3526cc4e9 (diff) | |
download | Qt-7f83a227ddfb22a373065c68e903b49ca590cef6.zip Qt-7f83a227ddfb22a373065c68e903b49ca590cef6.tar.gz Qt-7f83a227ddfb22a373065c68e903b49ca590cef6.tar.bz2 |
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.6
131 files changed, 2201 insertions, 959 deletions
@@ -15,6 +15,13 @@ use Cwd; use Config; use strict; +for (my $i = 0; $i < $#ARGV; $i++) { + if ($ARGV[$i] eq "-base-dir" && $i < $#ARGV - 1) { + $ENV{"QTDIR"} = $ARGV[$i + 1]; + last; + } +} + die "syncqt: QTDIR not defined" if ! $ENV{"QTDIR"}; # sanity check # global variables @@ -61,6 +68,8 @@ my $force_win = 0; my $force_relative = 0; my $check_includes = 0; my $copy_headers = 0; +my $create_uic_class_map = 1; +my $create_private_headers = 1; my @modules_to_sync ; $force_relative = 1 if ( -d "/System/Library/Frameworks" ); my $out_basedir = $basedir; @@ -84,6 +93,7 @@ sub showUsage print " -windows Force platform to Windows (default: " . ($force_win ? "yes" : "no") . ")\n"; print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n"; print " -outdir <PATH> Specify output directory for sync (default: $out_basedir)\n"; + print " -separate-module <NAME>:<PROFILEDIR>:<HEADERDIR> Create headers for <NAME> with original headers in <HEADERDIR> relative to <PROFILEDIR> \n"; print " -help This help\n"; exit 0; } @@ -576,9 +586,16 @@ while ( @ARGV ) { } elsif("$arg" eq "-module") { $var = "module"; $val = shift @ARGV; + } elsif("$arg" eq "-separate-module") { + $var = "separate-module"; + $val = shift @ARGV; } elsif("$arg" eq "-show") { $var = "showonly"; $val = "yes"; + } elsif("$arg" eq "-base-dir") { + # skip, it's been dealt with at the top of the file + shift @ARGV; + next; } elsif("$arg" eq '*') { # workaround for windows 9x where "%*" expands to "*" $var = 1; @@ -628,6 +645,13 @@ while ( @ARGV ) { print "module :$val:\n"; die "No such module: $val" unless(defined $modules{$val}); push @modules_to_sync, $val; + } elsif ("$var" eq "separate-module") { + my ($module, $prodir, $headerdir) = split(/:/, $val); + $modules{$module} = $prodir; + push @modules_to_sync, $module; + $moduleheaders{$module} = $headerdir; + $create_uic_class_map = 0; + $create_private_headers = 0; } elsif ("$var" eq "output") { my $outdir = $val; if(checkRelative($outdir)) { @@ -813,7 +837,7 @@ foreach (@modules_to_sync) { $header_copies++ if (syncHeader("$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0)); } } - } else { + } elsif ($create_private_headers) { @headers = ( "$out_basedir/include/$lib/private/$header" ); push @headers, "$out_basedir/include/Qt/private/$header" if ("$lib" ne "phonon"); @@ -909,7 +933,7 @@ foreach (@modules_to_sync) { } } } -unless($showonly) { +unless($showonly || !$create_uic_class_map) { my $class_lib_map = "$out_basedir/src/tools/uic/qclass_lib_map.h"; if(-e "$class_lib_map") { open CLASS_LIB_MAP, "<$class_lib_map"; @@ -2257,7 +2257,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then mkdir -p "$outpath/bin" echo "#!/bin/sh" >"$outpath/bin/syncqt" echo "QTDIR=\"$relpath\"; export QTDIR" >>"$outpath/bin/syncqt" - echo "perl \"$relpath/bin/syncqt\" -outdir \"$outpath\" $*" >>"$outpath/bin/syncqt" + echo "perl \"$relpath/bin/syncqt\" -outdir \"$outpath\" \"\$@\"" >>"$outpath/bin/syncqt" chmod 755 "$outpath/bin/syncqt" fi diff --git a/demos/boxes/scene.cpp b/demos/boxes/scene.cpp index b6b4500..97953f2 100644 --- a/demos/boxes/scene.cpp +++ b/demos/boxes/scene.cpp @@ -653,7 +653,8 @@ void Scene::initGL() static void loadMatrix(const QMatrix4x4& m) { - GLfloat mat[16]; + // static to prevent glLoadMatrixf to fail on certain drivers + static GLfloat mat[16]; const qreal *data = m.constData(); for (int index = 0; index < 16; ++index) mat[index] = data[index]; @@ -662,7 +663,8 @@ static void loadMatrix(const QMatrix4x4& m) static void multMatrix(const QMatrix4x4& m) { - GLfloat mat[16]; + // static to prevent glMultMatrixf to fail on certain drivers + static GLfloat mat[16]; const qreal *data = m.constData(); for (int index = 0; index < 16; ++index) mat[index] = data[index]; diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index 82136a0..3cb0616 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -673,6 +673,13 @@ void MediaPlayer::setFile(const QString &fileName) m_MediaObject.play(); } +void MediaPlayer::setLocation(const QString& location) +{ + setWindowTitle(location.right(location.length() - location.lastIndexOf('/') - 1)); + m_MediaObject.setCurrentSource(Phonon::MediaSource(QUrl::fromEncoded(location.toUtf8()))); + m_MediaObject.play(); +} + bool MediaPlayer::playPauseForDialog() { // If we're running on a small screen, we want to pause the video when @@ -850,9 +857,7 @@ void MediaPlayer::openUrl() bool ok = false; sourceURL = QInputDialog::getText(this, tr("Open Location"), tr("Please enter a valid address here:"), QLineEdit::Normal, sourceURL, &ok); if (ok && !sourceURL.isEmpty()) { - setWindowTitle(sourceURL.right(sourceURL.length() - sourceURL.lastIndexOf('/') - 1)); - m_MediaObject.setCurrentSource(Phonon::MediaSource(QUrl::fromEncoded(sourceURL.toUtf8()))); - m_MediaObject.play(); + setLocation(sourceURL); settings.setValue("location", sourceURL); } } @@ -892,10 +897,11 @@ void MediaPlayer::openRamFile() } if (!list.isEmpty()) { - m_MediaObject.setCurrentSource(Phonon::MediaSource(list[0])); - m_MediaObject.play(); + m_MediaObject.clearQueue(); + setLocation(list[0].toString()); for (int i = 1; i < list.count(); i++) m_MediaObject.enqueue(Phonon::MediaSource(list[i])); + m_MediaObject.play(); } forwardButton->setEnabled(!m_MediaObject.queue().isEmpty()); diff --git a/demos/qmediaplayer/mediaplayer.h b/demos/qmediaplayer/mediaplayer.h index 890b597..d6ae58b 100644 --- a/demos/qmediaplayer/mediaplayer.h +++ b/demos/qmediaplayer/mediaplayer.h @@ -112,6 +112,7 @@ public: void dropEvent(QDropEvent *e); void handleDrop(QDropEvent *e); void setFile(const QString &text); + void setLocation(const QString &location); void initVideoWindow(); void initSettingsDialog(); diff --git a/dist/README b/dist/README index e7dfb19..73c8be1 100644 --- a/dist/README +++ b/dist/README @@ -26,6 +26,10 @@ For Mac OS X Cocoa, the binary package requires Mac OS X 10.5 (Leopard) or later and GCC 4.0.1 to develop applications. Its applications will run on Mac OS X 10.5 and above. +If you want to install the precompiled binary package for Symbian, +follow these instructions: +http://qt.nokia.com/doc/%SHORTVERSION%/install-symbian-installer.html + DEMOS AND EXAMPLES diff --git a/dist/changes-4.6.1 b/dist/changes-4.6.1 index 2397228..145e09e 100644 --- a/dist/changes-4.6.1 +++ b/dist/changes-4.6.1 @@ -51,6 +51,8 @@ QtGui in the DDS, ETC1, PVRTC2, and PVRTC4 formats if the OpenGL graphics system is active and the appropriate extensions are present in the GL implementation. + - QGraphicsObject + * 'id' property was removed. Use the 'objectName' property instead. QtDBus ------ diff --git a/doc/src/development/rcc.qdoc b/doc/src/development/rcc.qdoc index ff82674..1541e11 100644 --- a/doc/src/development/rcc.qdoc +++ b/doc/src/development/rcc.qdoc @@ -57,37 +57,40 @@ \table \header \o Option \o Argument \o Description - \row \o \c{-o} \o \o Writes output to file rather than - stdout. + \row \o \c{-o} \o \c{file} \o Write output to \c{file} rather than to stdout. - \row \o \c{-name} \o \c name \o Creates an external initialization - function with name. + \row \o \c{-name} \o \c{name} \o Create an external initialization + function with \c{name}. - \row \o \c{-threshold} \o \c level \o Specifies a threshold (in bytes) - to use when compressing files. If - the file is smaller than the - threshold, it will not be - compressed, independent of what - the compression level is. + \row \o \c{-threshold} \o \c{level} \o Specifies a threshold \c{level} (in + bytes) to use when deciding whether + to compress a file. If the file is + smaller than the threshold \c{level}, + it is not compressed. The default + threshold level is 70 bytes. - \row \o \c{-compress} \o \c level \o Compresses input files with the - given level. Level is an integer - from 1 to 9 - 1 being the fastest, - producing the least compression; - 9 being the slowest, producing - the most compression. + \row \o \c{-compress} \o \c{level} \o Compress input files to the given + compression \c{level}, which is an + integer in the range 1 to 9. Level 1 + does the least compression but is + fastest. Level 9 does the most + compression but is slowest. To turn + off compression, use \c{-no-compress}. + The default value for \c{level} is -1, + which means use zlib's default + compression level. - \row \o \c{-root} \o \c path \o Prefixes the resource access path - with root path. + \row \o \c{-root} \o \c{path} \o Prefix the resource access path with \c{path}. + The default is no prefix. - \row \o \c{-no-compress} \o \o Disables all compression. + \row \o \c{-no-compress} \o \o Disable compression. - \row \o \c{-binary} \o \o Outputs a binary file for use as - a dynamic resource. + \row \o \c{-binary} \o \o Output a binary file for use as a dynamic resource. - \row \o \c{-version} \o \o Displays version information. + \row \o \c{-version} \o \o Display version information. + + \row \o \c{-help} \o \o Display usage information. - \row \o \c{-help} \o \o Displays usage information. \endtable See also \l{The Qt Resource System} for more information about embedding diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc index 116f8df..427f45a 100644 --- a/doc/src/platforms/symbian-introduction.qdoc +++ b/doc/src/platforms/symbian-introduction.qdoc @@ -124,12 +124,8 @@ \row \o \c release-gcce \o Build release binaries for hardware using GCCE. \row \o \c debug-armv5 \o Build debug binaries for hardware using RVCT. \row \o \c release-armv5 \o Build release binaries for hardware using RVCT. - \row \o \c run \o Run the application. Environment variable - \c QT_SIS_TARGET (see below) can be used to specify which - build target is run. By default it is the last build target. - Note that running the application on real device - using this command requires \c TRK application to be running - on the device. + \row \o \c run \o Run the application on the emulator. + \row \o \c runonphone \o Run the application on a device. \row \o \c sis \o Create signed \c .sis file for project. \endtable @@ -199,4 +195,24 @@ with the \c QT_SIS_OPTIONS=-i, like this: \snippet doc/src/snippets/code/doc_src_symbian-introduction.qdoc 5 + + \section1 Running applications from command line + + The application can be launched on the emulator using \c{make run} command. + + The application can be launched on a device using \c{make runonphone} command. + When this command is invoked, a \c .sis file is first created as if \c{make sis} + command was invoked (see above for details). + \bold{Note:} Running the application on a device using this command requires + \c TRK application to be running on the device. + + Additional environment variables that can be utilized with these commands are: + \table + \row \o \c QT_RUN_OPTIONS \o Any command line parameters you wish to pass + to your application. + \row \o \c QT_RUN_ON_PHONE_OPTIONS \o Options for runonphone application. + Execute \c runonphone from command line for + more information about available options. + \c{make runonphone} only. + \endtable */ diff --git a/doc/src/snippets/audio/main.cpp b/doc/src/snippets/audio/main.cpp index 019f208..f000075 100644 --- a/doc/src/snippets/audio/main.cpp +++ b/doc/src/snippets/audio/main.cpp @@ -89,9 +89,9 @@ private: { //![1] QAudioFormat format; - format.setFrequency(44100); + format.setSampleRate(44100); //![1] - format.setChannels(2); + format.setChannelCount(2); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp b/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp index 99fd0cf..bcb61f7 100644 --- a/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp +++ b/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp @@ -62,6 +62,7 @@ while (new_data_available()) { QByteArray chunk = get_new_data(); string += decoder->toUnicode(chunk); } +delete decoder; //! [2] diff --git a/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp b/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp index 736394f..3cd3db8 100644 --- a/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp +++ b/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp @@ -401,5 +401,22 @@ QByteArray text = QByteArray::fromHex("517420697320677265617421"); text.data(); // returns "Qt is great!" //! [45] +//! [46] +QString tmp = "test"; +QByteArray text = tmp.toLocal8Bit(); +char *data = new char[text.size()] +strcpy(data, text.data()); +delete [] data; +//! [46] + +//! [47] +QString tmp = "test"; +QByteArray text = tmp.toLocal8Bit(); +char *data = new char[text.size() + 1] +strcpy(data, text.data()); +delete [] data; +//! [47] + } + diff --git a/examples/multimedia/audiodevices/audiodevices.cpp b/examples/multimedia/audiodevices/audiodevices.cpp index a193f3d..6373d57 100644 --- a/examples/multimedia/audiodevices/audiodevices.cpp +++ b/examples/multimedia/audiodevices/audiodevices.cpp @@ -96,8 +96,8 @@ void AudioTest::test() } else { QAudioFormat nearest = deviceInfo.nearestFormat(settings); logOutput->append(tr("Failed")); - nearestFreq->setText(QString("%1").arg(nearest.frequency())); - nearestChannel->setText(QString("%1").arg(nearest.channels())); + nearestFreq->setText(QString("%1").arg(nearest.sampleRate())); + nearestChannel->setText(QString("%1").arg(nearest.channelCount())); nearestCodec->setText(nearest.codec()); nearestSampleSize->setText(QString("%1").arg(nearest.sampleSize())); @@ -149,18 +149,18 @@ void AudioTest::deviceChanged(int idx) deviceInfo = deviceBox->itemData(idx).value<QAudioDeviceInfo>(); frequencyBox->clear(); - QList<int> freqz = deviceInfo.supportedFrequencies(); - for (int i = 0; i < freqz.size(); ++i) + QList<int> freqz = deviceInfo.supportedSampleRates(); + for(int i = 0; i < freqz.size(); ++i) frequencyBox->addItem(QString("%1").arg(freqz.at(i))); - if (freqz.size()) - settings.setFrequency(freqz.at(0)); + if(freqz.size()) + settings.setSampleRate(freqz.at(0)); channelsBox->clear(); - QList<int> chz = deviceInfo.supportedChannels(); - for (int i = 0; i < chz.size(); ++i) + QList<int> chz = deviceInfo.supportedChannelCounts(); + for(int i = 0; i < chz.size(); ++i) channelsBox->addItem(QString("%1").arg(chz.at(i))); - if (chz.size()) - settings.setChannels(chz.at(0)); + if(chz.size()) + settings.setChannelCount(chz.at(0)); codecsBox->clear(); QStringList codecz = deviceInfo.supportedCodecs(); @@ -217,12 +217,12 @@ void AudioTest::deviceChanged(int idx) void AudioTest::freqChanged(int idx) { // freq has changed - settings.setFrequency(frequencyBox->itemText(idx).toInt()); + settings.setSampleRate(frequencyBox->itemText(idx).toInt()); } void AudioTest::channelChanged(int idx) { - settings.setChannels(channelsBox->itemText(idx).toInt()); + settings.setChannelCount(channelsBox->itemText(idx).toInt()); } void AudioTest::codecChanged(int idx) diff --git a/examples/multimedia/audioinput/audioinput.cpp b/examples/multimedia/audioinput/audioinput.cpp index 8cc9948..86650da 100644 --- a/examples/multimedia/audioinput/audioinput.cpp +++ b/examples/multimedia/audioinput/audioinput.cpp @@ -198,8 +198,8 @@ InputTest::InputTest() pullMode = true; - format.setFrequency(8000); - format.setChannels(1); + format.setSampleRate(8000); + format.setChannelCount(1); format.setSampleSize(16); format.setSampleType(QAudioFormat::SignedInt); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/examples/multimedia/audiooutput/audiooutput.cpp b/examples/multimedia/audiooutput/audiooutput.cpp index 0c57f4d..58dbbaf 100644 --- a/examples/multimedia/audiooutput/audiooutput.cpp +++ b/examples/multimedia/audiooutput/audiooutput.cpp @@ -164,8 +164,8 @@ AudioTest::AudioTest() gen->start(); - settings.setFrequency(SYSTEM_FREQ); - settings.setChannels(1); + settings.setSampleRate(SYSTEM_FREQ); + settings.setChannelCount(1); settings.setSampleSize(16); settings.setCodec("audio/pcm"); settings.setByteOrder(QAudioFormat::LittleEndian); diff --git a/examples/webkit/domtraversal/domtraversal.pro b/examples/webkit/domtraversal/domtraversal.pro index 49400de..ba5f2d8 100644 --- a/examples/webkit/domtraversal/domtraversal.pro +++ b/examples/webkit/domtraversal/domtraversal.pro @@ -9,3 +9,8 @@ target.path = $$[QT_INSTALL_EXAMPLES]/webkit/domtraversal sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/domtraversal INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000D7CB + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/webkit/fancybrowser/fancybrowser.pro b/examples/webkit/fancybrowser/fancybrowser.pro index e496241..3786d9c 100644 --- a/examples/webkit/fancybrowser/fancybrowser.pro +++ b/examples/webkit/fancybrowser/fancybrowser.pro @@ -10,4 +10,7 @@ sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/fancybrowser INSTALLS += target sources -symbian:TARGET.UID3 = 0xA000CF6C +symbian { + TARGET.UID3 = 0xA000CF6C + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/webkit/googlechat/googlechat.pro b/examples/webkit/googlechat/googlechat.pro index 8e4f9a6..3d32c1b 100644 --- a/examples/webkit/googlechat/googlechat.pro +++ b/examples/webkit/googlechat/googlechat.pro @@ -10,4 +10,7 @@ sources.files = $$SOURCES $$HEADERS $$FORMS *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/googlechat INSTALLS += target sources -symbian:TARGET.UID3 = 0xA000CF6E +symbian { + TARGET.UID3 = 0xA000CF6E + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/examples/webkit/simpleselector/simpleselector.pro b/examples/webkit/simpleselector/simpleselector.pro index 3f3037f..acd0ae7 100644 --- a/examples/webkit/simpleselector/simpleselector.pro +++ b/examples/webkit/simpleselector/simpleselector.pro @@ -9,3 +9,8 @@ target.path = $$[QT_INSTALL_EXAMPLES]/webkit/simpleselector sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro sources.path = $$[QT_INSTALL_EXAMPLES]/webkit/simpleselector INSTALLS += target sources + +symbian { + TARGET.UID3 = 0xA000D7CC + include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) +} diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 6d1c1fd..6e76c9e 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -1857,16 +1857,11 @@ void SymbianMakefileGenerator::generateExecutionTargets(QTextStream& t, const QS // create execution targets if (targetType == TypeExe) { if (platforms.contains("winscw")) { - t << "ifeq (\"DEBUG-winscw\", \"$(QT_SIS_TARGET)\")" << endl; t << "run:" << endl; t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl; - t << "else" << endl; } - t << "run: sis" << endl; + t << "runonphone: sis" << endl; t << "\trunonphone $(QT_RUN_ON_PHONE_OPTIONS) --sis " << fixedTarget << "_$(QT_SIS_TARGET).sis " << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl; - if (platforms.contains("winscw")) { - t << "endif" << endl; - } t << endl; } } diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index a559249..e7ef9b2 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -19,6 +19,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "mediaobject.h" #include "abstractaudioeffect.h" +#include "audioplayer.h" +#include "mmf_videoplayer.h" QT_BEGIN_NAMESPACE @@ -34,18 +36,13 @@ using namespace Phonon::MMF; */ AbstractAudioEffect::AbstractAudioEffect(QObject *parent, - const QList<EffectParameter> ¶ms) : MediaNode::MediaNode(parent) - , m_params(params) + const QList<EffectParameter> ¶ms) + : MediaNode::MediaNode(parent) + , m_player(0) + , m_params(params) { } -bool AbstractAudioEffect::disconnectMediaNode(MediaNode *target) -{ - MediaNode::disconnectMediaNode(target); - m_effect.reset(); - return true; -} - QList<EffectParameter> AbstractAudioEffect::parameters() const { return m_params; @@ -61,21 +58,39 @@ QVariant AbstractAudioEffect::parameterValue(const EffectParameter &queriedParam return val; } -bool AbstractAudioEffect::activateOnMediaObject(MediaObject *mo) -{ - AudioPlayer *const ap = qobject_cast<AudioPlayer *>(mo->abstractPlayer()); - - if (ap) - return activateOn(ap->player()); - else - return true; -} - void AbstractAudioEffect::setParameterValue(const EffectParameter ¶m, const QVariant &newValue) { m_values.insert(param.id(), newValue); parameterChanged(param.id(), newValue); + // TODO: handle audio effect errors + TRAP_IGNORE(m_effect->ApplyL()); +} + +void AbstractAudioEffect::connectMediaObject(MediaObject *mediaObject) +{ + Q_ASSERT_X(!m_player, Q_FUNC_INFO, "Player already connected"); + Q_ASSERT_X(!m_effect.data(), Q_FUNC_INFO, "Effect already created"); + + AbstractMediaPlayer *const player = + qobject_cast<AbstractMediaPlayer *>(mediaObject->abstractPlayer()); + + if (player) { + m_player = player; + + if (AudioPlayer *audioPlayer = qobject_cast<AudioPlayer *>(player)) { + connectAudioPlayer(audioPlayer->nativePlayer()); + applyParameters(); + // TODO: handle audio effect errors + TRAP_IGNORE(m_effect->EnableL()); + } + } +} + +void AbstractAudioEffect::disconnectMediaObject(MediaObject * /*mediaObject*/) +{ + m_player = 0; + m_effect.reset(); } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 01542c9..6f74a73 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -19,15 +19,16 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_ABSTRACTEFFECT_H #define PHONON_MMF_ABSTRACTEFFECT_H -#include "mmf_medianode.h" - #include <QScopedPointer> #include <AudioEffectBase.h> #include <Phonon/EffectInterface> #include <Phonon/EffectParameter> + #include "audioplayer.h" +#include "mmf_medianode.h" +#include "mmf_videoplayer.h" QT_BEGIN_NAMESPACE @@ -35,6 +36,7 @@ namespace Phonon { namespace MMF { +class AbstractMediaPlayer; /** * @short Base class for all effects for MMF. @@ -66,8 +68,6 @@ public: virtual void setParameterValue(const EffectParameter &, const QVariant &newValue); - virtual bool disconnectMediaNode(MediaNode *target); - enum Type { EffectAudioEqualizer = 1, @@ -81,21 +81,25 @@ public: }; protected: - virtual bool activateOn(CPlayerType *player) = 0; + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); + + virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player) = 0; + virtual void applyParameters() = 0; + virtual void parameterChanged(const int id, const QVariant &value) = 0; - /** - * Part of the implementation of AbstractAudioEffect. Forwards the call to - * activateOn(), essentially. - */ - virtual bool activateOnMediaObject(MediaObject *mo); - +protected: QScopedPointer<CAudioEffect> m_effect; + private: + AbstractMediaPlayer * m_player; const QList<EffectParameter> m_params; QHash<int, QVariant> m_values; }; + } } diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 99e96cd..544762a 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -20,6 +20,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "abstractmediaplayer.h" #include "defs.h" +#include "mediaobject.h" #include "utils.h" QT_BEGIN_NAMESPACE @@ -36,27 +37,26 @@ using namespace Phonon::MMF; //----------------------------------------------------------------------------- const int NullMaxVolume = -1; +const int BufferStatusTimerInterval = 100; // ms //----------------------------------------------------------------------------- // Constructor / destructor //----------------------------------------------------------------------------- -MMF::AbstractMediaPlayer::AbstractMediaPlayer() : - m_playPending(false) - , m_tickTimer(new QTimer(this)) - , m_mmfMaxVolume(NullMaxVolume) -{ - connect(m_tickTimer.data(), SIGNAL(timeout()), this, SLOT(tick())); -} - -MMF::AbstractMediaPlayer::AbstractMediaPlayer(const AbstractPlayer& player) : - AbstractPlayer(player) +MMF::AbstractMediaPlayer::AbstractMediaPlayer + (MediaObject *parent, const AbstractPlayer *player) + : AbstractPlayer(player) + , m_parent(parent) , m_playPending(false) - , m_tickTimer(new QTimer(this)) + , m_positionTimer(new QTimer(this)) + , m_bufferStatusTimer(new QTimer(this)) , m_mmfMaxVolume(NullMaxVolume) + , m_prefinishMarkSent(false) + , m_aboutToFinishSent(false) { - connect(m_tickTimer.data(), SIGNAL(timeout()), this, SLOT(tick())); + connect(m_positionTimer.data(), SIGNAL(timeout()), this, SLOT(positionTick())); + connect(m_bufferStatusTimer.data(), SIGNAL(timeout()), this, SLOT(bufferStatusTick())); } //----------------------------------------------------------------------------- @@ -70,7 +70,7 @@ void MMF::AbstractMediaPlayer::play() switch (privateState()) { case GroundState: - setError(NormalError); + setError(tr("Not ready to play")); break; case LoadingState: @@ -80,7 +80,7 @@ void MMF::AbstractMediaPlayer::play() case StoppedState: case PausedState: doPlay(); - startTickTimer(); + startPositionTimer(); changeState(PlayingState); break; @@ -104,21 +104,22 @@ void MMF::AbstractMediaPlayer::pause() TRACE_ENTRY("state %d", privateState()); m_playPending = false; + stopTimers(); switch (privateState()) { case GroundState: case LoadingState: case PausedState: + case StoppedState: // Do nothing break; - case StoppedState: case PlayingState: - case ErrorState: case BufferingState: - doPause(); - stopTickTimer(); changeState(PausedState); + // Fall through + case ErrorState: + doPause(); break; // Protection against adding new states and forgetting to update this switch @@ -135,6 +136,7 @@ void MMF::AbstractMediaPlayer::stop() TRACE_ENTRY("state %d", privateState()); m_playPending = false; + stopTimers(); switch (privateState()) { case GroundState: @@ -148,7 +150,6 @@ void MMF::AbstractMediaPlayer::stop() case BufferingState: case PausedState: doStop(); - stopTickTimer(); changeState(StoppedState); break; @@ -173,14 +174,21 @@ void MMF::AbstractMediaPlayer::seek(qint64 ms) case PlayingState: case LoadingState: { - const bool tickTimerWasRunning = m_tickTimer->isActive(); - stopTickTimer(); + bool wasPlaying = false; + if (state() == PlayingState) { + stopPositionTimer(); + doPause(); + wasPlaying = true; + } doSeek(ms); + resetMarksIfRewound(); - if (tickTimerWasRunning) { - startTickTimer(); + if(wasPlaying && state() != ErrorState) { + doPlay(); + startPositionTimer(); } + break; } case BufferingState: @@ -203,17 +211,12 @@ void MMF::AbstractMediaPlayer::doSetTickInterval(qint32 interval) TRACE_CONTEXT(AbstractMediaPlayer::doSetTickInterval, EAudioApi); TRACE_ENTRY("state %d m_interval %d interval %d", privateState(), tickInterval(), interval); - m_tickTimer->setInterval(interval); + m_positionTimer->setInterval(interval); TRACE_EXIT_0(); } -MediaSource MMF::AbstractMediaPlayer::source() const -{ - return m_source; -} - -void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& file) +void MMF::AbstractMediaPlayer::open(const MediaSource &source, RFile& file) { TRACE_CONTEXT(AbstractMediaPlayer::setFileSource, EAudioApi); TRACE_ENTRY("state %d source.type %d", privateState(), source.type()); @@ -221,15 +224,14 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f close(); changeState(GroundState); - // TODO: is it correct to assign even if the media type is not supported in - // the switch statement below? - m_source = source; - TInt symbianErr = KErrNone; + QString errorMessage; - switch (m_source.type()) { + switch (source.type()) { case MediaSource::LocalFile: { symbianErr = openFile(file); + if (KErrNone != symbianErr) + errorMessage = tr("Error opening file"); break; } @@ -238,68 +240,76 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f if (url.scheme() == QLatin1String("file")) { symbianErr = openFile(file); - } - else { - TRACE_0("Source type not supported"); - // TODO: support network URLs - symbianErr = KErrNotSupported; + if (KErrNone != symbianErr) + errorMessage = tr("Error opening file"); + } else { + symbianErr = openUrl(url.toString()); + if (KErrNone != symbianErr) + errorMessage = tr("Error opening URL"); } break; } - case MediaSource::Invalid: - case MediaSource::Disc: - case MediaSource::Stream: - TRACE_0("Source type not supported"); - symbianErr = KErrNotSupported; - break; - - case MediaSource::Empty: - TRACE_0("Empty source - doing nothing"); - TRACE_EXIT_0(); - return; + // Other source types are handled in MediaObject::createPlayer - // Protection against adding new media types and forgetting to update this switch + // Protection against adding new media types and forgetting to update this switch default: TRACE_PANIC(InvalidMediaTypePanic); } - if (KErrNone == symbianErr) { + if (errorMessage.isEmpty()) { changeState(LoadingState); } else { - TRACE("error %d", symbianErr) - setError(NormalError); + if (symbianErr) + setError(errorMessage, symbianErr); + else + setError(errorMessage); } TRACE_EXIT_0(); } -void MMF::AbstractMediaPlayer::setNextSource(const MediaSource &source) +void MMF::AbstractMediaPlayer::volumeChanged(qreal volume) { - TRACE_CONTEXT(AbstractMediaPlayer::setNextSource, EAudioApi); + TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal); TRACE_ENTRY("state %d", privateState()); - // TODO: handle 'next source' - - m_nextSource = source; - Q_UNUSED(source); + AbstractPlayer::volumeChanged(volume); + doVolumeChanged(); TRACE_EXIT_0(); } +//----------------------------------------------------------------------------- +// Private functions +//----------------------------------------------------------------------------- -void MMF::AbstractMediaPlayer::volumeChanged(qreal volume) +void MMF::AbstractMediaPlayer::startPositionTimer() { - TRACE_CONTEXT(AbstractMediaPlayer::volumeChanged, EAudioInternal); - TRACE_ENTRY("state %d", privateState()); + m_positionTimer->start(tickInterval()); +} - AbstractPlayer::volumeChanged(volume); - doVolumeChanged(); +void MMF::AbstractMediaPlayer::stopPositionTimer() +{ + m_positionTimer->stop(); +} - TRACE_EXIT_0(); +void MMF::AbstractMediaPlayer::startBufferStatusTimer() +{ + m_bufferStatusTimer->start(BufferStatusTimerInterval); } +void MMF::AbstractMediaPlayer::stopBufferStatusTimer() +{ + m_bufferStatusTimer->stop(); +} + +void MMF::AbstractMediaPlayer::stopTimers() +{ + stopPositionTimer(); + stopBufferStatusTimer(); +} void MMF::AbstractMediaPlayer::doVolumeChanged() { @@ -318,7 +328,7 @@ void MMF::AbstractMediaPlayer::doVolumeChanged() const int err = setDeviceVolume(volume); if (KErrNone != err) { - setError(NormalError); + setError(tr("Setting volume failed"), err); } break; } @@ -330,19 +340,23 @@ void MMF::AbstractMediaPlayer::doVolumeChanged() } } - //----------------------------------------------------------------------------- // Protected functions //----------------------------------------------------------------------------- -void MMF::AbstractMediaPlayer::startTickTimer() +void MMF::AbstractMediaPlayer::bufferingStarted() { - m_tickTimer->start(tickInterval()); + m_stateBeforeBuffering = privateState(); + changeState(BufferingState); + bufferStatusTick(); + startBufferStatusTimer(); } -void MMF::AbstractMediaPlayer::stopTickTimer() +void MMF::AbstractMediaPlayer::bufferingComplete() { - m_tickTimer->stop(); + stopBufferStatusTimer(); + emit MMF::AbstractPlayer::bufferStatus(100); + changeState(m_stateBeforeBuffering); } void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume) @@ -351,6 +365,23 @@ void MMF::AbstractMediaPlayer::maxVolumeChanged(int mmfMaxVolume) doVolumeChanged(); } +void MMF::AbstractMediaPlayer::playbackComplete(int error) +{ + stopTimers(); + + if (KErrNone == error) { + changeState(StoppedState); + + // MediaObject::switchToNextSource deletes the current player, so we + // call it via delayed slot invokation to ensure that this object does + // not get deleted during execution of a member function. + QMetaObject::invokeMethod(m_parent, "switchToNextSource", Qt::QueuedConnection); + } + else { + setError(tr("Playback complete"), error); + } +} + qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds &in) { return in.Int64() / 1000; @@ -360,10 +391,53 @@ qint64 MMF::AbstractMediaPlayer::toMilliSeconds(const TTimeIntervalMicroSeconds // Slots //----------------------------------------------------------------------------- -void MMF::AbstractMediaPlayer::tick() +void MMF::AbstractMediaPlayer::positionTick() +{ + emitMarksIfReached(); + + const qint64 current = currentTime(); + emit MMF::AbstractPlayer::tick(current); +} + +void MMF::AbstractMediaPlayer::emitMarksIfReached() +{ + const qint64 current = currentTime(); + const qint64 total = totalTime(); + const qint64 remaining = total - current; + + if (prefinishMark() && !m_prefinishMarkSent) { + if (remaining < (prefinishMark() + tickInterval()/2)) { + m_prefinishMarkSent = true; + emit prefinishMarkReached(remaining); + } + } + + if (!m_aboutToFinishSent) { + if (remaining < tickInterval()) { + m_aboutToFinishSent = true; + emit aboutToFinish(); + } + } +} + +void MMF::AbstractMediaPlayer::resetMarksIfRewound() +{ + const qint64 current = currentTime(); + const qint64 total = totalTime(); + const qint64 remaining = total - current; + + if (prefinishMark() && m_prefinishMarkSent) + if (remaining >= (prefinishMark() + tickInterval()/2)) + m_prefinishMarkSent = false; + + if (m_aboutToFinishSent) + if (remaining >= tickInterval()) + m_aboutToFinishSent = false; +} + +void MMF::AbstractMediaPlayer::bufferStatusTick() { - // For the MWC compiler, we need to qualify the base class. - emit MMF::AbstractPlayer::tick(currentTime()); + emit MMF::AbstractPlayer::bufferStatus(bufferStatus()); } void MMF::AbstractMediaPlayer::changeState(PrivateState newState) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.h b/src/3rdparty/phonon/mmf/abstractmediaplayer.h index cb6e437..abd6bff 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.h +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.h @@ -33,6 +33,7 @@ namespace Phonon namespace MMF { class AudioOutput; +class MediaObject; /** * Interface via which MMF client APIs for both audio and video can be @@ -43,19 +44,17 @@ class AbstractMediaPlayer : public AbstractPlayer Q_OBJECT protected: - AbstractMediaPlayer(); - explicit AbstractMediaPlayer(const AbstractPlayer& player); + AbstractMediaPlayer(MediaObject *parent, const AbstractPlayer *player); public: + virtual void open(const Phonon::MediaSource&, RFile&); + // MediaObjectInterface virtual void play(); virtual void pause(); virtual void stop(); virtual void seek(qint64 milliseconds); virtual bool isSeekable() const; - virtual MediaSource source() const; - virtual void setFileSource(const Phonon::MediaSource&, RFile&); - virtual void setNextSource(const MediaSource &source); virtual void volumeChanged(qreal volume); protected: @@ -68,6 +67,8 @@ protected: virtual void doSeek(qint64 pos) = 0; virtual int setDeviceVolume(int mmfVolume) = 0; virtual int openFile(RFile& file) = 0; + virtual int openUrl(const QString& url) = 0; + virtual int bufferStatus() const = 0; virtual void close() = 0; virtual void changeState(PrivateState newState); @@ -76,23 +77,30 @@ protected: virtual QPair<QString, QString> metaDataEntry(int index) const = 0; protected: - bool tickTimerRunning() const; - void startTickTimer(); - void stopTickTimer(); + void bufferingStarted(); + void bufferingComplete(); void maxVolumeChanged(int maxVolume); + void playbackComplete(int error); static qint64 toMilliSeconds(const TTimeIntervalMicroSeconds &); private: + void startPositionTimer(); + void stopPositionTimer(); + void startBufferStatusTimer(); + void stopBufferStatusTimer(); + void stopTimers(); void doVolumeChanged(); + void emitMarksIfReached(); + void resetMarksIfRewound(); private Q_SLOTS: - /** - * Receives signal from m_tickTimer - */ - void tick(); + void positionTick(); + void bufferStatusTick(); private: + MediaObject *const m_parent; + /** * This flag is set to true if play is called when the object is * in a Loading state. Once loading is complete, playback will @@ -100,12 +108,15 @@ private: */ bool m_playPending; - QScopedPointer<QTimer> m_tickTimer; + QScopedPointer<QTimer> m_positionTimer; + + QScopedPointer<QTimer> m_bufferStatusTimer; + PrivateState m_stateBeforeBuffering; int m_mmfMaxVolume; - MediaSource m_source; - MediaSource m_nextSource; + bool m_prefinishMarkSent; + bool m_aboutToFinishSent; QMultiMap<QString, QString> m_metaData; diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index caf4092..53973eb 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -33,7 +33,7 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::AbstractPlayer::AbstractPlayer() +MMF::AbstractPlayer::AbstractPlayer(const AbstractPlayer *player) : m_videoOutput(0) , m_volume(InitialVolume) , m_state(GroundState) @@ -42,19 +42,13 @@ MMF::AbstractPlayer::AbstractPlayer() , m_transitionTime(0) , m_prefinishMark(0) { - -} - -MMF::AbstractPlayer::AbstractPlayer(const AbstractPlayer& player) - : m_videoOutput(player.m_videoOutput) - , m_volume(player.m_volume) - , m_state(GroundState) - , m_error(NoError) - , m_tickInterval(player.tickInterval()) - , m_transitionTime(player.transitionTime()) - , m_prefinishMark(player.prefinishMark()) -{ - + if(player) { + m_videoOutput = player->m_videoOutput; + m_volume = player->m_volume; + m_tickInterval = player->m_tickInterval; + m_transitionTime = player->m_transitionTime; + m_prefinishMark = player->m_prefinishMark; + } } //----------------------------------------------------------------------------- @@ -113,19 +107,23 @@ void MMF::AbstractPlayer::videoOutputChanged() // Default behaviour is empty - overridden by VideoPlayer } -void MMF::AbstractPlayer::setError(Phonon::ErrorType error, - const QString &errorMessage) +void MMF::AbstractPlayer::setError(const QString &errorMessage) { TRACE_CONTEXT(AbstractPlayer::setError, EAudioInternal); - TRACE_ENTRY("state %d error %d", m_state, error); + TRACE_ENTRY("state %d", m_state); - m_error = error; + m_error = Phonon::NormalError; m_errorString = errorMessage; changeState(ErrorState); TRACE_EXIT_0(); } +void MMF::AbstractPlayer::setError(const QString &errorMessage, int symbianError) +{ + setError(errorMessage + ": " + Utils::symbianErrorToString(symbianError)); +} + Phonon::ErrorType MMF::AbstractPlayer::errorType() const { const Phonon::ErrorType result = (ErrorState == m_state) diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 2e9cfa0..40ad7f8 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -53,8 +53,9 @@ class AbstractPlayer : public QObject Q_OBJECT public: - AbstractPlayer(); - explicit AbstractPlayer(const AbstractPlayer& player); + AbstractPlayer(const AbstractPlayer *player); + + virtual void open(const Phonon::MediaSource&, RFile&) = 0; // MediaObjectInterface (implemented) qint32 tickInterval() const; @@ -75,22 +76,28 @@ public: virtual Phonon::ErrorType errorType() const; virtual QString errorString() const; virtual qint64 totalTime() const = 0; - virtual Phonon::MediaSource source() const = 0; - // This is a temporary hack to work around KErrInUse from MMF - // client utility OpenFileL calls - //virtual void setSource(const Phonon::MediaSource &) = 0; - virtual void setFileSource(const Phonon::MediaSource&, RFile&) = 0; - virtual void setNextSource(const Phonon::MediaSource &) = 0; virtual void volumeChanged(qreal volume); void setVideoOutput(VideoOutput* videoOutput); /** - * Records error and changes state to ErrorState + * Records error message and changes state to ErrorState + */ + void setError(const QString &errorMessage); + + /** + * Records error message and changes state to ErrorState + * + * Appends a human-readable version of symbianErrorCode to the error message, + * e.g. + * @code + * setError("Opening file failed", KErrPermissionDenied) + * @endcode + * results in the following error message: + * "Opening file failed: permission denied" */ - void setError(Phonon::ErrorType error, - const QString &errorMessage = QString()); + void setError(const QString &errorMessage, int symbianErrorCode); Phonon::State state() const; @@ -98,9 +105,12 @@ Q_SIGNALS: void totalTimeChanged(qint64 length); void finished(); void tick(qint64 time); + void bufferStatus(int percentFilled); void stateChanged(Phonon::State oldState, Phonon::State newState); void metaDataChanged(const QMultiMap<QString, QString>& metaData); + void aboutToFinish(); + void prefinishMarkReached(qint32 remaining); protected: /** diff --git a/src/3rdparty/phonon/mmf/audioequalizer.cpp b/src/3rdparty/phonon/mmf/audioequalizer.cpp index 7cc9bc7..c2936c5 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.cpp +++ b/src/3rdparty/phonon/mmf/audioequalizer.cpp @@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#include <AudioEqualizerBase.h> #include "audioequalizer.h" QT_BEGIN_NAMESPACE @@ -34,18 +35,37 @@ AudioEqualizer::AudioEqualizer(QObject *parent) : AbstractAudioEffect::AbstractA void AudioEqualizer::parameterChanged(const int pid, const QVariant &value) { - // There is no way to return an error from this function, so we just - // have to trap and ignore exceptions. - TRAP_IGNORE(static_cast<CAudioEqualizer *>(m_effect.data())->SetBandLevelL(pid, value.toInt())); + if (m_effect.data()) { + const int band = pid; + const int level = value.toInt(); + setBandLevel(band, level); + } } -bool AudioEqualizer::activateOn(CPlayerType *player) +void AudioEqualizer::connectAudioPlayer(AudioPlayer::NativePlayer *player) { CAudioEqualizer *ptr = 0; QT_TRAP_THROWING(ptr = CAudioEqualizer::NewL(*player)); m_effect.reset(ptr); +} - return true; +void AudioEqualizer::applyParameters() +{ + if (m_effect.data()) { + EffectParameter param; + foreach (param, parameters()) { + const int band = param.id(); + const int level = parameterValue(param).toInt(); + setBandLevel(band, level); + } + } +} + +void AudioEqualizer::setBandLevel(int band, int level) +{ + CAudioEqualizer *const effect = static_cast<CAudioEqualizer *>(m_effect.data()); + // TODO: handle audio effect errors + TRAP_IGNORE(effect->SetBandLevelL(band, level)); } QList<EffectParameter> AudioEqualizer::createParams() @@ -57,7 +77,7 @@ QList<EffectParameter> AudioEqualizer::createParams() AudioPlayer dummyPlayer; CAudioEqualizer *eqPtr = 0; - QT_TRAP_THROWING(eqPtr = CAudioEqualizer::NewL(*dummyPlayer.player());) + QT_TRAP_THROWING(eqPtr = CAudioEqualizer::NewL(*dummyPlayer.nativePlayer())); QScopedPointer<CAudioEqualizer> e(eqPtr); TInt32 dbMin; diff --git a/src/3rdparty/phonon/mmf/audioequalizer.h b/src/3rdparty/phonon/mmf/audioequalizer.h index d4c8165..10fe9ad 100644 --- a/src/3rdparty/phonon/mmf/audioequalizer.h +++ b/src/3rdparty/phonon/mmf/audioequalizer.h @@ -19,7 +19,6 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_AUDIOEQUALIZER_H #define PHONON_MMF_AUDIOEQUALIZER_H -#include <AudioEqualizerBase.h> #include "abstractaudioeffect.h" QT_BEGIN_NAMESPACE @@ -43,14 +42,17 @@ public: AudioEqualizer(QObject *parent); protected: - virtual void parameterChanged(const int id, - const QVariant &value); + // AbstractAudioEffect + virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player); + virtual void applyParameters(); + virtual void parameterChanged(const int id, const QVariant &value); - virtual bool activateOn(CPlayerType *player); +private: + void setBandLevel(int band, int level); private: static QList<EffectParameter> createParams(); - QScopedPointer<CAudioEqualizer> m_bassBoost; + }; } } diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index d6e0c13..c6be20b 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -81,13 +81,18 @@ bool MMF::AudioOutput::setOutputDevice(int index) return true; } -bool MMF::AudioOutput::activateOnMediaObject(MediaObject *mo) +void MMF::AudioOutput::connectMediaObject(MediaObject *mediaObject) { // Ensure that the MediaObject has the correct initial volume - mo->volumeChanged(m_volume); + mediaObject->volumeChanged(m_volume); // Connect MediaObject to receive future volume changes - connect(this, SIGNAL(volumeChanged(qreal)), mo, SLOT(volumeChanged(qreal))); - return true; + connect(this, SIGNAL(volumeChanged(qreal)), mediaObject, SLOT(volumeChanged(qreal))); +} + +void MMF::AudioOutput::disconnectMediaObject(MediaObject *mediaObject) +{ + // Disconnect all signal-slot connections + disconnect(this, 0, mediaObject, 0); } QHash<QByteArray, QVariant> MMF::AudioOutput::audioOutputDescription(int index) diff --git a/src/3rdparty/phonon/mmf/audiooutput.h b/src/3rdparty/phonon/mmf/audiooutput.h index 1e1e134..67aaa38 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.h +++ b/src/3rdparty/phonon/mmf/audiooutput.h @@ -74,7 +74,9 @@ public: }; protected: - virtual bool activateOnMediaObject(MediaObject *mo); + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); Q_SIGNALS: void volumeChanged(qreal volume); diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 8fccfe6..ee07229 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -34,13 +34,9 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::AudioPlayer::AudioPlayer() -{ - construct(); -} - -MMF::AudioPlayer::AudioPlayer(const AbstractPlayer& player) - : AbstractMediaPlayer(player) +MMF::AudioPlayer::AudioPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractMediaPlayer(parent, player) + , m_totalTime(0) { construct(); } @@ -50,10 +46,10 @@ void MMF::AudioPlayer::construct() TRACE_CONTEXT(AudioPlayer::AudioPlayer, EAudioApi); TRACE_ENTRY_0(); - TRAPD(err, m_player.reset(CPlayerType::NewL(*this, 0, EMdaPriorityPreferenceNone))); - if (KErrNone != err) { - changeState(ErrorState); - } + NativePlayer *player = 0; + QT_TRAP_THROWING(player = NativePlayer::NewL(*this, 0, EMdaPriorityPreferenceNone)); + m_player.reset(player); + m_player->RegisterForAudioLoadingNotification(*this); TRACE_EXIT_0(); } @@ -66,6 +62,11 @@ MMF::AudioPlayer::~AudioPlayer() TRACE_EXIT_0(); } +MMF::AudioPlayer::NativePlayer *MMF::AudioPlayer::nativePlayer() const +{ + return m_player.data(); +} + //----------------------------------------------------------------------------- // Public API //----------------------------------------------------------------------------- @@ -125,6 +126,24 @@ int MMF::AudioPlayer::openFile(RFile& file) return err; } +int MMF::AudioPlayer::openUrl(const QString& /*url*/) +{ + // Streaming playback is generally not supported by the implementation + // of the audio player API, so we use CVideoPlayerUtility for both + // audio and video streaming. + Utils::panic(AudioUtilityUrlNotSupported); + + // Silence warning + return 0; +} + +int MMF::AudioPlayer::bufferStatus() const +{ + int result = 0; + TRAP_IGNORE(m_player->GetAudioLoadingProgressL(result)); + return result; +} + void MMF::AudioPlayer::close() { m_player->Close(); @@ -151,7 +170,7 @@ qint64 MMF::AudioPlayer::currentTime() const // If we don't cast away constness here, we simply have to ignore // the error. - const_cast<AudioPlayer*>(this)->setError(NormalError); + const_cast<AudioPlayer*>(this)->setError(tr("Getting position failed"), err); } return result; @@ -159,7 +178,7 @@ qint64 MMF::AudioPlayer::currentTime() const qint64 MMF::AudioPlayer::totalTime() const { - return toMilliSeconds(m_player->Duration()); + return m_totalTime; } @@ -182,12 +201,12 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError, if (KErrNone == aError) { maxVolumeChanged(m_player->MaxVolume()); - emit totalTimeChanged(totalTime()); + m_totalTime = toMilliSeconds(m_player->Duration()); + emit totalTimeChanged(m_totalTime); updateMetaData(); changeState(StoppedState); } else { - // TODO: set different error states according to value of aError? - setError(NormalError); + setError(tr("Opening clip failed"), aError); } TRACE_EXIT_0(); @@ -202,53 +221,39 @@ void MMF::AudioPlayer::MapcPlayComplete(TInt aError) TRACE_CONTEXT(AudioPlayer::MapcPlayComplete, EAudioInternal); TRACE_ENTRY("state %d error %d", state(), aError); - stopTickTimer(); + // Call base class function which handles end of playback for both + // audio and video clips. + playbackComplete(aError); - if (KErrNone == aError) { - changeState(StoppedState); - // TODO: move on to m_nextSource - } else { - // TODO: do something with aError? - setError(NormalError); - } + TRACE_EXIT_0(); +} - /* - if (aError == KErrNone) { - if (m_nextSource.type() == MediaSource::Empty) { - emit finished(); - } else { - setSource(m_nextSource); - m_nextSource = MediaSource(); - } - - changeState(StoppedState); - } - else { - m_error = NormalError; - changeState(ErrorState); - } - */ +#ifdef QT_PHONON_MMF_AUDIO_DRM +void MMF::AudioPlayer::MaloLoadingStarted() +{ - TRACE_EXIT_0(); } -CPlayerType *MMF::AudioPlayer::player() const +void MMF::AudioPlayer::MaloLoadingComplete() { - return m_player.data(); + } +#endif // QT_PHONON_MMF_AUDIO_DRM -#ifdef QT_PHONON_MMF_AUDIO_DRM +//----------------------------------------------------------------------------- +// MAudioLoadingObserver callbacks +//----------------------------------------------------------------------------- + void MMF::AudioPlayer::MaloLoadingStarted() { - + bufferingStarted(); } void MMF::AudioPlayer::MaloLoadingComplete() { - + bufferingComplete(); } -#endif // QT_PHONON_MMF_AUDIO_DRM //----------------------------------------------------------------------------- diff --git a/src/3rdparty/phonon/mmf/audioplayer.h b/src/3rdparty/phonon/mmf/audioplayer.h index bc60076..0eb8bb7 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.h +++ b/src/3rdparty/phonon/mmf/audioplayer.h @@ -26,12 +26,10 @@ class TTimeIntervalMicroSeconds; #ifdef QT_PHONON_MMF_AUDIO_DRM #include <drmaudiosampleplayer.h> -typedef CDrmPlayerUtility CPlayerType; -typedef MDrmAudioPlayerCallback MPlayerObserverType; +typedef MDrmAudioPlayerCallback NativePlayerObserver; #else #include <mdaaudiosampleplayer.h> -typedef CMdaAudioPlayerUtility CPlayerType; -typedef MMdaAudioPlayerCallback MPlayerObserverType; +typedef MMdaAudioPlayerCallback NativePlayerObserver; #endif QT_BEGIN_NAMESPACE @@ -44,18 +42,23 @@ namespace MMF * @short Wrapper over MMF audio client utility */ class AudioPlayer : public AbstractMediaPlayer - , public MPlayerObserverType // typedef -#ifdef QT_PHONON_MMF_AUDIO_DRM + , public NativePlayerObserver , public MAudioLoadingObserver -#endif { Q_OBJECT public: - AudioPlayer(); - explicit AudioPlayer(const AbstractPlayer& player); + AudioPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); virtual ~AudioPlayer(); +#ifdef QT_PHONON_MMF_AUDIO_DRM +typedef CDrmPlayerUtility NativePlayer; +#else +typedef CMdaAudioPlayerUtility NativePlayer; +#endif + + NativePlayer *nativePlayer() const; + // AbstractMediaPlayer virtual void doPlay(); virtual void doPause(); @@ -63,6 +66,8 @@ public: virtual void doSeek(qint64 milliseconds); virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile& file); + virtual int openUrl(const QString& url); + virtual int bufferStatus() const; virtual void close(); // MediaObjectInterface @@ -70,15 +75,24 @@ public: virtual qint64 currentTime() const; virtual qint64 totalTime() const; + // AbstractMediaPlayer + virtual int numberOfMetaDataEntries() const; + virtual QPair<QString, QString> metaDataEntry(int index) const; + + /** + * This class owns the pointer. + */ + NativePlayer *player() const; + +private: + void construct(); + +private: #ifdef QT_PHONON_MMF_AUDIO_DRM // MDrmAudioPlayerCallback virtual void MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds &aDuration); virtual void MdapcPlayComplete(TInt aError); - - // MAudioLoadingObserver - virtual void MaloLoadingStarted(); - virtual void MaloLoadingComplete(); #else // MMdaAudioPlayerCallback virtual void MapcInitComplete(TInt aError, @@ -86,24 +100,19 @@ public: virtual void MapcPlayComplete(TInt aError); #endif - /** - * This class owns the pointer. - */ - CPlayerType *player() const; - -private: - void construct(); - - // AbstractMediaPlayer - virtual int numberOfMetaDataEntries() const; - virtual QPair<QString, QString> metaDataEntry(int index) const; + // MAudioLoadingObserver + virtual void MaloLoadingStarted(); + virtual void MaloLoadingComplete(); private: /** * Using CPlayerType typedef in order to be able to easily switch between * CMdaAudioPlayerUtility and CDrmPlayerUtility */ - QScopedPointer<CPlayerType> m_player; + QScopedPointer<NativePlayer> m_player; + + qint64 m_totalTime; + }; } } diff --git a/src/3rdparty/phonon/mmf/backend.cpp b/src/3rdparty/phonon/mmf/backend.cpp index 7e3a67f..0c07f66 100644 --- a/src/3rdparty/phonon/mmf/backend.cpp +++ b/src/3rdparty/phonon/mmf/backend.cpp @@ -139,29 +139,32 @@ bool Backend::startConnectionChange(QSet<QObject *>) return true; } -bool Backend::connectNodes(QObject *source, QObject *target) +bool Backend::connectNodes(QObject *sourceObject, QObject *targetObject) { TRACE_CONTEXT(Backend::connectNodes, EBackend); - TRACE_ENTRY("source 0x%08x target 0x%08x", source, target); - Q_ASSERT(qobject_cast<MediaNode *>(source)); - Q_ASSERT(qobject_cast<MediaNode *>(target)); + TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject); - MediaNode *const mediaSource = static_cast<MediaNode *>(source); - MediaNode *const mediaTarget = static_cast<MediaNode *>(target); + MediaNode *const source = qobject_cast<MediaNode *>(sourceObject); + MediaNode *const target = qobject_cast<MediaNode *>(targetObject); - return mediaSource->connectMediaNode(mediaTarget); + Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode"); + Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode"); + + return source->connectOutput(target); } -bool Backend::disconnectNodes(QObject *source, QObject *target) +bool Backend::disconnectNodes(QObject *sourceObject, QObject *targetObject) { TRACE_CONTEXT(Backend::disconnectNodes, EBackend); - TRACE_ENTRY("source 0x%08x target 0x%08x", source, target); - Q_ASSERT(qobject_cast<MediaNode *>(source)); - Q_ASSERT(qobject_cast<MediaNode *>(target)); + TRACE_ENTRY("source 0x%08x target 0x%08x", sourceObject, targetObject); + + MediaNode *const source = qobject_cast<MediaNode *>(sourceObject); + MediaNode *const target = qobject_cast<MediaNode *>(targetObject); - const bool result = static_cast<MediaNode *>(source)->disconnectMediaNode(static_cast<MediaNode *>(target)); + Q_ASSERT_X(source, Q_FUNC_INFO, "source is not a MediaNode"); + Q_ASSERT_X(target, Q_FUNC_INFO, "target is not a MediaNode"); - TRACE_RETURN("%d", result); + return source->disconnectOutput(target); } bool Backend::endConnectionChange(QSet<QObject *>) diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp index e34f9e7..ae96b45 100644 --- a/src/3rdparty/phonon/mmf/bassboost.cpp +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -16,6 +16,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. */ +#include <BassBoostBase.h> #include "bassboost.h" QT_BEGIN_NAMESPACE @@ -35,13 +36,19 @@ BassBoost::BassBoost(QObject *parent) : AbstractAudioEffect::AbstractAudioEffect void BassBoost::parameterChanged(const int, const QVariant &) { - // We should never be called, because we have no parameters. + Q_ASSERT_X(false, Q_FUNC_INFO, "BassBoost has not parameters"); } -bool BassBoost::activateOn(CPlayerType *player) +void BassBoost::connectAudioPlayer(AudioPlayer::NativePlayer *player) { - m_effect.reset(CBassBoost::NewL(*player, true)); - return true; + CBassBoost *ptr = 0; + QT_TRAP_THROWING(ptr = CBassBoost::NewL(*player)); + m_effect.reset(ptr); +} + +void BassBoost::applyParameters() +{ + // No parameters to apply } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/bassboost.h b/src/3rdparty/phonon/mmf/bassboost.h index c16393a..4ad0a6c 100644 --- a/src/3rdparty/phonon/mmf/bassboost.h +++ b/src/3rdparty/phonon/mmf/bassboost.h @@ -19,7 +19,6 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_BASSBOOST_H #define PHONON_MMF_BASSBOOST_H -#include <BassBoostBase.h> #include "abstractaudioeffect.h" QT_BEGIN_NAMESPACE @@ -41,13 +40,11 @@ public: BassBoost(QObject *parent); protected: - virtual void parameterChanged(const int id, - const QVariant &value); + // AbstractAudioEffect + virtual void connectAudioPlayer(AudioPlayer::NativePlayer *player); + virtual void applyParameters(); + virtual void parameterChanged(const int id, const QVariant &value); - virtual bool activateOn(CPlayerType *player); - -private: - QScopedPointer<CBassBoost> m_bassBoost; }; } } diff --git a/src/3rdparty/phonon/mmf/dummyplayer.cpp b/src/3rdparty/phonon/mmf/dummyplayer.cpp index e6f3855..6970088 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.cpp +++ b/src/3rdparty/phonon/mmf/dummyplayer.cpp @@ -31,12 +31,7 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::DummyPlayer::DummyPlayer() -{ - -} - -MMF::DummyPlayer::DummyPlayer(const AbstractPlayer& player) +MMF::DummyPlayer::DummyPlayer(const AbstractPlayer *player) : AbstractPlayer(player) { @@ -97,17 +92,7 @@ qint64 MMF::DummyPlayer::totalTime() const return 0; } -MediaSource MMF::DummyPlayer::source() const -{ - return MediaSource(); -} - -void MMF::DummyPlayer::setFileSource(const Phonon::MediaSource &, RFile &) -{ - -} - -void MMF::DummyPlayer::setNextSource(const MediaSource &) +void MMF::DummyPlayer::open(const Phonon::MediaSource &, RFile &) { } diff --git a/src/3rdparty/phonon/mmf/dummyplayer.h b/src/3rdparty/phonon/mmf/dummyplayer.h index c6270c9..6841b5d 100644 --- a/src/3rdparty/phonon/mmf/dummyplayer.h +++ b/src/3rdparty/phonon/mmf/dummyplayer.h @@ -42,8 +42,7 @@ class AudioOutput; class DummyPlayer : public AbstractPlayer { public: - DummyPlayer(); - DummyPlayer(const AbstractPlayer& player); + DummyPlayer(const AbstractPlayer *player = 0); // MediaObjectInterface virtual void play(); @@ -56,12 +55,9 @@ public: virtual Phonon::State state() const; virtual Phonon::ErrorType errorType() const; virtual qint64 totalTime() const; - virtual MediaSource source() const; - // virtual void setSource(const MediaSource &); - virtual void setFileSource(const Phonon::MediaSource&, RFile&); - virtual void setNextSource(const MediaSource &source); // AbstractPlayer + virtual void open(const Phonon::MediaSource&, RFile&); virtual void doSetTickInterval(qint32 interval); }; } diff --git a/src/3rdparty/phonon/mmf/effectfactory.cpp b/src/3rdparty/phonon/mmf/effectfactory.cpp index e9c5e27..cc94367 100644 --- a/src/3rdparty/phonon/mmf/effectfactory.cpp +++ b/src/3rdparty/phonon/mmf/effectfactory.cpp @@ -113,7 +113,7 @@ bool isEffectSupported() AudioPlayer audioPlayer; QScopedPointer<TEffect> eff; - TRAPD(errorCode, eff.reset(TEffect::NewL(*audioPlayer.player()))); + TRAPD(errorCode, eff.reset(TEffect::NewL(*audioPlayer.nativePlayer()))); return errorCode != KErrNone; } diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index 21dcfe1..4653fee 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -45,6 +45,7 @@ using namespace Phonon::MMF; MMF::MediaObject::MediaObject(QObject *parent) : MMF::MediaNode::MediaNode(parent) , m_recognizerOpened(false) + , m_nextSourceSet(false) { m_player.reset(new DummyPlayer()); @@ -211,18 +212,20 @@ qint64 MMF::MediaObject::totalTime() const MediaSource MMF::MediaObject::source() const { - return m_player->source(); + return m_source; } void MMF::MediaObject::setSource(const MediaSource &source) { - createPlayer(source); - - // This is a hack to work around KErrInUse from MMF client utility - // OpenFileL calls - m_player->setFileSource(source, m_file); + switchToSource(source); +} - emit currentSourceChanged(source); +void MMF::MediaObject::switchToSource(const MediaSource &source) +{ + createPlayer(source); + m_source = source; + m_player->open(m_source, m_file); + emit currentSourceChanged(m_source); } void MMF::MediaObject::createPlayer(const MediaSource &source) @@ -238,7 +241,6 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) const bool oldPlayerHasVideo = oldPlayer->hasVideo(); const bool oldPlayerSeekable = oldPlayer->isSeekable(); - Phonon::ErrorType error = NoError; QString errorMessage; // Determine media type @@ -254,8 +256,10 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) mediaType = fileMediaType(url.toLocalFile()); } else { - errorMessage = QLatin1String("Network streaming not supported yet"); - error = NormalError; + // Streaming playback is generally not supported by the implementation + // of the audio player API, so we use CVideoPlayerUtility for both + // audio and video streaming. + mediaType = MediaTypeVideo; } } break; @@ -263,8 +267,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) case MediaSource::Invalid: case MediaSource::Disc: case MediaSource::Stream: - TRACE_0("Unsupported media type"); - error = NormalError; + errorMessage = tr("Error opening source: type not supported"); break; case MediaSource::Empty: @@ -281,30 +284,16 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) switch (mediaType) { case MediaTypeUnknown: TRACE_0("Media type could not be determined"); - if (oldPlayer) { - newPlayer = new DummyPlayer(*oldPlayer); - } else { - newPlayer = new DummyPlayer(); - } - - error = NormalError; - errorMessage = tr("Media type could not be determined"); + newPlayer = new DummyPlayer(oldPlayer); + errorMessage = tr("Error opening source: media type could not be determined"); break; case MediaTypeAudio: - if (oldPlayer) { - newPlayer = new AudioPlayer(*oldPlayer); - } else { - newPlayer = new AudioPlayer(); - } + newPlayer = new AudioPlayer(this, oldPlayer); break; case MediaTypeVideo: - if (oldPlayer) { - newPlayer = new VideoPlayer(*oldPlayer); - } else { - newPlayer = new VideoPlayer(); - } + newPlayer = new VideoPlayer(this, oldPlayer); break; } @@ -322,13 +311,16 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) connect(m_player.data(), SIGNAL(stateChanged(Phonon::State,Phonon::State)), SIGNAL(stateChanged(Phonon::State,Phonon::State))); connect(m_player.data(), SIGNAL(finished()), SIGNAL(finished())); connect(m_player.data(), SIGNAL(tick(qint64)), SIGNAL(tick(qint64))); + connect(m_player.data(), SIGNAL(bufferStatus(int)), SIGNAL(bufferStatus(int))); connect(m_player.data(), SIGNAL(metaDataChanged(QMultiMap<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))); // We need to call setError() after doing the connects, otherwise the // error won't be received. - if (error != NoError) { + if (!errorMessage.isEmpty()) { Q_ASSERT(m_player); - m_player->setError(error, errorMessage); + m_player->setError(errorMessage); } TRACE_EXIT_0(); @@ -336,7 +328,8 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) void MMF::MediaObject::setNextSource(const MediaSource &source) { - m_player->setNextSource(source); + m_nextSource = source; + m_nextSourceSet = true; } qint32 MMF::MediaObject::prefinishMark() const @@ -365,6 +358,25 @@ void MMF::MediaObject::volumeChanged(qreal volume) } //----------------------------------------------------------------------------- +// MediaNode +//----------------------------------------------------------------------------- + +void MMF::MediaObject::connectMediaObject(MediaObject * /*mediaObject*/) +{ + // This function should never be called - see MediaNode::setMediaObject() + Q_ASSERT_X(false, Q_FUNC_INFO, + "Connection of MediaObject to MediaObject"); +} + +void MMF::MediaObject::disconnectMediaObject(MediaObject * /*mediaObject*/) +{ + // This function should never be called - see MediaNode::setMediaObject() + Q_ASSERT_X(false, Q_FUNC_INFO, + "Disconnection of MediaObject from MediaObject"); +} + + +//----------------------------------------------------------------------------- // Video output //----------------------------------------------------------------------------- @@ -379,10 +391,17 @@ AbstractPlayer *MMF::MediaObject::abstractPlayer() const return m_player.data(); } -bool MMF::MediaObject::activateOnMediaObject(MediaObject *) +//----------------------------------------------------------------------------- +// Playlist support +//----------------------------------------------------------------------------- + +void MMF::MediaObject::switchToNextSource() { - // Guess what, we do nothing. - return true; + if (m_nextSourceSet) { + m_nextSourceSet = false; + switchToSource(m_nextSource); + play(); + } } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index ee94ea2..668b953 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -75,6 +75,10 @@ public: virtual qint32 transitionTime() const; virtual void setTransitionTime(qint32); + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); + /** * This class owns the AbstractPlayer, and will delete it upon * destruction. @@ -83,21 +87,17 @@ public: void setVideoOutput(VideoOutput* videoOutput); - virtual bool activateOnMediaObject(MediaObject *); - public Q_SLOTS: void volumeChanged(qreal volume); + void switchToNextSource(); Q_SIGNALS: void totalTimeChanged(qint64 length); void hasVideoChanged(bool hasVideo); void seekableChanged(bool seekable); - // TODO: emit bufferStatus from MediaObject void bufferStatus(int); - // TODO: emit aboutToFinish from MediaObject void aboutToFinish(); - // TODO: emit prefinishMarkReached from MediaObject - void prefinishMarkReached(qint32); + void prefinishMarkReached(qint32 remaining); // TODO: emit metaDataChanged from MediaObject void metaDataChanged(const QMultiMap<QString, QString>& metaData); void currentSourceChanged(const MediaSource& source); @@ -107,6 +107,7 @@ Q_SIGNALS: void tick(qint64 time); private: + void switchToSource(const MediaSource &source); void createPlayer(const MediaSource &source); bool openRecognizer(); @@ -123,6 +124,10 @@ private: RApaLsSession m_recognizer; RFs m_fileServer; + MediaSource m_source; + MediaSource m_nextSource; + bool m_nextSourceSet; + // Storing the file handle here to work around KErrInUse error // from MMF player utility OpenFileL functions RFile m_file; diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.cpp b/src/3rdparty/phonon/mmf/mmf_medianode.cpp index 253c5e7..ca413d9 100644 --- a/src/3rdparty/phonon/mmf/mmf_medianode.cpp +++ b/src/3rdparty/phonon/mmf/mmf_medianode.cpp @@ -29,92 +29,123 @@ using namespace Phonon::MMF; \internal */ -MMF::MediaNode::MediaNode(QObject *parent) : QObject::QObject(parent) - , m_source(0) - , m_target(0) - , m_isApplied(false) +MMF::MediaNode::MediaNode(QObject *parent) + : QObject(parent) + , m_mediaObject(qobject_cast<MediaObject *>(this)) + , m_input(0) { -} - -bool MMF::MediaNode::connectMediaNode(MediaNode *target) -{ - m_target = target; - m_target->setSource(this); - return applyNodesOnMediaObject(target); } -bool MMF::MediaNode::disconnectMediaNode(MediaNode *target) +MMF::MediaNode::~MediaNode() { - Q_UNUSED(target); - m_target = 0; - m_isApplied = false; - return true; + // Phonon framework ensures nodes are disconnected before being destroyed. + Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO, + "Media node not disconnected before destruction"); } -void MMF::MediaNode::setSource(MediaNode *source) +bool MMF::MediaNode::connectOutput(MediaNode *output) { - m_source = source; + Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer"); + + bool connected = false; + + // Check that this connection will not result in a graph which + // containing more than one MediaObject + const bool mediaObjectMisMatch = + m_mediaObject + && output->m_mediaObject + && m_mediaObject != output->m_mediaObject; + + const bool canConnect = + !output->isMediaObject() + && !output->m_input + && !m_outputs.contains(output); + + if (canConnect && !mediaObjectMisMatch) { + output->m_input = this; + m_outputs += output; + updateMediaObject(); + connected = true; + } + + return connected; } -MMF::MediaNode *MMF::MediaNode::source() const +bool MMF::MediaNode::disconnectOutput(MediaNode *output) { - return m_source; + Q_ASSERT_X(output, Q_FUNC_INFO, "Null output pointer"); + + bool disconnected = false; + + if (m_outputs.contains(output) && this == output->m_input) { + output->m_input = 0; + const bool removed = m_outputs.removeOne(output); + Q_ASSERT_X(removed, Q_FUNC_INFO, "Output removal failed"); + + Q_ASSERT_X(!m_outputs.contains(output), Q_FUNC_INFO, + "Output list contains duplicate entries"); + + // Perform traversal across each of the two graphs separately + updateMediaObject(); + output->updateMediaObject(); + + disconnected = true; + } + + return disconnected; } -MMF::MediaNode *MMF::MediaNode::target() const +bool MMF::MediaNode::isMediaObject() const { - return m_target; + return (qobject_cast<const MediaObject *>(this) != 0); } -bool MMF::MediaNode::applyNodesOnMediaObject(MediaNode *) +void MMF::MediaNode::updateMediaObject() { - // Algorithmically, this can be expressed in a more efficient way by - // exercising available assumptions, but it complicates code for input - // data(length of the graph) which typically is very small. - - // First, we go to the very beginning of the graph. - MMF::MediaNode *current = this; - do { - MediaNode *const candidate = current->source(); - if (candidate) - current = candidate; - else - break; - } - while (current); - - // Now we do two things, while walking to the other end: - // 1. Find the MediaObject, if present - // 2. Collect a list of all unapplied MediaNodes - - QList<MediaNode *> unapplied; - MMF::MediaObject *mo = 0; + QList<MediaNode *> nodes; + MediaObject *mediaObject = 0; - do { - if (!current->m_isApplied) - unapplied.append(current); + // Traverse the graph, collecting a list of nodes, and locating + // the MediaObject node, if present + visit(nodes, mediaObject); - if (!mo) - mo = qobject_cast<MMF::MediaObject *>(current); + MediaNode *node = 0; + foreach(node, nodes) + node->setMediaObject(mediaObject); +} - current = current->target(); +void MMF::MediaNode::setMediaObject(MediaObject *mediaObject) +{ + if(!isMediaObject() && m_mediaObject != mediaObject) { + if (!mediaObject) + disconnectMediaObject(m_mediaObject); + else { + Q_ASSERT_X(!m_mediaObject, Q_FUNC_INFO, "MediaObject already set"); + connectMediaObject(mediaObject); + } + m_mediaObject = mediaObject; } - while (current); +} - // Now, lets activate all the objects, if we found the MediaObject. +void MMF::MediaNode::visit(QList<MediaNode *>& visited, MediaObject*& mediaObject) +{ + if (isMediaObject()) { + // There can never be more than one MediaObject per graph, due to the + // mediaObjectMisMatch test in connectOutput(). + Q_ASSERT_X(!mediaObject, Q_FUNC_INFO, "MediaObject already found"); + mediaObject = static_cast<MediaObject *>(this); + } - if (mo) { - for (int i = 0; i < unapplied.count(); ++i) { - MediaNode *const at = unapplied.at(i); + visited += this; - // We don't want to apply MediaObject on itself. - if (at != mo) - at->activateOnMediaObject(mo); - } - } + if (m_input && !visited.contains(m_input)) + m_input->visit(visited, mediaObject); - return true; + MediaNode *output = 0; + foreach (output, m_outputs) + if (!visited.contains(output)) + output->visit(visited, mediaObject); } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.h b/src/3rdparty/phonon/mmf/mmf_medianode.h index 4616ff1..0ed21c4 100644 --- a/src/3rdparty/phonon/mmf/mmf_medianode.h +++ b/src/3rdparty/phonon/mmf/mmf_medianode.h @@ -43,54 +43,62 @@ class MediaObject; /** * @short Base class for all nodes in the MMF backend. * - * MediaNode is the base class for all nodes in the chain for MMF. Currently - * they are: + * MediaNode is the base class for all nodes created by the MMF + * backend. * - * - MediaObject: a source of media - * - AbstractEffect: supplying audio effects - * - AudioOutput: pretty much a dummy interface, but is also MediaNode in order - * to simplify connection/disconnection. + * These nodes may be one of the following types: * - * MediaNode provides spectatability into the chain, and also allows the - * connection code to be written in a polymorphic manner, instead of putting it - * all in the Backend class. Due to that MMF has no concept of chaining, the - * order of the nodes in the graph has no meaning. + * - MediaObject + * This represents the source of media data. It encapsulates the + * appropriate MMF client API for playing audio or video. + * - AudioOutput + * This represents the audio output device. Since the MMF client API + * does not expose the output device directly, this backend node + * simply forwards volume control commands to the MediaObject. + * - VideoWidget + * A native widget on which video will be rendered. + * - An audio effect, derived form AbstractAudioEffect + * + * Because the MMF API does not support the concept of a media filter graph, + * this class must ensure the following: + * + * - Each media graph contains at most one MediaObject instance. + * - Every non-MediaObject node holds a reference to the MediaObject. This + * allows commands to be sent through the graph to the encapsulated MMF client + * API. */ class MediaNode : public QObject { Q_OBJECT public: MediaNode(QObject *parent); + ~MediaNode(); + + bool connectOutput(MediaNode *output); + bool disconnectOutput(MediaNode *output); + + virtual void connectMediaObject(MediaObject *mediaObject) = 0; + virtual void disconnectMediaObject(MediaObject *mediaObject) = 0; - virtual bool connectMediaNode(MediaNode *target); - virtual bool disconnectMediaNode(MediaNode *target); - void setSource(MediaNode *source); +private: + bool isMediaObject() const; - MediaNode *source() const; - MediaNode *target() const; + void updateMediaObject(); + void setMediaObject(MediaObject *mediaObject); -protected: - /** - * When connectMediaNode() is called and a MediaObject is part of - * the its graph, this function will be called for each MediaNode in the - * graph for which it hasn't been called yet. - * - * The caller guarantees that @p mo is always non-null. - */ - virtual bool activateOnMediaObject(MediaObject *mo) = 0; + typedef QList<const MediaNode *> NodeList; + void visit(QList<MediaNode *>& visited, MediaObject*& mediaObject); private: - /** - * Finds a MediaObject anywhere in the graph @p target is apart of, and - * calls activateOnMediaObject() for all MediaNodes in the graph for which - * it hasn't been applied to already. - */ - bool applyNodesOnMediaObject(MediaNode *target); - - MediaNode * m_source; - MediaNode * m_target; - bool m_isApplied; + MediaObject * m_mediaObject; + + // All nodes except MediaObject may have an input + MediaNode * m_input; + + // Only MediaObject can have more than one output + QList<MediaNode *> m_outputs; }; + } } diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index b6f53ae..127edb4 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -44,20 +44,8 @@ using namespace Phonon::MMF; // Constructor / destructor //----------------------------------------------------------------------------- -MMF::VideoPlayer::VideoPlayer() - : m_wsSession(CCoeEnv::Static()->WsSession()) - , m_screenDevice(*CCoeEnv::Static()->ScreenDevice()) - , m_window(0) - , m_totalTime(0) - , m_pendingChanges(false) - , m_dsaActive(false) - , m_dsaWasActive(false) -{ - construct(); -} - -MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player) - : AbstractMediaPlayer(player) +MMF::VideoPlayer::VideoPlayer(MediaObject *parent, const AbstractPlayer *player) + : AbstractMediaPlayer(parent, player) , m_wsSession(CCoeEnv::Static()->WsSession()) , m_screenDevice(*CCoeEnv::Static()->ScreenDevice()) , m_window(0) @@ -78,22 +66,22 @@ void MMF::VideoPlayer::construct() const TInt priority = 0; const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone; - TRAPD(err, - m_player.reset(CVideoPlayerUtility::NewL + CVideoPlayerUtility *player = 0; + QT_TRAP_THROWING(player = CVideoPlayerUtility::NewL ( *this, priority, preference, m_wsSession, m_screenDevice, *m_window, m_videoRect, m_videoRect - )) + ) ); + m_player.reset(player); // CVideoPlayerUtility::NewL starts DSA m_dsaActive = true; - if (KErrNone != err) - changeState(ErrorState); + m_player->RegisterForVideoLoadingNotification(*this); TRACE_EXIT_0(); } @@ -109,6 +97,11 @@ MMF::VideoPlayer::~VideoPlayer() TRACE_EXIT_0(); } +CVideoPlayerUtility* MMF::VideoPlayer::nativePlayer() const +{ + return m_player.data(); +} + //----------------------------------------------------------------------------- // Public API //----------------------------------------------------------------------------- @@ -127,9 +120,9 @@ void MMF::VideoPlayer::doPause() TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi); TRAPD(err, m_player->PauseL()); - if (KErrNone != err) { + if (KErrNone != err && state() != ErrorState) { TRACE("PauseL error %d", err); - setError(NormalError); + setError(tr("Pause failed"), err); } } @@ -142,24 +135,10 @@ void MMF::VideoPlayer::doSeek(qint64 ms) { TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi); - bool wasPlaying = false; - if (state() == PlayingState) { - // The call to SetPositionL does not have any effect if playback is - // ongoing, so we pause before seeking. - doPause(); - wasPlaying = true; - } - TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000))); - if (KErrNone == err) { - if (wasPlaying) - doPlay(); - } - else { - TRACE("SetPositionL error %d", err); - setError(NormalError); - } + if(KErrNone != err) + setError(tr("Seek failed"), err); } int MMF::VideoPlayer::setDeviceVolume(int mmfVolume) @@ -174,6 +153,19 @@ int MMF::VideoPlayer::openFile(RFile& file) return err; } +int MMF::VideoPlayer::openUrl(const QString& url) +{ + TRAPD(err, m_player->OpenUrlL(qt_QString2TPtrC(url))); + return err; +} + +int MMF::VideoPlayer::bufferStatus() const +{ + int result = 0; + TRAP_IGNORE(m_player->GetVideoLoadingProgressL(result)); + return result; +} + void MMF::VideoPlayer::close() { m_player->Close(); @@ -200,7 +192,7 @@ qint64 MMF::VideoPlayer::currentTime() const // If we don't cast away constness here, we simply have to ignore // the error. - const_cast<VideoPlayer*>(this)->setError(NormalError); + const_cast<VideoPlayer*>(this)->setError(tr("Getting position failed"), err); } return result; @@ -226,7 +218,7 @@ void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError) if (KErrNone == aError) m_player->Prepare(); else - setError(NormalError); + setError(tr("Opening clip failed"), aError); TRACE_EXIT_0(); } @@ -252,7 +244,7 @@ void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError) emit totalTimeChanged(totalTime()); changeState(StoppedState); } else { - setError(NormalError); + setError(tr("Buffering clip failed"), err); } TRACE_EXIT_0(); @@ -277,7 +269,6 @@ void MMF::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError) TRACE_CONTEXT(VideoPlayer::MvpuoFrameReady, EVideoApi); TRACE_ENTRY("state %d error %d", state(), aError); - // TODO Q_UNUSED(aFrame); Q_UNUSED(aError); // suppress warnings in release builds @@ -289,8 +280,9 @@ void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError) TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi) TRACE_ENTRY("state %d error %d", state(), aError); - Q_UNUSED(aError); // suppress warnings in release builds - changeState(StoppedState); + // Call base class function which handles end of playback for both + // audio and video clips. + playbackComplete(aError); TRACE_EXIT_0(); } @@ -300,7 +292,6 @@ void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi); TRACE_ENTRY("state %d", state()); - // TODO Q_UNUSED(aEvent); TRACE_EXIT_0(); @@ -308,6 +299,21 @@ void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent) //----------------------------------------------------------------------------- +// MVideoLoadingObserver callbacks +//----------------------------------------------------------------------------- + +void MMF::VideoPlayer::MvloLoadingStarted() +{ + bufferingStarted(); +} + +void MMF::VideoPlayer::MvloLoadingComplete() +{ + bufferingComplete(); +} + + +//----------------------------------------------------------------------------- // Video window updates //----------------------------------------------------------------------------- @@ -412,7 +418,7 @@ void MMF::VideoPlayer::startDirectScreenAccess() if(KErrNone == err) m_dsaActive = true; else - setError(NormalError); + setError(tr("Video display error"), err); } } @@ -424,7 +430,7 @@ bool MMF::VideoPlayer::stopDirectScreenAccess() if(KErrNone == err) m_dsaActive = false; else - setError(NormalError); + setError(tr("Video display error"), err); } return dsaWasActive; } @@ -600,7 +606,7 @@ void MMF::VideoPlayer::applyVideoWindowChange() TRAPD(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (1) err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } if(KErrNone == err) { @@ -615,13 +621,13 @@ void MMF::VideoPlayer::applyVideoWindowChange() if (KErrNone != err) { TRACE("SetDisplayWindowL err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } else { m_dsaActive = true; TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (2) err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } } } diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index abb1da8..0253ab9 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -39,14 +39,17 @@ namespace MMF */ class VideoPlayer : public AbstractMediaPlayer , public MVideoPlayerUtilityObserver + , public MVideoLoadingObserver { Q_OBJECT public: - VideoPlayer(); - explicit VideoPlayer(const AbstractPlayer& player); + VideoPlayer(MediaObject *parent = 0, const AbstractPlayer *player = 0); virtual ~VideoPlayer(); + typedef CVideoPlayerUtility NativePlayer; + NativePlayer *nativePlayer() const; + // AbstractPlayer virtual void doPlay(); virtual void doPause(); @@ -54,6 +57,8 @@ public: virtual void doSeek(qint64 milliseconds); virtual int setDeviceVolume(int mmfVolume); virtual int openFile(RFile& file); + virtual int openUrl(const QString& url); + virtual int bufferStatus() const; virtual void close(); // MediaObjectInterface @@ -61,12 +66,12 @@ public: virtual qint64 currentTime() const; virtual qint64 totalTime() const; - // MVideoPlayerUtilityObserver - virtual void MvpuoOpenComplete(TInt aError); - virtual void MvpuoPrepareComplete(TInt aError); - virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError); - virtual void MvpuoPlayComplete(TInt aError); - virtual void MvpuoEvent(const TMMFEvent &aEvent); + // AbstractPlayer + virtual void videoOutputChanged(); + + // AbstractMediaPlayer + virtual int numberOfMetaDataEntries() const; + virtual QPair<QString, QString> metaDataEntry(int index) const; public Q_SLOTS: void videoWindowChanged(); @@ -80,12 +85,8 @@ private: void doPrepareCompleteL(TInt aError); - // AbstractPlayer - virtual void videoOutputChanged(); - void getVideoWindow(); void initVideoOutput(); - void updateVideoRect(); void applyPendingChanges(); @@ -94,12 +95,20 @@ private: void startDirectScreenAccess(); bool stopDirectScreenAccess(); - // AbstractMediaPlayer - virtual int numberOfMetaDataEntries() const; - virtual QPair<QString, QString> metaDataEntry(int index) const; +private: + // MVideoPlayerUtilityObserver + virtual void MvpuoOpenComplete(TInt aError); + virtual void MvpuoPrepareComplete(TInt aError); + virtual void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError); + virtual void MvpuoPlayComplete(TInt aError); + virtual void MvpuoEvent(const TMMFEvent &aEvent); + + // MVideoLoadingObserver + virtual void MvloLoadingStarted(); + virtual void MvloLoadingComplete(); private: - QScopedPointer<CVideoPlayerUtility> m_player; + QScopedPointer<NativePlayer> m_player; // Not owned RWsSession& m_wsSession; diff --git a/src/3rdparty/phonon/mmf/objectdump.cpp b/src/3rdparty/phonon/mmf/objectdump.cpp index 3d10be4..778cde9 100644 --- a/src/3rdparty/phonon/mmf/objectdump.cpp +++ b/src/3rdparty/phonon/mmf/objectdump.cpp @@ -390,7 +390,7 @@ void QVisitorPrivate::dumpNode // No annotations - just dump the object pointer const bool isNodeLine = true; QByteArray buffer = branchBuffer(branches, isNodeLine, isLastChild); - qDebug() << 0; // TODO + qDebug() << 0; } else { // Dump annotations diff --git a/src/3rdparty/phonon/mmf/utils.cpp b/src/3rdparty/phonon/mmf/utils.cpp index d728fcf..2d17bd2 100644 --- a/src/3rdparty/phonon/mmf/utils.cpp +++ b/src/3rdparty/phonon/mmf/utils.cpp @@ -18,6 +18,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "utils.h" #include <e32std.h> +#include <mmf/common/mmferrors.h> QT_BEGIN_NAMESPACE @@ -69,6 +70,101 @@ MMF::MediaType MMF::Utils::mimeTypeToMediaType(const TDesC& mimeType) return result; } +QString MMF::Utils::symbianErrorToString(int errorCode) +{ + /** + * Here we translate only the error codes which are likely to be + * meaningful to the user. For example, when an error occurs + * during opening of a media file, displaying "not found" or + * "permission denied" is informative. On the other hand, + * differentiating between KErrGeneral and KErrArgument at the UI + * level does not make sense. + */ + switch (errorCode) + { + // System-wide errors + case KErrNone: + return tr("No error"); + case KErrNotFound: + return tr("Not found"); + case KErrNoMemory: + return tr("Out of memory"); + case KErrNotSupported: + return tr("Not supported"); + case KErrOverflow: + return tr("Overflow"); + case KErrUnderflow: + return tr("Underflow"); + case KErrAlreadyExists: + return tr("Already exists"); + case KErrPathNotFound: + return tr("Path not found"); + case KErrInUse: + return tr("In use"); + case KErrNotReady: + return tr("Not ready"); + case KErrAccessDenied: + return tr("Access denied"); + case KErrCouldNotConnect: + return tr("Could not connect"); + case KErrDisconnected: + return tr("Disconnected"); + case KErrPermissionDenied: + return tr("Permission denied"); + + // Multimedia framework errors + case KErrMMNotEnoughBandwidth: + return tr("Insufficient bandwidth"); + case KErrMMSocketServiceNotFound: + case KErrMMServerSocket: + return tr("Network unavailable"); + case KErrMMNetworkRead: + case KErrMMNetworkWrite: + case KErrMMUDPReceive: + return tr("Network communication error"); + case KErrMMServerNotSupported: + return tr("Streaming not supported"); + case KErrMMServerAlert: + return tr("Server alert"); + case KErrMMInvalidProtocol: + return tr("Invalid protocol"); + case KErrMMInvalidURL: + return tr("Invalid URL"); + case KErrMMMulticast: + return tr("Multicast error"); + case KErrMMProxyServer: + case KErrMMProxyServerConnect: + return tr("Proxy server error"); + case KErrMMProxyServerNotSupported: + return tr("Proxy server not supported"); + case KErrMMAudioDevice: + return tr("Audio output error"); + case KErrMMVideoDevice: + return tr("Video output error"); + case KErrMMDecoder: + return tr("Decoder error"); + case KErrMMPartialPlayback: + return tr("Audio or video components could not be played"); + case KErrMMDRMNotAuthorized: + return tr("DRM error"); + + /* + // We don't use QoS settings + case KErrMMQosLowBandwidth: + case KErrMMQosUnsupportedTrafficClass: + case KErrMMQosPoorTrafficClass: + case KErrMMQosUnsupportedParameters: + case KErrMMQosPoorParameters: + case KErrMMQosNotSupported: + */ + + // Catch-all for errors other than those above + default: + { + return tr("Unknown error (%1)").arg(errorCode); + } + } +} #ifndef QT_NO_DEBUG diff --git a/src/3rdparty/phonon/mmf/utils.h b/src/3rdparty/phonon/mmf/utils.h index 7e363e8..56ccafc 100644 --- a/src/3rdparty/phonon/mmf/utils.h +++ b/src/3rdparty/phonon/mmf/utils.h @@ -21,7 +21,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <private/qcore_symbian_p.h> #include <e32debug.h> // for RDebug - +#include <QtCore/QCoreApplication> // for Q_DECLARE_TR_FUNCTIONS #include <QColor> #include "defs.h" @@ -38,35 +38,44 @@ namespace MMF enum PanicCode { InvalidStatePanic = 1, InvalidMediaTypePanic = 2, - InvalidBackendInterfaceClass = 3 + InvalidBackendInterfaceClass = 3, + AudioUtilityUrlNotSupported = 4 }; -namespace Utils +class Utils { + Q_DECLARE_TR_FUNCTIONS(Utils) + +public: /** * Raise a fatal exception */ -void panic(PanicCode code); +static void panic(PanicCode code); /** * Determines whether the provided MIME type is an audio or video * type. If it is neither, the function returns MediaTypeUnknown. */ -MediaType mimeTypeToMediaType(const TDesC& mimeType); +static MediaType mimeTypeToMediaType(const TDesC& mimeType); + +/** + * Translates a Symbian error code into a user-readable string. + */ +static QString symbianErrorToString(int errorCode); #ifndef QT_NO_DEBUG /** * Retrieve color of specified pixel from the screen. */ -QColor getScreenPixel(const QPoint& pos); +static QColor getScreenPixel(const QPoint& pos); /** * Samples a small number of pixels from the screen, and dumps their * colors to the debug log. */ -void dumpScreenPixelSample(); +static void dumpScreenPixelSample(); #endif -} +}; /** * Available trace categories; diff --git a/src/3rdparty/phonon/mmf/videowidget.cpp b/src/3rdparty/phonon/mmf/videowidget.cpp index bd22307..bc9acfd 100644 --- a/src/3rdparty/phonon/mmf/videowidget.cpp +++ b/src/3rdparty/phonon/mmf/videowidget.cpp @@ -157,10 +157,18 @@ QWidget* MMF::VideoWidget::widget() return m_videoOutput.data(); } -bool MMF::VideoWidget::activateOnMediaObject(MediaObject *mo) +//----------------------------------------------------------------------------- +// MediaNode +//----------------------------------------------------------------------------- + +void MMF::VideoWidget::connectMediaObject(MediaObject *mediaObject) +{ + mediaObject->setVideoOutput(m_videoOutput.data()); +} + +void MMF::VideoWidget::disconnectMediaObject(MediaObject *mediaObject) { - mo->setVideoOutput(m_videoOutput.data()); - return true; + mediaObject->setVideoOutput(0); } QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h index 2f0978b..a876748 100644 --- a/src/3rdparty/phonon/mmf/videowidget.h +++ b/src/3rdparty/phonon/mmf/videowidget.h @@ -61,7 +61,9 @@ public: virtual QWidget *widget(); protected: - virtual bool activateOnMediaObject(MediaObject *mo); + // MediaNode + void connectMediaObject(MediaObject *mediaObject); + void disconnectMediaObject(MediaObject *mediaObject); private: QScopedPointer<VideoOutput> m_videoOutput; diff --git a/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp b/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp index afde7ce..3785bab 100644 --- a/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/API/JSClassRef.cpp @@ -61,8 +61,8 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (const JSStaticValue* staticValue = definition->staticValues) { m_staticValues = new OpaqueJSClassStaticValuesTable(); while (staticValue->name) { - m_staticValues->add(UString::Rep::createFromUTF8(staticValue->name), - new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes)); + StaticValueEntry* e = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes); + m_staticValues->add(UString::Rep::createFromUTF8(staticValue->name), e); ++staticValue; } } @@ -70,8 +70,8 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (const JSStaticFunction* staticFunction = definition->staticFunctions) { m_staticFunctions = new OpaqueJSClassStaticFunctionsTable(); while (staticFunction->name) { - m_staticFunctions->add(UString::Rep::createFromUTF8(staticFunction->name), - new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes)); + StaticFunctionEntry* e = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes); + m_staticFunctions->add(UString::Rep::createFromUTF8(staticFunction->name), e); ++staticFunction; } } @@ -149,8 +149,9 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end(); for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) { ASSERT(!it->first->identifierTable()); - staticValues->add(UString::Rep::createCopying(it->first->data(), it->first->size()), - new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes)); + StaticValueEntry* e = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes); + staticValues->add(UString::Rep::createCopying(it->first->data(), it->first->size()), e); + } } else @@ -162,8 +163,8 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end(); for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) { ASSERT(!it->first->identifierTable()); - staticFunctions->add(UString::Rep::createCopying(it->first->data(), it->first->size()), - new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes)); + StaticFunctionEntry* e = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes); + staticFunctions->add(UString::Rep::createCopying(it->first->data(), it->first->size()), e); } } else diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 1694966..e292418 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,26 @@ +2010-01-07 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by NOBODY (OOPS!). + + RVCT compiler with "-Otime -O3" optimization tries to optimize out + inline new'ed pointers that are passed as arguments. + Proposed patch assigns new'ed pointer explicitly outside function call. + + * API/JSClassRef.cpp: + (OpaqueJSClass::OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + +2010-01-07 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by NOBODY (OOPS!). + + Added time-based optimization and increased optimization level to O3, + conditionally for COMPILER(RVCT), + for increasing performance of JavaScript execution. + (Default settings are Ospace and O2) + + * runtime/Structure.h: + 2009-11-19 Thiago Macieira <thiago.macieira@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h index f355c53..ecdd997 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Structure.h @@ -45,6 +45,12 @@ #define DUMP_PROPERTYMAP_STATS 0 #endif +#if COMPILER(RVCT) +#pragma arm +#pragma Otime +#pragma O3 +#endif + namespace JSC { class MarkStack; diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 6b107cd..0b88429 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - b217cdfedc7b5e7581325bda718192247f03dd5d + 99ccc1c3e4db5354246720f9b9aa3d282e64497d diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index acc8a6a..516fadd 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,33 @@ +2010-01-07 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Allow the application to override online/offline network status + https://bugs.webkit.org/show_bug.cgi?id=32684 + + Added API to NetworkStateNotifier for forcing network status. + + * platform/network/NetworkStateNotifier.h: + * platform/network/qt/NetworkStateNotifierPrivate.h: + * platform/network/qt/NetworkStateNotifierQt.cpp: + (WebCore::NetworkStateNotifierPrivate::NetworkStateNotifierPrivate): + (WebCore::NetworkStateNotifierPrivate::onlineStateChanged): + (WebCore::NetworkStateNotifierPrivate::networkAccessPermissionChanged): + (WebCore::NetworkStateNotifier::updateState): + (WebCore::NetworkStateNotifier::NetworkStateNotifier): + (WebCore::NetworkStateNotifier::setNetworkAccessAllowed): + +2010-01-07 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Fix linkage against Qt mobility API bearer management module + + Use the documented .pro file syntax to link against the correct + library and (more importantly) get the include paths correct. + + * WebCore.pro: + 2010-01-07 Laszlo Gombos <laszlo.1.gombos@nokia.com> Reviewed by NOBODY (OOPS!). diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index be64e3b..3eba696 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -2876,8 +2876,8 @@ contains(DEFINES, ENABLE_QT_BEARER=1) { SOURCES += \ platform/network/qt/NetworkStateNotifierQt.cpp - LIBS += -lQtBearer - + CONFIG += mobility + MOBILITY += bearer } contains(DEFINES, ENABLE_SVG=1) { diff --git a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h index f8c5654..700a062 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h +++ b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h @@ -56,7 +56,11 @@ public: void setNetworkStateChangedFunction(void (*)()); bool onLine() const { return m_isOnLine; } - + +#if (PLATFORM(QT) && ENABLE(QT_BEARER)) + void setNetworkAccessAllowed(bool); +#endif + private: bool m_isOnLine; void (*m_networkStateChangedFunction)(); diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h index 7af6392..536b06a 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h @@ -37,10 +37,12 @@ public: ~NetworkStateNotifierPrivate(); public slots: void onlineStateChanged(bool); + void networkAccessPermissionChanged(bool); public: QtMobility::QNetworkConfigurationManager* m_configurationManager; bool m_online; + bool m_networkAccessAllowed; NetworkStateNotifier* m_notifier; }; diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp index f74398b..e694264 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp @@ -30,6 +30,7 @@ namespace WebCore { NetworkStateNotifierPrivate::NetworkStateNotifierPrivate(NetworkStateNotifier* notifier) : m_configurationManager(new QNetworkConfigurationManager()) , m_online(m_configurationManager->isOnline()) + , m_networkAccessAllowed(true) , m_notifier(notifier) { Q_ASSERT(notifier); @@ -42,7 +43,18 @@ void NetworkStateNotifierPrivate::onlineStateChanged(bool isOnline) return; m_online = isOnline; - m_notifier->updateState(); + if (m_networkAccessAllowed) + m_notifier->updateState(); +} + +void NetworkStateNotifierPrivate::networkAccessPermissionChanged(bool isAllowed) +{ + if (isAllowed == m_networkAccessAllowed) + return; + + m_networkAccessAllowed = isAllowed; + if (m_online) + m_notifier->updateState(); } NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate() @@ -52,10 +64,10 @@ NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate() void NetworkStateNotifier::updateState() { - if (m_isOnLine == p->m_online) + if (m_isOnLine == (p->m_online && p->m_networkAccessAllowed)) return; - m_isOnLine = p->m_online; + m_isOnLine = p->m_online && p->m_networkAccessAllowed; if (m_networkStateChangedFunction) m_networkStateChangedFunction(); } @@ -65,7 +77,12 @@ NetworkStateNotifier::NetworkStateNotifier() , m_networkStateChangedFunction(0) { p = new NetworkStateNotifierPrivate(this); - m_isOnLine = p->m_online; + m_isOnLine = p->m_online && p->m_networkAccessAllowed; +} + +void NetworkStateNotifier::setNetworkAccessAllowed(bool isAllowed) +{ + p->networkAccessPermissionChanged(isAllowed); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp index b637d04..79ef16f 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp @@ -47,6 +47,17 @@ #include <QUrl> #include <QFileInfo> +#if ENABLE(QT_BEARER) +#include "NetworkStateNotifier.h" +#endif + +void QWEBKIT_EXPORT qt_networkAccessAllowed(bool isAllowed) +{ +#if ENABLE(QT_BEARER) + WebCore::networkStateNotifier().setNetworkAccessAllowed(isAllowed); +#endif +} + class QWebSettingsPrivate { public: QWebSettingsPrivate(WebCore::Settings* wcSettings = 0) diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index d7c3c52..31fad69 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,17 @@ +2010-01-07 Yael Aharon <yael.aharon@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Allow the application to override online/offline network status + https://bugs.webkit.org/show_bug.cgi?id=32684 + + Add a setting so that applications can overide the network status. + Applications that use this setting still need to block network access + through QNAM. + + * Api/qwebsettings.cpp: + (qt_networkAccessAllowed): + 2010-01-07 Yongjun Zhang <yongjun.zhang@nokia.com>, Laszlo Gombos <laszlo.1.gombos@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index d84bb80..38e1886 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -511,6 +511,7 @@ public: AA_MacPluginApplication = 5, AA_DontUseNativeMenuBar = 6, AA_MacDontSwapCtrlAndMeta = 7, + AA_S60DontConstructApplicationPanes = 8, // Add new attributes before this line AA_AttributeCount diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index f0c6820..9ef2101 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -134,7 +134,6 @@ \value AA_DontShowIconsInMenus Actions with the Icon property won't be shown in any menus unless specifically set by the QAction::iconVisibleInMenu property. - Menus that are currently open or menus already created in the native Mac OS X menubar \e{may not} pick up a change in this attribute. Changes in the QAction::iconVisibleInMenu property will always be picked up. @@ -164,6 +163,12 @@ Command+C on the keyboard regardless of the value set, though what is output for QKeySequence::toString(QKeySequence::PortableText) will be different). + \value AA_S60DontConstructApplicationPanes Stops Qt from initializing the S60 status + pane and softkey pane on Symbian. This is useful to save memory and reduce + startup time for applications that will run in fullscreen mode during their + whole lifetime. This attribute must be set before QApplication is + constructed. + \omitvalue AA_AttributeCount */ diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index d8b6b00..bec0075 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1419,22 +1419,20 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const #if !defined(QT_NO_LIBRARY) if((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { - PSID pOwner = 0; - PSID pGroup = 0; - PACL pDacl; - PSECURITY_DESCRIPTOR pSD; - ACCESS_MASK access_mask; - - enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 }; resolveLibs(); if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) { + enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 }; QString fname = filePath.endsWith(QLatin1String(".lnk")) ? readLink(filePath) : filePath; + PSID pOwner = 0; + PSID pGroup = 0; + PACL pDacl; + PSECURITY_DESCRIPTOR pSD; DWORD res = ptrGetNamedSecurityInfoW((wchar_t*)fname.utf16(), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &pOwner, &pGroup, &pDacl, 0, &pSD); - if(res == ERROR_SUCCESS) { + ACCESS_MASK access_mask; TRUSTEE_W trustee; { //user if(ptrGetEffectiveRightsFromAclW(pDacl, ¤tUserTrusteeW, &access_mask) != ERROR_SUCCESS) @@ -1720,40 +1718,51 @@ uint QFSFileEngine::ownerId(FileOwner /*own*/) const QString QFSFileEngine::owner(FileOwner own) const { + QString name; #if !defined(QT_NO_LIBRARY) Q_D(const QFSFileEngine); - if((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { - PSID pOwner = 0; - PSECURITY_DESCRIPTOR pSD; - QString name; - QFSFileEnginePrivate::resolveLibs(); - - if(ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { - if(ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT, - own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, - NULL, &pOwner, NULL, NULL, &pSD) == ERROR_SUCCESS) { - DWORD lowner = 0, ldomain = 0; - SID_NAME_USE use; - // First call, to determine size of the strings (with '\0'). - ptrLookupAccountSidW(NULL, pOwner, NULL, &lowner, NULL, &ldomain, (SID_NAME_USE*)&use); - wchar_t *owner = new wchar_t[lowner]; - wchar_t *domain = new wchar_t[ldomain]; - // Second call, size is without '\0' - if(ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner, &lowner, - (LPWSTR)domain, &ldomain, (SID_NAME_USE*)&use)) { - name = QString::fromUtf16((ushort*)owner); - } - LocalFree(pSD); - delete [] owner; - delete [] domain; - } - } - return name; + + if ((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) { + QFSFileEnginePrivate::resolveLibs(); + if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) { + PSID pOwner = 0; + PSECURITY_DESCRIPTOR pSD; + if (ptrGetNamedSecurityInfoW((wchar_t*)d->filePath.utf16(), SE_FILE_OBJECT, + own == OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION, + own == OwnerUser ? &pOwner : 0, own == OwnerGroup ? &pOwner : 0, + 0, 0, &pSD) == ERROR_SUCCESS) { + DWORD lowner = 64; + DWORD ldomain = 64; + QVarLengthArray<wchar_t, 64> owner(lowner); + QVarLengthArray<wchar_t, 64> domain(ldomain); + SID_NAME_USE use = SidTypeUnknown; + // First call, to determine size of the strings (with '\0'). + if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, + (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + if (lowner > (DWORD)owner.size()) + owner.resize(lowner); + if (ldomain > (DWORD)domain.size()) + domain.resize(ldomain); + // Second call, try on resized buf-s + if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner, + (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) { + lowner = 0; + } + } else { + lowner = 0; + } + } + if (lowner != 0) + name = QString::fromWCharArray(owner.data()); + LocalFree(pSD); + } + } } #else Q_UNUSED(own); #endif - return QString(); + return name; } bool QFSFileEngine::setPermissions(uint perms) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 1ba5e3f..74e5f74 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -350,8 +350,8 @@ public: }; int stateFlags; - QByteArray encodedNormalized; - const QByteArray & normalized(); + mutable QByteArray encodedNormalized; + const QByteArray & normalized() const; mutable QUrlErrorInfo errorInfo; QString createErrorString(); @@ -3850,6 +3850,9 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const if (!QURL_HASFLAG(stateFlags, Parsed)) parse(); else ensureEncodedParts(); + if (options==0x100) // private - see qHash(QUrl) + return normalized(); + QByteArray url; if (!(options & QUrl::RemoveScheme) && !scheme.isEmpty()) { @@ -3920,12 +3923,13 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const #define qToLower(ch) (((ch|32) >= 'a' && (ch|32) <= 'z') ? (ch|32) : ch) -const QByteArray &QUrlPrivate::normalized() +const QByteArray &QUrlPrivate::normalized() const { if (QURL_HASFLAG(stateFlags, QUrlPrivate::Normalized)) return encodedNormalized; - QURL_SETFLAG(stateFlags, QUrlPrivate::Normalized); + QUrlPrivate *that = const_cast<QUrlPrivate *>(this); + QURL_SETFLAG(that->stateFlags, QUrlPrivate::Normalized); QUrlPrivate tmp = *this; tmp.scheme = tmp.scheme.toLower(); diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index c4a84fc..d2fbf5a 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -903,8 +903,8 @@ QByteArray &QByteArray::operator=(const char *str) The last byte in the byte array is at position size() - 1. In addition, QByteArray ensures that the byte at position size() is always '\\0', so that you can use the return value of data() and - constData() as arguments to functions that expect - '\\0'-terminated strings. + constData() as arguments to functions that expect '\\0'-terminated + strings. Example: \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 6 @@ -997,7 +997,9 @@ QByteArray &QByteArray::operator=(const char *str) Returns a pointer to the data stored in the byte array. The pointer can be used to access and modify the bytes that compose - the array. The data is '\\0'-terminated. + the array. The data is '\\0'-terminated, i.e. the number of + bytes in the returned character string is size() + 1 for the + '\\0' terminator. Example: \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 8 @@ -1009,6 +1011,16 @@ QByteArray &QByteArray::operator=(const char *str) This function is mostly useful to pass a byte array to a function that accepts a \c{const char *}. + The following example makes a copy of the char* returned by + data(), but it will corrupt the heap and cause a crash because it + does not allocate a byte for the '\\0' at the end: + + \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 46 + + This one allocates the correct amount of space: + + \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 47 + Note: A QByteArray can store any byte values including '\\0's, but most functions that take \c{char *} arguments assume that the data ends at the first '\\0' they encounter. @@ -1591,8 +1603,9 @@ QByteArray& QByteArray::append(const char *str) array and returns a reference to this byte array. If \a len is negative, the length of the string will be determined - automatically using qstrlen(). If \a len is zero or the length of the - string is zero, nothing will be appended to the byte array. + automatically using qstrlen(). If \a len is zero or \a str is + null, nothing is appended to the byte array. Ensure that \a len is + \e not longer than \a str. */ QByteArray &QByteArray::append(const char *str, int len) diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index f1415f1..3650051 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -888,7 +888,14 @@ bool QDialog::s60AdjustedPosition() if (doS60Positioning) { // naive way to deduce screen orientation if (S60->screenHeightInPixels > S60->screenWidthInPixels) { - p.setY(S60->screenHeightInPixels-height()-qt_TSize2QSize(S60->buttonGroupContainer()->Size()).height()); + int cbaHeight; + const CEikButtonGroupContainer* bgContainer = S60->buttonGroupContainer(); + if (!bgContainer) { + cbaHeight = 0; + } else { + cbaHeight = qt_TSize2QSize(bgContainer->Size()).height(); + } + p.setY(S60->screenHeightInPixels-height()-cbaHeight); p.setX(0); } else { const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent); diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/gui/dialogs/qfilesystemmodel_p.h index 93a71e1..6c85a7c 100644 --- a/src/gui/dialogs/qfilesystemmodel_p.h +++ b/src/gui/dialogs/qfilesystemmodel_p.h @@ -238,15 +238,15 @@ public: void sortChildren(int column, const QModelIndex &parent); inline int translateVisibleLocation(QFileSystemNode *parent, int row) const { - if (sortOrder == Qt::AscendingOrder) - return row; - if (parent->dirtyChildrenIndex == -1 || row < parent->dirtyChildrenIndex) - if (parent->dirtyChildrenIndex != -1) - return parent->dirtyChildrenIndex - row - 1; - else + if (sortOrder != Qt::AscendingOrder) { + if (parent->dirtyChildrenIndex == -1) return parent->visibleChildren.count() - row - 1; - else - return row; + + if (row < parent->dirtyChildrenIndex) + return parent->dirtyChildrenIndex - row - 1; + } + + return row; } inline static QString myComputer() { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 034d1f7..5c6a8ae 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -292,6 +292,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() processDirtyItemsEmitted(false), selectionChanging(0), needSortTopLevelItems(true), + unpolishedItemsModified(true), holesInTopLevelSiblingIndex(false), topLevelSequentialOrdering(true), scenePosDescendantsUpdatePending(false), @@ -428,12 +429,12 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) */ void QGraphicsScenePrivate::_q_polishItems() { - QSet<QGraphicsItem *>::Iterator it; + QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin(); const QVariant booleanTrueVariant(true); while (!unpolishedItems.isEmpty()) { - it = unpolishedItems.begin(); QGraphicsItem *item = *it; - unpolishedItems.erase(it); + it = unpolishedItems.erase(it); + unpolishedItemsModified = false; if (!item->d_ptr->explicitlyHidden) { item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); @@ -442,6 +443,8 @@ void QGraphicsScenePrivate::_q_polishItems() QEvent event(QEvent::Polish); QApplication::sendEvent((QGraphicsWidget *)item, &event); } + if (unpolishedItemsModified) + it = unpolishedItems.begin(); } } @@ -636,6 +639,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) hoverItems.removeAll(item); cachedItemsUnderMouse.removeAll(item); unpolishedItems.remove(item); + unpolishedItemsModified = true; resetDirtyItem(item); //We remove all references of item from the sceneEventFilter arrays @@ -2578,9 +2582,10 @@ void QGraphicsScene::addItem(QGraphicsItem *item) item->d_ptr->resolveFont(d->font.resolve()); item->d_ptr->resolvePalette(d->palette.resolve()); - if (d->unpolishedItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); - d->unpolishedItems.insert(item); + if (d->unpolishedItems.isEmpty()) + QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); + d->unpolishedItems.insert(item); + d->unpolishedItemsModified = true; // Reenable selectionChanged() for individual items --d->selectionChanging; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 26beb5a..d10811c 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -111,6 +111,7 @@ public: QSet<QGraphicsItem *> unpolishedItems; QList<QGraphicsItem *> topLevelItems; bool needSortTopLevelItems; + bool unpolishedItemsModified; bool holesInTopLevelSiblingIndex; bool topLevelSequentialOrdering; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 6f0de2b..674d5da 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -357,7 +357,9 @@ QPixmap QPixmap::copy(const QRect &rect) const if (isNull()) return QPixmap(); - const QRect r = rect.isEmpty() ? QRect(0, 0, width(), height()) : rect; + QRect r(0, 0, width(), height()); + if (!rect.isEmpty()) + r = r.intersected(rect); QPixmapData *d = data->createCompatiblePixmapData(); d->copy(data.data(), r); diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index e6c3775..d5406cb 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -855,7 +855,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); - const uchar *data = image.bits(); + const uchar *data = (static_cast<const QImage *>(&image))->bits(); int bpl = image.bytesPerLine(); row_pointers = new png_bytep[height]; uint y; diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index bbeb8b2..e9643aa 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -3064,6 +3064,8 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons { Q_Q(const QTreeView); QPixmap pixmap(rect.size()); + if (rect.size().isEmpty()) + return pixmap; pixmap.fill(Qt::transparent); //the base might not be opaque, and we don't want uninitialized pixels. QPainter painter(&pixmap); painter.fillRect(QRect(QPoint(0,0), rect.size()), q->palette().base()); diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 9b64343..3ee0a71 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -930,7 +930,7 @@ void QSymbianControl::PositionChanged() void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) { - if (m_ignoreFocusChanged) + if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop) return; // Popups never get focused, but still receive the FocusChanged when they are hidden. diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 9950697..c14798a 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -508,6 +508,13 @@ extern "C" { } else { [self setNeedsDisplay:YES]; } + + // Make sure the opengl context is updated on resize. + if (0 && qwidgetprivate->isGLWidget) { + qwidgetprivate->needWindowChange = true; + QEvent event(QEvent::MacGLWindowChange); + qApp->sendEvent(qwidget, &event); + } } - (void)drawRect:(NSRect)aRect diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index c04cbb4..354f90b 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -211,7 +211,8 @@ bool QSoftKeyManager::event(QEvent *e) void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys) { // lets not update softkeys if s60 native dialog or menu is shown - if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) + if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes) + || CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) return; CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer(); diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp index 70534af..068ca0c 100644 --- a/src/gui/painting/qpaintengine_s60.cpp +++ b/src/gui/painting/qpaintengine_s60.cpp @@ -47,18 +47,25 @@ QT_BEGIN_NAMESPACE class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate { public: - QS60PaintEnginePrivate(QS60PaintEngine *engine) { Q_UNUSED(engine); } + QS60PaintEnginePrivate() {} }; QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PixmapData *data) - : QRasterPaintEngine(*(new QS60PaintEnginePrivate(this)), device), pixmapData(data) + : QRasterPaintEngine(*(new QS60PaintEnginePrivate), device), pixmapData(data) { } bool QS60PaintEngine::begin(QPaintDevice *device) { + Q_D(QS60PaintEngine); + pixmapData->beginDataAccess(); - return QRasterPaintEngine::begin(device); + bool ret = QRasterPaintEngine::begin(device); + // Make sure QPaintEngine::paintDevice() returns the proper device. + // QRasterPaintEngine changes pdev to QImage in case of RasterClass QPixmapData + // which is incorrect in Symbian. + d->pdev = device; + return ret; } bool QS60PaintEngine::end() diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index ea0ab40..7b7f325 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -47,6 +47,10 @@ #include "private/qnativeimage_p.h" #include "private/qfontengine_ft_p.h" +#ifndef QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH +#define QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH 256 +#endif + QT_BEGIN_NAMESPACE // #define CACHE_DEBUG @@ -112,7 +116,7 @@ void QTextureGlyphCache::populate(const QTextItemInt &ti, rowHeight += margin * 2; if (isNull()) - createCache(256, rowHeight); + createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, rowHeight); // now actually use the coords and paint the wanted glyps into cache. QHash<glyph_t, Coord>::iterator iter = listItemCoordinates.begin(); diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp index 80b730b..012985b 100644 --- a/src/gui/s60framework/qs60mainappui.cpp +++ b/src/gui/s60framework/qs60mainappui.cpp @@ -104,10 +104,16 @@ void QS60MainAppUi::ConstructL() // ENoAppResourceFile and ENonStandardResourceFile makes UI to work without // resource files in most SDKs. S60 3rd FP1 public seems to require resource file // even these flags are defined - BaseConstructL(CAknAppUi::EAknEnableSkin); + TInt flags = CAknAppUi::EAknEnableSkin; + if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) { + flags |= CAknAppUi::ENoScreenFurniture | CAknAppUi::ENonStandardResourceFile; + } + BaseConstructL(flags); - CEikButtonGroupContainer* nativeContainer = Cba(); - nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); + if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) { + CEikButtonGroupContainer* nativeContainer = Cba(); + nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS); + } } /*! diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 41efaa3..abb9e1e 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -1736,7 +1736,11 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom case CC_SpinBox: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { - GtkWidget *gtkSpinButton = d->gtkWidget(QLS("GtkSpinButton")); + + GtkWidget *gtkSpinButton = d->gtkWidget( + spinBox->buttonSymbols == QAbstractSpinBox::NoButtons ? + QLS("GtkEntry") : + QLS("GtkSpinButton")); bool isEnabled = (spinBox->state & State_Enabled); bool hover = isEnabled && (spinBox->state & State_MouseOver); bool sunken = (spinBox->state & State_Sunken); @@ -1744,32 +1748,35 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown); bool reverse = (spinBox->direction == Qt::RightToLeft); - //### Move this to subControlRect - QRect upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget); - upRect.setTop(option->rect.top()); + QRect editArea = option->rect; + QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget); + QRect upRect, downRect, buttonRect; + if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) { + upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget); + downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget); - if (reverse) - upRect.setLeft(option->rect.left()); - else - upRect.setRight(option->rect.right()); + //### Move this to subControlRect + upRect.setTop(option->rect.top()); - QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget); - QRect downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget); - downRect.setBottom(option->rect.bottom()); + if (reverse) + upRect.setLeft(option->rect.left()); + else + upRect.setRight(option->rect.right()); - if (reverse) - downRect.setLeft(option->rect.left()); - else - downRect.setRight(option->rect.right()); + downRect.setBottom(option->rect.bottom()); - QRect buttonRect = upRect | downRect; - QRect editArea = option->rect; + if (reverse) + downRect.setLeft(option->rect.left()); + else + downRect.setRight(option->rect.right()); - if (reverse) - editArea.setLeft(upRect.right()); - else - editArea.setRight(upRect.left()); + buttonRect = upRect | downRect; + if (reverse) + editArea.setLeft(upRect.right()); + else + editArea.setRight(upRect.left()); + } if (spinBox->frame) { GtkShadowType shadow = GTK_SHADOW_OUT; GtkStateType state = gtkPainter.gtkState(option); @@ -1803,29 +1810,31 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, style, key); gtkPainter.paintShadow(gtkSpinButton, "entry", editArea, state, GTK_SHADOW_IN, gtkSpinButton->style, key); - gtkPainter.paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key); - - upRect.setSize(downRect.size()); - if (!(option->state & State_Enabled)) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); - else if (upIsActive && sunken) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); - else if (upIsActive && hover) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); - else - gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); - - if (!(option->state & State_Enabled)) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); - else if (downIsActive && sunken) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); - else if (downIsActive && hover) - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); - else - gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); + if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) { + gtkPainter.paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key); + + upRect.setSize(downRect.size()); + if (!(option->state & State_Enabled)) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); + else if (upIsActive && sunken) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); + else if (upIsActive && hover) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); + else + gtkPainter.paintBox( gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); + + if (!(option->state & State_Enabled)) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key); + else if (downIsActive && sunken) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key); + else if (downIsActive && hover) + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key); + else + gtkPainter.paintBox( gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key); - if (option->state & State_HasFocus) - GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); + if (option->state & State_HasFocus) + GTK_WIDGET_UNSET_FLAGS(gtkSpinButton, GTK_HAS_FOCUS); + } } if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) { @@ -1850,7 +1859,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom painter->drawLine(centerX - 2, centerY, centerX + 2, centerY); } - } else { + } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows) { int size = d->getSpinboxArrowSize(); int w = size / 2 - 1; w -= w % 2 - 1; // force odd @@ -2495,7 +2504,6 @@ void QGtkStyle::drawControl(ControlElement element, const int windowsItemHMargin = 3; // menu item hor text margin const int windowsItemVMargin = 26; // menu item ver text margin const int windowsRightBorder = 15; // right border on windows - GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu")); GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")) : d->gtkWidget(QLS("GtkMenu.GtkMenuItem")); @@ -2509,6 +2517,7 @@ void QGtkStyle::drawControl(ControlElement element, gboolean wide_separators = 0; gint separator_height = 0; guint horizontal_padding = 3; + QRect separatorRect = option->rect; if (!d->gtk_check_version(2, 10, 0)) { d->gtk_widget_style_get(gtkMenuSeparator, "wide-separators", &wide_separators, @@ -2516,13 +2525,16 @@ void QGtkStyle::drawControl(ControlElement element, "horizontal-padding", &horizontal_padding, NULL); } + separatorRect.setHeight(option->rect.height() - 2 * gtkMenuSeparator->style->ythickness); + separatorRect.setWidth(option->rect.width() - 2 * (horizontal_padding + gtkMenuSeparator->style->xthickness)); + separatorRect.moveCenter(option->rect.center()); if (wide_separators) - gtkPainter.paintBox( gtkMenuSeparator, "hseparator", - option->rect.adjusted(0, 0, 0, -1), GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenu->style); + gtkPainter.paintBox( gtkMenuSeparator, "hseparator", + separatorRect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenuSeparator->style); else gtkPainter.paintHline( gtkMenuSeparator, "hseparator", - menuItem->rect, GTK_STATE_NORMAL, gtkMenu->style, - option->rect.left() + horizontal_padding, option->rect.width() - 2*horizontal_padding, 2); + separatorRect, GTK_STATE_NORMAL, gtkMenuSeparator->style, + 0, option->rect.right() - 1, 1); painter->restore(); break; } @@ -2530,7 +2542,7 @@ void QGtkStyle::drawControl(ControlElement element, bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled; if (selected) { - QRect rect = option->rect.adjusted(0, 0, 0, -1); + QRect rect = option->rect; #ifndef QT_NO_COMBOBOX if (qobject_cast<const QComboBox*>(widget)) rect = option->rect; @@ -2556,7 +2568,7 @@ void QGtkStyle::drawControl(ControlElement element, #endif if (!ignoreCheckMark) { // Check - QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2, checkSize, checkSize); + QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2 + 1, checkSize, checkSize); checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect); if (checkable && menuItem->icon.isNull()) { @@ -2680,7 +2692,7 @@ void QGtkStyle::drawControl(ControlElement element, int tab = menuitem->tabWidth; int xm = windowsItemFrame + checkcol + windowsItemHMargin; int xpos = menuitem->rect.x() + xm + 1; - QRect textRect(xpos, y + windowsItemVMargin - 1, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); + QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin); QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect); QString s = menuitem->text; @@ -3150,44 +3162,38 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, newSize += QSize(6, 0); } break; - case CT_MenuItem: if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { int textMargin = 8; if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { GtkWidget *gtkMenuSeparator = d->gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem")); - gboolean wide_separators; - gint separator_height; - d->gtk_widget_style_get(gtkMenuSeparator, - "wide-separators", &wide_separators, - "separator-height", &separator_height, - NULL); - newSize = QSize(size.width(), wide_separators ? separator_height - 1 : 7 ); - + GtkRequisition sizeReq = {0, 0}; + d->gtk_widget_size_request(gtkMenuSeparator, &sizeReq); + newSize = QSize(size.width(), sizeReq.height); break; } - GtkWidget *gtkMenuItem = d->gtkWidget(QLS("GtkMenu.GtkMenuItem")); + GtkWidget *gtkMenuItem = d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")); GtkStyle* style = gtkMenuItem->style; - newSize += QSize(textMargin + style->xthickness - 1, style->ythickness - 3); + + // Note we get the perfect height for the default font since we + // set a fake text label on the gtkMenuItem + // But if custom fonts are used on the widget we need a minimum size + GtkRequisition sizeReq = {0, 0}; + d->gtk_widget_size_request(gtkMenuItem, &sizeReq); + newSize.setHeight(qMax(newSize.height() - 4, sizeReq.height)); + newSize += QSize(textMargin + style->xthickness - 1, 0); // Cleanlooks assumes a check column of 20 pixels so we need to // expand it a bit gint checkSize; - d->gtk_widget_style_get(d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")), "indicator-size", &checkSize, NULL); - newSize.setHeight(qMax(newSize.height(), checkSize + 2)); + d->gtk_widget_style_get(gtkMenuItem, "indicator-size", &checkSize, NULL); newSize.setWidth(newSize.width() + qMax(0, checkSize - 20)); } break; - case CT_Menu: - // This is evil, but QMenu adds 1 pixel too much - newSize -= QSize(0, 1); - - break; - case CT_SpinBox: // QSpinBox does some nasty things that depends on CT_LineEdit newSize = size + QSize(0, -d->gtkWidget(QLS("GtkSpinButton"))->style->ythickness * 2); diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp index 5060be2..a033407 100644 --- a/src/gui/styles/qgtkstyle_p.cpp +++ b/src/gui/styles/qgtkstyle_p.cpp @@ -151,6 +151,7 @@ Ptr_gtk_menu_item_set_submenu QGtkStylePrivate::gtk_menu_item_set_submenu = 0; Ptr_gtk_settings_get_default QGtkStylePrivate::gtk_settings_get_default = 0; Ptr_gtk_separator_menu_item_new QGtkStylePrivate::gtk_separator_menu_item_new = 0; Ptr_gtk_widget_size_allocate QGtkStylePrivate::gtk_widget_size_allocate = 0; +Ptr_gtk_widget_size_request QGtkStylePrivate::gtk_widget_size_request = 0; Ptr_gtk_widget_set_direction QGtkStylePrivate::gtk_widget_set_direction = 0; Ptr_gtk_widget_path QGtkStylePrivate::gtk_widget_path = 0; Ptr_gtk_container_get_type QGtkStylePrivate::gtk_container_get_type = 0; @@ -159,7 +160,6 @@ Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0; Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0; Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0; Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0; - Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0; Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0; Ptr_pango_font_description_get_family QGtkStylePrivate::pango_font_description_get_family = 0; @@ -410,11 +410,13 @@ void QGtkStylePrivate::resolveGtk() const gtk_combo_box_entry_new = (Ptr_gtk_combo_box_entry_new)libgtk.resolve("gtk_combo_box_entry_new"); gtk_container_forall = (Ptr_gtk_container_forall)libgtk.resolve("gtk_container_forall"); gtk_widget_size_allocate =(Ptr_gtk_widget_size_allocate)libgtk.resolve("gtk_widget_size_allocate"); + gtk_widget_size_request =(Ptr_gtk_widget_size_request)libgtk.resolve("gtk_widget_size_request"); gtk_widget_set_direction =(Ptr_gtk_widget_set_direction)libgtk.resolve("gtk_widget_set_direction"); gtk_widget_path =(Ptr_gtk_widget_path)libgtk.resolve("gtk_widget_path"); gtk_container_get_type =(Ptr_gtk_container_get_type)libgtk.resolve("gtk_container_get_type"); gtk_window_get_type =(Ptr_gtk_window_get_type)libgtk.resolve("gtk_window_get_type"); gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type"); + gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths"); gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version"); gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free"); @@ -447,10 +449,13 @@ void QGtkStylePrivate::initGtkMenu() const gtk_widget_realize(gtkMenu); GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new(); + g_object_set(gtkMenuItem, "label", "X", NULL); + gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem); gtk_widget_realize(gtkMenuItem); GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new(); + g_object_set(gtkCheckMenuItem, "label", "X", NULL); gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem); gtk_widget_realize(gtkCheckMenuItem); diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h index ad672db..db5b9b9 100644 --- a/src/gui/styles/qgtkstyle_p.h +++ b/src/gui/styles/qgtkstyle_p.h @@ -147,8 +147,10 @@ typedef void (*Ptr_gtk_paint_vline) (GtkStyle *, GdkWindow *, GtkStateType, co typedef void (*Ptr_gtk_menu_item_set_submenu) (GtkMenuItem *, GtkWidget *); typedef void (*Ptr_gtk_container_forall) (GtkContainer *, GtkCallback, gpointer); typedef void (*Ptr_gtk_widget_size_allocate) (GtkWidget *, GtkAllocation*); +typedef void (*Ptr_gtk_widget_size_request) (GtkWidget *widget, GtkRequisition *requisition); typedef void (*Ptr_gtk_widget_set_direction) (GtkWidget *, GtkTextDirection); typedef void (*Ptr_gtk_widget_path) (GtkWidget *, guint *, gchar **, gchar**); + typedef void (*Ptr_gtk_toolbar_insert) (GtkToolbar *toolbar, GtkToolItem *item, int pos); typedef void (*Ptr_gtk_menu_shell_append)(GtkMenuShell *, GtkWidget *); typedef GtkType (*Ptr_gtk_container_get_type) (void); @@ -365,6 +367,7 @@ public: static Ptr_gtk_settings_get_default gtk_settings_get_default; static Ptr_gtk_separator_menu_item_new gtk_separator_menu_item_new; static Ptr_gtk_widget_size_allocate gtk_widget_size_allocate; + static Ptr_gtk_widget_size_request gtk_widget_size_request; static Ptr_gtk_widget_set_direction gtk_widget_set_direction; static Ptr_gtk_widget_path gtk_widget_path; static Ptr_gtk_container_get_type gtk_container_get_type; diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index cf27eac..498313b 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -5611,9 +5611,6 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c case SE_ItemViewItemFocusRect: if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) { QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem); - QStyleOptionViewItemV4 optCopy(*vopt); - optCopy.rect = subRule.contentsRect(vopt->rect); - QRect rect = ParentStyle::subElementRect(se, &optCopy, w); PseudoElement pe = PseudoElement_None; if (se == SE_ItemViewItemText || se == SE_ItemViewItemFocusRect) pe = PseudoElement_ViewItemText; @@ -5623,8 +5620,13 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c pe = PseudoElement_ViewItemIndicator; else break; - QRenderRule subRule2 = renderRule(w, opt, pe); - return positionRect(w, subRule2, pe, rect, opt->direction); + if (subRule.hasGeometry() || subRule.hasBox() || !subRule.hasNativeBorder() || hasStyleRule(w, pe)) { + QRenderRule subRule2 = renderRule(w, opt, pe); + QStyleOptionViewItemV4 optCopy(*vopt); + optCopy.rect = subRule.contentsRect(vopt->rect); + QRect rect = ParentStyle::subElementRect(se, &optCopy, w); + return positionRect(w, subRule2, pe, rect, opt->direction); + } } break; #endif // QT_NO_ITEMVIEWS diff --git a/src/multimedia/audio/qaudio_mac.cpp b/src/multimedia/audio/qaudio_mac.cpp index 14fee8b..61a00ce 100644 --- a/src/multimedia/audio/qaudio_mac.cpp +++ b/src/multimedia/audio/qaudio_mac.cpp @@ -48,8 +48,8 @@ QT_BEGIN_NAMESPACE QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat) { dbg.nospace() << "QAudioFormat(" << - audioFormat.frequency() << "," << - audioFormat.channels() << "," << + audioFormat.sampleRate() << "," << + audioFormat.channelCount() << "," << audioFormat.sampleSize()<< "," << audioFormat.codec() << "," << audioFormat.byteOrder() << "," << @@ -64,8 +64,8 @@ QAudioFormat toQAudioFormat(AudioStreamBasicDescription const& sf) { QAudioFormat audioFormat; - audioFormat.setFrequency(sf.mSampleRate); - audioFormat.setChannels(sf.mChannelsPerFrame); + audioFormat.setSampleRate(sf.mSampleRate); + audioFormat.setChannelCount(sf.mChannelsPerFrame); audioFormat.setSampleSize(sf.mBitsPerChannel); audioFormat.setCodec(QString::fromLatin1("audio/pcm")); audioFormat.setByteOrder(sf.mFormatFlags & kLinearPCMFormatFlagIsBigEndian != 0 ? QAudioFormat::BigEndian : QAudioFormat::LittleEndian); @@ -84,9 +84,9 @@ AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& au AudioStreamBasicDescription sf; sf.mFormatFlags = kAudioFormatFlagIsPacked; - sf.mSampleRate = audioFormat.frequency(); + sf.mSampleRate = audioFormat.sampleRate(); sf.mFramesPerPacket = 1; - sf.mChannelsPerFrame = audioFormat.channels(); + sf.mChannelsPerFrame = audioFormat.channelCount(); sf.mBitsPerChannel = audioFormat.sampleSize(); sf.mBytesPerFrame = sf.mChannelsPerFrame * (sf.mBitsPerChannel / 8); sf.mBytesPerPacket = sf.mFramesPerPacket * sf.mBytesPerFrame; diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp index 092efc5..ca20eda 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo.cpp @@ -100,13 +100,13 @@ public: You can also query each device for the formats it supports. A format in this context is a set consisting of a specific byte - order, channel, codec, frequency, sample rate, and sample type. A + order, channel, codec, sample rate, sample size and sample type. A format is represented by the QAudioFormat class. The values supported by the the device for each of these parameters can be fetched with supportedByteOrders(), supportedChannels(), supportedCodecs(), - supportedFrequencies(), supportedSampleSizes(), and + supportedSampleRates(), supportedSampleSizes(), and supportedSampleTypes(). The combinations supported are dependent on the platform, audio plugins installed and the audio device capabilities. If you need a specific format, you can check if the device supports it with isFormatSupported(), or fetch a @@ -259,7 +259,16 @@ QStringList QAudioDeviceInfo::supportedCodecs() const } /*! - Returns a list of supported frequencies. + Returns a list of supported sample rates. +*/ + +QList<int> QAudioDeviceInfo::supportedSampleRates() const +{ + return supportedFrequencies(); +} + +/*! + \internal */ QList<int> QAudioDeviceInfo::supportedFrequencies() const @@ -268,7 +277,16 @@ QList<int> QAudioDeviceInfo::supportedFrequencies() const } /*! - Returns a list of supported channels. + Returns a list of supported channel counts. +*/ + +QList<int> QAudioDeviceInfo::supportedChannelCounts() const +{ + return supportedChannels(); +} + +/*! + \internal */ QList<int> QAudioDeviceInfo::supportedChannels() const diff --git a/src/multimedia/audio/qaudiodeviceinfo.h b/src/multimedia/audio/qaudiodeviceinfo.h index 62dc8a2..1cc0731 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.h +++ b/src/multimedia/audio/qaudiodeviceinfo.h @@ -84,7 +84,9 @@ public: QStringList supportedCodecs() const; QList<int> supportedFrequencies() const; + QList<int> supportedSampleRates() const; QList<int> supportedChannels() const; + QList<int> supportedChannelCounts() const; QList<int> supportedSampleSizes() const; QList<QAudioFormat::Endian> supportedByteOrders() const; QList<QAudioFormat::SampleType> supportedSampleTypes() const; diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index 36270a7..a77a428 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -78,20 +78,20 @@ QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const { QAudioFormat nearest; if(mode == QAudio::AudioOutput) { - nearest.setFrequency(44100); - nearest.setChannels(2); + nearest.setSampleRate(44100); + nearest.setChannelCount(2); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(16); nearest.setCodec(QLatin1String("audio/pcm")); } else { - nearest.setFrequency(8000); - nearest.setChannels(1); + nearest.setSampleRate(8000); + nearest.setChannelCount(1); nearest.setSampleType(QAudioFormat::UnSignedInt); nearest.setSampleSize(8); nearest.setCodec(QLatin1String("audio/pcm")); if(!testSettings(nearest)) { - nearest.setChannels(2); + nearest.setChannelCount(2); nearest.setSampleSize(16); nearest.setSampleType(QAudioFormat::SignedInt); } @@ -253,8 +253,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const snd_pcm_hw_params_any( handle, params ); // set the values! - snd_pcm_hw_params_set_channels(handle,params,format.channels()); - snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + snd_pcm_hw_params_set_channels(handle,params,format.channelCount()); + snd_pcm_hw_params_set_rate(handle,params,format.sampleRate(),dir); switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) @@ -295,18 +295,18 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const } else testCodec = true; - if(err>=0 && format.channels() != -1) { - err = snd_pcm_hw_params_test_channels(handle,params,format.channels()); + if(err>=0 && format.channelCount() != -1) { + err = snd_pcm_hw_params_test_channels(handle,params,format.channelCount()); if(err>=0) - err = snd_pcm_hw_params_set_channels(handle,params,format.channels()); + err = snd_pcm_hw_params_set_channels(handle,params,format.channelCount()); if(err>=0) testChannel = true; } - if(err>=0 && format.frequency() != -1) { - err = snd_pcm_hw_params_test_rate(handle,params,format.frequency(),0); + if(err>=0 && format.sampleRate() != -1) { + err = snd_pcm_hw_params_test_rate(handle,params,format.sampleRate(),0); if(err>=0) - err = snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + err = snd_pcm_hw_params_set_rate(handle,params,format.sampleRate(),dir); if(err>=0) testFreq = true; } diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index ecd03e5..9334069 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -144,10 +144,10 @@ QAudioFormat QAudioDeviceInfoInternal::nearestFormat(const QAudioFormat& format) rc.setCodec(QString::fromLatin1("audio/pcm")); - if (rc.frequency() != target.frequency()) - rc.setFrequency(target.frequency()); - if (rc.channels() != target.channels()) - rc.setChannels(target.channels()); + if (rc.sampleRate() != target.sampleRate()) + rc.setSampleRate(target.sampleRate()); + if (rc.channelCount() != target.channelCount()) + rc.setChannelCount(target.channelCount()); if (rc.sampleSize() != target.sampleSize()) rc.setSampleSize(target.sampleSize()); if (rc.byteOrder() != target.byteOrder()) diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp index f6b8154..373e23d 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -94,15 +94,15 @@ QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const { QAudioFormat nearest; if(mode == QAudio::AudioOutput) { - nearest.setFrequency(44100); - nearest.setChannels(2); + nearest.setSampleRate(44100); + nearest.setChannelCount(2); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(16); nearest.setCodec(QLatin1String("audio/pcm")); } else { - nearest.setFrequency(11025); - nearest.setChannels(1); + nearest.setSampleRate(11025); + nearest.setChannelCount(1); nearest.setByteOrder(QAudioFormat::LittleEndian); nearest.setSampleType(QAudioFormat::SignedInt); nearest.setSampleSize(8); @@ -181,12 +181,12 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const if(!format.codec().startsWith(QLatin1String("audio/pcm"))) failed = true; - if(!failed && !(format.channels() == 1 || format.channels() == 2)) + if(!failed && !(format.channelCount() == 1 || format.channelCount() == 2)) failed = true; if(!failed) { - if(!(format.frequency() == 8000 || format.frequency() == 11025 || format.frequency() == 22050 || - format.frequency() == 44100 || format.frequency() == 48000 || format.frequency() == 96000)) + if(!(format.sampleRate() == 8000 || format.sampleRate() == 11025 || format.sampleRate() == 22050 || + format.sampleRate() == 44100 || format.sampleRate() == 48000 || format.sampleRate() == 96000)) failed = true; } diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp index da6a783..58bb571 100644 --- a/src/multimedia/audio/qaudioformat.cpp +++ b/src/multimedia/audio/qaudioformat.cpp @@ -144,7 +144,7 @@ public: Values are initialized as follows: \list \o frequency() = -1 - \o channels() = -1 + \o channelCount() = -1 \o sampleSize() = -1 \o byteOrder() = QAudioFormat::Endian(QSysInfo::ByteOrder) \o sampleType() = QAudioFormat::Unknown @@ -224,7 +224,16 @@ bool QAudioFormat::isValid() const } /*! - Sets the frequency (sample rate) to \a frequency. + Sets the sample rate to \a samplerate Hertz. +*/ + +void QAudioFormat::setSampleRate(int samplerate) +{ + d->frequency = samplerate; +} + +/*! + \internal */ void QAudioFormat::setFrequency(int frequency) @@ -233,7 +242,16 @@ void QAudioFormat::setFrequency(int frequency) } /*! - Returns the current frequency (sample rate) value. + Returns the current sample rate in Hertz. +*/ + +int QAudioFormat::sampleRate() const +{ + return d->frequency; +} + +/*! + \internal */ int QAudioFormat::frequency() const @@ -242,7 +260,16 @@ int QAudioFormat::frequency() const } /*! - Sets the number of channels to the \a channels value specified. + Sets the channel count to \a channels. +*/ + +void QAudioFormat::setChannelCount(int channels) +{ + d->channels = channels; +} + +/*! + \internal */ void QAudioFormat::setChannels(int channels) @@ -251,7 +278,16 @@ void QAudioFormat::setChannels(int channels) } /*! - Returns the current number of channels. + Returns the current channel count value. +*/ + +int QAudioFormat::channelCount() const +{ + return d->channels; +} + +/*! + \internal */ int QAudioFormat::channels() const diff --git a/src/multimedia/audio/qaudioformat.h b/src/multimedia/audio/qaudioformat.h index cb58d1c..b255907 100644 --- a/src/multimedia/audio/qaudioformat.h +++ b/src/multimedia/audio/qaudioformat.h @@ -76,6 +76,12 @@ public: void setFrequency(int frequency); int frequency() const; + void setSampleRate(int samplerate); + int sampleRate() const; + + void setChannelCount(int channels); + int channelCount() const; + void setChannels(int channels); int channels() const; diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 484a533..6fc4284 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -88,8 +88,8 @@ QT_BEGIN_NAMESPACE QAudioFormat format; // set up the format you want, eg. - format.setFrequency(8000); - format.setChannels(1); + format.setSampleRate(8000); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index e957cb4..ea68c8d6 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -256,7 +256,7 @@ bool QAudioInputPrivate::open() int dir; int err=-1; int count=0; - unsigned int freakuency=settings.frequency(); + unsigned int freakuency=settings.sampleRate(); QString dev = QString(QLatin1String(m_device.constData())); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput); @@ -332,7 +332,7 @@ bool QAudioInputPrivate::open() } } if ( !fatal ) { - err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() ); + err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioInput: snd_pcm_hw_params_set_channels: err = %1").arg(err); @@ -505,7 +505,7 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) errorState = QAudio::NoError; deviceState = QAudio::IdleState; } else { - totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.frequency(); + totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.sampleRate(); resuming = false; errorState = QAudio::NoError; deviceState = QAudio::ActiveState; @@ -534,7 +534,7 @@ void QAudioInputPrivate::resume() resuming = true; deviceState = QAudio::ActiveState; int chunks = buffer_size/period_size; - timer->start(buffer_time*chunks/2000); + timer->start(period_time*chunks/2000); emit stateChanged(deviceState); } } @@ -702,7 +702,7 @@ qint64 InputPrivate::readData( char* data, qint64 len) count++; } if(err > 0 && readFrames > 0) { - audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.frequency()*1000; + audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.sampleRate()*1000; audioDevice->deviceState = QAudio::ActiveState; return err; } diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp index 7251513..f5be8ee 100644 --- a/src/multimedia/audio/qaudioinput_mac_p.cpp +++ b/src/multimedia/audio/qaudioinput_mac_p.cpp @@ -814,7 +814,7 @@ int QAudioInputPrivate::notifyInterval() const qint64 QAudioInputPrivate::processedUSecs() const { - return totalFrames * 1000000 / audioFormat.frequency(); + return totalFrames * 1000000 / audioFormat.sampleRate(); } qint64 QAudioInputPrivate::elapsedUSecs() const diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp index 17e8bfb..5c597ef 100644 --- a/src/multimedia/audio/qaudioinput_win32_p.cpp +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -225,16 +225,16 @@ bool QAudioInputPrivate::open() header = 0; if(buffer_size == 0) { // Default buffer size, 100ms, default period size is 20ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.1; + buffer_size = settings.sampleRate()*settings.channelCount()*(settings.sampleSize()/8)*0.1; period_size = buffer_size/5; } else { period_size = buffer_size/5; } timeStamp.restart(); elapsedTimeOffset = 0; - wfx.nSamplesPerSec = settings.frequency(); + wfx.nSamplesPerSec = settings.sampleRate(); wfx.wBitsPerSample = settings.sampleSize(); - wfx.nChannels = settings.channels(); + wfx.nChannels = settings.channelCount(); wfx.cbSize = 0; wfx.wFormatTag = WAVE_FORMAT_PCM; @@ -374,8 +374,8 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) } else { totalTimeValue += waveBlocks[header].dwBytesRecorded - /((settings.channels()*settings.sampleSize()/8)) - *10000/settings.frequency()*100; + /((settings.channelCount()*settings.sampleSize()/8)) + *10000/settings.sampleRate()*100; errorState = QAudio::NoError; deviceState = QAudio::ActiveState; resuming = false; @@ -388,8 +388,8 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l; #endif totalTimeValue += waveBlocks[header].dwBytesRecorded - /((settings.channels()*settings.sampleSize()/8)) - *10000/settings.frequency()*100; + /((settings.channelCount()*settings.sampleSize()/8)) + *10000/settings.sampleRate()*100; errorState = QAudio::NoError; deviceState = QAudio::ActiveState; resuming = false; diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index 6d09212..613056c 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -83,8 +83,8 @@ QT_BEGIN_NAMESPACE QAudioFormat format; // Set up the format, eg. - format.setFrequency(8000); - format.setChannels(1); + format.setSampleRate(8000); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp index 7b89cef..43b65ec 100644 --- a/src/multimedia/audio/qaudiooutput_alsa_p.cpp +++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp @@ -279,7 +279,7 @@ bool QAudioOutputPrivate::open() int dir; int err=-1; int count=0; - unsigned int freakuency=settings.frequency(); + unsigned int freakuency=settings.sampleRate(); QString dev = QLatin1String(m_device.constData()); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); @@ -354,7 +354,7 @@ bool QAudioOutputPrivate::open() } } if ( !fatal ) { - err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channels() ); + err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() ); if ( err < 0 ) { fatal = true; errMessage = QString::fromLatin1("QAudioOutput: snd_pcm_hw_params_set_channels: err = %1").arg(err); @@ -494,7 +494,7 @@ qint64 QAudioOutputPrivate::write( const char *data, qint64 len ) err = snd_pcm_writei( handle, data, frames ); } if(err > 0) { - totalTimeValue += err*1000000/settings.frequency(); + totalTimeValue += err*1000000/settings.sampleRate(); resuming = false; errorState = QAudio::NoError; deviceState = QAudio::ActiveState; diff --git a/src/multimedia/audio/qaudiooutput_mac_p.cpp b/src/multimedia/audio/qaudiooutput_mac_p.cpp index 518f78f..4367ee7 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.cpp +++ b/src/multimedia/audio/qaudiooutput_mac_p.cpp @@ -87,8 +87,8 @@ public: m_device(0) { m_buffer = new QAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize))); - m_bytesPerFrame = (audioFormat.sampleSize() / 8) * audioFormat.channels(); - m_periodTime = m_maxPeriodSize / m_bytesPerFrame * 1000 / audioFormat.frequency(); + m_bytesPerFrame = (audioFormat.sampleSize() / 8) * audioFormat.channelCount(); + m_periodTime = m_maxPeriodSize / m_bytesPerFrame * 1000 / audioFormat.sampleRate(); m_fillTimer = new QTimer(this); connect(m_fillTimer, SIGNAL(timeout()), SLOT(fillBuffer())); @@ -546,7 +546,7 @@ int QAudioOutputPrivate::notifyInterval() const qint64 QAudioOutputPrivate::processedUSecs() const { - return totalFrames * 1000000 / audioFormat.frequency(); + return totalFrames * 1000000 / audioFormat.sampleRate(); } qint64 QAudioOutputPrivate::elapsedUSecs() const diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index c31e048..b6e9762 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -213,7 +213,7 @@ bool QAudioOutputPrivate::open() #endif if(buffer_size == 0) { // Default buffer size, 200ms, default period size is 40ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2; + buffer_size = settings.sampleRate()*settings.channelCount()*(settings.sampleSize()/8)*0.2; period_size = buffer_size/5; } else { period_size = buffer_size/5; @@ -232,9 +232,9 @@ bool QAudioOutputPrivate::open() timeStamp.restart(); elapsedTimeOffset = 0; - wfx.nSamplesPerSec = settings.frequency(); + wfx.nSamplesPerSec = settings.sampleRate(); wfx.wBitsPerSample = settings.sampleSize(); - wfx.nChannels = settings.channels(); + wfx.nChannels = settings.channelCount(); wfx.cbSize = 0; wfx.wFormatTag = WAVE_FORMAT_PCM; @@ -289,8 +289,8 @@ void QAudioOutputPrivate::close() return; deviceState = QAudio::StoppedState; - int delay = (buffer_size-bytesFree())*1000/(settings.frequency() - *settings.channels()*(settings.sampleSize()/8)); + int delay = (buffer_size-bytesFree())*1000/(settings.sampleRate() + *settings.channelCount()*(settings.sampleSize()/8)); waveOutReset(hWaveOut); Sleep(delay+10); @@ -386,8 +386,8 @@ qint64 QAudioOutputPrivate::write( const char *data, qint64 len ) LeaveCriticalSection(&waveOutCriticalSection); #endif totalTimeValue += current->dwBufferLength - /(settings.channels()*(settings.sampleSize()/8)) - *1000000/settings.frequency();; + /(settings.channelCount()*(settings.sampleSize()/8)) + *1000000/settings.sampleRate();; waveCurrentBlock++; waveCurrentBlock %= buffer_size/period_size; current = &waveBlocks[waveCurrentBlock]; diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 44a0a79..2c56524 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -415,14 +415,13 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor lowPriorityQueue.prepend(pair); break; } - QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); + // this used to be called via invokeMethod and a QueuedConnection + _q_startNextRequest(); return reply; } void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair) { - Q_Q(QHttpNetworkConnection); - QHttpNetworkRequest request = pair.first; switch (request.priority()) { case QHttpNetworkRequest::HighPriority: @@ -433,7 +432,8 @@ void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair) lowPriorityQueue.prepend(pair); break; } - QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); + // this used to be called via invokeMethod and a QueuedConnection + _q_startNextRequest(); } void QHttpNetworkConnectionPrivate::dequeueAndSendRequest(QAbstractSocket *socket) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 1a68e97..7cf632f 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -166,6 +166,8 @@ bool QHttpNetworkConnectionChannel::sendRequest() QByteArray header = QHttpNetworkRequestPrivate::header(request, false); #endif socket->write(header); + // flushing is dangerous (QSslSocket calls transmit which might read or error) +// socket->flush(); QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice(); if (uploadByteDevice) { // connect the signals so this function gets called again @@ -258,7 +260,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called // this is needed if the sends an reply before we have finished sending the request. In that // case receiveReply had been called before but ignored the server reply - receiveReply(); + QMetaObject::invokeMethod(connection, "_q_receiveReply", Qt::QueuedConnection); break; } case QHttpNetworkConnectionChannel::ReadingState: @@ -272,7 +274,7 @@ bool QHttpNetworkConnectionChannel::sendRequest() } -void QHttpNetworkConnectionChannel::receiveReply() +void QHttpNetworkConnectionChannel::_q_receiveReply() { Q_ASSERT(socket); @@ -567,7 +569,7 @@ void QHttpNetworkConnectionChannel::allDone() connection->d_func()->fillPipeline(socket); // continue reading - receiveReply(); + _q_receiveReply(); } } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) { eatWhitespace(); @@ -739,7 +741,7 @@ void QHttpNetworkConnectionChannel::_q_readyRead() if (isSocketWaiting() || isSocketReading()) { state = QHttpNetworkConnectionChannel::ReadingState; if (reply) - receiveReply(); + _q_receiveReply(); } } @@ -758,7 +760,7 @@ void QHttpNetworkConnectionChannel::_q_disconnected() if (isSocketWaiting() || isSocketReading()) { state = QHttpNetworkConnectionChannel::ReadingState; if (reply) - receiveReply(); + _q_receiveReply(); } else if (state == QHttpNetworkConnectionChannel::IdleState && resendCurrent) { // re-sending request because the socket was in ClosingState QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index bbe43cd..c30c236 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -144,7 +144,6 @@ public: void close(); bool sendRequest(); - void receiveReply(); bool ensureConnection(); @@ -166,6 +165,7 @@ public: bool isSocketReading() const; protected slots: + void _q_receiveReply(); void _q_bytesWritten(qint64 bytes); // proceed sending void _q_readyRead(); // pending data to read void _q_disconnected(); // disconnected from host diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index dda799d..ada00df 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -393,13 +393,19 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, if (lastModified.isValid()) httpRequest.setHeaderField("If-Modified-Since", QNetworkHeadersPrivate::toHttpDate(lastModified)); - it = cacheHeaders.findRawHeader("Cache-Control"); - if (it != cacheHeaders.rawHeaders.constEnd()) { - QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second); - if (cacheControl.contains("must-revalidate")) - return; + if (CacheLoadControlAttribute == QNetworkRequest::PreferNetwork) { + it = cacheHeaders.findRawHeader("Cache-Control"); + if (it != cacheHeaders.rawHeaders.constEnd()) { + QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second); + if (cacheControl.contains("must-revalidate")) + return; + } } + QDateTime currentDateTime = QDateTime::currentDateTime(); + QDateTime expirationDate = metaData.expirationDate(); + +#if 0 /* * age_value * is the value of Age: header received by the cache with @@ -415,21 +421,24 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, * now * is the current (local) time */ - QDateTime currentDateTime = QDateTime::currentDateTime(); int age_value = 0; it = cacheHeaders.findRawHeader("age"); if (it != cacheHeaders.rawHeaders.constEnd()) - age_value = QNetworkHeadersPrivate::fromHttpDate(it->second).toTime_t(); + age_value = it->second.toInt(); + QDateTime dateHeader; int date_value = 0; it = cacheHeaders.findRawHeader("date"); - if (it != cacheHeaders.rawHeaders.constEnd()) - date_value = QNetworkHeadersPrivate::fromHttpDate(it->second).toTime_t(); + if (it != cacheHeaders.rawHeaders.constEnd()) { + dateHeader = QNetworkHeadersPrivate::fromHttpDate(it->second); + date_value = dateHeader.toTime_t(); + } int now = currentDateTime.toUTC().toTime_t(); int request_time = now; int response_time = now; + // Algorithm from RFC 2616 section 13.2.3 int apparent_age = qMax(0, response_time - date_value); int corrected_received_age = qMax(apparent_age, age_value); int response_delay = response_time - request_time; @@ -438,7 +447,6 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, int current_age = corrected_initial_age + resident_time; // RFC 2616 13.2.4 Expiration Calculations - QDateTime expirationDate = metaData.expirationDate(); if (!expirationDate.isValid()) { if (lastModified.isValid()) { int diff = currentDateTime.secsTo(lastModified); @@ -453,10 +461,15 @@ void QNetworkAccessHttpBackend::validateCache(QHttpNetworkRequest &httpRequest, } } - int freshness_lifetime = currentDateTime.secsTo(expirationDate); + // the cache-saving code below sets the expirationDate with date+max_age + // if "max-age" is present, or to Expires otherwise + int freshness_lifetime = dateHeader.secsTo(expirationDate); bool response_is_fresh = (freshness_lifetime > current_age); +#else + bool response_is_fresh = currentDateTime.secsTo(expirationDate) >= 0; +#endif - if (!response_is_fresh && CacheLoadControlAttribute == QNetworkRequest::PreferNetwork) + if (!response_is_fresh) return; loadedFromCache = true; @@ -581,9 +594,10 @@ void QNetworkAccessHttpBackend::open() if (transparentProxy.type() == QNetworkProxy::DefaultProxy && cacheProxy.type() == QNetworkProxy::DefaultProxy) { // unsuitable proxies - error(QNetworkReply::ProxyNotFoundError, - tr("No suitable proxy found")); - finished(); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError), + Q_ARG(QString, QCoreApplication::translate("QNetworkAccessHttpBackend", "No suitable proxy found"))); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } #endif diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index bc3980d..705323d 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -104,6 +104,7 @@ private slots: void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth); void httpError(QNetworkReply::NetworkError error, const QString &errorString); bool sendCacheContents(const QNetworkCacheMetaData &metaData); + void finished(); // override private: QHttpNetworkReply *httpReply; @@ -118,7 +119,6 @@ private: #endif void disconnectFromHttp(); - void finished(); // override void setupConnection(); void validateCache(QHttpNetworkRequest &httpRequest, bool &loadedFromCache); void invalidateCache(); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 2f57fee..d27fbe7 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -723,8 +723,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // third step: find a backend priv->backend = d->findBackend(op, request); - // fourth step: setup the reply - priv->setup(op, request, outgoingData); #ifndef QT_NO_NETWORKPROXY QList<QNetworkProxy> proxyList = d->queryProxy(QNetworkProxyQuery(request.url())); priv->proxyList = proxyList; @@ -733,6 +731,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera priv->backend->setParent(reply); priv->backend->reply = priv; } + // fourth step: setup the reply + priv->setup(op, request, outgoingData); #ifndef QT_NO_OPENSSL reply->setSslConfiguration(request.sslConfiguration()); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 42e802f..285864d 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -72,6 +72,9 @@ void QNetworkReplyImplPrivate::_q_startOperation() } state = Working; + // note: if that method is called directly, it cannot happen that the backend is 0, + // because we just checked via a qobject_cast that we got a http backend (see + // QNetworkReplyImplPrivate::setup()) if (!backend) { error(QNetworkReplyImpl::ProtocolUnknownError, QCoreApplication::translate("QNetworkReply", "Protocol \"%1\" is unknown").arg(url.scheme())); // not really true!; @@ -203,7 +206,6 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData() } } - void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *data) { @@ -246,7 +248,14 @@ void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const // No outgoing data (e.g. HTTP GET request) // or no backend // if no backend, _q_startOperation will handle the error of this - QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + + // for HTTP, we want to send out the request as fast as possible to the network, without + // invoking methods in a QueuedConnection + if (qobject_cast<QNetworkAccessHttpBackend *>(backend)) { + _q_startOperation(); + } else { + QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); + } } q->QIODevice::open(QIODevice::ReadOnly); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 7ff0ef2..6b65886 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -559,6 +559,9 @@ void QGL2PaintEngineExPrivate::resetGLState() glDepthMask(true); glDepthFunc(GL_LESS); glClearDepth(1); + glStencilMask(0xff); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_ALWAYS, 0, 0xff); } void QGL2PaintEngineEx::endNativePainting() diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 8944c1b..547b33e 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4952,8 +4952,6 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi if (!glcx) glcx = new QGLContext(QGLFormat::defaultFormat(), q); - - q->setAttribute(Qt::WA_NoSystemBackground); } #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index ef2fa6c..6ed07e5 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -606,10 +606,22 @@ void QGLContext::updatePaintDevice() } } } else if (d->paintDevice->devType() == QInternal::Pixmap) { - QPixmap *pm = (QPixmap *)d->paintDevice; - PixMapHandle mac_pm = GetGWorldPixMap((GWorldPtr)pm->macQDHandle()); - aglSetOffScreen((AGLContext)d->cx, pm->width(), pm->height(), - GetPixRowBytes(mac_pm), GetPixBaseAddr(mac_pm)); + QPixmap *pm = reinterpret_cast<QPixmap *>(d->paintDevice); + + unsigned long qdformat = k32ARGBPixelFormat; + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) + qdformat = k32BGRAPixelFormat; + Rect rect; + SetRect(&rect, 0, 0, pm->width(), pm->height()); + + GWorldPtr gworld; + NewGWorldFromPtr(&gworld, qdformat, &rect, 0, 0, 0, + reinterpret_cast<char *>(qt_mac_pixmap_get_base(pm)), + qt_mac_pixmap_get_bytes_per_line(pm)); + + PixMapHandle pixmapHandle = GetGWorldPixMap(gworld); + aglSetOffScreen(reinterpret_cast<AGLContext>(d->cx), pm->width(), pm->height(), + GetPixRowBytes(pixmapHandle), GetPixBaseAddr(pixmapHandle)); } else { qWarning("QGLContext::updatePaintDevice(): Not sure how to render OpenGL on this device!"); } diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 0d3a892..85daf95 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -56,9 +56,9 @@ QT_BEGIN_NAMESPACE bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual); // -// QGLTempContext is a lass for creating a temporary GL context (which is -// needed during QGLWidget initialization to retrieve GL extension info). -// Faster to construct than a full QGLWidget. +// QGLTempContext is a class for creating a temporary GL context +// (which is needed during QGLWidget initialization to retrieve GL +// extension info). Faster to construct than a full QGLWidget. // class QGLTempContext { @@ -68,82 +68,82 @@ public: window(0), context(0), surface(0) - { - display = eglGetDisplay(EGLNativeDisplayType(X11->display)); + { + display = eglGetDisplay(EGLNativeDisplayType(X11->display)); - if (!eglInitialize(display, NULL, NULL)) { - qWarning("QGLTempContext: Unable to initialize EGL display."); - return; - } + if (!eglInitialize(display, NULL, NULL)) { + qWarning("QGLTempContext: Unable to initialize EGL display."); + return; + } - EGLConfig config; - int numConfigs = 0; - EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGLConfig config; + int numConfigs = 0; + EGLint attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, #ifdef QT_OPENGL_ES_2 - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #endif - EGL_NONE - }; + EGL_NONE + }; - eglChooseConfig(display, attribs, &config, 1, &numConfigs); - if (!numConfigs) { - qWarning("QGLTempContext: No EGL configurations available."); - return; - } + eglChooseConfig(display, attribs, &config, 1, &numConfigs); + if (!numConfigs) { + qWarning("QGLTempContext: No EGL configurations available."); + return; + } - XVisualInfo visualInfo; - XVisualInfo *vi; - int numVisuals; - EGLint id = 0; - - eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &id); - if (id == 0) { - // EGL_NATIVE_VISUAL_ID is optional and might not be supported - // on some implementations - we'll have to do it the hard way - QX11Info xinfo; - qt_egl_setup_x11_visual(visualInfo, display, config, xinfo, false); - } else { - visualInfo.visualid = id; - } - vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); - if (!vi || numVisuals < 1) { - qWarning("QGLTempContext: Unable to get X11 visual info id."); - return; - } + XVisualInfo visualInfo; + XVisualInfo *vi; + int numVisuals; + EGLint id = 0; + + eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &id); + if (id == 0) { + // EGL_NATIVE_VISUAL_ID is optional and might not be supported + // on some implementations - we'll have to do it the hard way + QX11Info xinfo; + qt_egl_setup_x11_visual(visualInfo, display, config, xinfo, false); + } else { + visualInfo.visualid = id; + } + vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); + if (!vi || numVisuals < 1) { + qWarning("QGLTempContext: Unable to get X11 visual info id."); + return; + } - window = XCreateWindow(X11->display, RootWindow(X11->display, screen), - 0, 0, 1, 1, 0, - vi->depth, InputOutput, vi->visual, - 0, 0); + window = XCreateWindow(X11->display, RootWindow(X11->display, screen), + 0, 0, 1, 1, 0, + vi->depth, InputOutput, vi->visual, + 0, 0); - surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType) window, NULL); + surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType) window, NULL); - if (surface == EGL_NO_SURFACE) { - qWarning("QGLTempContext: Error creating EGL surface."); - XFree(vi); - XDestroyWindow(X11->display, window); - return; - } + if (surface == EGL_NO_SURFACE) { + qWarning("QGLTempContext: Error creating EGL surface."); + XFree(vi); + XDestroyWindow(X11->display, window); + return; + } - EGLint contextAttribs[] = { + EGLint contextAttribs[] = { #ifdef QT_OPENGL_ES_2 - EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_CONTEXT_CLIENT_VERSION, 2, #endif - EGL_NONE - }; - context = eglCreateContext(display, config, 0, contextAttribs); - if (context != EGL_NO_CONTEXT - && eglMakeCurrent(display, surface, surface, context)) - { - initialized = true; - } else { - qWarning("QGLTempContext: Error creating EGL context."); - eglDestroySurface(display, surface); - XDestroyWindow(X11->display, window); - } - XFree(vi); + EGL_NONE + }; + context = eglCreateContext(display, config, 0, contextAttribs); + if (context != EGL_NO_CONTEXT + && eglMakeCurrent(display, surface, surface, context)) + { + initialized = true; + } else { + qWarning("QGLTempContext: Error creating EGL context."); + eglDestroySurface(display, surface); + XDestroyWindow(X11->display, window); } + XFree(vi); + } ~QGLTempContext() { if (initialized) { @@ -349,7 +349,7 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo - + #if !defined(QT_NO_XRENDER) if (vi.visualid == 0 && useArgbVisual) { // Try to use XRender to find an ARGB visual we can use diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index e024396..eb35419 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -35,10 +35,8 @@ symbian: { qtlibraries.pkg_postrules += qts60plugindeployment sqlitedeployment = \ - "; Deploy sqlite onto phone that does not have it (this should be replaced with embedded sis file when available)" \ - "IF NOT package(0x2002533b) " \ - "\"$${EPOCROOT}epoc32/release/$(PLATFORM)/$(TARGET)/sqlite3.dll\" - \"c:\\sys\\bin\\sqlite3.dll\"" \ - "ENDIF" + "; Deploy sqlite onto phone that does not have it already" \ + "@\"sqlite3.sis\", (0x2002af5f)" qtlibraries.pkg_postrules += sqlitedeployment qtlibraries.path = c:/sys/bin @@ -61,6 +59,7 @@ symbian: { contains(CONFIG, stl) { qtlibraries.pkg_prerules += "(0x2000F866), 1, 0, 0, {\"Standard C++ Library Common\"}" } + qtlibraries.pkg_prerules += "(0x2002af5f), 0, 5, 0, {\"sqlite3\"}" !contains(QT_CONFIG, no-jpeg): imageformats_plugins.sources += qjpeg.dll !contains(QT_CONFIG, no-gif): imageformats_plugins.sources += qgif.dll diff --git a/src/s60installs/sqlite3.sis b/src/s60installs/sqlite3.sis Binary files differnew file mode 100644 index 0000000..1785365 --- /dev/null +++ b/src/s60installs/sqlite3.sis diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 33653d6..e41cd55 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -452,8 +452,16 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, else return false; } else if (file.isFile()) { - const bool arc = addFile(alias, RCCFileInfo(alias.section(slash, -1), file, language, country, - RCCFileInfo::NoFlags, compressLevel, compressThreshold)); + const bool arc = + addFile(alias, + RCCFileInfo(alias.section(slash, -1), + file, + language, + country, + RCCFileInfo::NoFlags, + compressLevel, + compressThreshold) + ); if (!arc) m_failedResources.push_back(absFileName); } else { @@ -473,9 +481,16 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, it.next(); QFileInfo child(it.fileInfo()); if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) { - const bool arc = addFile(alias + child.fileName(), - RCCFileInfo(child.fileName(), child, language, country, - RCCFileInfo::NoFlags, compressLevel, compressThreshold)); + const bool arc = + addFile(alias + child.fileName(), + RCCFileInfo(child.fileName(), + child, + language, + country, + RCCFileInfo::NoFlags, + compressLevel, + compressThreshold) + ); if (!arc) m_failedResources.push_back(child.fileName()); } diff --git a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index 7fd994d..e5646c1 100644 --- a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -136,7 +136,7 @@ void tst_QAbstractNetworkCache::expires_data() QTest::newRow("200-0") << QNetworkRequest::AlwaysNetwork << "httpcachetest_expires200.cgi" << AlwaysFalse; QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_expires200.cgi" << false; QTest::newRow("200-2") << QNetworkRequest::AlwaysCache << "httpcachetest_expires200.cgi" << AlwaysTrue; - QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_expires200.cgi" << true; + QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_expires200.cgi" << false; } void tst_QAbstractNetworkCache::expires() @@ -158,7 +158,7 @@ void tst_QAbstractNetworkCache::lastModified_data() QTest::newRow("200-0") << QNetworkRequest::AlwaysNetwork << "httpcachetest_lastModified200.cgi" << AlwaysFalse; QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_lastModified200.cgi" << false; QTest::newRow("200-2") << QNetworkRequest::AlwaysCache << "httpcachetest_lastModified200.cgi" << AlwaysTrue; - QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_lastModified200.cgi" << true; + QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_lastModified200.cgi" << false; } void tst_QAbstractNetworkCache::lastModified() @@ -180,7 +180,7 @@ void tst_QAbstractNetworkCache::etag_data() QTest::newRow("200-0") << QNetworkRequest::AlwaysNetwork << "httpcachetest_etag200.cgi" << AlwaysFalse; QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_etag200.cgi" << false; QTest::newRow("200-2") << QNetworkRequest::AlwaysCache << "httpcachetest_etag200.cgi" << AlwaysTrue; - QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_etag200.cgi" << true; + QTest::newRow("200-3") << QNetworkRequest::PreferCache << "httpcachetest_etag200.cgi" << false; } void tst_QAbstractNetworkCache::etag() diff --git a/tests/auto/qapplication/heart.svg b/tests/auto/qapplication/heart.svg new file mode 100644 index 0000000..8c982cd --- /dev/null +++ b/tests/auto/qapplication/heart.svg @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --><svg viewBox="100 200 550 500" height="841.88976pt" id="svg1" inkscape:version="0.40+cvs" sodipodi:docbase="C:\Documents and Settings\Jon Phillips\My Documents\projects\clipart-project\submissions" sodipodi:docname="heart-left-highlight.svg" sodipodi:version="0.32" width="595.27559pt" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"> +<metadata> +<rdf:RDF xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> +<cc:Work rdf:about=""> +<dc:title>Heart Left-Highlight</dc:title> +<dc:description>This is a normal valentines day heart.</dc:description> +<dc:subject> +<rdf:Bag> +<rdf:li>holiday</rdf:li> +<rdf:li>valentines</rdf:li> +<rdf:li></rdf:li> +<rdf:li>valentine</rdf:li> +<rdf:li>hash(0x8a091c0)</rdf:li> +<rdf:li>hash(0x8a0916c)</rdf:li> +<rdf:li>signs_and_symbols</rdf:li> +<rdf:li>hash(0x8a091f0)</rdf:li> +<rdf:li>day</rdf:li> +</rdf:Bag> +</dc:subject> +<dc:publisher> +<cc:Agent rdf:about="http://www.openclipart.org"> +<dc:title>Jon Phillips</dc:title> +</cc:Agent> +</dc:publisher> +<dc:creator> +<cc:Agent> +<dc:title>Jon Phillips</dc:title> +</cc:Agent> +</dc:creator> +<dc:rights> +<cc:Agent> +<dc:title>Jon Phillips</dc:title> +</cc:Agent> +</dc:rights> +<dc:date></dc:date> +<dc:format>image/svg+xml</dc:format> +<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> +<cc:license rdf:resource="http://web.resource.org/cc/PublicDomain"/> +<dc:language>en</dc:language> +</cc:Work> +<cc:License rdf:about="http://web.resource.org/cc/PublicDomain"> +<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/> +<cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/> +<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/> +</cc:License> +</rdf:RDF> +</metadata> +<defs id="defs3"/> +<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:current-layer="layer1" inkscape:cx="549.40674" inkscape:cy="596.00159" inkscape:document-units="px" inkscape:guide-bbox="true" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="615" inkscape:window-width="866" inkscape:window-x="88" inkscape:window-y="116" inkscape:zoom="0.35000000" pagecolor="#ffffff" showguides="true"/> +<g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1"> +<path d="M 263.41570,235.14588 C 197.17570,235.14588 143.41575,288.90587 143.41575,355.14588 C 143.41575,489.90139 279.34890,525.23318 371.97820,658.45392 C 459.55244,526.05056 600.54070,485.59932 600.54070,355.14588 C 600.54070,288.90588 546.78080,235.14587 480.54070,235.14588 C 432.49280,235.14588 391.13910,263.51631 371.97820,304.33338 C 352.81740,263.51630 311.46370,235.14587 263.41570,235.14588 z " id="path7" sodipodi:nodetypes="ccccccc" style="fill:#e60000;fill-opacity:1.0000000;stroke:#000000;stroke-width:18.700001;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"/> +<path d="M 265.00000,253.59375 C 207.04033,253.59375 160.00000,300.63407 160.00000,358.59375 C 160.00000,476.50415 278.91857,507.43251 359.96875,624.00000 C 366.52868,614.08205 220.00000,478.47309 220.00000,378.59375 C 220.00000,320.63407 267.04033,273.59375 325.00000,273.59375 C 325.50453,273.59375 325.99718,273.64912 326.50000,273.65625 C 309.22436,261.07286 288.00557,253.59374 265.00000,253.59375 z " id="path220" sodipodi:nodetypes="ccccccc" style="fill:#e6e6e6;fill-opacity:0.64556962;stroke:none;stroke-width:18.700001;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"/> +</g> +</svg> diff --git a/tests/auto/qapplication/test/test.pro b/tests/auto/qapplication/test/test.pro index 7c3de3c..e68af26 100644 --- a/tests/auto/qapplication/test/test.pro +++ b/tests/auto/qapplication/test/test.pro @@ -16,7 +16,9 @@ symbian*: { additional.path = desktopsettingsaware someTest.sources = test.pro someTest.path = test - DEPLOYMENT = additional deploy someTest + windowIcon.sources = ../heart.svg + DEPLOYMENT = additional deploy someTest windowIcon + LIBS += -lcone -lavkon } win32 { diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index afd3b3a..b464867 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -53,6 +53,9 @@ #ifdef Q_OS_WINCE #include <windows.h> #endif +#ifdef Q_OS_SYMBIAN +#include <aknenv.h> +#endif //TESTED_CLASS= //TESTED_FILES= @@ -138,6 +141,8 @@ private slots: void touchEventPropagation(); + void symbianNoApplicationPanes(); + void symbianNeedForTraps(); void symbianLeaveThroughMain(); }; @@ -2036,6 +2041,89 @@ void tst_QApplication::touchEventPropagation() } } +void tst_QApplication::symbianNoApplicationPanes() +{ +#ifndef Q_OS_SYMBIAN + QSKIP("This is a Symbian only test", SkipAll); +#else + QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes); + + // Run in a block so that QApplication is destroyed before resetting the attribute. + { + // Actually I wasn't able to get the forced orientation change to work properly, + // but I'll leave the code here for the future in case we manage to test that + // later. If someone knows how to force an orientation switch in an autotest, do + // feel free to fix this testcase. + int argc = 0; + QApplication app(argc, 0); + QWidget *w; + + w = new QWidget; + w->show(); + QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); + app.processEvents(); + delete w; + + w = new QWidget; + w->show(); + QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showMaximized(); + QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showMaximized(); + QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showFullScreen(); + QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); + app.processEvents(); + delete w; + + w = new QWidget; + w->showFullScreen(); + QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi()) + ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); + app.processEvents(); + delete w; + + // These will have no effect, since there is no status pane, but they shouldn't + // crash either. + w = new QWidget; + w->show(); + w->setWindowTitle("Testing title"); + app.processEvents(); + delete w; + + w = new QWidget; + w->show(); + w->setWindowIcon(QIcon(QPixmap("heart.svg"))); + app.processEvents(); + delete w; + + QDesktopWidget desktop; + QCOMPARE(desktop.availableGeometry(), desktop.screenGeometry()); + } + + QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes, false); + + // No other error condition. Program will crash if unsuccessful. +#endif +} + #ifdef Q_OS_SYMBIAN class CBaseDummy : public CBase { diff --git a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp index d3d81e6..e332e11 100644 --- a/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp +++ b/tests/auto/qaudiodeviceinfo/tst_qaudiodeviceinfo.cpp @@ -128,7 +128,7 @@ void tst_QAudioDeviceInfo::codecs() void tst_QAudioDeviceInfo::channels() { if(available) { - QList<int> avail = device->supportedChannels(); + QList<int> avail = device->supportedChannelCounts(); QVERIFY(avail.size() > 0); } } @@ -160,7 +160,7 @@ void tst_QAudioDeviceInfo::sampleTypes() void tst_QAudioDeviceInfo::frequencies() { if(available) { - QList<int> avail = device->supportedFrequencies(); + QList<int> avail = device->supportedSampleRates(); QVERIFY(avail.size() > 0); } } @@ -169,8 +169,8 @@ void tst_QAudioDeviceInfo::isformat() { if(available) { QAudioFormat format; - format.setFrequency(44100); - format.setChannels(2); + format.setSampleRate(44100); + format.setChannelCount(2); format.setSampleType(QAudioFormat::SignedInt); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleSize(16); @@ -185,8 +185,8 @@ void tst_QAudioDeviceInfo::preferred() { if(available) { QAudioFormat format = device->preferredFormat(); - QVERIFY(format.frequency() == 44100); - QVERIFY(format.channels() == 2); + QVERIFY(format.sampleRate() == 44100); + QVERIFY(format.channelCount() == 2); } } @@ -194,9 +194,9 @@ void tst_QAudioDeviceInfo::nearest() { if(available) { QAudioFormat format1, format2; - format1.setFrequency(8000); + format1.setSampleRate(8000); format2 = device->nearestFormat(format1); - QVERIFY(format2.frequency() == 44100); + QVERIFY(format2.sampleRate() == 44100); } } diff --git a/tests/auto/qaudioformat/tst_qaudioformat.cpp b/tests/auto/qaudioformat/tst_qaudioformat.cpp index 0206798..a7200c4 100644 --- a/tests/auto/qaudioformat/tst_qaudioformat.cpp +++ b/tests/auto/qaudioformat/tst_qaudioformat.cpp @@ -77,8 +77,8 @@ void tst_QAudioFormat::checkNull() QAudioFormat audioFormat1(audioFormat0); QVERIFY(!audioFormat1.isValid()); - audioFormat0.setFrequency(44100); - audioFormat0.setChannels(2); + audioFormat0.setSampleRate(44100); + audioFormat0.setChannelCount(2); audioFormat0.setSampleSize(16); audioFormat0.setCodec("audio/pcm"); audioFormat0.setSampleType(QAudioFormat::SignedInt); @@ -88,15 +88,15 @@ void tst_QAudioFormat::checkNull() void tst_QAudioFormat::checkFrequency() { QAudioFormat audioFormat; - audioFormat.setFrequency(44100); - QVERIFY(audioFormat.frequency() == 44100); + audioFormat.setSampleRate(44100); + QVERIFY(audioFormat.sampleRate() == 44100); } void tst_QAudioFormat::checkChannels() { QAudioFormat audioFormat; - audioFormat.setChannels(2); - QVERIFY(audioFormat.channels() == 2); + audioFormat.setChannelCount(2); + QVERIFY(audioFormat.channelCount() == 2); } void tst_QAudioFormat::checkSampleSize() @@ -137,15 +137,15 @@ void tst_QAudioFormat::checkEquality() QVERIFY(!(audioFormat0 != audioFormat1)); // on filled formats - audioFormat0.setFrequency(8000); - audioFormat0.setChannels(1); + audioFormat0.setSampleRate(8000); + audioFormat0.setChannelCount(1); audioFormat0.setSampleSize(8); audioFormat0.setCodec("audio/pcm"); audioFormat0.setByteOrder(QAudioFormat::LittleEndian); audioFormat0.setSampleType(QAudioFormat::UnSignedInt); - audioFormat1.setFrequency(8000); - audioFormat1.setChannels(1); + audioFormat1.setSampleRate(8000); + audioFormat1.setChannelCount(1); audioFormat1.setSampleSize(8); audioFormat1.setCodec("audio/pcm"); audioFormat1.setByteOrder(QAudioFormat::LittleEndian); @@ -154,7 +154,7 @@ void tst_QAudioFormat::checkEquality() QVERIFY(audioFormat0 == audioFormat1); QVERIFY(!(audioFormat0 != audioFormat1)); - audioFormat0.setFrequency(44100); + audioFormat0.setSampleRate(44100); QVERIFY(audioFormat0 != audioFormat1); QVERIFY(!(audioFormat0 == audioFormat1)); } @@ -164,8 +164,8 @@ void tst_QAudioFormat::checkAssignment() QAudioFormat audioFormat0; QAudioFormat audioFormat1; - audioFormat0.setFrequency(8000); - audioFormat0.setChannels(1); + audioFormat0.setSampleRate(8000); + audioFormat0.setChannelCount(1); audioFormat0.setSampleSize(8); audioFormat0.setCodec("audio/pcm"); audioFormat0.setByteOrder(QAudioFormat::LittleEndian); diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp index 40b7fbb..9468413 100644 --- a/tests/auto/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -68,8 +68,8 @@ private: void tst_QAudioInput::initTestCase() { - format.setFrequency(8000); - format.setChannels(1); + format.setSampleRate(8000); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); @@ -94,8 +94,8 @@ void tst_QAudioInput::settings() // Confirm the setting we added in the init function. QAudioFormat f = audio->format(); - QVERIFY(format.channels() == f.channels()); - QVERIFY(format.frequency() == f.frequency()); + QVERIFY(format.channelCount() == f.channelCount()); + QVERIFY(format.sampleRate() == f.sampleRate()); QVERIFY(format.sampleSize() == f.sampleSize()); QVERIFY(format.codec() == f.codec()); QVERIFY(format.byteOrder() == f.byteOrder()); diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index aeb2286..5005838 100644 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -71,8 +71,8 @@ private: void tst_QAudioOutput::initTestCase() { - format.setFrequency(8000); - format.setChannels(1); + format.setSampleRate(8000); + format.setChannelCount(1); format.setSampleSize(8); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); @@ -95,8 +95,8 @@ void tst_QAudioOutput::settings() // Confirm the setting we added in the init function. QAudioFormat f = audio->format(); - QVERIFY(format.channels() == f.channels()); - QVERIFY(format.frequency() == f.frequency()); + QVERIFY(format.channelCount() == f.channelCount()); + QVERIFY(format.sampleRate() == f.sampleRate()); QVERIFY(format.sampleSize() == f.sampleSize()); QVERIFY(format.codec() == f.codec()); QVERIFY(format.byteOrder() == f.byteOrder()); diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 20cf922..33753f1 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -54,6 +54,7 @@ #include <QtNetwork/QLocalServer> #include <QtNetwork/QHostInfo> #include <QtNetwork/QFtp> +#include <QtNetwork/QAbstractNetworkCache> #include <QtNetwork/qauthenticator.h> #include <QtNetwork/qnetworkaccessmanager.h> #include <QtNetwork/qnetworkrequest.h> @@ -198,6 +199,8 @@ private Q_SLOTS: #endif void ioGetFromHttpBrokenServer_data(); void ioGetFromHttpBrokenServer(); + void ioGetFromHttpWithCache_data(); + void ioGetFromHttpWithCache(); void ioGetWithManyProxies_data(); void ioGetWithManyProxies(); @@ -318,8 +321,9 @@ public: QByteArray dataToTransmit; QByteArray receivedData; bool doClose; + int totalConnections; - MiniHttpServer(const QByteArray &data) : client(0), dataToTransmit(data), doClose(true) + MiniHttpServer(const QByteArray &data) : client(0), dataToTransmit(data), doClose(true), totalConnections(0) { listen(); connect(this, SIGNAL(newConnection()), this, SLOT(doAccept())); @@ -329,6 +333,7 @@ public slots: void doAccept() { client = nextPendingConnection(); + ++totalConnections; connect(client, SIGNAL(readyRead()), this, SLOT(sendData())); } @@ -379,6 +384,61 @@ public: } }; +class MyMemoryCache: public QAbstractNetworkCache +{ +public: + typedef QPair<QNetworkCacheMetaData, QByteArray> CachedContent; + typedef QHash<QByteArray, CachedContent> CacheData; + CacheData cache; + + MyMemoryCache(QObject *parent) : QAbstractNetworkCache(parent) {} + + QNetworkCacheMetaData metaData(const QUrl &url) + { + return cache.value(url.toEncoded()).first; + } + + void updateMetaData(const QNetworkCacheMetaData &metaData) + { + cache[metaData.url().toEncoded()].first = metaData; + } + + QIODevice *data(const QUrl &url) + { + CacheData::ConstIterator it = cache.find(url.toEncoded()); + if (it == cache.constEnd()) + return 0; + QBuffer *io = new QBuffer(this); + io->setData(it->second); + io->open(QIODevice::ReadOnly); + io->seek(0); + return io; + } + + bool remove(const QUrl &url) + { + cache.remove(url.toEncoded()); + return true; + } + + qint64 cacheSize() const + { + qint64 total = 0; + foreach (const CachedContent &entry, cache) + total += entry.second.size(); + return total; + } + + QIODevice *prepare(const QNetworkCacheMetaData &) + { Q_ASSERT(0 && "Should not have tried to add to the cache"); return 0; } + void insert(QIODevice *) + { Q_ASSERT(0 && "Should not have tried to add to the cache"); } + + void clear() { cache.clear(); } +}; +Q_DECLARE_METATYPE(MyMemoryCache::CachedContent) +Q_DECLARE_METATYPE(MyMemoryCache::CacheData) + class DataReader: public QObject { Q_OBJECT @@ -762,6 +822,7 @@ void tst_QNetworkReply::cleanup() // clear the internal cache QNetworkAccessManagerPrivate::clearCache(&manager); manager.setProxy(QNetworkProxy()); + manager.setCache(0); // clear cookies cookieJar->setAllCookies(QList<QNetworkCookie>()); @@ -1984,6 +2045,146 @@ void tst_QNetworkReply::ioGetFromHttpBrokenServer() QVERIFY(reply->error() != QNetworkReply::NoError); } +void tst_QNetworkReply::ioGetFromHttpWithCache_data() +{ + qRegisterMetaType<MyMemoryCache::CachedContent>(); + QTest::addColumn<QByteArray>("dataToSend"); + QTest::addColumn<QString>("body"); + QTest::addColumn<MyMemoryCache::CachedContent>("cachedReply"); + QTest::addColumn<int>("cacheMode"); + QTest::addColumn<bool>("loadedFromCache"); + QTest::addColumn<bool>("networkUsed"); + + QByteArray reply200 = + "HTTP/1.0 200\r\n" + "Connection: keep-alive\r\n" + "Content-Type: text/plain\r\n" + "Cache-control: no-cache\r\n" + "Content-length: 8\r\n" + "\r\n" + "Reloaded"; + QByteArray reply304 = + "HTTP/1.0 304 Use Cache\r\n" + "Connection: keep-alive\r\n" + "\r\n"; + + QTest::newRow("not-cached,always-network") + << reply200 << "Reloaded" << MyMemoryCache::CachedContent() << int(QNetworkRequest::AlwaysNetwork) << false << true; + QTest::newRow("not-cached,prefer-network") + << reply200 << "Reloaded" << MyMemoryCache::CachedContent() << int(QNetworkRequest::PreferNetwork) << false << true; + QTest::newRow("not-cached,prefer-cache") + << reply200 << "Reloaded" << MyMemoryCache::CachedContent() << int(QNetworkRequest::PreferCache) << false << true; + + QDateTime present = QDateTime::currentDateTime().toUTC(); + QDateTime past = present.addSecs(-3600); + QDateTime future = present.addSecs(3600); + static const char dateFormat[] = "ddd, dd MMM yyyy hh:mm:ss 'GMT'"; + + QNetworkCacheMetaData::RawHeaderList rawHeaders; + MyMemoryCache::CachedContent content; + content.second = "Not-reloaded"; + content.first.setLastModified(past); + + // + // Set to expired + // + rawHeaders.clear(); + rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1()) + << QNetworkCacheMetaData::RawHeader("Cache-control", "max-age=0"); // isn't used in cache loading + content.first.setRawHeaders(rawHeaders); + content.first.setLastModified(past); + + QTest::newRow("expired,200,prefer-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << false << true; + QTest::newRow("expired,200,prefer-cache") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferCache) << false << true; + + QTest::newRow("expired,304,prefer-network") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << true; + QTest::newRow("expired,304,prefer-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << true; + + // + // Set to not-expired + // + rawHeaders.clear(); + rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1()) + << QNetworkCacheMetaData::RawHeader("Cache-control", "max-age=7200"); // isn't used in cache loading + content.first.setRawHeaders(rawHeaders); + content.first.setExpirationDate(future); + + QTest::newRow("not-expired,200,always-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::AlwaysNetwork) << false << true; + QTest::newRow("not-expired,200,prefer-network") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << false; + QTest::newRow("not-expired,200,prefer-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("not-expired,200,always-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; + + QTest::newRow("not-expired,304,prefer-network") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << false; + QTest::newRow("not-expired,304,prefer-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("not-expired,304,always-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; + + // + // Set must-revalidate now + // + rawHeaders.clear(); + rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1()) + << QNetworkCacheMetaData::RawHeader("Cache-control", "max-age=7200, must-revalidate"); // must-revalidate is used + content.first.setRawHeaders(rawHeaders); + + QTest::newRow("must-revalidate,200,always-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::AlwaysNetwork) << false << true; + QTest::newRow("must-revalidate,200,prefer-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << false << true; + QTest::newRow("must-revalidate,200,prefer-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("must-revalidate,200,always-cache") + << reply200 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; + + QTest::newRow("must-revalidate,304,prefer-network") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << true << true; + QTest::newRow("must-revalidate,304,prefer-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << true << false; + QTest::newRow("must-revalidate,304,always-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << true << false; +} + +void tst_QNetworkReply::ioGetFromHttpWithCache() +{ + QFETCH(QByteArray, dataToSend); + MiniHttpServer server(dataToSend); + server.doClose = false; + + MyMemoryCache *memoryCache = new MyMemoryCache(&manager); + manager.setCache(memoryCache); + + QFETCH(MyMemoryCache::CachedContent, cachedReply); + QUrl url = "http://localhost:" + QString::number(server.serverPort()); + cachedReply.first.setUrl(url); + if (!cachedReply.second.isNull()) + memoryCache->cache.insert(url.toEncoded(), cachedReply); + + QFETCH(int, cacheMode); + QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, cacheMode); + request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false); + QNetworkReplyPtr reply = manager.get(request); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QTEST(reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool(), "loadedFromCache"); + QTEST(server.totalConnections > 0, "networkUsed"); + QFETCH(QString, body); + QCOMPARE(reply->readAll().constData(), qPrintable(body)); +} + void tst_QNetworkReply::ioGetWithManyProxies_data() { QTest::addColumn<QList<QNetworkProxy> >("proxyList"); diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index 1b2f268..e0512a9 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -1114,7 +1114,10 @@ class ProxyStyle : public QStyle const QStyleOption* opt, const QWidget* w) const { - return style->subElementRect(se, opt, w); + Q_UNUSED(se); + Q_UNUSED(opt); + Q_UNUSED(w); + return QRect(0, 0, 3, 3); } void drawComplexControl(QStyle::ComplexControl cc, @@ -1232,7 +1235,7 @@ void tst_QStyleSheetStyle::proxyStyle() pb4->setStyleSheet(styleSheet); // We are creating our Proxy based on current style... - // In this case it would be the QStyleSheetStyle that is delete + // In this case it would be the QStyleSheetStyle that is deleted // later on. We need to get access to the "real" QStyle to be able to // draw correctly. ProxyStyle* newProxy = new ProxyStyle(qApp->style()); @@ -1248,6 +1251,13 @@ void tst_QStyleSheetStyle::proxyStyle() w->show(); QTest::qWait(100); + + // Test for QTBUG-7198 - style sheet overrides custom element size + QStyleOptionViewItemV4 opt; + opt.initFrom(w); + opt.features |= QStyleOptionViewItemV2::HasCheckIndicator; + QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, + &opt, pb5).width() == 3); delete w; delete proxy; delete newProxy; diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 7bb4bb1..1c78f1f 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -8,6 +8,7 @@ SUBDIRS = containers-associative \ qhostinfo \ qpainter \ qtestlib-simple events \ + qtext \ qiodevice \ qpixmap \ blendbench \ diff --git a/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp index d2f8090..5bd07f9 100644 --- a/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/benchmarks/qgraphicsscene/tst_qgraphicsscene.cpp @@ -64,6 +64,7 @@ private slots: void addItem(); void itemAt_data(); void itemAt(); + void initialShow(); }; tst_QGraphicsScene::tst_QGraphicsScene() @@ -227,5 +228,21 @@ void tst_QGraphicsScene::itemAt() qApp->processEvents(); } +void tst_QGraphicsScene::initialShow() +{ + QGraphicsScene scene; + + QBENCHMARK { + for (int y = 0; y < 30000; ++y) { + QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 50, 50); + item->setPos((y/2) * item->rect().width(), (y/2) * item->rect().height()); + scene.addItem(item); + } + scene.itemAt(0, 0); // triggers indexing + //This call polish the items so we bench their processing too. + qApp->processEvents(); + } +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" diff --git a/tests/benchmarks/qtext/bidi.txt b/tests/benchmarks/qtext/bidi.txt new file mode 100644 index 0000000..7c74cb4 --- /dev/null +++ b/tests/benchmarks/qtext/bidi.txt @@ -0,0 +1,4 @@ +chinese +欧洲,软件+互联网
用统一码 (Unicode) 走遍世界
将于1997年 3 月10日-12日在德国 Mainz 市举行的第十届统一码国际研讨会现在开始注册。 本次会议将汇集各方面的专家。 涉及的领域包括: 国际互联网和统一码 ,国际化和本地化 ,统一码在操作系统和应用软件中的实现 ,字型 ,文本格式以及多文种计算等。
当世界需要沟通时,请用Unicode! +hebrew-bidi +אײראָפּע: פּראָגראַמװאַרג און די װעלטנעץ: אוניקאָד איבער דער גאָרער װעלט פֿאַרשרײַבט זיך שױן אױף דער צענטער אינטערנאַציאָנאַלער אוניקאָד-קאָנפֿערענץ, װאָס װעט פֿאָרקומען דעם 10טן ביזן 12טן מאַרץ, 1997, אין מײַנץ, דײַטשלאַנד. די קאָנפֿערענץ װעט צוזאַמענברענגן מבֿינים פֿון װעלטנעץ, אוניקאָד, אי אַלװעלטלעכן אי סבֿיבֿהדיקן פּראָגראַמװאַרג, אַרײַנשטעלן אוניקאָד אין אָפּעריר-סיסטעמען און אָנװענדונגען, שריפֿטן, טעקסט-אױסשטעל, און מערשפּראַכיקע קאָמפּיוטערײַ. diff --git a/tests/benchmarks/qtext/main.cpp b/tests/benchmarks/qtext/main.cpp new file mode 100644 index 0000000..3c973b6 --- /dev/null +++ b/tests/benchmarks/qtext/main.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +#include <QTextDocument> +#include <QTextLayout> +#include <QFile> +#include <qtest.h> + +class tst_QText: public QObject +{ + Q_OBJECT +private slots: + void loadHtml_data(); + void loadHtml(); + + void shaping_data(); + void shaping(); +}; + +void tst_QText::loadHtml_data() +{ + QTest::addColumn<QString>("source"); + QTest::newRow("empty") << QString(); + QTest::newRow("simple") << QString::fromLatin1("<html><b>Foo</b></html>"); + QTest::newRow("simple2") << QString::fromLatin1("<b>Foo</b>"); + + QString parag = QString::fromLatin1("<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. <b>Duis <i>autem</i> vel eum </b> iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>"); + QString header = QString::fromLatin1("<html><head><title>test</title></head><body>"); + QTest::newRow("long") << QString::fromLatin1("<html><head><title>test</title></head><body>") + parag + parag + parag + + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + parag + + QString::fromLatin1("</html>"); + QTest::newRow("table") << header + QLatin1String("<table border=\"1\"1><tr><td>xx</td></tr><tr><td colspan=\"2\">") + + parag + QLatin1String("</td></tr></table></html"); + QTest::newRow("crappy") << header + QLatin1String("<table border=\"1\"1><tr><td>xx</td></tr><tr><td colspan=\"2\">") + + parag; +} + +void tst_QText::loadHtml() +{ + QFETCH(QString, source); + QTextDocument doc; + QBENCHMARK { + doc.setHtml(source); + } +} + +void tst_QText::shaping_data() +{ + QTest::addColumn<QString>("parag"); + QTest::newRow("empty") << QString(); + QTest::newRow("lorem") << QString::fromLatin1("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."); + QTest::newRow("short") << QString::fromLatin1("Lorem ipsum dolor sit amet"); + + QFile file(QString::fromLatin1(SRCDIR) + QLatin1String("/bidi.txt")); + QVERIFY(file.open(QFile::ReadOnly)); + QByteArray data = file.readAll(); + QVERIFY(data.count() > 1000); + QStringList list = QString::fromUtf8(data.data()).split(QLatin1Char('\n'), QString::SkipEmptyParts); + QVERIFY(list.count() %2 == 0); // even amount as we have title and then content. + for (int i=0; i < list.count(); i+=2) { + QTest::newRow(list.at(i).toLatin1()) << list.at(i+1); + } +} + +void tst_QText::shaping() +{ + QFETCH(QString, parag); + + QTextLayout lay(parag); + lay.setCacheEnabled(false); + + // do one run to make sure any fonts are loaded. + lay.beginLayout(); + lay.createLine(); + lay.endLayout(); + + QBENCHMARK { + lay.beginLayout(); + lay.createLine(); + lay.endLayout(); + } +} + +QTEST_MAIN(tst_QText) + +#include "main.moc" diff --git a/tests/benchmarks/qtext/qtext.pro b/tests/benchmarks/qtext/qtext.pro new file mode 100644 index 0000000..ce4f604 --- /dev/null +++ b/tests/benchmarks/qtext/qtext.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_QText + +SOURCES += main.cpp + +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index 6a1de89..d8c306f 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -155,6 +155,10 @@ int main(int argc, char *argv[]) serialPortName = id.portName; } } + if(serialPortName.isEmpty()) { + errstream << "No phone found, ensure USB cable is connected or specify manually with -p" << endl; + return 1; + } } QScopedPointer<trk::Launcher> launcher; diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro index d243121..cf0c055 100644 --- a/tools/runonphone/runonphone.pro +++ b/tools/runonphone/runonphone.pro @@ -15,5 +15,6 @@ HEADERS += trksignalhandler.h \ windows { SOURCES += serenum_win.cpp LIBS += -lsetupapi \ - -luuid + -luuid \ + -ladvapi32 } diff --git a/tools/runonphone/serenum_win.cpp b/tools/runonphone/serenum_win.cpp index 374cf3a..572161c 100644 --- a/tools/runonphone/serenum_win.cpp +++ b/tools/runonphone/serenum_win.cpp @@ -77,8 +77,7 @@ QList<SerialPortId> enumerateSerialPorts() } HKEY key = SetupDiOpenDevRegKey(infoset, &info, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if(key != INVALID_HANDLE_VALUE) { -#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 - //RegGetValue not supported on XP, SHRegGetValue not supported by mingw :( + //RegGetValue not supported on XP, SHRegGetValue not supported by mingw, so use the old method of enumerating all the values for (DWORD dwi=0;;dwi++) { DWORD vsize = valueName.size(); if (ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, 0, &size)) { @@ -93,14 +92,6 @@ QList<SerialPortId> enumerateSerialPorts() break; } } -#else - if (ERROR_SUCCESS == SHRegGetValue(key, 0, "PortName", SRRF_RT_REG_SZ, 0, &size)) { - QByteArray ba(size, 0); - if (ERROR_SUCCESS == RegGetValue(key, 0, "PortName", SRRF_RT_REG_SZ, (BYTE*)(ba.data()), &size)) { - portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1); - } - } -#endif RegCloseKey(key); } SerialPortId id; diff --git a/util/qlalr/qlalr.pro b/util/qlalr/qlalr.pro index 881a36a..1994a73 100644 --- a/util/qlalr/qlalr.pro +++ b/util/qlalr/qlalr.pro @@ -1,6 +1,7 @@ TEMPLATE = app QT = core +CONFIG += console TARGET = qlalr mac:CONFIG -= app_bundle |