diff options
author | Sami Merila <sami.merila@nokia.com> | 2010-09-16 07:52:35 (GMT) |
---|---|---|
committer | Sami Merila <sami.merila@nokia.com> | 2010-09-16 07:52:35 (GMT) |
commit | 92c4522ff48c616738f5ba3e117c347c40cc2537 (patch) | |
tree | 18b68bb6a0fa0029324e3a2285be705b2514fc15 | |
parent | f055e5daf17d73a56ac956c273a0a7160e634e7b (diff) | |
parent | 554eedb76ecceca5123992147ed1aa48aabc6662 (diff) | |
download | Qt-92c4522ff48c616738f5ba3e117c347c40cc2537.zip Qt-92c4522ff48c616738f5ba3e117c347c40cc2537.tar.gz Qt-92c4522ff48c616738f5ba3e117c347c40cc2537.tar.bz2 |
Merge branch '4.7' of git@scm.dev.nokia.troll.no:qt/qt-s60-public into 4.7
39 files changed, 1564 insertions, 210 deletions
diff --git a/examples/declarative/modelviews/listview/content/pics/arrow-down.png b/examples/declarative/modelviews/listview/content/pics/arrow-down.png Binary files differnew file mode 100644 index 0000000..29d1d44 --- /dev/null +++ b/examples/declarative/modelviews/listview/content/pics/arrow-down.png diff --git a/examples/declarative/modelviews/listview/content/pics/arrow-up.png b/examples/declarative/modelviews/listview/content/pics/arrow-up.png Binary files differnew file mode 100644 index 0000000..e437312 --- /dev/null +++ b/examples/declarative/modelviews/listview/content/pics/arrow-up.png diff --git a/examples/declarative/modelviews/listview/content/pics/list-delete.png b/examples/declarative/modelviews/listview/content/pics/list-delete.png Binary files differnew file mode 100644 index 0000000..df2a147 --- /dev/null +++ b/examples/declarative/modelviews/listview/content/pics/list-delete.png diff --git a/examples/declarative/modelviews/listview/content/pics/minus-sign.png b/examples/declarative/modelviews/listview/content/pics/minus-sign.png Binary files differindex 2bb1a59..d6f233d 100644 --- a/examples/declarative/modelviews/listview/content/pics/minus-sign.png +++ b/examples/declarative/modelviews/listview/content/pics/minus-sign.png diff --git a/examples/declarative/modelviews/listview/content/pics/plus-sign.png b/examples/declarative/modelviews/listview/content/pics/plus-sign.png Binary files differindex e029787..40df113 100644 --- a/examples/declarative/modelviews/listview/content/pics/plus-sign.png +++ b/examples/declarative/modelviews/listview/content/pics/plus-sign.png diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index c66c1b8..32c31ee 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -56,12 +56,21 @@ SymbianSbsv2MakefileGenerator::~SymbianSbsv2MakefileGenerator() { } #define FLM_DEST_DIR "epoc32/tools/makefile_templates/qt" #define FLM_SOURCE_DIR "/mkspecs/symbian-sbsv2/flm/qt" -#define UNDETECTED_GCCE_VERSION "0" #define PLATFORM_GCCE "gcce" #define PLATFORM_WINSCW "winscw" -#define PLATFORM_ARMV5 "armv5" +#define PLATFORM_ARM_PREFIX "arm" #define BUILD_DEBUG "udeb" #define BUILD_RELEASE "urel" +#define SBS_RVCT_PREFIX "rvct" + +static QString winscwPlatform; +static QString armPlatformPrefix; +static QString gccePlatform; +static QString sbsRvctPrefix; + +#if defined(Q_OS_UNIX) + extern char **environ; +#endif // Copies Qt FLMs to correct location under epocroot. // This is not done by configure as it is possible to change epocroot after configure. @@ -96,64 +105,95 @@ void SymbianSbsv2MakefileGenerator::exportFlm() } } -QString SymbianSbsv2MakefileGenerator::gcceVersion() +void SymbianSbsv2MakefileGenerator::findInstalledCompilerVersions(const QString &matchExpression, + const QString &versionPrefix, + QStringList *versionList) { - static QString gcceVersionStr; - - if (gcceVersionStr.isEmpty()) { - // First check if QT_GCCE_VERSION has been set, and use that if it is - QByteArray qtGcceVersion = qgetenv("QT_GCCE_VERSION"); - if (!qtGcceVersion.isEmpty()) { - // Check that QT_GCCE_VERSION is in proper format - QString check(qtGcceVersion); - check.replace(QRegExp("^\\d+\\.\\d+\\.\\d+$"),QString()); - if (check.isEmpty()) { - gcceVersionStr = PLATFORM_GCCE + QString(qtGcceVersion).replace(".","_"); - return gcceVersionStr; - } else { - fprintf(stderr, "Warning: Environment variable QT_GCCE_VERSION ('%s') is in incorrect " - "format, expected format is: '1.2.3'. Attempting to autodetect GCCE version.", - qtGcceVersion.constData()); + // No need to be able to find env variables on other operating systems, + // as only linux and windows have support for symbian-sbsv2 toolchain +#if defined(Q_OS_UNIX) || defined(Q_OS_WIN) + char *entry = 0; + int count = 0; + QRegExp matcher(matchExpression); + while ((entry = environ[count++])) { + if (matcher.exactMatch(QString::fromLocal8Bit(entry)) + && fileInfo(matcher.cap(matcher.captureCount())).exists()) { + // First capture (index 0) is the whole match, which is skipped. + // Next n captures are version numbers, which are interesting. + // Final capture is the env var value, which we alrady used, so that is skipped, too. + int capture = 1; + int finalCapture = matcher.captureCount() - 1; + QString version = versionPrefix; + while (capture <= finalCapture) { + version.append(matcher.cap(capture)); + if (capture != finalCapture) + version.append(QLatin1Char('.')); + capture++; } + *versionList << version; } - // Sbsv2 has separate env variable defined for each gcce version, so try to determine - // which user is likely to want to use by checking version 4.0.0 to 9.9.9 and taking - // the highest found version that actually points to a valid path. - // This is kind of a kludge, but since qmake doesn't bootstrap QProcess, there - // is no Qt API available to get all environment variables. - for (int i = 9; i >= 4; i--) { - for (int j = 9; j >= 0; j--) { - for (int k = 9; k >= 0; k--) { - QByteArray gcceVar = qgetenv(qPrintable(QString("SBS_GCCE%1%2%3BIN").arg(i).arg(j).arg(k))); - if (!gcceVar.isEmpty() && fileInfo(QString::fromLocal8Bit(gcceVar.constData())).exists()) { - gcceVersionStr = QString(PLATFORM_GCCE "%1_%2_%3").arg(i).arg(j).arg(k); - return gcceVersionStr; - } - } - } + } +#endif +} + +void SymbianSbsv2MakefileGenerator::findGcceVersions(QStringList *gcceVersionList, + QString *defaultVersion) +{ + QString matchStr = QLatin1String("SBS_GCCE(\\d)(\\d)(\\d)BIN=(.*)"); + findInstalledCompilerVersions(matchStr, gccePlatform, gcceVersionList); + + QString qtGcceVersion = QString::fromLocal8Bit(qgetenv("QT_GCCE_VERSION")); + + if (!qtGcceVersion.isEmpty()) { + if (QRegExp("\\d+\\.\\d+\\.\\d+").exactMatch(qtGcceVersion)) { + *defaultVersion = gccePlatform + qtGcceVersion; + } else { + fprintf(stderr, "Warning: Variable QT_GCCE_VERSION ('%s') is in incorrect " + "format, expected format is: 'x.y.z'. Attempting to autodetect GCCE version.\n", + qPrintable(qtGcceVersion)); } } - // Indicate undetected version to avoid rechecking multiple times - if (gcceVersionStr.isEmpty()) - gcceVersionStr = UNDETECTED_GCCE_VERSION; + if (defaultVersion->isEmpty() && gcceVersionList->size()) { + gcceVersionList->sort(); + *defaultVersion = gcceVersionList->last(); + } +} + +void SymbianSbsv2MakefileGenerator::findRvctVersions(QStringList *rvctVersionList, + QString *defaultVersion) +{ + QString matchStr = QLatin1String("RVCT(\\d)(\\d)BIN=(.*)"); + findInstalledCompilerVersions(matchStr, sbsRvctPrefix, rvctVersionList); + + QString qtRvctVersion = QString::fromLocal8Bit(qgetenv("QT_RVCT_VERSION")); - return gcceVersionStr; + if (!qtRvctVersion.isEmpty()) { + if (QRegExp("\\d+\\.\\d+").exactMatch(qtRvctVersion)) { + *defaultVersion = sbsRvctPrefix + qtRvctVersion; + } else { + fprintf(stderr, "Warning: Variable QT_RVCT_VERSION ('%s') is in incorrect " + "format, expected format is: 'x.y'.\n", + qPrintable(qtRvctVersion)); + } + } } -QString SymbianSbsv2MakefileGenerator::configClause(QString &platform, - QString &build, - QString &winscwClauseTemplate, - QString &gcceClauseTemplate, - QString &genericClauseTemplate) +QString SymbianSbsv2MakefileGenerator::configClause(const QString &platform, + const QString &build, + const QString &compilerVersion, + const QString &clauseTemplate) { QString retval; - if (QString::compare(platform, PLATFORM_WINSCW) == 0) - retval = winscwClauseTemplate.arg(build); - else if (QString::compare(platform, PLATFORM_GCCE) == 0) - retval = gcceClauseTemplate.arg(build); - else - retval = genericClauseTemplate.arg(platform).arg(build); + if (QString::compare(platform, winscwPlatform) == 0) { + retval = clauseTemplate.arg(build); + } else if (platform.startsWith(armPlatformPrefix)) { + QString fixedCompilerVersion = compilerVersion; + fixedCompilerVersion.replace(".","_"); + retval = clauseTemplate.arg(platform.mid(sizeof(PLATFORM_ARM_PREFIX)-1)) + .arg(build) + .arg(fixedCompilerVersion); + } // else - Unsupported platform for makefile target, return empty clause return retval; } @@ -185,52 +225,101 @@ void SymbianSbsv2MakefileGenerator::writeMkFile(const QString& wrapperFileName, void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool isPrimaryMakefile) { - static QString debugBuild(BUILD_DEBUG); - static QString releaseBuild(BUILD_RELEASE); + static QString debugBuild; + static QString releaseBuild; + static QString defaultGcceCompilerVersion; + static QString defaultRvctCompilerVersion; + static QStringList rvctVersions; + static QStringList gcceVersions; + static QStringList allArmCompilerVersions; + + // Initialize static variables used in makefile creation + if (debugBuild.isEmpty()) { + debugBuild.append(QLatin1String(BUILD_DEBUG)); + releaseBuild.append(QLatin1String(BUILD_RELEASE)); + winscwPlatform.append(QLatin1String(PLATFORM_WINSCW)); + gccePlatform.append(QLatin1String(PLATFORM_GCCE)); + armPlatformPrefix.append(QLatin1String(PLATFORM_ARM_PREFIX)); + sbsRvctPrefix.append(QLatin1String(SBS_RVCT_PREFIX)); + + findGcceVersions(&gcceVersions, &defaultGcceCompilerVersion); + findRvctVersions(&rvctVersions, &defaultRvctCompilerVersion); + + allArmCompilerVersions << rvctVersions << gcceVersions; + + if (!allArmCompilerVersions.size()) { + fprintf(stderr, "Warning: No HW compilers detected. " + "Please install either GCCE or RVCT compiler to enable release builds.\n"); + } + } QStringList allPlatforms; foreach(QString platform, project->values("SYMBIAN_PLATFORMS")) { allPlatforms << platform.toLower(); } + if (!gcceVersions.size()) + allPlatforms.removeAll(gccePlatform); + QString testClause; if (project->isActiveConfig(SYMBIAN_TEST_CONFIG)) testClause = QLatin1String(".test"); else testClause = QLatin1String(""); - QString genericClause = " -c %1_%2" + testClause; - QString winscwClause = " -c winscw_%1.mwccinc" + testClause; - QString gcceClause; - bool stripArmv5 = false; + // Note: armClause is used for gcce, too, which has a side effect + // of requiring armv* platform(s) in SYMBIAN_PLATFORMS in order + // to get any compiler version specific targets. + QString armClause = " -c " PLATFORM_ARM_PREFIX ".%1.%2.%3" + testClause; + QString genericArmClause; + if (defaultRvctCompilerVersion.isEmpty()) { + // Note: Argument %3 needs to be empty string in this version of clause + genericArmClause = " -c " PLATFORM_ARM_PREFIX "%1_%2%3" + testClause; + } else { + // If defaultRvctCompilerVersion is defined, use specific sbs clause for "generic" clause + genericArmClause = armClause; + } + QString winscwClause = " -c " PLATFORM_WINSCW "_%1.mwccinc" + testClause;; - if (allPlatforms.contains(PLATFORM_GCCE)) { - if (QString::compare(gcceVersion(), UNDETECTED_GCCE_VERSION) == 0) { - allPlatforms.removeAll(PLATFORM_GCCE); - } else { - gcceClause = " -c arm.v5.%1." + gcceVersion() + testClause; - // Since gcce building is enabled, do not add armv5 for any sbs command - // that also contains gcce, because those will build same targets. - stripArmv5 = true; + QStringList armPlatforms = allPlatforms.filter(QRegExp("^" PLATFORM_ARM_PREFIX)); + + if (!allArmCompilerVersions.size()) { + foreach (QString item, armPlatforms) { + allPlatforms.removeAll(item); } + armPlatforms.clear(); } QStringList allClauses; QStringList debugClauses; QStringList releaseClauses; + // Only winscw and arm platforms are supported QStringList debugPlatforms = allPlatforms; QStringList releasePlatforms = allPlatforms; - releasePlatforms.removeAll(PLATFORM_WINSCW); // No release for emulator + releasePlatforms.removeAll(winscwPlatform); // No release for emulator - foreach(QString item, debugPlatforms) { - if (item != PLATFORM_ARMV5 || !stripArmv5) - debugClauses << configClause(item, debugBuild, winscwClause, gcceClause, genericClause); + if (!releasePlatforms.size()) { + fprintf(stderr, "Warning: No valid release platforms in SYMBIAN_PLATFORMS (%s)\n" + "Most likely required compiler(s) are not properly installed.\n", + qPrintable(project->values("SYMBIAN_PLATFORMS").join(" "))); } - foreach(QString item, releasePlatforms) { - if (item != PLATFORM_ARMV5 || !stripArmv5) - releaseClauses << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause); + + if (debugPlatforms.contains(winscwPlatform)) + debugClauses << configClause(winscwPlatform, debugBuild, QString(), winscwClause); + + foreach(QString item, armPlatforms) { + // Only use single clause per arm platform even if multiple compiler versions were found, + // otherwise we get makefile target collisions from sbsv2 toolchain. + if (rvctVersions.size()) { + debugClauses << configClause(item, debugBuild, defaultRvctCompilerVersion, genericArmClause); + releaseClauses << configClause(item, releaseBuild, defaultRvctCompilerVersion, genericArmClause); + } else { + debugClauses << configClause(item, debugBuild, defaultGcceCompilerVersion, armClause); + releaseClauses << configClause(item, releaseBuild, defaultGcceCompilerVersion, armClause); + } } + allClauses << debugClauses << releaseClauses; QTextStream t(&wrapperFile); @@ -270,22 +359,20 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << " -I\"" << values.at(i) << "\" "; } } - t << endl; - t << "first: default" << endl; - if (debugPlatforms.contains(PLATFORM_WINSCW)) - t << "default: debug-winscw"; - else if (debugPlatforms.contains(PLATFORM_ARMV5)) - t << "default: debug-armv5"; - else if (debugPlatforms.size()) - t << "default: debug-" << debugPlatforms.first(); - else - t << "default: all"; t << endl; + t << "first: default" << endl << endl; if (!isPrimaryMakefile) { - t << "all:" << endl; + t << "all:" << endl << endl; + t << "default: all" << endl << endl; } else { - t << "all: debug release" << endl; + t << "all: debug release" << endl << endl; + if (debugPlatforms.contains(winscwPlatform)) + t << "default: debug-winscw"; + else if (debugPlatforms.size()) + t << "default: debug-" << debugPlatforms.first(); + else + t << "default: all"; t << endl; QString qmakeCmd = "\t$(QMAKE) \"" + project->projectFile() + "\" " + buildArgs(); @@ -302,30 +389,80 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << "debug: " << BLD_INF_FILENAME << endl; t << "\t$(SBS)"; - foreach(QString item, debugClauses) { - t << item; + foreach(QString clause, debugClauses) { + t << clause; + } + t << endl; + t << "clean-debug: " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean"; + foreach(QString clause, debugClauses) { + t << clause; } t << endl; t << "release: " << BLD_INF_FILENAME << endl; t << "\t$(SBS)"; - foreach(QString item, releaseClauses) { - t << item; + foreach(QString clause, releaseClauses) { + t << clause; } t << endl; + t << "clean-release: " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean"; + foreach(QString clause, releaseClauses) { + t << clause; + } + t << endl << endl; + + QString defaultGcceArmVersion; + if (armPlatforms.size()) { + defaultGcceArmVersion = armPlatforms.first(); + } else { + defaultGcceArmVersion = QLatin1String("armv5"); + } - // For more specific builds, targets are in this form: build-platform, e.g. release-armv5 + // For more specific builds, targets are in this form: + // release-armv5 - generic target, compiler version determined by toolchain or autodetection + // release-armv5-rvct4.0 - compiler version specific target foreach(QString item, debugPlatforms) { + QString clause; + if (item.compare(winscwPlatform) == 0) + clause = configClause(item, debugBuild, QString(), winscwClause); + else if (item.compare(gccePlatform) == 0 ) + clause = configClause(defaultGcceArmVersion, debugBuild, defaultGcceCompilerVersion, armClause); + else // use generic arm clause + clause = configClause(item, debugBuild, defaultRvctCompilerVersion, genericArmClause); + t << "debug-" << item << ": " << BLD_INF_FILENAME << endl; - t << "\t$(SBS)"; - t << configClause(item, debugBuild, winscwClause, gcceClause, genericClause); - t << endl; + t << "\t$(SBS)" << clause << endl; + t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean" << clause << endl; } foreach(QString item, releasePlatforms) { + QString clause; + if (item.compare(gccePlatform) == 0 ) + clause = configClause(defaultGcceArmVersion, releaseBuild, defaultGcceCompilerVersion, armClause); + else // use generic arm clause + clause = configClause(item, releaseBuild, defaultRvctCompilerVersion, genericArmClause); + t << "release-" << item << ": " << BLD_INF_FILENAME << endl; - t << "\t$(SBS)"; - t << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause); - t << endl; + t << "\t$(SBS)" << clause << endl; + t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean" << clause << endl; + } + + foreach(QString item, armPlatforms) { + foreach(QString compilerVersion, allArmCompilerVersions) { + QString debugClause = configClause(item, debugBuild, compilerVersion, armClause); + QString releaseClause = configClause(item, releaseBuild, compilerVersion, armClause); + t << "debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS)" << debugClause << endl; + t << "clean-debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean" << debugClause << endl; + t << "release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS)" << releaseClause << endl; + t << "clean-release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; + t << "\t$(SBS) reallyclean" << releaseClause << endl; + } } t << endl; @@ -344,7 +481,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << endl << endl; } - // Add all extra targets including extra compiler targest also to wrapper makefile, + // Add all extra targets including extra compiler targets also to wrapper makefile, // even though many of them may have already been added to bld.inf as FLMs. // This is to enable use of targets like 'mocables', which call targets generated by extra compilers. if (targetType != TypeSubdirs) { @@ -365,32 +502,6 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo } t << endl << endl; - t << "clean-debug: " << BLD_INF_FILENAME << endl; - t << "\t$(SBS) reallyclean"; - foreach(QString clause, debugClauses) { - t << clause; - } - t << endl << endl; - t << "clean-release: " << BLD_INF_FILENAME << endl; - t << "\t$(SBS) reallyclean"; - foreach(QString clause, releaseClauses) { - t << clause; - } - t << endl << endl; - - // For more specific builds, targets are in this form: clean-build-platform, e.g. clean-release-armv5 - foreach(QString item, debugPlatforms) { - t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl; - t << "\t$(SBS) reallyclean"; - t << configClause(item, debugBuild, winscwClause, gcceClause, genericClause); - t << endl; - } - foreach(QString item, releasePlatforms) { - t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl; - t << "\t$(SBS) reallyclean"; - t << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause); - t << endl; - } t << endl; } diff --git a/qmake/generators/symbian/symmake_sbsv2.h b/qmake/generators/symbian/symmake_sbsv2.h index 6644a03..557e3dd 100644 --- a/qmake/generators/symbian/symmake_sbsv2.h +++ b/qmake/generators/symbian/symmake_sbsv2.h @@ -65,12 +65,15 @@ public: private: void exportFlm(); - QString gcceVersion(); - QString configClause(QString &platform, - QString &build, - QString &winscwClauseTemplate, - QString &gcceClauseTemplate, - QString &genericClauseTemplate); + void findGcceVersions(QStringList *gcceVersionList, QString *defaultVersion); + void findRvctVersions(QStringList *rvctVersionList, QString *defaultVersion); + void findInstalledCompilerVersions(const QString &matchExpression, + const QString &versionPrefix, + QStringList *versionList); + QString configClause(const QString &platform, + const QString &build, + const QString &compilerVersion, + const QString &clauseTemplate); void writeSbsDeploymentList(const DeploymentList& depList, QTextStream& t); diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 2108b92..e16ffe8 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -156,7 +156,18 @@ void qMetaTypeLoadHelper(QDataStream &stream, T *t) } #endif // QT_NO_DATASTREAM -template <typename T> struct QMetaTypeId2; +template <typename T> +struct QMetaTypeId +{ + enum { Defined = 0 }; +}; + +template <typename T> +struct QMetaTypeId2 +{ + enum { Defined = QMetaTypeId<T>::Defined }; + static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); } +}; namespace QtPrivate { template <typename T, bool Defined = QMetaTypeId2<T>::Defined> @@ -210,19 +221,6 @@ void qRegisterMetaTypeStreamOperators(const char *typeName #endif // QT_NO_DATASTREAM template <typename T> -struct QMetaTypeId -{ - enum { Defined = 0 }; -}; - -template <typename T> -struct QMetaTypeId2 -{ - enum { Defined = QMetaTypeId<T>::Defined }; - static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); } -}; - -template <typename T> inline int qMetaTypeId( #ifndef qdoc T * /* dummy */ = 0 diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index c0b664f..5a94afb 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -1051,10 +1051,63 @@ void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty<QObject> o->setParent(prop->object); } +static inline int children_count_helper(QGraphicsObject *object) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object); + return d->children.count(); +} + +static inline QObject *children_at_helper(QGraphicsObject *object, int index) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object); + if (index >= 0 && index < d->children.count()) + return d->children.at(index)->toGraphicsObject(); + else + return 0; +} + +static inline void children_clear_helper(QGraphicsObject *object) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(object); + int childCount = d->children.count(); + for (int index = 0 ;index < childCount; index++) + QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, /*newParentVariant=*/0, /*thisPointerVariant=*/0); +} + +int QDeclarativeFlickablePrivate::data_count(QDeclarativeListProperty<QObject> *prop) +{ + return QDeclarativeItemPrivate::resources_count(prop) + + children_count_helper(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem); +} + +QObject *QDeclarativeFlickablePrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i) +{ + int resourcesCount = QDeclarativeItemPrivate::resources_count(prop); + if (i < resourcesCount) + return QDeclarativeItemPrivate::resources_at(prop, i); + const int j = i - resourcesCount; + QGraphicsObject *contentObject = static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem; + if (j < children_count_helper(contentObject)) + return children_at_helper(contentObject, j); + return 0; +} + +void QDeclarativeFlickablePrivate::data_clear(QDeclarativeListProperty<QObject> *prop) +{ + QDeclarativeItemPrivate::resources_clear(prop); + QGraphicsObject *contentObject = + static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem; + children_clear_helper(contentObject); +} + QDeclarativeListProperty<QObject> QDeclarativeFlickable::flickableData() { Q_D(QDeclarativeFlickable); - return QDeclarativeListProperty<QObject>(this, (void *)d, QDeclarativeFlickablePrivate::data_append); + return QDeclarativeListProperty<QObject>(this, (void *)d, QDeclarativeFlickablePrivate::data_append, + QDeclarativeFlickablePrivate::data_count, + QDeclarativeFlickablePrivate::data_at, + QDeclarativeFlickablePrivate::data_clear + ); } QDeclarativeListProperty<QGraphicsObject> QDeclarativeFlickable::flickableChildren() diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 2da034c..beee741 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -173,6 +173,9 @@ public: // flickableData property static void data_append(QDeclarativeListProperty<QObject> *, QObject *); + static int data_count(QDeclarativeListProperty<QObject> *); + static QObject *data_at(QDeclarativeListProperty<QObject> *, int); + static void data_clear(QDeclarativeListProperty<QObject> *); }; class QDeclarativeFlickableVisibleArea : public QObject diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 11f9179..0ac616d 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -44,6 +44,7 @@ #include "private/qdeclarativeevents_p_p.h" #include <private/qdeclarativeengine_p.h> +#include <private/qgraphicsitem_p.h> #include <qdeclarativeengine.h> #include <qdeclarativeopenmetaobject_p.h> @@ -1619,6 +1620,51 @@ void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *pro } } +static inline int children_count_helper(QDeclarativeListProperty<QObject> *prop) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object)); + return d->children.count(); +} + +static inline QObject *children_at_helper(QDeclarativeListProperty<QObject> *prop, int index) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object)); + if (index >= 0 && index < d->children.count()) + return d->children.at(index)->toGraphicsObject(); + else + return 0; +} + +static inline void children_clear_helper(QDeclarativeListProperty<QObject> *prop) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(prop->object)); + int childCount = d->children.count(); + for (int index = 0 ;index < childCount; index++) + QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, /*newParentVariant=*/0, /*thisPointerVariant=*/0); +} + +int QDeclarativeItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop) +{ + return resources_count(prop) + children_count_helper(prop); +} + +QObject *QDeclarativeItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i) +{ + int resourcesCount = resources_count(prop); + if (i < resourcesCount) + return resources_at(prop, i); + const int j = i - resourcesCount; + if (j < children_count_helper(prop)) + return children_at_helper(prop, j); + return 0; +} + +void QDeclarativeItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop) +{ + resources_clear(prop); + children_clear_helper(prop); +} + QObject *QDeclarativeItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index) { const QObjectList children = prop->object->children(); @@ -1638,6 +1684,13 @@ int QDeclarativeItemPrivate::resources_count(QDeclarativeListProperty<QObject> * return prop->object->children().count(); } +void QDeclarativeItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop) +{ + const QObjectList children = prop->object->children(); + for (int index = 0; index < children.count(); index++) + children.at(index)->setParent(0); +} + int QDeclarativeItemPrivate::transform_count(QDeclarativeListProperty<QGraphicsTransform> *list) { QGraphicsObject *object = qobject_cast<QGraphicsObject *>(list->object); @@ -1724,7 +1777,11 @@ void QDeclarativeItemPrivate::parentProperty(QObject *o, void *rv, QDeclarativeN QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::data() { - return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append); + return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::data_append, + QDeclarativeItemPrivate::data_count, + QDeclarativeItemPrivate::data_at, + QDeclarativeItemPrivate::data_clear + ); } /*! @@ -2413,7 +2470,9 @@ QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources() { return QDeclarativeListProperty<QObject>(q_func(), 0, QDeclarativeItemPrivate::resources_append, QDeclarativeItemPrivate::resources_count, - QDeclarativeItemPrivate::resources_at); + QDeclarativeItemPrivate::resources_at, + QDeclarativeItemPrivate::resources_clear + ); } /*! diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index fffb4f7..f85fa27 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -176,11 +176,15 @@ public: // data property static void data_append(QDeclarativeListProperty<QObject> *, QObject *); + static int data_count(QDeclarativeListProperty<QObject> *); + static QObject *data_at(QDeclarativeListProperty<QObject> *, int); + static void data_clear(QDeclarativeListProperty<QObject> *); // resources property static QObject *resources_at(QDeclarativeListProperty<QObject> *, int); static void resources_append(QDeclarativeListProperty<QObject> *, QObject *); static int resources_count(QDeclarativeListProperty<QObject> *); + static void resources_clear(QDeclarativeListProperty<QObject> *); // transform property static int transform_count(QDeclarativeListProperty<QGraphicsTransform> *list); diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index a46ee73..a70886e 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -287,16 +287,12 @@ public: m_roles = m_listModelInterface->roles(); for (int ii = 0; ii < m_roles.count(); ++ii) m_roleNames.insert(m_listModelInterface->toString(m_roles.at(ii)).toUtf8(), m_roles.at(ii)); - if (m_roles.count() == 1) - m_roleNames.insert("modelData", m_roles.at(0)); } else if (m_abstractItemModel) { for (QHash<int,QByteArray>::const_iterator it = m_abstractItemModel->roleNames().begin(); it != m_abstractItemModel->roleNames().end(); ++it) { m_roles.append(it.key()); m_roleNames.insert(*it, it.key()); } - if (m_roles.count() == 1) - m_roleNames.insert("modelData", m_roles.at(0)); if (m_roles.count()) m_roleNames.insert("hasModelChildren", -1); } else if (m_listAccessor) { @@ -314,7 +310,8 @@ public: } } - QHash<int,int> roleToPropId; + QHash<int,int> m_roleToPropId; + int m_modelDataPropId; void createMetaData() { if (!m_metaDataCreated) { ensureRoles(); @@ -322,9 +319,12 @@ public: QHash<QByteArray, int>::const_iterator it = m_roleNames.begin(); while (it != m_roleNames.end()) { int propId = m_delegateDataType->createProperty(it.key()) - m_delegateDataType->propertyOffset(); - roleToPropId.insert(*it, propId); + m_roleToPropId.insert(*it, propId); ++it; } + // Add modelData property + if (m_roles.count() == 1) + m_modelDataPropId = m_delegateDataType->createProperty("modelData") - m_delegateDataType->propertyOffset(); m_metaDataCreated = true; } } @@ -430,6 +430,11 @@ public: void setIndex(int index); int propForRole(int) const; + int modelDataPropertyId() const { + QDeclarativeVisualDataModelPrivate *model = QDeclarativeVisualDataModelPrivate::get(m_model); + return model->m_modelDataPropId; + } + void setValue(int, const QVariant &); bool hasValue(int id) const { return m_meta->hasValue(id); @@ -450,8 +455,8 @@ private: int QDeclarativeVisualDataModelData::propForRole(int id) const { QDeclarativeVisualDataModelPrivate *model = QDeclarativeVisualDataModelPrivate::get(m_model); - QHash<int,int>::const_iterator it = model->roleToPropId.find(id); - if (it != model->roleToPropId.end()) + QHash<int,int>::const_iterator it = model->m_roleToPropId.find(id); + if (it != model->m_roleToPropId.end()) return *it; return -1; @@ -518,14 +523,16 @@ QVariant QDeclarativeVisualDataModelDataMetaObject::initialValue(int propId) } } else if (model->m_abstractItemModel) { model->ensureRoles(); + QModelIndex index = model->m_abstractItemModel->index(data->m_index, 0, model->m_root); if (propName == "hasModelChildren") { - QModelIndex index = model->m_abstractItemModel->index(data->m_index, 0, model->m_root); return model->m_abstractItemModel->hasChildren(index); } else { QHash<QByteArray,int>::const_iterator it = model->m_roleNames.find(propName); if (it != model->m_roleNames.end()) { - QModelIndex index = model->m_abstractItemModel->index(data->m_index, 0, model->m_root); return model->m_abstractItemModel->data(index, *it); + } else if (model->m_roles.count() == 1 && propName == "modelData") { + //for compatibility with other lists, assign modelData if there is only a single role + return model->m_abstractItemModel->data(index, model->m_roles.first()); } } } @@ -1195,6 +1202,19 @@ void QDeclarativeVisualDataModel::_q_itemsChanged(int index, int count, qmlInfo(this) << "Changing role not present in item: " << roleName; } } + if (roles.count() == 1) { + // Handle the modelData role we add if there is just one role. + int propId = data->modelDataPropertyId(); + if (data->hasValue(propId)) { + int role = roles.at(0); + if (d->m_listModelInterface) { + data->setValue(propId, d->m_listModelInterface->data(idx, QList<int>() << role).value(role)); + } else if (d->m_abstractItemModel) { + QModelIndex index = d->m_abstractItemModel->index(idx, 0, d->m_root); + data->setValue(propId, d->m_abstractItemModel->data(index, role)); + } + } + } } } } diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index e096305..cb6ad8c 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -48,6 +48,7 @@ #include "private/qdeclarativecontext_p.h" #include "private/qdeclarativedata_p.h" #include "private/qdeclarativestringconverters_p.h" +#include "private/qdeclarativestate_p_p.h" #include <QVariant> #include <QtCore/qdebug.h> @@ -373,6 +374,18 @@ void QDeclarativeAbstractBinding::removeFromObject() } } +static void bindingDummyDeleter(QDeclarativeAbstractBinding *) +{ +} + +QDeclarativeAbstractBinding::Pointer QDeclarativeAbstractBinding::weakPointer() +{ + if (m_selfPointer.isNull()) + m_selfPointer = QSharedPointer<QDeclarativeAbstractBinding>(this, bindingDummyDeleter); + + return m_selfPointer.toWeakRef(); +} + void QDeclarativeAbstractBinding::clear() { if (m_mePtr) { diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h index 598f09f..941a1b3 100644 --- a/src/declarative/qml/qdeclarativebinding_p.h +++ b/src/declarative/qml/qdeclarativebinding_p.h @@ -67,6 +67,8 @@ QT_BEGIN_NAMESPACE class Q_DECLARATIVE_EXPORT QDeclarativeAbstractBinding { public: + typedef QWeakPointer<QDeclarativeAbstractBinding> Pointer; + QDeclarativeAbstractBinding(); virtual void destroy(); @@ -86,21 +88,26 @@ public: void addToObject(QObject *); void removeFromObject(); + static Pointer getPointer(QDeclarativeAbstractBinding *p) { return p ? p->weakPointer() : Pointer(); } + protected: virtual ~QDeclarativeAbstractBinding(); void clear(); private: + Pointer weakPointer(); friend class QDeclarativeData; friend class QDeclarativeValueTypeProxyBinding; friend class QDeclarativePropertyPrivate; friend class QDeclarativeVME; + friend class QtSharedPointer::ExternalRefCount<QDeclarativeAbstractBinding>; QObject *m_object; QDeclarativeAbstractBinding **m_mePtr; QDeclarativeAbstractBinding **m_prevBinding; QDeclarativeAbstractBinding *m_nextBinding; + QSharedPointer<QDeclarativeAbstractBinding> m_selfPointer; }; class QDeclarativeValueTypeProxyBinding : public QDeclarativeAbstractBinding diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 1b1454b..a551cc8 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -74,7 +74,7 @@ class QDeclarativeEngine; class QDeclarativeCompiledData; class QDeclarativeComponentAttached; -class QDeclarativeComponentPrivate : public QObjectPrivate, public QDeclarativeTypeData::TypeDataCallback +class Q_AUTOTEST_EXPORT QDeclarativeComponentPrivate : public QObjectPrivate, public QDeclarativeTypeData::TypeDataCallback { Q_DECLARE_PUBLIC(QDeclarativeComponent) diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 9de5a77..80db230 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -906,7 +906,7 @@ QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject return ddata->indestructible?CppOwnership:JavaScriptOwnership; } -void qmlExecuteDeferred(QObject *object) +Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object) { QDeclarativeData *data = QDeclarativeData::get(object); diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index 98e9a58..fda62ee 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE -Q_DECL_IMPORT extern int qt_defaultDpi(); +Q_GUI_EXPORT int qt_defaultDpi(); template<typename T> int qmlRegisterValueTypeEnums(const char *qmlName) diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index d15d1f6..cdd5041 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -165,7 +165,7 @@ protected: }; class QDeclarativeScriptActionPrivate; -class QDeclarativeScriptAction : public QDeclarativeAbstractAnimation +class Q_DECLARATIVE_EXPORT QDeclarativeScriptAction : public QDeclarativeAbstractAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeScriptAction) diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index e897458..8d01b80 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -52,6 +52,7 @@ #include <qdeclarativeguard_p.h> #include <qdeclarativeproperty_p.h> #include <qdeclarativecontext_p.h> +#include <qdeclarativestate_p_p.h> #include <QtCore/qdebug.h> @@ -200,14 +201,14 @@ public: }; -class QDeclarativePropertyChangesPrivate : public QObjectPrivate +class QDeclarativePropertyChangesPrivate : public QDeclarativeStateOperationPrivate { Q_DECLARE_PUBLIC(QDeclarativePropertyChanges) public: - QDeclarativePropertyChangesPrivate() : object(0), decoded(true), restore(true), + QDeclarativePropertyChangesPrivate() : decoded(true), restore(true), isExplicit(false) {} - QObject *object; + QDeclarativeGuard<QObject> object; QByteArray data; bool decoded : 1; @@ -497,4 +498,272 @@ void QDeclarativePropertyChanges::setIsExplicit(bool e) d->isExplicit = e; } +bool QDeclarativePropertyChanges::containsValue(const QByteArray &name) const +{ + Q_D(const QDeclarativePropertyChanges); + typedef QPair<QByteArray, QVariant> PropertyEntry; + + QListIterator<PropertyEntry> propertyIterator(d->properties); + while (propertyIterator.hasNext()) { + const PropertyEntry &entry = propertyIterator.next(); + if (entry.first == name) { + return true; + } + } + + return false; +} + +bool QDeclarativePropertyChanges::containsExpression(const QByteArray &name) const +{ + Q_D(const QDeclarativePropertyChanges); + typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry; + + QListIterator<ExpressionEntry> expressionIterator(d->expressions); + while (expressionIterator.hasNext()) { + const ExpressionEntry &entry = expressionIterator.next(); + if (entry.first == name) { + return true; + } + } + + return false; +} + +bool QDeclarativePropertyChanges::containsProperty(const QByteArray &name) const +{ + return containsValue(name) || containsExpression(name); +} + +void QDeclarativePropertyChanges::changeValue(const QByteArray &name, const QVariant &value) +{ + Q_D(QDeclarativePropertyChanges); + typedef QPair<QByteArray, QVariant> PropertyEntry; + typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry; + + QMutableListIterator<ExpressionEntry> expressionIterator(d->expressions); + while (expressionIterator.hasNext()) { + const ExpressionEntry &entry = expressionIterator.next(); + if (entry.first == name) { + expressionIterator.remove(); + if (state() && state()->isStateActive()) { + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(d->property(name)); + if (oldBinding) { + QDeclarativePropertyPrivate::setBinding(d->property(name), 0); + oldBinding->destroy(); + } + d->property(name).write(value); + } + + d->properties.append(PropertyEntry(name, value)); + return; + } + } + + QMutableListIterator<PropertyEntry> propertyIterator(d->properties); + while (propertyIterator.hasNext()) { + PropertyEntry &entry = propertyIterator.next(); + if (entry.first == name) { + entry.second = value; + if (state() && state()->isStateActive()) + d->property(name).write(value); + return; + } + } + + QDeclarativeAction action; + action.restore = restoreEntryValues(); + action.property = d->property(name); + action.fromValue = action.property.read(); + action.specifiedObject = object(); + action.specifiedProperty = QString::fromUtf8(name); + action.toValue = value; + + propertyIterator.insert(PropertyEntry(name, value)); + if (state() && state()->isStateActive()) { + state()->addEntryToRevertList(action); + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(action.property); + if (oldBinding) + oldBinding->setEnabled(false, QDeclarativePropertyPrivate::DontRemoveBinding | QDeclarativePropertyPrivate::BypassInterceptor); + d->property(name).write(value); + } +} + +void QDeclarativePropertyChanges::changeExpression(const QByteArray &name, const QString &expression) +{ + Q_D(QDeclarativePropertyChanges); + typedef QPair<QByteArray, QVariant> PropertyEntry; + typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry; + + bool hadValue = false; + + QMutableListIterator<PropertyEntry> propertyIterator(d->properties); + while (propertyIterator.hasNext()) { + PropertyEntry &entry = propertyIterator.next(); + if (entry.first == name) { + propertyIterator.remove(); + hadValue = true; + break; + } + } + + QMutableListIterator<ExpressionEntry> expressionIterator(d->expressions); + while (expressionIterator.hasNext()) { + const ExpressionEntry &entry = expressionIterator.next(); + if (entry.first == name) { + entry.second->setExpression(expression); + if (state() && state()->isStateActive()) { + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(d->property(name)); + if (oldBinding) { + QDeclarativePropertyPrivate::setBinding(d->property(name), 0); + oldBinding->destroy(); + } + + QDeclarativeBinding *newBinding = new QDeclarativeBinding(expression, object(), qmlContext(this)); + newBinding->setTarget(d->property(name)); + QDeclarativePropertyPrivate::setBinding(d->property(name), newBinding, QDeclarativePropertyPrivate::DontRemoveBinding | QDeclarativePropertyPrivate::BypassInterceptor); + } + return; + } + } + + QDeclarativeExpression *newExpression = new QDeclarativeExpression(qmlContext(this), d->object, expression); + expressionIterator.insert(ExpressionEntry(name, newExpression)); + + if (state() && state()->isStateActive()) { + if (hadValue) { + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(d->property(name)); + if (oldBinding) { + oldBinding->setEnabled(false, QDeclarativePropertyPrivate::DontRemoveBinding | QDeclarativePropertyPrivate::BypassInterceptor); + state()->changeBindingInRevertList(object(), name, oldBinding); + } + + QDeclarativeBinding *newBinding = new QDeclarativeBinding(expression, object(), qmlContext(this)); + newBinding->setTarget(d->property(name)); + QDeclarativePropertyPrivate::setBinding(d->property(name), newBinding, QDeclarativePropertyPrivate::DontRemoveBinding | QDeclarativePropertyPrivate::BypassInterceptor); + } else { + QDeclarativeAction action; + action.restore = restoreEntryValues(); + action.property = d->property(name); + action.fromValue = action.property.read(); + action.specifiedObject = object(); + action.specifiedProperty = QString::fromUtf8(name); + + + if (d->isExplicit) { + action.toValue = newExpression->evaluate(); + } else { + QDeclarativeBinding *newBinding = new QDeclarativeBinding(newExpression->expression(), object(), qmlContext(this)); + newBinding->setTarget(d->property(name)); + action.toBinding = newBinding; + action.deletableToBinding = true; + + state()->addEntryToRevertList(action); + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(action.property); + if (oldBinding) + oldBinding->setEnabled(false, QDeclarativePropertyPrivate::DontRemoveBinding | QDeclarativePropertyPrivate::BypassInterceptor); + + QDeclarativePropertyPrivate::setBinding(action.property, newBinding, QDeclarativePropertyPrivate::DontRemoveBinding | QDeclarativePropertyPrivate::BypassInterceptor); + } + } + } + // what about the signal handler? +} + +QVariant QDeclarativePropertyChanges::property(const QByteArray &name) const +{ + Q_D(const QDeclarativePropertyChanges); + typedef QPair<QByteArray, QVariant> PropertyEntry; + typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry; + + QListIterator<PropertyEntry> propertyIterator(d->properties); + while (propertyIterator.hasNext()) { + const PropertyEntry &entry = propertyIterator.next(); + if (entry.first == name) { + return entry.second; + } + } + + QListIterator<ExpressionEntry> expressionIterator(d->expressions); + while (expressionIterator.hasNext()) { + const ExpressionEntry &entry = expressionIterator.next(); + if (entry.first == name) { + return QVariant(entry.second->expression()); + } + } + + return QVariant(); +} + +void QDeclarativePropertyChanges::removeProperty(const QByteArray &name) +{ + Q_D(QDeclarativePropertyChanges); + typedef QPair<QByteArray, QVariant> PropertyEntry; + typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry; + + QMutableListIterator<ExpressionEntry> expressionIterator(d->expressions); + while (expressionIterator.hasNext()) { + const ExpressionEntry &entry = expressionIterator.next(); + if (entry.first == name) { + expressionIterator.remove(); + state()->removeEntryFromRevertList(object(), name); + return; + } + } + + QMutableListIterator<PropertyEntry> propertyIterator(d->properties); + while (propertyIterator.hasNext()) { + const PropertyEntry &entry = propertyIterator.next(); + if (entry.first == name) { + propertyIterator.remove(); + state()->removeEntryFromRevertList(object(), name); + return; + } + } +} + +QVariant QDeclarativePropertyChanges::value(const QByteArray &name) const +{ + Q_D(const QDeclarativePropertyChanges); + typedef QPair<QByteArray, QVariant> PropertyEntry; + + QListIterator<PropertyEntry> propertyIterator(d->properties); + while (propertyIterator.hasNext()) { + const PropertyEntry &entry = propertyIterator.next(); + if (entry.first == name) { + return entry.second; + } + } + + return QVariant(); +} + +QString QDeclarativePropertyChanges::expression(const QByteArray &name) const +{ + Q_D(const QDeclarativePropertyChanges); + typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry; + + QListIterator<ExpressionEntry> expressionIterator(d->expressions); + while (expressionIterator.hasNext()) { + const ExpressionEntry &entry = expressionIterator.next(); + if (entry.first == name) { + return entry.second->expression(); + } + } + + return QString(); +} + +void QDeclarativePropertyChanges::detachFromState() +{ + if (state()) + state()->removeAllEntriesFromRevertList(object()); +} + +void QDeclarativePropertyChanges::attachToState() +{ + if (state()) + state()->addEntriesToRevertList(actions()); +} + QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativepropertychanges_p.h b/src/declarative/util/qdeclarativepropertychanges_p.h index 8578086..199928f 100644 --- a/src/declarative/util/qdeclarativepropertychanges_p.h +++ b/src/declarative/util/qdeclarativepropertychanges_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativePropertyChangesPrivate; -class Q_AUTOTEST_EXPORT QDeclarativePropertyChanges : public QDeclarativeStateOperation +class Q_DECLARATIVE_EXPORT QDeclarativePropertyChanges : public QDeclarativeStateOperation { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativePropertyChanges) @@ -74,6 +74,20 @@ public: void setIsExplicit(bool); virtual ActionList actions(); + + bool containsProperty(const QByteArray &name) const; + bool containsValue(const QByteArray &name) const; + bool containsExpression(const QByteArray &name) const; + void changeValue(const QByteArray &name, const QVariant &value); + void changeExpression(const QByteArray &name, const QString &expression); + void removeProperty(const QByteArray &name); + QVariant value(const QByteArray &name) const; + QString expression(const QByteArray &name) const; + + void detachFromState(); + void attachToState(); + + QVariant property(const QByteArray &name) const; }; class QDeclarativePropertyChangesParser : public QDeclarativeCustomParser diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 1ed7923..0f5413e 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -304,7 +304,7 @@ void QDeclarativeStatePrivate::complete() for (int ii = 0; ii < reverting.count(); ++ii) { for (int jj = 0; jj < revertList.count(); ++jj) { - if (revertList.at(jj).property == reverting.at(ii)) { + if (revertList.at(jj).property() == reverting.at(ii)) { revertList.removeAt(jj); break; } @@ -370,6 +370,192 @@ void QDeclarativeAction::deleteFromBinding() } } +bool QDeclarativeState::containsPropertyInRevertList(QObject *target, const QByteArray &name) const +{ + Q_D(const QDeclarativeState); + + if (isStateActive()) { + QListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList); + + while (revertListIterator.hasNext()) { + const QDeclarativeSimpleAction &simpleAction = revertListIterator.next(); + if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name) + return true; + } + } + + return false; +} + +bool QDeclarativeState::changeValueInRevertList(QObject *target, const QByteArray &name, const QVariant &revertValue) +{ + Q_D(QDeclarativeState); + + if (isStateActive()) { + QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList); + + while (revertListIterator.hasNext()) { + QDeclarativeSimpleAction &simpleAction = revertListIterator.next(); + if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name) { + simpleAction.setValue(revertValue); + return true; + } + } + } + + return false; +} + +bool QDeclarativeState::changeBindingInRevertList(QObject *target, const QByteArray &name, QDeclarativeAbstractBinding *binding) +{ + Q_D(QDeclarativeState); + + if (isStateActive()) { + QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList); + + while (revertListIterator.hasNext()) { + QDeclarativeSimpleAction &simpleAction = revertListIterator.next(); + if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name) { + if (simpleAction.binding()) + simpleAction.binding()->destroy(); + + simpleAction.setBinding(binding); + return true; + } + } + } + + return false; +} + +bool QDeclarativeState::removeEntryFromRevertList(QObject *target, const QByteArray &name) +{ + Q_D(QDeclarativeState); + + if (isStateActive()) { + QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList); + + while (revertListIterator.hasNext()) { + QDeclarativeSimpleAction &simpleAction = revertListIterator.next(); + if (simpleAction.property().object() == target && simpleAction.property().name().toUtf8() == name) { + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(simpleAction.property()); + if (oldBinding) { + QDeclarativePropertyPrivate::setBinding(simpleAction.property(), 0); + oldBinding->destroy(); + } + + simpleAction.property().write(simpleAction.value()); + if (simpleAction.binding()) + QDeclarativePropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding()); + + revertListIterator.remove(); + return true; + } + } + } + + return false; +} + +void QDeclarativeState::addEntryToRevertList(const QDeclarativeAction &action) +{ + Q_D(QDeclarativeState); + + QDeclarativeSimpleAction simpleAction(action); + + d->revertList.append(simpleAction); +} + +void QDeclarativeState::removeAllEntriesFromRevertList(QObject *target) +{ + Q_D(QDeclarativeState); + + if (isStateActive()) { + QMutableListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList); + + while (revertListIterator.hasNext()) { + QDeclarativeSimpleAction &simpleAction = revertListIterator.next(); + if (simpleAction.property().object() == target) { + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(simpleAction.property()); + if (oldBinding) { + QDeclarativePropertyPrivate::setBinding(simpleAction.property(), 0); + oldBinding->destroy(); + } + + simpleAction.property().write(simpleAction.value()); + if (simpleAction.binding()) + QDeclarativePropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding()); + + revertListIterator.remove(); + } + } + } +} + +void QDeclarativeState::addEntriesToRevertList(const QList<QDeclarativeAction> &actionList) +{ + Q_D(QDeclarativeState); + if (isStateActive()) { + QList<QDeclarativeSimpleAction> simpleActionList; + + QListIterator<QDeclarativeAction> actionListIterator(actionList); + while(actionListIterator.hasNext()) { + const QDeclarativeAction &action = actionListIterator.next(); + QDeclarativeSimpleAction simpleAction(action); + action.property.write(action.toValue); + if (action.toBinding) { + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(simpleAction.property()); + if (oldBinding) + QDeclarativePropertyPrivate::setBinding(simpleAction.property(), 0); + QDeclarativePropertyPrivate::setBinding(simpleAction.property(), action.toBinding, QDeclarativePropertyPrivate::DontRemoveBinding); + } + + simpleActionList.append(simpleAction); + } + + d->revertList.append(simpleActionList); + } +} + +QVariant QDeclarativeState::valueInRevertList(QObject *target, const QByteArray &name) const +{ + Q_D(const QDeclarativeState); + + if (isStateActive()) { + QListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList); + + while (revertListIterator.hasNext()) { + const QDeclarativeSimpleAction &simpleAction = revertListIterator.next(); + if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name) + return simpleAction.value(); + } + } + + return QVariant(); +} + +QDeclarativeAbstractBinding *QDeclarativeState::bindingInRevertList(QObject *target, const QByteArray &name) const +{ + Q_D(const QDeclarativeState); + + if (isStateActive()) { + QListIterator<QDeclarativeSimpleAction> revertListIterator(d->revertList); + + while (revertListIterator.hasNext()) { + const QDeclarativeSimpleAction &simpleAction = revertListIterator.next(); + if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name) + return simpleAction.binding(); + } + } + + return 0; +} + +bool QDeclarativeState::isStateActive() const +{ + return stateGroup() && stateGroup()->state() == name(); +} + void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransition *trans, QDeclarativeState *revert) { Q_D(QDeclarativeState); @@ -403,13 +589,13 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit continue; bool found = false; for (int jj = 0; jj < d->revertList.count(); ++jj) { - QDeclarativeActionEvent *event = d->revertList.at(jj).event; + QDeclarativeActionEvent *event = d->revertList.at(jj).event(); if (event && event->typeName() == action.event->typeName()) { if (action.event->override(event)) { found = true; - if (action.event != d->revertList.at(jj).event && action.event->needsCopy()) { - action.event->copyOriginals(d->revertList.at(jj).event); + if (action.event != d->revertList.at(jj).event() && action.event->needsCopy()) { + action.event->copyOriginals(d->revertList.at(jj).event()); QDeclarativeSimpleAction r(action); additionalReverts << r; @@ -434,9 +620,9 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit action.fromBinding = QDeclarativePropertyPrivate::binding(action.property); for (int jj = 0; jj < d->revertList.count(); ++jj) { - if (d->revertList.at(jj).property == action.property) { + if (d->revertList.at(jj).property() == action.property) { found = true; - if (d->revertList.at(jj).binding != action.fromBinding) { + if (d->revertList.at(jj).binding() != action.fromBinding) { action.deleteFromBinding(); } break; @@ -445,7 +631,7 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit if (!found) { if (!action.restore) { - action.deleteFromBinding(); + action.deleteFromBinding();; } else { // Only need to revert the applyList action if the previous // state doesn't have a higher priority revert already @@ -460,8 +646,8 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit // into this state need to be translated into apply actions for (int ii = 0; ii < d->revertList.count(); ++ii) { bool found = false; - if (d->revertList.at(ii).event) { - QDeclarativeActionEvent *event = d->revertList.at(ii).event; + if (d->revertList.at(ii).event()) { + QDeclarativeActionEvent *event = d->revertList.at(ii).event(); if (!event->isReversable()) continue; for (int jj = 0; !found && jj < applyList.count(); ++jj) { @@ -474,31 +660,31 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit } else { for (int jj = 0; !found && jj < applyList.count(); ++jj) { const QDeclarativeAction &action = applyList.at(jj); - if (action.property == d->revertList.at(ii).property) + if (action.property == d->revertList.at(ii).property()) found = true; } } if (!found) { - QVariant cur = d->revertList.at(ii).property.read(); + QVariant cur = d->revertList.at(ii).property().read(); QDeclarativeAbstractBinding *delBinding = - QDeclarativePropertyPrivate::setBinding(d->revertList.at(ii).property, 0); + QDeclarativePropertyPrivate::setBinding(d->revertList.at(ii).property(), 0); if (delBinding) delBinding->destroy(); QDeclarativeAction a; - a.property = d->revertList.at(ii).property; + a.property = d->revertList.at(ii).property(); a.fromValue = cur; - a.toValue = d->revertList.at(ii).value; - a.toBinding = d->revertList.at(ii).binding; - a.specifiedObject = d->revertList.at(ii).specifiedObject; - a.specifiedProperty = d->revertList.at(ii).specifiedProperty; - a.event = d->revertList.at(ii).event; - a.reverseEvent = d->revertList.at(ii).reverseEvent; + a.toValue = d->revertList.at(ii).value(); + a.toBinding = d->revertList.at(ii).binding(); + a.specifiedObject = d->revertList.at(ii).specifiedObject(); + a.specifiedProperty = d->revertList.at(ii).specifiedProperty(); + a.event = d->revertList.at(ii).event(); + a.reverseEvent = d->revertList.at(ii).reverseEvent(); if (a.event && a.event->isRewindable()) a.event->saveCurrentValues(); applyList << a; // Store these special reverts in the reverting list - d->reverting << d->revertList.at(ii).property; + d->reverting << d->revertList.at(ii).property(); } } // All the local reverts now become part of the ongoing revertList @@ -526,4 +712,16 @@ QDeclarativeStateOperation::ActionList QDeclarativeStateOperation::actions() return ActionList(); } +QDeclarativeState *QDeclarativeStateOperation::state() const +{ + Q_D(const QDeclarativeStateOperation); + return d->m_state; +} + +void QDeclarativeStateOperation::setState(QDeclarativeState *state) +{ + Q_D(QDeclarativeStateOperation); + d->m_state = state; +} + QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h index 2e2ce7b..a0ab11b 100644 --- a/src/declarative/util/qdeclarativestate_p.h +++ b/src/declarative/util/qdeclarativestate_p.h @@ -111,6 +111,8 @@ public: //### rename to QDeclarativeStateChange? class QDeclarativeStateGroup; +class QDeclarativeState; +class QDeclarativeStateOperationPrivate; class Q_DECLARATIVE_EXPORT QDeclarativeStateOperation : public QObject { Q_OBJECT @@ -121,8 +123,15 @@ public: virtual ActionList actions(); + QDeclarativeState *state() const; + void setState(QDeclarativeState *state); + protected: QDeclarativeStateOperation(QObjectPrivate &dd, QObject *parent = 0); + +private: + Q_DECLARE_PRIVATE(QDeclarativeStateOperation) + Q_DISABLE_COPY(QDeclarativeStateOperation) }; typedef QDeclarativeStateOperation::ActionList QDeclarativeStateActions; @@ -169,6 +178,18 @@ public: QDeclarativeStateGroup *stateGroup() const; void setStateGroup(QDeclarativeStateGroup *); + bool containsPropertyInRevertList(QObject *target, const QByteArray &name) const; + bool changeValueInRevertList(QObject *target, const QByteArray &name, const QVariant &revertValue); + bool changeBindingInRevertList(QObject *target, const QByteArray &name, QDeclarativeAbstractBinding *binding); + bool removeEntryFromRevertList(QObject *target, const QByteArray &name); + void addEntryToRevertList(const QDeclarativeAction &action); + void removeAllEntriesFromRevertList(QObject *target); + void addEntriesToRevertList(const QList<QDeclarativeAction> &actions); + QVariant valueInRevertList(QObject *target, const QByteArray &name) const; + QDeclarativeAbstractBinding *bindingInRevertList(QObject *target, const QByteArray &name) const; + + bool isStateActive() const; + Q_SIGNALS: void completed(); diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index 2ef9bb0..4fd8f21 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -61,6 +61,8 @@ #include <private/qdeclarativeproperty_p.h> #include <private/qdeclarativeguard_p.h> +#include <private/qdeclarativebinding_p.h> + #include <private/qobject_p.h> QT_BEGIN_NAMESPACE @@ -69,30 +71,123 @@ class QDeclarativeSimpleAction { public: enum State { StartState, EndState }; - QDeclarativeSimpleAction(const QDeclarativeAction &a, State state = StartState) + QDeclarativeSimpleAction(const QDeclarativeAction &a, State state = StartState) { - property = a.property; - specifiedObject = a.specifiedObject; - specifiedProperty = a.specifiedProperty; - event = a.event; + m_property = a.property; + m_specifiedObject = a.specifiedObject; + m_specifiedProperty = a.specifiedProperty; + m_event = a.event; if (state == StartState) { - value = a.fromValue; - binding = QDeclarativePropertyPrivate::binding(property); - reverseEvent = true; + m_value = a.fromValue; + if (QDeclarativePropertyPrivate::binding(m_property)) { + m_binding = QDeclarativeAbstractBinding::getPointer(QDeclarativePropertyPrivate::binding(m_property)); + } + m_reverseEvent = true; } else { - value = a.toValue; - binding = a.toBinding; - reverseEvent = false; + m_value = a.toValue; + m_binding = QDeclarativeAbstractBinding::getPointer(a.toBinding); + m_reverseEvent = false; } } - QDeclarativeProperty property; - QVariant value; - QDeclarativeAbstractBinding *binding; - QObject *specifiedObject; - QString specifiedProperty; - QDeclarativeActionEvent *event; - bool reverseEvent; + ~QDeclarativeSimpleAction() + { + } + + QDeclarativeSimpleAction(const QDeclarativeSimpleAction &other) + : m_property(other.m_property), + m_value(other.m_value), + m_binding(QDeclarativeAbstractBinding::getPointer(other.binding())), + m_specifiedObject(other.m_specifiedObject), + m_specifiedProperty(other.m_specifiedProperty), + m_event(other.m_event), + m_reverseEvent(other.m_reverseEvent) + { + } + + QDeclarativeSimpleAction &operator =(const QDeclarativeSimpleAction &other) + { + m_property = other.m_property; + m_value = other.m_value; + m_binding = QDeclarativeAbstractBinding::getPointer(other.binding()); + m_specifiedObject = other.m_specifiedObject; + m_specifiedProperty = other.m_specifiedProperty; + m_event = other.m_event; + m_reverseEvent = other.m_reverseEvent; + + return *this; + } + + void setProperty(const QDeclarativeProperty &property) + { + m_property = property; + } + + const QDeclarativeProperty &property() const + { + return m_property; + } + + void setValue(const QVariant &value) + { + m_value = value; + } + + const QVariant &value() const + { + return m_value; + } + + void setBinding(QDeclarativeAbstractBinding *binding) + { + m_binding = QDeclarativeAbstractBinding::getPointer(binding); + } + + QDeclarativeAbstractBinding *binding() const + { + return m_binding.data(); + } + + QObject *specifiedObject() const + { + return m_specifiedObject; + } + + const QString &specifiedProperty() const + { + return m_specifiedProperty; + } + + QDeclarativeActionEvent *event() const + { + return m_event; + } + + bool reverseEvent() const + { + return m_reverseEvent; + } + +private: + QDeclarativeProperty m_property; + QVariant m_value; + QDeclarativeAbstractBinding::Pointer m_binding; + QObject *m_specifiedObject; + QString m_specifiedProperty; + QDeclarativeActionEvent *m_event; + bool m_reverseEvent; +}; + +class QDeclarativeStateOperationPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QDeclarativeStateOperation) + +public: + + QDeclarativeStateOperationPrivate() + : m_state(0) {} + + QDeclarativeState *m_state; }; class QDeclarativeStatePrivate : public QObjectPrivate @@ -122,10 +217,14 @@ public: static void operations_append(QDeclarativeListProperty<QDeclarativeStateOperation> *prop, QDeclarativeStateOperation *op) { QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data); + op->setState(qobject_cast<QDeclarativeState*>(prop->object)); list->append(OperationGuard(op, list)); } static void operations_clear(QDeclarativeListProperty<QDeclarativeStateOperation> *prop) { QList<OperationGuard> *list = static_cast<QList<OperationGuard> *>(prop->data); + QMutableListIterator<OperationGuard> listIterator(*list); + while(listIterator.hasNext()) + listIterator.next()->setState(0); list->clear(); } static int operations_count(QDeclarativeListProperty<QDeclarativeStateOperation> *prop) { diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index a78fc54..8cb813c 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -52,6 +52,7 @@ #include "private/qdeclarativecontext_p.h" #include "private/qdeclarativeproperty_p.h" #include "private/qdeclarativebinding_p.h" +#include "private/qdeclarativestate_p_p.h" #include <QtCore/qdebug.h> #include <QtGui/qgraphicsitem.h> @@ -61,7 +62,7 @@ QT_BEGIN_NAMESPACE -class QDeclarativeParentChangePrivate : public QObjectPrivate +class QDeclarativeParentChangePrivate : public QDeclarativeStateOperationPrivate { Q_DECLARE_PUBLIC(QDeclarativeParentChange) public: @@ -580,7 +581,7 @@ void QDeclarativeParentChange::rewind() d->doChange(d->rewindParent, d->rewindStackBefore); } -class QDeclarativeStateChangeScriptPrivate : public QObjectPrivate +class QDeclarativeStateChangeScriptPrivate : public QDeclarativeStateOperationPrivate { public: QDeclarativeStateChangeScriptPrivate() {} @@ -965,7 +966,7 @@ void QDeclarativeAnchorSet::resetCenterIn() } -class QDeclarativeAnchorChangesPrivate : public QObjectPrivate +class QDeclarativeAnchorChangesPrivate : public QDeclarativeStateOperationPrivate { public: QDeclarativeAnchorChangesPrivate() @@ -1030,6 +1031,11 @@ public: bool applyOrigVCenter; bool applyOrigBaseline; + QDeclarativeNullableValue<qreal> origWidth; + QDeclarativeNullableValue<qreal> origHeight; + qreal origX; + qreal origY; + QList<QDeclarativeAbstractBinding*> oldBindings; QDeclarativeProperty leftProp; @@ -1321,6 +1327,42 @@ void QDeclarativeAnchorChanges::reverse(Reason reason) QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding); if (d->origBaselineBinding) QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding); + + //restore any absolute geometry changed by the state's anchors + QDeclarativeAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::Vertical_Mask; + QDeclarativeAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QDeclarativeAnchors::Vertical_Mask; + QDeclarativeAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::Horizontal_Mask; + QDeclarativeAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QDeclarativeAnchors::Horizontal_Mask; + + bool stateSetWidth = (stateHAnchors && + stateHAnchors != QDeclarativeAnchors::LeftAnchor && + stateHAnchors != QDeclarativeAnchors::RightAnchor && + stateHAnchors != QDeclarativeAnchors::HCenterAnchor); + bool origSetWidth = (origHAnchors && + origHAnchors != QDeclarativeAnchors::LeftAnchor && + origHAnchors != QDeclarativeAnchors::RightAnchor && + origHAnchors != QDeclarativeAnchors::HCenterAnchor); + if (d->origWidth.isValid() && stateSetWidth && !origSetWidth) + d->target->setWidth(d->origWidth.value); + + bool stateSetHeight = (stateVAnchors && + stateVAnchors != QDeclarativeAnchors::TopAnchor && + stateVAnchors != QDeclarativeAnchors::BottomAnchor && + stateVAnchors != QDeclarativeAnchors::VCenterAnchor && + stateVAnchors != QDeclarativeAnchors::BaselineAnchor); + bool origSetHeight = (origVAnchors && + origVAnchors != QDeclarativeAnchors::TopAnchor && + origVAnchors != QDeclarativeAnchors::BottomAnchor && + origVAnchors != QDeclarativeAnchors::VCenterAnchor && + origVAnchors != QDeclarativeAnchors::BaselineAnchor); + if (d->origHeight.isValid() && stateSetHeight && !origSetHeight) + d->target->setHeight(d->origHeight.value); + + if (stateHAnchors && !origHAnchors) + d->target->setX(d->origX); + + if (stateVAnchors && !origVAnchors) + d->target->setY(d->origY); } QString QDeclarativeAnchorChanges::typeName() const @@ -1383,6 +1425,14 @@ void QDeclarativeAnchorChanges::saveOriginals() d->origVCenterBinding = QDeclarativePropertyPrivate::binding(d->vCenterProp); d->origBaselineBinding = QDeclarativePropertyPrivate::binding(d->baselineProp); + QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target); + if (targetPrivate->widthValid) + d->origWidth = d->target->width(); + if (targetPrivate->heightValid) + d->origHeight = d->target->height(); + d->origX = d->target->x(); + d->origY = d->target->y(); + d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false; @@ -1415,6 +1465,11 @@ void QDeclarativeAnchorChanges::copyOriginals(QDeclarativeActionEvent *other) d->origVCenterBinding = acp->origVCenterBinding; d->origBaselineBinding = acp->origBaselineBinding; + d->origWidth = acp->origWidth; + d->origHeight = acp->origHeight; + d->origX = acp->origX; + d->origY = acp->origY; + d->oldBindings.clear(); d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding << acp->topBinding << acp->bottomBinding << acp->baselineBinding; diff --git a/src/declarative/util/qdeclarativetransitionmanager.cpp b/src/declarative/util/qdeclarativetransitionmanager.cpp index d82c4bb..89b0044 100644 --- a/src/declarative/util/qdeclarativetransitionmanager.cpp +++ b/src/declarative/util/qdeclarativetransitionmanager.cpp @@ -86,8 +86,8 @@ void QDeclarativeTransitionManager::complete() d->applyBindings(); for (int ii = 0; ii < d->completeList.count(); ++ii) { - const QDeclarativeProperty &prop = d->completeList.at(ii).property; - prop.write(d->completeList.at(ii).value); + const QDeclarativeProperty &prop = d->completeList.at(ii).property(); + prop.write(d->completeList.at(ii).value()); } d->completeList.clear(); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7a5b8de..2600d06 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7676,6 +7676,14 @@ QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGra return 0; } +void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); + int childCount = d->children.count(); + for (int index = 0; index < childCount; index++) + QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, /*newParentVariant=*/0, /*thisPointerVariant=*/0); +} + /*! Returns a list of this item's children. @@ -7689,7 +7697,7 @@ QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList() if (isObject) { QGraphicsObject *that = static_cast<QGraphicsObject *>(q); return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append, - children_count, children_at); + children_count, children_at, children_clear); } else { //QGraphicsItem is not supported for this property return QDeclarativeListProperty<QGraphicsObject>(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index d60dffb..cce9439 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -487,6 +487,7 @@ public: static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item); static int children_count(QDeclarativeListProperty<QGraphicsObject> *list); static QGraphicsObject *children_at(QDeclarativeListProperty<QGraphicsObject> *list, int); + static void children_clear(QDeclarativeListProperty<QGraphicsObject> *list); inline QTransform transformToParent() const; inline void ensureSortedChildren(); diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def index 50c948a..a2bff5d 100644 --- a/src/s60installs/bwins/QtDeclarativeu.def +++ b/src/s60installs/bwins/QtDeclarativeu.def @@ -1639,4 +1639,55 @@ EXPORTS ?baselineOffsetChanged@QDeclarativeItem@@IAEXM@Z @ 1638 NONAME ; void QDeclarativeItem::baselineOffsetChanged(float) ??6QDeclarativeInfo@@QAEAAV0@VQChar@@@Z @ 1639 NONAME ; class QDeclarativeInfo & QDeclarativeInfo::operator<<(class QChar) ?newObjects@QDeclarativeEngineDebug@@IAEXXZ @ 1640 NONAME ; void QDeclarativeEngineDebug::newObjects(void) + ?qt_metacast@QDeclarativePropertyChanges@@UAEPAXPBD@Z @ 1641 NONAME ; void * QDeclarativePropertyChanges::qt_metacast(char const *) + ?actions@QDeclarativePropertyChanges@@UAE?AV?$QList@VQDeclarativeAction@@@@XZ @ 1642 NONAME ; class QList<class QDeclarativeAction> QDeclarativePropertyChanges::actions(void) + ??1QDeclarativePropertyChanges@@UAE@XZ @ 1643 NONAME ; QDeclarativePropertyChanges::~QDeclarativePropertyChanges(void) + ??_EQDeclarativePropertyChanges@@UAE@I@Z @ 1644 NONAME ; QDeclarativePropertyChanges::~QDeclarativePropertyChanges(unsigned int) + ?setObject@QDeclarativePropertyChanges@@QAEXPAVQObject@@@Z @ 1645 NONAME ; void QDeclarativePropertyChanges::setObject(class QObject *) + ?staticMetaObject@QDeclarativePropertyChanges@@2UQMetaObject@@B @ 1646 NONAME ; struct QMetaObject const QDeclarativePropertyChanges::staticMetaObject + ?removeEntryFromRevertList@QDeclarativeState@@QAE_NPAVQObject@@ABVQByteArray@@@Z @ 1647 NONAME ; bool QDeclarativeState::removeEntryFromRevertList(class QObject *, class QByteArray const &) + ?restoreEntryValues@QDeclarativePropertyChanges@@QBE_NXZ @ 1648 NONAME ; bool QDeclarativePropertyChanges::restoreEntryValues(void) const + ?setRestoreEntryValues@QDeclarativePropertyChanges@@QAEX_N@Z @ 1649 NONAME ; void QDeclarativePropertyChanges::setRestoreEntryValues(bool) + ?changeValue@QDeclarativePropertyChanges@@QAEXABVQByteArray@@ABVQVariant@@@Z @ 1650 NONAME ; void QDeclarativePropertyChanges::changeValue(class QByteArray const &, class QVariant const &) + ?metaObject@QDeclarativePropertyChanges@@UBEPBUQMetaObject@@XZ @ 1651 NONAME ; struct QMetaObject const * QDeclarativePropertyChanges::metaObject(void) const + ?data_clear@QDeclarativeItemPrivate@@SAXPAV?$QDeclarativeListProperty@VQObject@@@@@Z @ 1652 NONAME ; void QDeclarativeItemPrivate::data_clear(class QDeclarativeListProperty<class QObject> *) + ?containsPropertyInRevertList@QDeclarativeState@@QBE_NPAVQObject@@ABVQByteArray@@@Z @ 1653 NONAME ; bool QDeclarativeState::containsPropertyInRevertList(class QObject *, class QByteArray const &) const + ?containsValue@QDeclarativePropertyChanges@@QBE_NABVQByteArray@@@Z @ 1654 NONAME ; bool QDeclarativePropertyChanges::containsValue(class QByteArray const &) const + ?bindingInRevertList@QDeclarativeState@@QBEPAVQDeclarativeAbstractBinding@@PAVQObject@@ABVQByteArray@@@Z @ 1655 NONAME ; class QDeclarativeAbstractBinding * QDeclarativeState::bindingInRevertList(class QObject *, class QByteArray const &) const + ?d_func@QDeclarativePropertyChanges@@ABEPBVQDeclarativePropertyChangesPrivate@@XZ @ 1656 NONAME ; class QDeclarativePropertyChangesPrivate const * QDeclarativePropertyChanges::d_func(void) const + ?containsProperty@QDeclarativePropertyChanges@@QBE_NABVQByteArray@@@Z @ 1657 NONAME ; bool QDeclarativePropertyChanges::containsProperty(class QByteArray const &) const + ?trUtf8@QDeclarativePropertyChanges@@SA?AVQString@@PBD0H@Z @ 1658 NONAME ; class QString QDeclarativePropertyChanges::trUtf8(char const *, char const *, int) + ?property@QDeclarativePropertyChanges@@QBE?AVQVariant@@ABVQByteArray@@@Z @ 1659 NONAME ; class QVariant QDeclarativePropertyChanges::property(class QByteArray const &) const + ?containsExpression@QDeclarativePropertyChanges@@QBE_NABVQByteArray@@@Z @ 1660 NONAME ; bool QDeclarativePropertyChanges::containsExpression(class QByteArray const &) const + ?d_func@QDeclarativeStateOperation@@ABEPBVQDeclarativeStateOperationPrivate@@XZ @ 1661 NONAME ; class QDeclarativeStateOperationPrivate const * QDeclarativeStateOperation::d_func(void) const + ?d_func@QDeclarativePropertyChanges@@AAEPAVQDeclarativePropertyChangesPrivate@@XZ @ 1662 NONAME ; class QDeclarativePropertyChangesPrivate * QDeclarativePropertyChanges::d_func(void) + ?state@QDeclarativeStateOperation@@QBEPAVQDeclarativeState@@XZ @ 1663 NONAME ; class QDeclarativeState * QDeclarativeStateOperation::state(void) const + ?value@QDeclarativePropertyChanges@@QBE?AVQVariant@@ABVQByteArray@@@Z @ 1664 NONAME ; class QVariant QDeclarativePropertyChanges::value(class QByteArray const &) const + ?qt_metacall@QDeclarativePropertyChanges@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 1665 NONAME ; int QDeclarativePropertyChanges::qt_metacall(enum QMetaObject::Call, int, void * *) + ?trUtf8@QDeclarativePropertyChanges@@SA?AVQString@@PBD0@Z @ 1666 NONAME ; class QString QDeclarativePropertyChanges::trUtf8(char const *, char const *) + ?attachToState@QDeclarativePropertyChanges@@QAEXXZ @ 1667 NONAME ; void QDeclarativePropertyChanges::attachToState(void) + ?changeExpression@QDeclarativePropertyChanges@@QAEXABVQByteArray@@ABVQString@@@Z @ 1668 NONAME ; void QDeclarativePropertyChanges::changeExpression(class QByteArray const &, class QString const &) + ?addEntryToRevertList@QDeclarativeState@@QAEXABVQDeclarativeAction@@@Z @ 1669 NONAME ; void QDeclarativeState::addEntryToRevertList(class QDeclarativeAction const &) + ??0QDeclarativePropertyChanges@@QAE@XZ @ 1670 NONAME ; QDeclarativePropertyChanges::QDeclarativePropertyChanges(void) + ?resources_clear@QDeclarativeItemPrivate@@SAXPAV?$QDeclarativeListProperty@VQObject@@@@@Z @ 1671 NONAME ; void QDeclarativeItemPrivate::resources_clear(class QDeclarativeListProperty<class QObject> *) + ?isExplicit@QDeclarativePropertyChanges@@QBE_NXZ @ 1672 NONAME ; bool QDeclarativePropertyChanges::isExplicit(void) const + ?setState@QDeclarativeStateOperation@@QAEXPAVQDeclarativeState@@@Z @ 1673 NONAME ; void QDeclarativeStateOperation::setState(class QDeclarativeState *) + ?detachFromState@QDeclarativePropertyChanges@@QAEXXZ @ 1674 NONAME ; void QDeclarativePropertyChanges::detachFromState(void) + ?tr@QDeclarativePropertyChanges@@SA?AVQString@@PBD0H@Z @ 1675 NONAME ; class QString QDeclarativePropertyChanges::tr(char const *, char const *, int) + ?addEntriesToRevertList@QDeclarativeState@@QAEXABV?$QList@VQDeclarativeAction@@@@@Z @ 1676 NONAME ; void QDeclarativeState::addEntriesToRevertList(class QList<class QDeclarativeAction> const &) + ?expression@QDeclarativePropertyChanges@@QBE?AVQString@@ABVQByteArray@@@Z @ 1677 NONAME ; class QString QDeclarativePropertyChanges::expression(class QByteArray const &) const + ?object@QDeclarativePropertyChanges@@QBEPAVQObject@@XZ @ 1678 NONAME ; class QObject * QDeclarativePropertyChanges::object(void) const + ?valueInRevertList@QDeclarativeState@@QBE?AVQVariant@@PAVQObject@@ABVQByteArray@@@Z @ 1679 NONAME ; class QVariant QDeclarativeState::valueInRevertList(class QObject *, class QByteArray const &) const + ?removeAllEntriesFromRevertList@QDeclarativeState@@QAEXPAVQObject@@@Z @ 1680 NONAME ; void QDeclarativeState::removeAllEntriesFromRevertList(class QObject *) + ?d_func@QDeclarativeStateOperation@@AAEPAVQDeclarativeStateOperationPrivate@@XZ @ 1681 NONAME ; class QDeclarativeStateOperationPrivate * QDeclarativeStateOperation::d_func(void) + ?changeValueInRevertList@QDeclarativeState@@QAE_NPAVQObject@@ABVQByteArray@@ABVQVariant@@@Z @ 1682 NONAME ; bool QDeclarativeState::changeValueInRevertList(class QObject *, class QByteArray const &, class QVariant const &) + ?setIsExplicit@QDeclarativePropertyChanges@@QAEX_N@Z @ 1683 NONAME ; void QDeclarativePropertyChanges::setIsExplicit(bool) + ?isStateActive@QDeclarativeState@@QBE_NXZ @ 1684 NONAME ; bool QDeclarativeState::isStateActive(void) const + ?data_count@QDeclarativeItemPrivate@@SAHPAV?$QDeclarativeListProperty@VQObject@@@@@Z @ 1685 NONAME ; int QDeclarativeItemPrivate::data_count(class QDeclarativeListProperty<class QObject> *) + ?removeProperty@QDeclarativePropertyChanges@@QAEXABVQByteArray@@@Z @ 1686 NONAME ; void QDeclarativePropertyChanges::removeProperty(class QByteArray const &) + ?data_at@QDeclarativeItemPrivate@@SAPAVQObject@@PAV?$QDeclarativeListProperty@VQObject@@@@H@Z @ 1687 NONAME ; class QObject * QDeclarativeItemPrivate::data_at(class QDeclarativeListProperty<class QObject> *, int) + ?tr@QDeclarativePropertyChanges@@SA?AVQString@@PBD0@Z @ 1688 NONAME ; class QString QDeclarativePropertyChanges::tr(char const *, char const *) + ?changeBindingInRevertList@QDeclarativeState@@QAE_NPAVQObject@@ABVQByteArray@@PAVQDeclarativeAbstractBinding@@@Z @ 1689 NONAME ; bool QDeclarativeState::changeBindingInRevertList(class QObject *, class QByteArray const &, class QDeclarativeAbstractBinding *) + ?getStaticMetaObject@QDeclarativePropertyChanges@@SAABUQMetaObject@@XZ @ 1690 NONAME ; struct QMetaObject const & QDeclarativePropertyChanges::getStaticMetaObject(void) + ?weakPointer@QDeclarativeAbstractBinding@@QAE?AV?$QWeakPointer@VQDeclarativeAbstractBinding@@@@XZ @ 1691 NONAME ; class QWeakPointer<class QDeclarativeAbstractBinding> QDeclarativeAbstractBinding::weakPointer(void) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 01630e2..f9e88d7 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12885,4 +12885,5 @@ EXPORTS ??0QGraphicsViewPrivate@@QAE@XZ @ 12884 NONAME ; QGraphicsViewPrivate::QGraphicsViewPrivate(void) ?flushDetachedPixmaps@QPixmapCache@@SAXXZ @ 12885 NONAME ; void QPixmapCache::flushDetachedPixmaps(void) ?replayLastMouseEvent@QGraphicsViewPrivate@@QAEXXZ @ 12886 NONAME ; void QGraphicsViewPrivate::replayLastMouseEvent(void) + ?children_clear@QGraphicsItemPrivate@@SAXPAV?$QDeclarativeListProperty@VQGraphicsObject@@@@@Z @ 12887 NONAME ; void QGraphicsItemPrivate::children_clear(class QDeclarativeListProperty<class QGraphicsObject> *) diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index 2a14abe..37325fa 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -1675,4 +1675,51 @@ EXPORTS _ZrsR11QDataStreamRN29QDeclarativeEngineDebugServer22QDeclarativeObjectDataE @ 1674 NONAME _ZrsR11QDataStreamRN29QDeclarativeEngineDebugServer26QDeclarativeObjectPropertyE @ 1675 NONAME _ZN23QDeclarativeEngineDebug10newObjectsEv @ 1676 NONAME + _ZN17QDeclarativeState20addEntryToRevertListERK18QDeclarativeAction @ 1677 NONAME + _ZN17QDeclarativeState22addEntriesToRevertListERK5QListI18QDeclarativeActionE @ 1678 NONAME + _ZN17QDeclarativeState23changeValueInRevertListEP7QObjectRK10QByteArrayRK8QVariant @ 1679 NONAME + _ZN17QDeclarativeState25changeBindingInRevertListEP7QObjectRK10QByteArrayP27QDeclarativeAbstractBinding @ 1680 NONAME + _ZN17QDeclarativeState25removeEntryFromRevertListEP7QObjectRK10QByteArray @ 1681 NONAME + _ZN17QDeclarativeState30removeAllEntriesFromRevertListEP7QObject @ 1682 NONAME + _ZN23QDeclarativeItemPrivate10data_clearEP24QDeclarativeListPropertyI7QObjectE @ 1683 NONAME + _ZN23QDeclarativeItemPrivate10data_countEP24QDeclarativeListPropertyI7QObjectE @ 1684 NONAME + _ZN23QDeclarativeItemPrivate15resources_clearEP24QDeclarativeListPropertyI7QObjectE @ 1685 NONAME + _ZN23QDeclarativeItemPrivate7data_atEP24QDeclarativeListPropertyI7QObjectEi @ 1686 NONAME + _ZN26QDeclarativeStateOperation8setStateEP17QDeclarativeState @ 1687 NONAME + _ZN27QDeclarativeAbstractBinding11weakPointerEv @ 1688 NONAME + _ZN27QDeclarativePropertyChanges11changeValueERK10QByteArrayRK8QVariant @ 1689 NONAME + _ZN27QDeclarativePropertyChanges11qt_metacallEN11QMetaObject4CallEiPPv @ 1690 NONAME + _ZN27QDeclarativePropertyChanges11qt_metacastEPKc @ 1691 NONAME + _ZN27QDeclarativePropertyChanges13attachToStateEv @ 1692 NONAME + _ZN27QDeclarativePropertyChanges13setIsExplicitEb @ 1693 NONAME + _ZN27QDeclarativePropertyChanges14removePropertyERK10QByteArray @ 1694 NONAME + _ZN27QDeclarativePropertyChanges15detachFromStateEv @ 1695 NONAME + _ZN27QDeclarativePropertyChanges16changeExpressionERK10QByteArrayRK7QString @ 1696 NONAME + _ZN27QDeclarativePropertyChanges16staticMetaObjectE @ 1697 NONAME DATA 16 + _ZN27QDeclarativePropertyChanges19getStaticMetaObjectEv @ 1698 NONAME + _ZN27QDeclarativePropertyChanges21setRestoreEntryValuesEb @ 1699 NONAME + _ZN27QDeclarativePropertyChanges7actionsEv @ 1700 NONAME + _ZN27QDeclarativePropertyChanges9setObjectEP7QObject @ 1701 NONAME + _ZN27QDeclarativePropertyChangesC1Ev @ 1702 NONAME + _ZN27QDeclarativePropertyChangesC2Ev @ 1703 NONAME + _ZN27QDeclarativePropertyChangesD0Ev @ 1704 NONAME + _ZN27QDeclarativePropertyChangesD1Ev @ 1705 NONAME + _ZN27QDeclarativePropertyChangesD2Ev @ 1706 NONAME + _ZNK17QDeclarativeState13isStateActiveEv @ 1707 NONAME + _ZNK17QDeclarativeState17valueInRevertListEP7QObjectRK10QByteArray @ 1708 NONAME + _ZNK17QDeclarativeState19bindingInRevertListEP7QObjectRK10QByteArray @ 1709 NONAME + _ZNK17QDeclarativeState28containsPropertyInRevertListEP7QObjectRK10QByteArray @ 1710 NONAME + _ZNK26QDeclarativeStateOperation5stateEv @ 1711 NONAME + _ZNK27QDeclarativePropertyChanges10expressionERK10QByteArray @ 1712 NONAME + _ZNK27QDeclarativePropertyChanges10isExplicitEv @ 1713 NONAME + _ZNK27QDeclarativePropertyChanges10metaObjectEv @ 1714 NONAME + _ZNK27QDeclarativePropertyChanges13containsValueERK10QByteArray @ 1715 NONAME + _ZNK27QDeclarativePropertyChanges16containsPropertyERK10QByteArray @ 1716 NONAME + _ZNK27QDeclarativePropertyChanges18containsExpressionERK10QByteArray @ 1717 NONAME + _ZNK27QDeclarativePropertyChanges18restoreEntryValuesEv @ 1718 NONAME + _ZNK27QDeclarativePropertyChanges5valueERK10QByteArray @ 1719 NONAME + _ZNK27QDeclarativePropertyChanges6objectEv @ 1720 NONAME + _ZNK27QDeclarativePropertyChanges8propertyERK10QByteArray @ 1721 NONAME + _ZTI27QDeclarativePropertyChanges @ 1722 NONAME + _ZTV27QDeclarativePropertyChanges @ 1723 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index c6d9ddb..6696beb 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12093,4 +12093,5 @@ EXPORTS _ZN18QTapAndHoldGesture10setTimeoutEi @ 12092 NONAME _ZN18QTapAndHoldGesture7timeoutEv @ 12093 NONAME _ZN20QGraphicsItemPrivate26childrenBoundingRectHelperEP10QTransformP6QRectFb @ 12094 NONAME + _ZN20QGraphicsItemPrivate14children_clearEP24QDeclarativeListPropertyI15QGraphicsObjectE @ 12095 NONAME diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug2.qml b/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug2.qml new file mode 100644 index 0000000..4ed2815 --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug2.qml @@ -0,0 +1,25 @@ +import Qt 4.7 + +Rectangle { + id: root + width:200; height:300 + + Rectangle { + id: rectangle + objectName: "mover" + color: "green" + width:50; height:50 + } + + states: [ + State { + name: "anchored" + AnchorChanges { + target: rectangle + anchors.left: root.left + anchors.right: root.right + anchors.bottom: root.bottom + } + } + ] +} diff --git a/tests/auto/declarative/qdeclarativestates/data/editProperties.qml b/tests/auto/declarative/qdeclarativestates/data/editProperties.qml new file mode 100644 index 0000000..4cb1ddd --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/editProperties.qml @@ -0,0 +1,34 @@ +import Qt 4.7 +Rectangle { + id: myRectangle + + property color sourceColor: "blue" + width: 400; height: 400 + color: "red" + + Rectangle { + id: rect2 + objectName: "rect2" + width: parent.width + 2 + height: 200 + color: "yellow" + } + + states: [ + State { + name: "blue" + PropertyChanges { + target: rect2 + width:50 + height: 40 + } + }, + State { + name: "green" + PropertyChanges { + target: rect2 + width: myRectangle.width / 2 + height: myRectangle.width / 4 + } + }] +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index 0621602..0d10c10 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -48,6 +48,7 @@ #include <private/qdeclarativepropertychanges_p.h> #include <private/qdeclarativestategroup_p.h> #include <private/qdeclarativeitem_p.h> +#include <private/qdeclarativeproperty_p.h> #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -122,6 +123,7 @@ private slots: void anchorChanges5(); void anchorChangesCrash(); void anchorRewindBug(); + void anchorRewindBug2(); void script(); void restoreEntryValues(); void explicitChanges(); @@ -140,6 +142,7 @@ private slots: void unnamedWhen(); void returnToBase(); void extendsBug(); + void editProperties(); }; void tst_qdeclarativestates::initTestCase() @@ -858,6 +861,32 @@ void tst_qdeclarativestates::anchorRewindBug() delete rect; } +// QTBUG-11834 +void tst_qdeclarativestates::anchorRewindBug2() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorRewindBug2.qml"); + QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(rectComponent.create()); + QVERIFY(rect != 0); + + QDeclarativeRectangle *mover = rect->findChild<QDeclarativeRectangle*>("mover"); + + QVERIFY(mover != 0); + QCOMPARE(mover->y(), qreal(0.0)); + QCOMPARE(mover->width(), qreal(50.0)); + + QDeclarativeItemPrivate::get(rect)->setState("anchored"); + QCOMPARE(mover->y(), qreal(250.0)); + QCOMPARE(mover->width(), qreal(200.0)); + + QDeclarativeItemPrivate::get(rect)->setState(""); + QCOMPARE(mover->y(), qreal(0.0)); + QCOMPARE(mover->width(), qreal(50.0)); + + delete rect; +} + void tst_qdeclarativestates::script() { QDeclarativeEngine engine; @@ -1218,6 +1247,134 @@ void tst_qdeclarativestates::extendsBug() QCOMPARE(greenRect->y(), qreal(100)); } +void tst_qdeclarativestates::editProperties() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, SRCDIR "/data/editProperties.qml"); + QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create()); + QVERIFY(rect != 0); + + QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect); + + QDeclarativeStateGroup *stateGroup = rectPrivate->_states(); + QVERIFY(stateGroup != 0); + qmlExecuteDeferred(stateGroup); + + QDeclarativeState *blueState = stateGroup->findState("blue"); + QVERIFY(blueState != 0); + qmlExecuteDeferred(blueState); + + QDeclarativePropertyChanges *propertyChangesBlue = qobject_cast<QDeclarativePropertyChanges*>(blueState->operationAt(0)); + QVERIFY(propertyChangesBlue != 0); + + QDeclarativeState *greenState = stateGroup->findState("green"); + QVERIFY(greenState != 0); + qmlExecuteDeferred(greenState); + + QDeclarativePropertyChanges *propertyChangesGreen = qobject_cast<QDeclarativePropertyChanges*>(greenState->operationAt(0)); + QVERIFY(propertyChangesGreen != 0); + + QDeclarativeRectangle *childRect = rect->findChild<QDeclarativeRectangle*>("rect2"); + QVERIFY(childRect != 0); + QCOMPARE(childRect->width(), qreal(402)); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QCOMPARE(childRect->height(), qreal(200)); + + rectPrivate->setState("blue"); + QCOMPARE(childRect->width(), qreal(50)); + QCOMPARE(childRect->height(), qreal(40)); + QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QVERIFY(blueState->bindingInRevertList(childRect, "width")); + + + rectPrivate->setState("green"); + QCOMPARE(childRect->width(), qreal(200)); + QCOMPARE(childRect->height(), qreal(100)); + QVERIFY(greenState->bindingInRevertList(childRect, "width")); + + + rectPrivate->setState(""); + + + QCOMPARE(propertyChangesBlue->actions().length(), 2); + QVERIFY(propertyChangesBlue->containsValue("width")); + QVERIFY(!propertyChangesBlue->containsProperty("x")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 50); + QVERIFY(!propertyChangesBlue->value("x").isValid()); + + propertyChangesBlue->changeValue("width", 60); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 60); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + + + propertyChangesBlue->changeExpression("width", "myRectangle.width / 2"); + QVERIFY(!propertyChangesBlue->containsValue("width")); + QVERIFY(propertyChangesBlue->containsExpression("width")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 0); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + + propertyChangesBlue->changeValue("width", 50); + QVERIFY(propertyChangesBlue->containsValue("width")); + QVERIFY(!propertyChangesBlue->containsExpression("width")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 50); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + rectPrivate->setState("blue"); + QCOMPARE(childRect->width(), qreal(50)); + QCOMPARE(childRect->height(), qreal(40)); + + propertyChangesBlue->changeValue("width", 60); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 60); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + QCOMPARE(childRect->width(), qreal(60)); + QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + + propertyChangesBlue->changeExpression("width", "myRectangle.width / 2"); + QVERIFY(!propertyChangesBlue->containsValue("width")); + QVERIFY(propertyChangesBlue->containsExpression("width")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 0); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QCOMPARE(childRect->width(), qreal(200)); + + propertyChangesBlue->changeValue("width", 50); + QCOMPARE(childRect->width(), qreal(50)); + + rectPrivate->setState(""); + QCOMPARE(childRect->width(), qreal(402)); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + + QCOMPARE(propertyChangesGreen->actions().length(), 2); + rectPrivate->setState("green"); + QCOMPARE(childRect->width(), qreal(200)); + QCOMPARE(childRect->height(), qreal(100)); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QVERIFY(greenState->bindingInRevertList(childRect, "width")); + QCOMPARE(propertyChangesGreen->actions().length(), 2); + + + propertyChangesGreen->removeProperty("height"); + QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "height"))); + QCOMPARE(childRect->height(), qreal(200)); + + QVERIFY(greenState->bindingInRevertList(childRect, "width")); + QVERIFY(greenState->containsPropertyInRevertList(childRect, "width")); + propertyChangesGreen->removeProperty("width"); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QCOMPARE(childRect->width(), qreal(402)); + QVERIFY(!greenState->bindingInRevertList(childRect, "width")); + QVERIFY(!greenState->containsPropertyInRevertList(childRect, "width")); + + propertyChangesBlue->removeProperty("width"); + QCOMPARE(childRect->width(), qreal(402)); + + rectPrivate->setState("blue"); + QCOMPARE(childRect->width(), qreal(402)); + QCOMPARE(childRect->height(), qreal(40)); +} + QTEST_MAIN(tst_qdeclarativestates) #include "tst_qdeclarativestates.moc" diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/data/singlerole1.qml b/tests/auto/declarative/qdeclarativevisualdatamodel/data/singlerole1.qml new file mode 100644 index 0000000..7ea74f2 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/data/singlerole1.qml @@ -0,0 +1,11 @@ +import Qt 4.7 + +ListView { + width: 100 + height: 100 + anchors.fill: parent + model: myModel + delegate: Component { + Text { objectName: "name"; text: name } + } +} diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/data/singlerole2.qml b/tests/auto/declarative/qdeclarativevisualdatamodel/data/singlerole2.qml new file mode 100644 index 0000000..6654d6b --- /dev/null +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/data/singlerole2.qml @@ -0,0 +1,11 @@ +import Qt 4.7 + +ListView { + width: 100 + height: 100 + anchors.fill: parent + model: myModel + delegate: Component { + Text { objectName: "name"; text: modelData } + } +} diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp index 95ef4fc..d73a872 100644 --- a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp @@ -75,6 +75,39 @@ static void initStandardTreeModel(QStandardItemModel *model) model->insertRow(2, item); } +class SingleRoleModel : public QAbstractListModel +{ + Q_OBJECT + +public: + SingleRoleModel(QObject *parent = 0) { + QHash<int, QByteArray> roles; + roles.insert(Qt::DisplayRole , "name"); + setRoleNames(roles); + list << "one" << "two" << "three" << "four"; + } + +public slots: + void set(int idx, QString string) { + list[idx] = string; + emit dataChanged(index(idx,0), index(idx,0)); + } + +protected: + int rowCount(const QModelIndex &parent = QModelIndex()) const { + return list.count(); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { + if (role == Qt::DisplayRole) + return list.at(index.row()); + return QVariant(); + } + +private: + QStringList list; +}; + + class tst_qdeclarativevisualdatamodel : public QObject { Q_OBJECT @@ -86,6 +119,7 @@ private slots: void updateLayout(); void childChanged(); void objectListModel(); + void singleRole(); private: QDeclarativeEngine engine; @@ -282,6 +316,54 @@ void tst_qdeclarativevisualdatamodel::objectListModel() QCOMPARE(name->text(), QString("Changed")); } +void tst_qdeclarativevisualdatamodel::singleRole() +{ + { + QDeclarativeView view; + + SingleRoleModel model; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(SRCDIR "/data/singlerole1.qml")); + + QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject()); + QVERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "name", 1); + QCOMPARE(name->text(), QString("two")); + + model.set(1, "Changed"); + QCOMPARE(name->text(), QString("Changed")); + } + { + QDeclarativeView view; + + SingleRoleModel model; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(SRCDIR "/data/singlerole2.qml")); + + QDeclarativeListView *listview = qobject_cast<QDeclarativeListView*>(view.rootObject()); + QVERIFY(listview != 0); + + QDeclarativeItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "name", 1); + QCOMPARE(name->text(), QString("two")); + + model.set(1, "Changed"); + QCOMPARE(name->text(), QString("Changed")); + } +} + template<typename T> T *tst_qdeclarativevisualdatamodel::findItem(QGraphicsObject *parent, const QString &objectName, int index) { diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index b38e80d..c59621a 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -692,12 +692,14 @@ QDeclarativeViewer::~QDeclarativeViewer() void QDeclarativeViewer::enableExperimentalGestures() { +#ifndef QT_NO_GESTURES canvas->viewport()->grabGesture(Qt::TapGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent); canvas->viewport()->grabGesture(Qt::TapAndHoldGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent); canvas->viewport()->grabGesture(Qt::PanGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent); canvas->viewport()->grabGesture(Qt::PinchGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent); canvas->viewport()->grabGesture(Qt::SwipeGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent); canvas->viewport()->setAttribute(Qt::WA_AcceptTouchEvents); +#endif } QDeclarativeView *QDeclarativeViewer::view() const @@ -1067,11 +1069,7 @@ void QDeclarativeViewer::loadDummyDataFiles(const QString& directory) QStringList list = dir.entryList(); for (int i = 0; i < list.size(); ++i) { QString qml = list.at(i); - QFile f(dir.filePath(qml)); - f.open(QIODevice::ReadOnly); - QByteArray data = f.readAll(); - QDeclarativeComponent comp(canvas->engine()); - comp.setData(data, QUrl()); + QDeclarativeComponent comp(canvas->engine(), dir.filePath(qml)); QObject *dummyData = comp.create(); if(comp.isError()) { |